diff --git a/.github/guides/MAPS_AND_AWAY_MISSIONS.md b/.github/guides/MAPS_AND_AWAY_MISSIONS.md
index 41e81d3d64a..5cda5ad88dd 100644
--- a/.github/guides/MAPS_AND_AWAY_MISSIONS.md
+++ b/.github/guides/MAPS_AND_AWAY_MISSIONS.md
@@ -1,17 +1,18 @@
## MAPS
-/tg/station currently has five station maps in rotation.
+/tg/station currently has six station maps in rotation.
+* [Birdshot](https://tgstation13.org/wiki/Birdshot)
* [DeltaStation](https://tgstation13.org/wiki/DeltaStation)
* [IceBoxStation](https://tgstation13.org/wiki/IceboxStation)
-* [KiloStation](https://tgstation13.org/wiki/KiloStation)
* [MetaStation](https://tgstation13.org/wiki/MetaStation)
+* [NorthStar](https://tgstation13.org/wiki/The_North_Star)
* [TramStation](https://tgstation13.org/wiki/Tramstation)
Debug station maps.
* [RuntimeStation](https://tgstation13.org/wiki/RuntimeStation)
* [MultiZ](https://tgstation13.org/wiki/MultiZ)
-All maps have their own code file that is in the base of the `_maps` directory, or elsewhere in the codebase. For example, all of the station maps in rotation each have a corresponding JSON file and are loaded using `maps/_basemap.dm`. Maps are loaded dynamically when the game starts. Follow this guideline when adding your own map, to your fork, for easy compatibility.
+All maps have their own code file that is in the base of the `_maps` directory, or elsewhere in the codebase. For example, all of the station maps in rotation each have a corresponding JSON file and are loaded using the server's [configuration](#configuration) passed onto the Mapping subsystem. Maps are loaded dynamically when the game starts. Follow this guideline when adding your own map, to your fork, for easy compatibility.
The map that will be loaded for the upcoming round is determined by reading `data/next_map.json`, which is a copy of the JSON files found in the `_maps` tree. If this file does not exist, the default map from `config/maps.txt` will be loaded. Failing that, MetaStation will be loaded. If you want to set a specific map to load next round you can use the Change Map verb in game before restarting the server or copy a JSON from `_maps` to `data/next_map.json` before starting the server. Also, for debugging purposes, ticking a corresponding map's code file in Dream Maker will force that map to load every round.
diff --git a/.github/workflows/ci_suite.yml b/.github/workflows/ci_suite.yml
index 3926a3b8108..9cc4698ed66 100644
--- a/.github/workflows/ci_suite.yml
+++ b/.github/workflows/ci_suite.yml
@@ -66,15 +66,7 @@ jobs:
tools/bootstrap/python -m define_sanity.check
tools/bootstrap/python -m dmi.test
tools/bootstrap/python -m mapmerge2.dmm_test
- - name: Output Annotations
- if: success() || failure()
- run: |
- ~/dreamchecker > ${GITHUB_WORKSPACE}/output-annotations.txt 2>&1
- - name: Process Annotations
- uses: yogstation13/DreamAnnotate@v2
- if: success() || failure()
- with:
- outputFile: output-annotations.txt
+ ~/dreamchecker 2>&1 | bash tools/ci/annotate_dm.sh
compile_all_maps:
if: "!contains(github.event.head_commit.message, '[ci skip]')"
diff --git a/.github/workflows/run_integration_tests.yml b/.github/workflows/run_integration_tests.yml
index 22cec5d48bb..0c4ba61a8a4 100644
--- a/.github/workflows/run_integration_tests.yml
+++ b/.github/workflows/run_integration_tests.yml
@@ -63,7 +63,6 @@ jobs:
tools/build/build --ci dm -DCIBUILDING -DANSICOLORS -WError -NWTG0001
- name: Run Tests
run: |
- cp libbyond_sleeping_procs.so ~/.byond/bin/libbyond_sleeping_procs.so
source $HOME/BYOND/byond/bin/byondsetup
bash tools/ci/run_server.sh ${{ inputs.map }}
- name: Upload screenshot tests
diff --git a/.gitignore b/.gitignore
index f8688c913d8..1c74dfcdf37 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,9 +24,6 @@
# Ignore compiled linux libs in the root folder, e.g. librust_g.so
/*.so
-# Remove when removing byond_status
-!/libbyond_sleeping_procs.so
-
#Ignore compiled files and other files generated during compilation.
*.mdme
*.mdme.*
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 d2226a68b2d..5a81999984f 100644
--- a/_maps/RandomRuins/IceRuins/skyrat/icemoon_underground_syndicate_base1_skyrat.dmm
+++ b/_maps/RandomRuins/IceRuins/skyrat/icemoon_underground_syndicate_base1_skyrat.dmm
@@ -1190,10 +1190,6 @@
/obj/machinery/chem_master,
/turf/open/floor/iron,
/area/ruin/syndicate_lava_base/medbay)
-"jc" = (
-/obj/machinery/light/directional/east,
-/turf/open/floor/iron/dark,
-/area/ruin/syndicate_lava_base/bar)
"jf" = (
/obj/effect/turf_decal/vg_decals/department/bar{
dir = 1
@@ -4633,6 +4629,7 @@
dir = 8
},
/obj/machinery/computer/security/telescreen/entertainment/directional/east,
+/obj/machinery/light/directional/east,
/turf/open/floor/iron/dark,
/area/ruin/syndicate_lava_base/bar)
"Pc" = (
@@ -7386,7 +7383,7 @@ MT
dR
NY
OV
-jc
+XT
XT
cZ
xf
diff --git a/_maps/RandomRuins/LavaRuins/bubberstation/lavaland_dauntless.dmm b/_maps/RandomRuins/LavaRuins/bubberstation/lavaland_dauntless.dmm
index 62b06bf30c0..6716ca61c9e 100644
--- a/_maps/RandomRuins/LavaRuins/bubberstation/lavaland_dauntless.dmm
+++ b/_maps/RandomRuins/LavaRuins/bubberstation/lavaland_dauntless.dmm
@@ -5695,7 +5695,7 @@
/turf/open/floor/iron/dark/small,
/area/ruin/space/has_grav/bubbers/dauntless/sec/prison)
"DJ" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/trimline/dark_blue/filled/line{
dir = 4
},
@@ -7184,7 +7184,9 @@
/turf/open/floor/iron/white/textured_large,
/area/ruin/space/has_grav/bubbers/dauntless/med/treatment)
"Ks" = (
-/obj/machinery/recycler,
+/obj/machinery/recycler{
+ dir = 8
+ },
/obj/machinery/conveyor{
id = "syndidisp";
dir = 4
@@ -9286,7 +9288,7 @@
/obj/effect/turf_decal/trimline/dark_blue/filled/line{
dir = 6
},
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/white/diagonal,
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_battle_site.dmm b/_maps/RandomRuins/LavaRuins/lavaland_battle_site.dmm
new file mode 100644
index 00000000000..7dbc17d40f9
--- /dev/null
+++ b/_maps/RandomRuins/LavaRuins/lavaland_battle_site.dmm
@@ -0,0 +1,464 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/closed/mineral/strong/wasteland,
+/area/lavaland/surface/outdoors)
+"f" = (
+/obj/effect/mob_spawn/corpse/human/skeleton,
+/obj/item/clothing/head/costume/crown{
+ pixel_x = 15;
+ pixel_y = 6;
+ desc = "A crown that was fit for a king, looks like it didn't get them very far.";
+ name = "dented crown"
+ },
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"g" = (
+/obj/structure/water_source/puddle,
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"h" = (
+/obj/effect/mob_spawn/corpse/human/skeleton,
+/obj/item/shield/buckler,
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"j" = (
+/turf/template_noop,
+/area/template_noop)
+"m" = (
+/obj/effect/decal/cleanable/shreds,
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"n" = (
+/obj/structure/stone_tile/block/burnt,
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"o" = (
+/obj/structure/stone_tile/burnt{
+ dir = 1
+ },
+/obj/structure/stone_tile/burnt{
+ dir = 8
+ },
+/obj/effect/decal/cleanable/blood/drip,
+/mob/living/basic/mining/goliath,
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"p" = (
+/obj/item/stack/rods{
+ pixel_x = 10
+ },
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"q" = (
+/obj/structure/flora/rock,
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"s" = (
+/mob/living/basic/mining/goliath,
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"t" = (
+/obj/effect/decal/cleanable/blood/gibs/old,
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"u" = (
+/obj/effect/decal/cleanable/blood/old,
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"x" = (
+/obj/effect/decal/cleanable/blood/drip,
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"D" = (
+/obj/structure/statue/bone/rib{
+ name = "colossal tailbone"
+ },
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"F" = (
+/obj/effect/decal/cleanable/blood/drip,
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/obj/structure/statue/bone/rib,
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"G" = (
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"H" = (
+/obj/structure/firepit,
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"I" = (
+/obj/structure/closet/crate/wooden,
+/obj/item/stack/sheet/animalhide/goliath_hide,
+/obj/item/flashlight/flare/torch,
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"J" = (
+/obj/structure/flora/ash/cap_shroom,
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"K" = (
+/obj/structure/closet/crate/wooden,
+/obj/item/stack/sheet/sinew,
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"L" = (
+/obj/effect/decal/cleanable/blood/hitsplatter{
+ dir = 4
+ },
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"M" = (
+/obj/structure/statue/bone/skull,
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"O" = (
+/obj/structure/statue/bone/rib{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"P" = (
+/obj/effect/mob_spawn/corpse/human/skeleton,
+/obj/item/shovel/spade,
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"S" = (
+/obj/structure/chair/wood/wings{
+ color = "#ffff00"
+ },
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"T" = (
+/obj/effect/mob_spawn/corpse/human/skeleton,
+/obj/item/spear/bonespear{
+ pixel_x = 13;
+ pixel_y = 12
+ },
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"U" = (
+/obj/structure/statue/bone/rib,
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"V" = (
+/obj/effect/mob_spawn/corpse/human/skeleton,
+/obj/item/stack/rods{
+ pixel_x = -1;
+ pixel_y = -7
+ },
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"X" = (
+/obj/structure/stone_tile/burnt,
+/obj/structure/stone_tile/burnt{
+ dir = 4
+ },
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"Y" = (
+/obj/effect/mob_spawn/corpse/human/skeleton,
+/obj/item/stack/rods{
+ pixel_y = -12;
+ pixel_x = 2
+ },
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+
+(1,1,1) = {"
+j
+j
+j
+j
+j
+j
+j
+j
+j
+j
+j
+j
+j
+j
+j
+j
+"}
+(2,1,1) = {"
+j
+j
+a
+j
+j
+j
+j
+j
+j
+j
+j
+j
+a
+j
+j
+j
+"}
+(3,1,1) = {"
+j
+a
+a
+a
+j
+j
+J
+G
+G
+G
+j
+j
+a
+a
+a
+j
+"}
+(4,1,1) = {"
+j
+j
+a
+a
+G
+K
+G
+u
+T
+x
+J
+a
+a
+a
+j
+j
+"}
+(5,1,1) = {"
+j
+j
+j
+J
+I
+G
+G
+q
+L
+G
+s
+g
+a
+G
+j
+j
+"}
+(6,1,1) = {"
+j
+j
+j
+G
+s
+x
+x
+G
+x
+G
+x
+G
+G
+D
+j
+j
+"}
+(7,1,1) = {"
+j
+j
+V
+q
+G
+p
+t
+J
+G
+q
+J
+O
+q
+G
+j
+j
+"}
+(8,1,1) = {"
+j
+j
+m
+u
+G
+q
+f
+O
+J
+O
+G
+n
+J
+x
+j
+j
+"}
+(9,1,1) = {"
+j
+j
+G
+x
+G
+M
+S
+n
+o
+n
+X
+F
+u
+G
+j
+j
+"}
+(10,1,1) = {"
+j
+j
+J
+G
+G
+u
+J
+U
+G
+U
+J
+G
+G
+G
+j
+j
+"}
+(11,1,1) = {"
+j
+j
+j
+q
+h
+G
+G
+G
+q
+G
+G
+J
+m
+q
+j
+j
+"}
+(12,1,1) = {"
+j
+j
+j
+G
+G
+x
+H
+x
+G
+G
+q
+Y
+G
+a
+j
+j
+"}
+(13,1,1) = {"
+j
+j
+a
+G
+J
+G
+G
+P
+G
+u
+G
+a
+a
+a
+a
+j
+"}
+(14,1,1) = {"
+j
+a
+a
+a
+j
+j
+G
+G
+q
+G
+j
+j
+a
+a
+j
+j
+"}
+(15,1,1) = {"
+j
+a
+a
+j
+j
+j
+j
+j
+j
+j
+j
+a
+a
+a
+j
+j
+"}
+(16,1,1) = {"
+j
+j
+j
+j
+j
+j
+j
+j
+j
+j
+j
+j
+j
+j
+j
+j
+"}
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm b/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm
index 9fb7d46ce58..127267c24eb 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm
@@ -6,10 +6,6 @@
/obj/machinery/oven/range,
/turf/open/floor/wood,
/area/ruin/powered/beach)
-"ae" = (
-/obj/structure/closet/secure_closet/bar/lavaland_bartender_booze,
-/turf/open/floor/wood,
-/area/ruin/powered/beach)
"aj" = (
/turf/closed/wall/mineral/sandstone,
/area/ruin/powered/beach)
@@ -527,6 +523,11 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer4,
/turf/closed/wall/mineral/sandstone,
/area/ruin/powered/beach)
+"qK" = (
+/obj/structure/closet/secure_closet/bar/lavaland_bartender_clothes,
+/obj/machinery/light/small/directional/east,
+/turf/open/floor/wood,
+/area/ruin/powered/beach)
"qT" = (
/obj/machinery/light/directional/east,
/obj/machinery/atmospherics/components/unary/vent_pump/on{
@@ -947,6 +948,10 @@
/obj/machinery/light/directional/west,
/turf/open/floor/iron/stairs/left,
/area/ruin/powered/beach)
+"HW" = (
+/obj/structure/closet/secure_closet/bar/lavaland_bartender_booze,
+/turf/open/floor/wood,
+/area/ruin/powered/beach)
"Il" = (
/obj/structure/table/wood,
/obj/item/reagent_containers/condiment/saltshaker,
@@ -1178,11 +1183,6 @@
"RE" = (
/turf/closed/wall/mineral/wood/nonmetal,
/area/ruin/powered/beach)
-"RZ" = (
-/obj/structure/closet/secure_closet/bar/lavaland_bartender_clothes,
-/obj/machinery/light/small/directional/east,
-/turf/open/floor/wood,
-/area/ruin/powered/beach)
"Sn" = (
/obj/machinery/door/airlock/maintenance{
name = "Supply Room"
@@ -1277,6 +1277,16 @@
/obj/structure/noticeboard/staff,
/turf/closed/wall/mineral/wood/nonmetal,
/area/ruin/powered/beach)
+"UI" = (
+/obj/structure/closet/cabinet,
+/obj/item/storage/backpack/duffelbag,
+/obj/item/clothing/under/shorts/blue,
+/obj/item/clothing/suit/costume/wellworn_shirt/graphic/ian,
+/obj/item/clothing/shoes/sandal/beach,
+/obj/item/clothing/glasses/sunglasses,
+/obj/item/clothing/neck/beads,
+/turf/open/floor/wood,
+/area/ruin/powered/beach)
"UT" = (
/obj/structure/flora/bush/sparsegrass/style_random,
/turf/open/misc/beach/sand,
@@ -1377,16 +1387,6 @@
/obj/structure/fluff/beach_umbrella/science,
/turf/open/misc/beach/sand,
/area/ruin/powered/beach)
-"XR" = (
-/obj/structure/closet/cabinet,
-/obj/item/storage/backpack/duffelbag,
-/obj/item/clothing/under/shorts/blue,
-/obj/item/clothing/suit/costume/ianshirt,
-/obj/item/clothing/shoes/sandal/beach,
-/obj/item/clothing/glasses/sunglasses,
-/obj/item/clothing/neck/beads,
-/turf/open/floor/wood,
-/area/ruin/powered/beach)
"XW" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
dir = 4
@@ -1514,7 +1514,7 @@ VI
UT
SY
aj
-ae
+HW
aC
aC
Eq
@@ -1546,7 +1546,7 @@ VI
VI
FH
aj
-RZ
+qK
aC
aC
CK
@@ -2206,7 +2206,7 @@ aC
aj
EE
Rk
-XR
+UI
aj
tB
aC
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm b/_maps/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm
index 7ab354935c3..ef650913f14 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm
@@ -671,7 +671,7 @@
/area/ruin/powered/clownplanet)
"RW" = (
/obj/effect/mapping_helpers/no_lava,
-/mob/living/simple_animal/hostile/retaliate/clown,
+/mob/living/basic/clown,
/turf/open/floor/noslip,
/area/ruin/powered/clownplanet)
"Tj" = (
@@ -714,7 +714,7 @@
"YI" = (
/obj/machinery/light/small/directional/south,
/obj/effect/mapping_helpers/no_lava,
-/mob/living/simple_animal/hostile/retaliate/clown,
+/mob/living/basic/clown,
/turf/open/floor/noslip,
/area/ruin/powered/clownplanet)
"Zg" = (
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm
index c3c5ae2a121..4cc31bca411 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm
@@ -1585,7 +1585,7 @@
/area/ruin/syndicate_lava_base/bar)
"mA" = (
/obj/machinery/light/small/directional/west,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/item/reagent_containers/blood/o_minus,
/obj/machinery/firealarm/directional/west,
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1/mistake_feasible.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1/mistake_feasible.dmm
index 2639f59e520..4b4daf0586b 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1/mistake_feasible.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1/mistake_feasible.dmm
@@ -2,18 +2,6 @@
"aa" = (
/turf/template_noop,
/area/template_noop)
-"ab" = (
-/obj/machinery/light/small/directional/south,
-/obj/structure/bed/roller,
-/obj/machinery/iv_drip,
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/decal/cleanable/dirt,
-/mob/living/carbon/human/species/monkey{
- faction = list("neutral","Syndicate")
- },
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron/dark,
-/area/ruin/syndicate_lava_base/testlab)
"ac" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/hatch{
@@ -29,14 +17,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/ruin/syndicate_lava_base/testlab)
-"ad" = (
-/obj/structure/table/reinforced,
-/obj/item/restraints/handcuffs,
-/obj/item/taperecorder,
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron/dark,
-/area/ruin/syndicate_lava_base/testlab)
"ae" = (
/obj/machinery/firealarm/directional/south,
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
@@ -45,19 +25,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/ruin/syndicate_lava_base/testlab)
-"af" = (
-/obj/structure/chair{
- dir = 1
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer4{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron/dark,
-/area/ruin/syndicate_lava_base/testlab)
"ag" = (
/obj/structure/table/reinforced,
/obj/item/restraints/handcuffs,
@@ -79,12 +46,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/ruin/syndicate_lava_base/testlab)
-"aj" = (
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer4{
- dir = 4
- },
-/turf/open/floor/engine,
-/area/ruin/syndicate_lava_base/testlab)
"ak" = (
/obj/structure/table/reinforced,
/obj/effect/decal/cleanable/dirt,
@@ -95,14 +56,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/ruin/syndicate_lava_base/testlab)
-"al" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer4,
-/obj/structure/extinguisher_cabinet/directional/east,
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron/dark,
-/area/ruin/syndicate_lava_base/testlab)
"am" = (
/obj/effect/spawner/structure/window/reinforced/plasma/plastitanium,
/obj/machinery/door/firedoor,
@@ -134,35 +87,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/ruin/syndicate_lava_base/testlab)
-"aq" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
- dir = 10
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer4{
- dir = 10
- },
-/turf/open/floor/engine,
-/area/ruin/syndicate_lava_base/testlab)
-"ar" = (
-/obj/effect/spawner/structure/window/reinforced/plasma/plastitanium,
-/obj/machinery/door/firedoor,
-/obj/machinery/door/poddoor/preopen{
- id = "lavalandsyndi";
- name = "Syndicate Research Experimentation Shutters"
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer4,
-/turf/open/floor/plating,
-/area/ruin/syndicate_lava_base/testlab)
-"as" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer4{
- dir = 4
- },
-/turf/open/floor/engine,
-/area/ruin/syndicate_lava_base/testlab)
"at" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -186,45 +110,8 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/ruin/syndicate_lava_base/testlab)
-"aw" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer4{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/obj/effect/mapping_helpers/airalarm/syndicate_access,
-/obj/machinery/airalarm/directional/south,
-/turf/open/floor/iron/dark,
-/area/ruin/syndicate_lava_base/testlab)
-"ax" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer4{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
- dir = 4
- },
-/turf/open/floor/engine,
-/area/ruin/syndicate_lava_base/testlab)
-"ay" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/machinery/atmospherics/components/unary/vent_pump/on{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer4{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron/dark,
-/area/ruin/syndicate_lava_base/testlab)
-"az" = (
-/obj/machinery/firealarm/directional/south,
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer4{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron/dark,
-/area/ruin/syndicate_lava_base/testlab)
"aA" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/dirt,
@@ -252,12 +139,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/ruin/syndicate_lava_base/testlab)
-"aC" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer4{
- dir = 4
- },
-/turf/open/floor/engine,
-/area/ruin/syndicate_lava_base/testlab)
"aD" = (
/turf/closed/wall/mineral/plastitanium/nodiagonal,
/area/ruin/syndicate_lava_base/testlab)
@@ -274,27 +155,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/ruin/syndicate_lava_base/testlab)
-"aF" = (
-/obj/machinery/door/firedoor,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer4,
-/obj/machinery/door/airlock/hatch{
- name = "Experimentation Lab"
- },
-/obj/effect/mapping_helpers/airlock/access/all/syndicate/general,
-/obj/structure/cable,
-/obj/modular_map_connector,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron/dark,
-/area/ruin/syndicate_lava_base/testlab)
-"aG" = (
-/obj/machinery/light/small/directional/south,
-/obj/structure/table/reinforced,
-/obj/item/storage/box/monkeycubes/syndicate,
-/obj/item/storage/box/monkeycubes/syndicate,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron/dark,
-/area/ruin/syndicate_lava_base/testlab)
"aH" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/engine,
@@ -312,11 +172,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/ruin/syndicate_lava_base/testlab)
-"aK" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer4,
-/turf/open/floor/engine,
-/area/ruin/syndicate_lava_base/testlab)
"aL" = (
/obj/effect/spawner/structure/window/reinforced/plasma/plastitanium,
/turf/open/floor/plating,
@@ -352,16 +207,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/engine,
/area/ruin/syndicate_lava_base/testlab)
-"aR" = (
-/obj/structure/table/reinforced,
-/obj/effect/decal/cleanable/dirt,
-/obj/item/paper_bin,
-/obj/item/pen,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer4,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron/dark,
-/area/ruin/syndicate_lava_base/testlab)
"aS" = (
/obj/machinery/light/small/directional/east,
/turf/open/floor/engine,
@@ -377,20 +222,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/plating,
/area/ruin/syndicate_lava_base/testlab)
-"aU" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
-/turf/open/floor/engine,
-/area/ruin/syndicate_lava_base/testlab)
-"aV" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer4{
- dir = 4
- },
-/obj/machinery/atmospherics/components/unary/vent_pump/on{
- dir = 4
- },
-/turf/open/floor/engine,
-/area/ruin/syndicate_lava_base/testlab)
"aW" = (
/obj/machinery/light/small/directional/north,
/turf/open/floor/engine,
@@ -408,7 +239,7 @@
/turf/open/floor/engine,
/area/ruin/syndicate_lava_base/testlab)
"aZ" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/dirt,
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 720737e7e03..6ae86149550 100644
--- a/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_syndicate_base1_skyrat.dmm
+++ b/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_syndicate_base1_skyrat.dmm
@@ -2275,10 +2275,6 @@
/obj/machinery/chem_dispenser/mutagensaltpeter,
/turf/open/floor/iron/dark/smooth_large,
/area/ruin/syndicate_lava_base/bar)
-"xH" = (
-/obj/machinery/light/directional/east,
-/turf/open/floor/iron/dark,
-/area/ruin/syndicate_lava_base/bar)
"xL" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible,
/turf/open/floor/iron/dark,
@@ -4043,6 +4039,7 @@
dir = 8
},
/obj/machinery/computer/security/telescreen/entertainment/directional/east,
+/obj/machinery/light/directional/east,
/turf/open/floor/iron/dark,
/area/ruin/syndicate_lava_base/bar)
"Oz" = (
@@ -6922,7 +6919,7 @@ WW
QQ
wo
Oy
-xH
+Dk
Dk
QN
ej
diff --git a/_maps/RandomRuins/SpaceRuins/anomaly_research.dmm b/_maps/RandomRuins/SpaceRuins/anomaly_research.dmm
index 50a3ba98cba..e3015469bce 100644
--- a/_maps/RandomRuins/SpaceRuins/anomaly_research.dmm
+++ b/_maps/RandomRuins/SpaceRuins/anomaly_research.dmm
@@ -32,7 +32,7 @@
/obj/effect/spawner/structure/window,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron/white,
+/turf/open/floor/plating,
/area/misc/anomaly_research)
"bP" = (
/obj/structure/table/wood,
@@ -54,10 +54,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/smooth,
/area/misc/anomaly_research)
-"cA" = (
-/obj/effect/spawner/structure/window/reinforced,
-/turf/open/floor/iron/white,
-/area/misc/anomaly_research)
"cD" = (
/obj/effect/turf_decal/stripes/line,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -217,10 +213,6 @@
},
/turf/open/floor/iron/white,
/area/misc/anomaly_research)
-"hh" = (
-/obj/effect/spawner/structure/window/plasma,
-/turf/open/floor/wood,
-/area/misc/anomaly_research)
"hl" = (
/obj/effect/turf_decal/stripes/line{
dir = 6
@@ -268,8 +260,7 @@
/area/misc/anomaly_research)
"ii" = (
/obj/effect/spawner/structure/window/reinforced,
-/obj/effect/spawner/structure/window/reinforced,
-/turf/open/floor/iron/white,
+/turf/open/floor/plating,
/area/misc/anomaly_research)
"ip" = (
/obj/effect/turf_decal/tile/neutral{
@@ -947,7 +938,7 @@
/area/misc/anomaly_research)
"yR" = (
/obj/effect/spawner/structure/window,
-/turf/open/floor/iron/white,
+/turf/open/floor/plating,
/area/misc/anomaly_research)
"yS" = (
/obj/effect/turf_decal/tile/purple/opposingcorners,
@@ -1028,7 +1019,7 @@
/area/misc/anomaly_research)
"Cl" = (
/obj/effect/spawner/structure/window/plasma,
-/turf/open/floor/engine,
+/turf/open/floor/plating,
/area/misc/anomaly_research)
"CI" = (
/turf/open/floor/engine,
@@ -1217,7 +1208,7 @@
"GG" = (
/obj/effect/spawner/structure/window,
/obj/machinery/duct,
-/turf/open/floor/iron/white,
+/turf/open/floor/plating,
/area/misc/anomaly_research)
"GI" = (
/obj/effect/turf_decal/stripes/white/line,
@@ -1308,7 +1299,7 @@
/area/misc/anomaly_research)
"IC" = (
/obj/effect/spawner/structure/window/reinforced/plasma,
-/turf/open/floor/iron/dark/textured,
+/turf/open/floor/plating,
/area/misc/anomaly_research)
"IH" = (
/obj/effect/spawner/random/big_anomaly,
@@ -1658,11 +1649,6 @@
/obj/effect/turf_decal/siding/white,
/turf/open/floor/iron/dark,
/area/misc/anomaly_research)
-"Ss" = (
-/obj/effect/spawner/structure/window/reinforced/plasma,
-/obj/effect/spawner/structure/window/reinforced/plasma,
-/turf/open/floor/iron/dark/textured,
-/area/misc/anomaly_research)
"SQ" = (
/obj/structure/table/reinforced,
/obj/effect/turf_decal/stripes/white/line,
@@ -2176,11 +2162,11 @@ dr
xE
xE
AV
-Ss
-Ss
-Ss
-Ss
-Ss
+IC
+IC
+IC
+IC
+IC
AV
AV
AV
@@ -3312,9 +3298,9 @@ AV
AV
Xo
AV
-cA
-cA
-cA
+ii
+ii
+ii
eW
QP
HT
@@ -3390,7 +3376,7 @@ sF
Gr
mC
nh
-cA
+ii
tG
ZL
Ng
@@ -3428,7 +3414,7 @@ kt
En
dy
Gg
-cA
+ii
Ls
Iw
Ff
@@ -3504,7 +3490,7 @@ uN
vG
lz
ut
-cA
+ii
Cf
sE
tG
@@ -3580,7 +3566,7 @@ bP
FE
PY
CP
-hh
+Cl
xE
xE
xE
@@ -3618,7 +3604,7 @@ UC
LZ
Tt
PY
-hh
+Cl
xE
xE
xE
@@ -3656,7 +3642,7 @@ TF
ev
Tt
tf
-hh
+Cl
xE
xE
xE
diff --git a/_maps/RandomRuins/SpaceRuins/clownplanet.dmm b/_maps/RandomRuins/SpaceRuins/clownplanet.dmm
index b0cc8cc29e2..fa0b50cc443 100644
--- a/_maps/RandomRuins/SpaceRuins/clownplanet.dmm
+++ b/_maps/RandomRuins/SpaceRuins/clownplanet.dmm
@@ -26,7 +26,7 @@
/turf/open/floor/engine,
/area/ruin/space/has_grav/powered/clownplanet)
"ah" = (
-/mob/living/simple_animal/hostile/retaliate/clown/clownhulk/destroyer,
+/mob/living/basic/clown/clownhulk/destroyer,
/turf/open/floor/engine,
/area/ruin/space/has_grav/powered/clownplanet)
"ai" = (
diff --git a/_maps/RandomRuins/SpaceRuins/dangerous_research.dmm b/_maps/RandomRuins/SpaceRuins/dangerous_research.dmm
index 2263b07e6f5..a1b7d571679 100644
--- a/_maps/RandomRuins/SpaceRuins/dangerous_research.dmm
+++ b/_maps/RandomRuins/SpaceRuins/dangerous_research.dmm
@@ -98,7 +98,7 @@
/turf/open/floor/iron/white,
/area/ruin/space/has_grav/dangerous_research/medical)
"aZ" = (
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/structure/table,
/turf/open/floor/plating/rust,
/area/ruin/space/has_grav/dangerous_research/medical)
@@ -2816,7 +2816,7 @@
/area/ruin/space/has_grav/dangerous_research/dorms)
"La" = (
/obj/effect/decal/cleanable/dirt,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/turf/open/floor/iron/white,
/area/ruin/space/has_grav/dangerous_research/lab)
"Lc" = (
diff --git a/_maps/RandomRuins/SpaceRuins/derelict9.dmm b/_maps/RandomRuins/SpaceRuins/derelict9.dmm
new file mode 100644
index 00000000000..2fa948a60fa
--- /dev/null
+++ b/_maps/RandomRuins/SpaceRuins/derelict9.dmm
@@ -0,0 +1,900 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/closed/mineral/random,
+/area/ruin/space)
+"b" = (
+/turf/closed/indestructible/riveted,
+/area/ruin/space/has_grav)
+"c" = (
+/obj/item/storage/toolbox/mechanical/old,
+/obj/structure/rack,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/spawner/random/maintenance/three,
+/turf/open/floor/plating/airless,
+/area/ruin/space)
+"h" = (
+/obj/structure/closet/crate,
+/obj/item/weldingtool,
+/obj/item/clothing/glasses/welding,
+/turf/open/misc/asteroid/airless,
+/area/ruin/space)
+"j" = (
+/obj/structure/closet/crate/secure/loot,
+/turf/open/floor/pod/dark,
+/area/ruin/space/has_grav)
+"l" = (
+/turf/template_noop,
+/area/template_noop)
+"m" = (
+/turf/closed/wall/rock,
+/area/ruin/space)
+"q" = (
+/obj/effect/mob_spawn/corpse/human/pirate/melee/space,
+/obj/effect/decal/cleanable/blood,
+/turf/open/misc/asteroid/airless,
+/area/ruin/space)
+"r" = (
+/obj/effect/decal/cleanable/blood,
+/turf/open/misc/asteroid/airless,
+/area/ruin/space)
+"s" = (
+/obj/effect/mapping_helpers/bombable_wall,
+/turf/closed/indestructible/riveted,
+/area/ruin/space/has_grav)
+"t" = (
+/obj/effect/gibspawner/human/bodypartless,
+/obj/effect/mob_spawn/corpse/human/charredskeleton,
+/turf/open/misc/asteroid/airless,
+/area/ruin/space)
+"u" = (
+/obj/structure/rack,
+/obj/effect/spawner/random/clothing/beret_or_rabbitears,
+/obj/effect/spawner/random/clothing/mafia_outfit,
+/turf/open/floor/pod/dark,
+/area/ruin/space/has_grav)
+"x" = (
+/turf/open/floor/pod,
+/area/ruin/space/has_grav)
+"B" = (
+/obj/structure/rack,
+/obj/effect/spawner/random/clothing/funny_hats,
+/obj/effect/spawner/random/clothing/gloves,
+/turf/open/floor/pod/dark,
+/area/ruin/space/has_grav)
+"C" = (
+/obj/structure/rack,
+/obj/effect/spawner/random/clothing/mafia_outfit,
+/obj/effect/spawner/random/clothing/pirate_or_bandana,
+/turf/open/floor/pod/dark,
+/area/ruin/space/has_grav)
+"E" = (
+/obj/structure/mineral_door/wood,
+/turf/open/misc/asteroid/airless,
+/area/ruin/space)
+"G" = (
+/obj/structure/safe,
+/obj/item/clothing/head/collectable/petehat,
+/turf/open/floor/pod/light,
+/area/ruin/space/has_grav)
+"I" = (
+/obj/machinery/porta_turret/syndicate/pod,
+/turf/closed/wall/r_wall,
+/area/ruin/space)
+"J" = (
+/obj/item/gun/energy/laser/musket,
+/obj/effect/decal/cleanable/blood,
+/turf/open/misc/asteroid/airless,
+/area/ruin/space)
+"K" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating/airless,
+/area/ruin/space)
+"M" = (
+/obj/structure/reagent_dispensers/fueltank,
+/turf/open/misc/asteroid/airless,
+/area/ruin/space)
+"O" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/spawner/random/maintenance,
+/turf/open/floor/plating/airless,
+/area/ruin/space)
+"Q" = (
+/turf/open/floor/pod/light,
+/area/ruin/space/has_grav)
+"S" = (
+/obj/item/flashlight/lantern,
+/turf/open/misc/asteroid/airless,
+/area/ruin/space)
+"T" = (
+/turf/open/misc/asteroid/airless,
+/area/ruin/space)
+"U" = (
+/obj/structure/rack,
+/obj/effect/spawner/random/clothing/kittyears_or_rabbitears,
+/obj/effect/spawner/random/clothing/lizardboots,
+/turf/open/floor/pod/dark,
+/area/ruin/space/has_grav)
+"X" = (
+/obj/structure/rack,
+/obj/effect/spawner/random/clothing/twentyfive_percent_cyborg_mask,
+/obj/effect/spawner/random/clothing/costume,
+/turf/open/floor/pod/dark,
+/area/ruin/space/has_grav)
+"Y" = (
+/obj/machinery/light/dim/directional/north,
+/turf/open/floor/pod,
+/area/ruin/space/has_grav)
+"Z" = (
+/turf/closed/indestructible/fakedoor,
+/area/ruin/space/has_grav)
+
+(1,1,1) = {"
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+a
+a
+a
+l
+l
+l
+l
+"}
+(2,1,1) = {"
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+T
+l
+l
+a
+l
+"}
+(3,1,1) = {"
+l
+l
+l
+l
+l
+l
+l
+a
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+a
+a
+l
+l
+l
+l
+l
+l
+l
+l
+l
+"}
+(4,1,1) = {"
+l
+l
+l
+l
+T
+a
+a
+a
+T
+l
+l
+I
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+T
+l
+l
+l
+l
+l
+l
+l
+l
+l
+a
+"}
+(5,1,1) = {"
+T
+T
+T
+T
+T
+a
+a
+m
+r
+T
+r
+a
+l
+a
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+T
+a
+a
+l
+l
+T
+"}
+(6,1,1) = {"
+l
+T
+T
+a
+a
+a
+a
+T
+q
+T
+m
+a
+a
+a
+a
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+T
+a
+a
+T
+l
+l
+l
+"}
+(7,1,1) = {"
+l
+T
+a
+a
+a
+a
+a
+J
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+l
+l
+l
+l
+l
+l
+l
+l
+l
+a
+a
+T
+l
+l
+l
+"}
+(8,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+O
+m
+a
+a
+a
+a
+a
+T
+T
+T
+T
+l
+l
+l
+a
+r
+l
+l
+l
+l
+"}
+(9,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+T
+T
+K
+K
+T
+O
+a
+a
+a
+a
+T
+T
+T
+T
+T
+l
+l
+l
+l
+l
+l
+l
+"}
+(10,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+b
+b
+b
+s
+b
+b
+r
+T
+T
+K
+a
+a
+a
+a
+T
+T
+T
+l
+l
+l
+l
+l
+l
+T
+T
+"}
+(11,1,1) = {"
+l
+a
+a
+a
+a
+a
+a
+a
+b
+j
+B
+X
+U
+b
+T
+t
+T
+m
+a
+a
+a
+a
+T
+T
+T
+l
+l
+l
+l
+l
+l
+a
+a
+"}
+(12,1,1) = {"
+l
+l
+a
+a
+a
+a
+a
+a
+b
+x
+x
+x
+x
+b
+K
+T
+T
+a
+a
+a
+a
+a
+a
+T
+T
+l
+l
+l
+l
+l
+l
+l
+l
+"}
+(13,1,1) = {"
+l
+T
+T
+a
+a
+a
+a
+a
+b
+Y
+G
+Q
+x
+Z
+K
+K
+r
+a
+a
+a
+a
+a
+a
+T
+T
+l
+l
+l
+l
+l
+l
+l
+l
+"}
+(14,1,1) = {"
+l
+l
+T
+T
+a
+a
+a
+a
+b
+x
+x
+x
+x
+b
+c
+T
+S
+m
+a
+a
+a
+a
+T
+T
+l
+l
+l
+l
+l
+T
+l
+l
+l
+"}
+(15,1,1) = {"
+l
+l
+l
+l
+l
+a
+a
+a
+b
+u
+j
+C
+j
+b
+r
+r
+T
+T
+r
+m
+a
+a
+T
+l
+l
+l
+l
+T
+T
+T
+l
+l
+l
+"}
+(16,1,1) = {"
+l
+l
+l
+l
+a
+a
+a
+a
+b
+b
+b
+b
+b
+b
+K
+r
+m
+a
+r
+E
+T
+T
+T
+l
+l
+T
+T
+T
+T
+T
+a
+l
+l
+"}
+(17,1,1) = {"
+l
+l
+l
+l
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+m
+T
+r
+T
+T
+T
+a
+T
+T
+a
+a
+a
+l
+l
+"}
+(18,1,1) = {"
+l
+l
+l
+l
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+M
+h
+a
+a
+a
+a
+a
+a
+a
+a
+l
+l
+"}
+(19,1,1) = {"
+l
+l
+l
+l
+l
+a
+a
+a
+a
+a
+a
+T
+T
+T
+T
+T
+T
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+T
+l
+"}
+(20,1,1) = {"
+l
+l
+l
+l
+l
+l
+T
+T
+a
+a
+T
+T
+l
+l
+l
+T
+T
+T
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+l
+l
+l
+"}
+(21,1,1) = {"
+l
+l
+l
+l
+l
+l
+l
+l
+T
+T
+T
+l
+l
+l
+l
+l
+l
+T
+T
+a
+a
+a
+a
+a
+a
+a
+a
+T
+T
+T
+l
+l
+l
+"}
+(22,1,1) = {"
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+a
+a
+T
+T
+T
+l
+l
+l
+l
+"}
diff --git a/_maps/RandomRuins/SpaceRuins/hilbertresearchfacility.dmm b/_maps/RandomRuins/SpaceRuins/hilbertresearchfacility.dmm
index f94d2051a42..3d03f4acd18 100644
--- a/_maps/RandomRuins/SpaceRuins/hilbertresearchfacility.dmm
+++ b/_maps/RandomRuins/SpaceRuins/hilbertresearchfacility.dmm
@@ -330,7 +330,7 @@
},
/obj/structure/industrial_lift/tram/purple,
/obj/effect/landmark/tram/platform/hilbert/middle,
-/obj/effect/landmark/tram/nav/hilbert/research,
+/obj/effect/landmark/tram/nav/hilbert,
/turf/open/floor/engine,
/area/ruin/space/has_grav/powered/hilbertresearchfacility)
"iY" = (
diff --git a/_maps/RandomRuins/SpaceRuins/interdyne.dmm b/_maps/RandomRuins/SpaceRuins/interdyne.dmm
index 3ae6031bd71..bd0ba4cc2ff 100644
--- a/_maps/RandomRuins/SpaceRuins/interdyne.dmm
+++ b/_maps/RandomRuins/SpaceRuins/interdyne.dmm
@@ -1020,7 +1020,7 @@
/turf/open/floor/mineral/plastitanium/red,
/area/ruin/space/has_grav/interdyne)
"PD" = (
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/structure/table/reinforced/rglass,
/turf/open/floor/mineral/plastitanium,
/area/ruin/space/has_grav/interdyne)
diff --git a/_maps/RandomRuins/SpaceRuins/oldstation.dmm b/_maps/RandomRuins/SpaceRuins/oldstation.dmm
index 7405b8ef6cd..aa8c1dcf927 100644
--- a/_maps/RandomRuins/SpaceRuins/oldstation.dmm
+++ b/_maps/RandomRuins/SpaceRuins/oldstation.dmm
@@ -831,7 +831,7 @@
/area/ruin/space/ancientstation/delta/ai)
"dD" = (
/obj/effect/decal/cleanable/dirt,
-/obj/item/roller,
+/obj/item/emergency_bed,
/obj/structure/cable,
/obj/effect/turf_decal/tile/blue/half/contrasted{
dir = 4
@@ -1277,6 +1277,7 @@
pixel_x = 3;
pixel_y = 3
},
+/obj/item/autopsy_scanner,
/turf/open/floor/iron/white,
/area/ruin/space/ancientstation/delta/rnd)
"fw" = (
@@ -1524,9 +1525,9 @@
/area/ruin/space/ancientstation/delta/rnd)
"gP" = (
/obj/effect/decal/cleanable/dirt,
-/obj/structure/table,
-/obj/item/tank/internals/anesthetic,
-/obj/item/clothing/mask/breath/medical,
+/obj/machinery/computer/operating/oldstation{
+ dir = 4
+ },
/turf/open/floor/iron/white,
/area/ruin/space/ancientstation/delta/rnd)
"gQ" = (
@@ -4900,14 +4901,6 @@
},
/turf/template_noop,
/area/space/nearstation)
-"zW" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/decal/cleanable/dirt,
-/obj/structure/closet/crate/bin,
-/obj/effect/spawner/random/trash/garbage,
-/obj/effect/spawner/random/trash/garbage,
-/turf/open/floor/iron,
-/area/ruin/space/ancientstation/delta/rnd)
"zX" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/tile/yellow{
@@ -4958,6 +4951,12 @@
},
/turf/open/floor/iron,
/area/ruin/space/ancientstation/charlie/hall)
+"Aj" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/rnd/server/oldstation,
+/turf/open/floor/iron,
+/area/ruin/space/ancientstation/delta/rnd)
"Al" = (
/turf/closed/mineral/iron,
/area/space/nearstation)
@@ -14186,7 +14185,7 @@ kw
Hk
kw
iq
-ze
+Aj
WV
ob
hY
@@ -14384,7 +14383,7 @@ kw
jk
lF
hS
-zW
+ze
WV
ca
SI
diff --git a/_maps/RandomRuins/SpaceRuins/onehalf.dmm b/_maps/RandomRuins/SpaceRuins/onehalf.dmm
index 470a3cde253..0048ccb3976 100644
--- a/_maps/RandomRuins/SpaceRuins/onehalf.dmm
+++ b/_maps/RandomRuins/SpaceRuins/onehalf.dmm
@@ -121,7 +121,7 @@
/turf/open/floor/iron/airless,
/area/ruin/space/has_grav/onehalf/hallway)
"aA" = (
-/obj/item/roller,
+/obj/item/emergency_bed,
/turf/open/floor/iron/white,
/area/ruin/space/has_grav/onehalf/dorms_med)
"aB" = (
diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/cargodiselost.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/cargodiselost.dmm
index 79a80371d07..57d2cafa4df 100644
--- a/_maps/RandomRuins/SpaceRuins/skyrat/cargodiselost.dmm
+++ b/_maps/RandomRuins/SpaceRuins/skyrat/cargodiselost.dmm
@@ -51,6 +51,7 @@
dir = 8
},
/obj/item/kirbyplants/random,
+/obj/machinery/light_switch/directional/west,
/turf/open/floor/iron/dark,
/area/ruin/space/has_grav/cargodise_freighter/bridge)
"aN" = (
@@ -331,6 +332,7 @@
/obj/effect/turf_decal/tile/blue/anticorner/contrasted{
dir = 8
},
+/obj/machinery/light_switch/directional/west,
/turf/open/floor/iron/white,
/area/ruin/space/has_grav/cargodise_freighter/trauma)
"eC" = (
@@ -481,6 +483,7 @@
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 4
},
+/obj/machinery/light_switch/directional/north,
/turf/open/floor/wood/parquet,
/area/ruin/space/has_grav/cargodise_freighter/bridge)
"hr" = (
@@ -673,6 +676,11 @@
/obj/structure/cable,
/turf/open/floor/iron/dark,
/area/ruin/space/has_grav/cargodise_freighter/cargo)
+"kn" = (
+/obj/item/kirbyplants/random,
+/obj/machinery/light_switch/directional/north,
+/turf/open/floor/wood/parquet,
+/area/ruin/space/has_grav/cargodise_freighter/quarters)
"kt" = (
/obj/machinery/seed_extractor,
/turf/open/floor/wood/tile,
@@ -907,6 +915,9 @@
/obj/machinery/airalarm/directional/east,
/obj/effect/mapping_helpers/airalarm/all_access,
/obj/machinery/light/cold/directional/east,
+/obj/structure/closet/crate,
+/obj/item/mod/core/standard,
+/obj/item/mod/core/standard,
/turf/open/floor/iron/smooth,
/area/ruin/space/has_grav/cargodise_freighter/utility)
"oz" = (
@@ -929,6 +940,7 @@
/obj/effect/turf_decal/tile/brown/half/contrasted{
dir = 8
},
+/obj/structure/tank_dispenser/oxygen,
/turf/open/floor/iron/dark,
/area/ruin/space/has_grav/cargodise_freighter/mining)
"oY" = (
@@ -1107,6 +1119,7 @@
/obj/effect/turf_decal/tile/yellow/anticorner/contrasted{
dir = 1
},
+/obj/machinery/light_switch/directional/north,
/turf/open/floor/iron/dark,
/area/ruin/space/has_grav/cargodise_freighter/cargo)
"sJ" = (
@@ -1155,6 +1168,7 @@
/obj/item/circuitboard/machine/rtg/advanced,
/obj/item/folded_navigation_gigabeacon,
/obj/structure/cable,
+/obj/item/circuitboard/computer/powermonitor,
/turf/open/floor/plating,
/area/ruin/space/has_grav/cargodise_freighter/utility)
"ty" = (
@@ -1338,6 +1352,12 @@
amount = 25
},
/obj/item/stack/sheet/mineral/plasma/thirty,
+/obj/item/stack/sheet/plastic/fifty,
+/obj/item/stack/sheet/mineral/silver,
+/obj/item/stack/sheet/mineral/silver,
+/obj/item/stack/sheet/mineral/silver,
+/obj/item/stack/sheet/mineral/silver,
+/obj/item/stack/sheet/mineral/silver,
/turf/open/floor/plating,
/area/ruin/space/has_grav/cargodise_freighter/utility)
"wT" = (
@@ -1384,6 +1404,16 @@
/obj/machinery/light/cold/directional/west,
/turf/open/floor/wood/parquet,
/area/ruin/space/has_grav/cargodise_freighter/kitchen)
+"xy" = (
+/obj/effect/turf_decal/tile/yellow/anticorner{
+ dir = 4
+ },
+/obj/item/kirbyplants/random,
+/obj/machinery/light/directional/east,
+/turf/open/floor/iron/dark/smooth_corner{
+ dir = 8
+ },
+/area/ruin/space/has_grav/cargodise_freighter/primaryhall)
"xC" = (
/obj/structure/bed/double,
/obj/item/bedsheet/qm/double,
@@ -1584,6 +1614,13 @@
},
/turf/open/floor/iron/white,
/area/ruin/space/has_grav/cargodise_freighter/trauma)
+"Au" = (
+/obj/effect/turf_decal/tile/brown/half/contrasted{
+ dir = 8
+ },
+/obj/machinery/light_switch/directional/west,
+/turf/open/floor/iron/dark,
+/area/ruin/space/has_grav/cargodise_freighter/mining)
"Ay" = (
/obj/structure/table/wood,
/obj/item/toy/cards/deck,
@@ -1812,6 +1849,7 @@
"Et" = (
/obj/structure/cable,
/obj/machinery/light/cold/directional/south,
+/obj/machinery/light_switch/directional/west,
/turf/open/floor/plating,
/area/ruin/space/has_grav/cargodise_freighter/utility)
"Ew" = (
@@ -2311,7 +2349,6 @@
/obj/structure/closet/crate/goldcrate,
/obj/item/stack/sheet/mineral/plasma/five,
/obj/item/stack/sheet/plasteel/twenty,
-/obj/item/stack/sheet/plastic/five,
/obj/item/stack/sheet/mineral/diamond,
/obj/effect/spawner/random/entertainment/money_large,
/obj/effect/spawner/random/entertainment/money_large,
@@ -2380,6 +2417,11 @@
/obj/item/clothing/glasses/hud/security/sunglasses/gars/giga,
/turf/open/floor/iron/dark,
/area/ruin/space/has_grav/cargodise_freighter/cargo)
+"Mu" = (
+/obj/structure/cable,
+/obj/structure/reagent_dispensers/fueltank/large,
+/turf/open/floor/plating,
+/area/ruin/space/has_grav/cargodise_freighter/utility)
"ME" = (
/turf/closed/wall/r_wall/syndicate,
/area/ruin/space/has_grav/cargodise_freighter/hydroponics)
@@ -2405,7 +2447,7 @@
/area/ruin/space/has_grav/cargodise_freighter/vault)
"MZ" = (
/obj/structure/extinguisher_cabinet/directional/east,
-/obj/machinery/light/cold/directional/east,
+/obj/structure/sink/kitchen/directional/west,
/turf/open/floor/iron/kitchen,
/area/ruin/space/has_grav/cargodise_freighter/kitchen)
"Ni" = (
@@ -2451,6 +2493,7 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 4
},
+/obj/machinery/light/directional/west,
/turf/open/floor/iron/dark/smooth_half{
dir = 1
},
@@ -2662,7 +2705,7 @@
/obj/item/storage/organbox{
pixel_y = 6
},
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/effect/turf_decal/tile/blue/half/contrasted{
dir = 8
},
@@ -2830,6 +2873,7 @@
/area/ruin/space/has_grav/cargodise_freighter/primaryhall)
"UD" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden,
+/obj/structure/reagent_dispensers/watertank/high,
/turf/open/floor/wood/tile,
/area/ruin/space/has_grav/cargodise_freighter/hydroponics)
"UH" = (
@@ -2887,6 +2931,7 @@
dir = 4
},
/mob/living/simple_animal/hostile/looter,
+/obj/machinery/light_switch/directional/east,
/turf/open/floor/iron/dark/smooth_half{
dir = 1
},
@@ -2991,6 +3036,7 @@
id = "freighterkitchen";
name = "Kitchen Shutters"
},
+/obj/machinery/light/directional/south,
/turf/open/floor/iron/kitchen,
/area/ruin/space/has_grav/cargodise_freighter/kitchen)
"WE" = (
@@ -3210,6 +3256,7 @@
/obj/effect/turf_decal/tile/yellow/anticorner{
dir = 8
},
+/obj/machinery/light/directional/west,
/turf/open/floor/iron/dark/smooth_corner{
dir = 4
},
@@ -3224,6 +3271,7 @@
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 8
},
+/obj/machinery/light_switch/directional/north,
/turf/open/floor/iron/dark,
/area/ruin/space/has_grav/cargodise_freighter/kitchen)
"Zz" = (
@@ -3615,7 +3663,7 @@ SZ
VL
Ai
is
-hM
+Mu
NE
Ar
QU
@@ -4398,7 +4446,7 @@ sc
Sd
pp
cd
-oV
+Au
oV
tY
Hv
@@ -4840,7 +4888,7 @@ vh
Jy
vh
vh
-Zz
+xy
PW
tV
gm
@@ -5215,7 +5263,7 @@ Do
tN
aK
kX
-Kt
+kn
qG
St
kz
diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/interdynefob.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/interdynefob.dmm
index dcc29862a51..e12bdf68d11 100644
--- a/_maps/RandomRuins/SpaceRuins/skyrat/interdynefob.dmm
+++ b/_maps/RandomRuins/SpaceRuins/skyrat/interdynefob.dmm
@@ -1132,8 +1132,14 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/structure/cable,
/obj/structure/table,
-/obj/item/stack/sheet/mineral/plastitanium,
-/obj/item/stack/sheet/plastitaniumglass,
+/obj/item/stack/sheet/plasteel/twenty{
+ pixel_x = -2
+ },
+/obj/item/stack/sheet/mineral/titanium/fifty{
+ amount = 20;
+ pixel_x = 6;
+ pixel_y = 4
+ },
/turf/open/floor/iron/dark/textured_large,
/area/ruin/space/has_grav/skyrat/interdynefob/engineering)
"eO" = (
@@ -1994,7 +2000,7 @@
pixel_x = 10;
pixel_y = -9
},
-/obj/item/reagent_containers/condiment/quality_oil{
+/obj/item/reagent_containers/condiment/olive_oil{
pixel_x = 3;
pixel_y = -2
},
@@ -4563,14 +4569,15 @@
/obj/effect/turf_decal/siding/dark,
/obj/machinery/light/cold/directional/west,
/obj/item/seeds/tobacco,
+/obj/effect/turf_decal/siding/dark/corner{
+ dir = 1
+ },
+/obj/item/seeds/korta_nut,
/obj/item/reagent_containers/cup/watering_can,
/obj/item/cultivator,
/obj/item/plant_analyzer,
/obj/item/secateurs,
/obj/item/shovel/spade,
-/obj/effect/turf_decal/siding/dark/corner{
- dir = 1
- },
/turf/open/floor/iron/dark/small,
/area/ruin/space/has_grav/skyrat/interdynefob/security/prison)
"tT" = (
@@ -9302,7 +9309,7 @@
dir = 1
},
/obj/machinery/light/cold/directional/west,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/turf/open/floor/iron/white/diagonal,
/area/ruin/space/has_grav/skyrat/interdynefob/medbay)
"Ra" = (
@@ -10598,7 +10605,9 @@
},
/area/ruin/space/has_grav/skyrat/interdynefob/service/diner)
"Wt" = (
-/obj/structure/bed,
+/obj/structure/bed/medical{
+ dir = 4
+ },
/obj/item/bedsheet/medical,
/turf/open/floor/iron/white/small,
/area/ruin/space/has_grav/skyrat/interdynefob/medbay)
@@ -11224,7 +11233,9 @@
/area/ruin/space/has_grav/skyrat/interdynefob/bridge/admiral)
"Zs" = (
/obj/item/bedsheet/medical,
-/obj/structure/bed,
+/obj/structure/bed/medical{
+ dir = 4
+ },
/turf/open/floor/iron/white/small,
/area/ruin/space/has_grav/skyrat/interdynefob/medbay)
"Zt" = (
diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/piratefort.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/piratefort.dmm
index ef9ab04ab16..da0c9652a5e 100644
--- a/_maps/RandomRuins/SpaceRuins/skyrat/piratefort.dmm
+++ b/_maps/RandomRuins/SpaceRuins/skyrat/piratefort.dmm
@@ -501,8 +501,8 @@
/area/ruin/space/has_grav/powered)
"ru" = (
/obj/structure/closet/secure_closet/freezer/fridge/all_access,
-/obj/item/reagent_containers/condiment/quality_oil,
-/obj/item/reagent_containers/condiment/quality_oil,
+/obj/item/reagent_containers/condiment/olive_oil,
+/obj/item/reagent_containers/condiment/olive_oil,
/turf/open/floor/iron/kitchen,
/area/ruin/space/has_grav/powered)
"rA" = (
@@ -629,7 +629,7 @@
/turf/open/floor/iron/dark,
/area/ruin/space/has_grav/powered)
"vU" = (
-/mob/living/simple_animal/hostile/mining_drone{
+/mob/living/basic/mining_drone{
faction = list("pirate")
},
/obj/effect/turf_decal/bot,
diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon2.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon2.dmm
index 256ea411142..1897f962201 100644
--- a/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon2.dmm
+++ b/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon2.dmm
@@ -144,7 +144,7 @@
dir = 8
},
/obj/structure/table/rolling,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/item/clothing/gloves/latex{
pixel_y = 10
},
@@ -7102,7 +7102,7 @@
dir = 4
},
/obj/structure/table/rolling,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/item/clothing/gloves/latex{
pixel_y = 10
},
@@ -8696,8 +8696,8 @@
/turf/open/floor/iron,
/area/ruin/space/has_grav/port_tarkon/centerhall)
"WM" = (
-/obj/machinery/oven,
/obj/machinery/light/small/directional/east,
+/obj/machinery/oven/range,
/turf/open/floor/iron/cafeteria,
/area/ruin/space/has_grav/port_tarkon/kitchen)
"WO" = (
diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon3.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon3.dmm
index 4d834c7bb9b..ae5484c9891 100644
--- a/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon3.dmm
+++ b/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon3.dmm
@@ -118,7 +118,7 @@
dir = 8
},
/obj/structure/table/rolling,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/effect/decal/cleanable/dirt,
/obj/item/clothing/gloves/latex{
pixel_y = 10
@@ -6734,7 +6734,7 @@
dir = 4
},
/obj/structure/table/rolling,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/effect/decal/cleanable/dirt,
/obj/item/clothing/gloves/latex{
pixel_y = 10
@@ -8259,9 +8259,9 @@
/turf/open/misc/asteroid,
/area/ruin/space/has_grav)
"WM" = (
-/obj/machinery/oven,
/obj/effect/decal/cleanable/dirt,
/obj/machinery/light/small/directional/east,
+/obj/machinery/oven/range,
/turf/open/floor/iron/cafeteria,
/area/ruin/space/has_grav/port_tarkon/kitchen)
"WO" = (
diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon4.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon4.dmm
index 2ca2d452e9d..6e42ed738cd 100644
--- a/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon4.dmm
+++ b/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon4.dmm
@@ -98,7 +98,7 @@
dir = 8
},
/obj/structure/table/rolling,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/item/clothing/gloves/latex{
pixel_y = 10
},
@@ -5903,7 +5903,7 @@
dir = 4
},
/obj/structure/table/rolling,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/item/clothing/gloves/latex{
pixel_y = 10
},
@@ -7328,8 +7328,8 @@
/turf/open/floor/iron/airless,
/area/ruin/space/has_grav/port_tarkon/forehall)
"WM" = (
-/obj/machinery/oven,
/obj/machinery/light/small/directional/east,
+/obj/machinery/oven/range,
/turf/open/floor/iron/cafeteria,
/area/ruin/space/has_grav/port_tarkon/kitchen)
"WO" = (
diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon5.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon5.dmm
index 45f045e745a..eef26fbf6d9 100644
--- a/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon5.dmm
+++ b/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon5.dmm
@@ -114,7 +114,7 @@
dir = 8
},
/obj/structure/table/rolling,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/item/clothing/gloves/latex{
pixel_y = 10
},
@@ -6448,7 +6448,7 @@
dir = 4
},
/obj/structure/table/rolling,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/item/clothing/gloves/latex{
pixel_y = 10
},
@@ -8041,8 +8041,8 @@
/turf/open/floor/iron,
/area/ruin/space/has_grav/port_tarkon)
"WM" = (
-/obj/machinery/oven,
/obj/machinery/light/small/directional/east,
+/obj/machinery/oven/range,
/turf/open/floor/iron/cafeteria,
/area/ruin/space/has_grav/port_tarkon/kitchen)
"WO" = (
diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/scrapheap.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/scrapheap.dmm
index 3e18590cb99..3f65766b5af 100644
--- a/_maps/RandomRuins/SpaceRuins/skyrat/scrapheap.dmm
+++ b/_maps/RandomRuins/SpaceRuins/skyrat/scrapheap.dmm
@@ -431,7 +431,7 @@
/turf/open/floor/iron,
/area/ruin/space/has_grav/powered/skyrat/scrapheap)
"lN" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 5
},
@@ -562,7 +562,9 @@
/turf/open/floor/carpet/lone,
/area/ruin/space/has_grav/powered/skyrat/scrapheap)
"pQ" = (
-/obj/structure/bed,
+/obj/structure/bed/medical{
+ dir = 4
+ },
/obj/item/bedsheet/random,
/obj/machinery/door/window{
dir = 8
@@ -785,7 +787,9 @@
/turf/open/floor/iron/dark,
/area/ruin/space/has_grav/powered/skyrat/scrapheap)
"vG" = (
-/obj/structure/bed,
+/obj/structure/bed/medical{
+ dir = 4
+ },
/obj/item/bedsheet/random,
/obj/machinery/door/window{
dir = 8
@@ -870,7 +874,9 @@
/area/ruin/space/has_grav/powered/skyrat/scrapheap)
"yl" = (
/obj/machinery/light/red/directional/east,
-/obj/structure/bed,
+/obj/structure/bed/medical{
+ dir = 4
+ },
/obj/item/bedsheet/random,
/obj/machinery/door/window{
dir = 8
@@ -1005,7 +1011,7 @@
/turf/open/floor/iron/white/textured_large,
/area/ruin/space/has_grav/powered/skyrat/scrapheap)
"Cg" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 1
},
@@ -1119,7 +1125,7 @@
/area/ruin/space/has_grav/powered/skyrat/scrapheap)
"Ej" = (
/obj/structure/rack/shelf,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/turf/open/floor/iron/white,
/area/ruin/space/has_grav/powered/skyrat/scrapheap)
"El" = (
@@ -1630,7 +1636,9 @@
/turf/open/floor/iron,
/area/ruin/space/has_grav/powered/skyrat/scrapheap)
"PJ" = (
-/obj/structure/bed,
+/obj/structure/bed/medical{
+ dir = 4
+ },
/obj/item/bedsheet/random,
/obj/machinery/door/window{
dir = 8
@@ -1833,7 +1841,9 @@
/turf/open/floor/wood/tile,
/area/ruin/space/has_grav/powered/skyrat/scrapheap)
"Vo" = (
-/obj/structure/bed,
+/obj/structure/bed/medical{
+ dir = 4
+ },
/obj/item/bedsheet/random,
/obj/machinery/door/window{
dir = 8
diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/wreckedhomestead.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/wreckedhomestead.dmm
index 8bc3f3fed9b..3524b7a08a3 100644
--- a/_maps/RandomRuins/SpaceRuins/skyrat/wreckedhomestead.dmm
+++ b/_maps/RandomRuins/SpaceRuins/skyrat/wreckedhomestead.dmm
@@ -76,7 +76,7 @@
/area/ruin/unpowered)
"mP" = (
/obj/structure/table/reinforced,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/item/reagent_containers/cup/beaker/cryoxadone,
/obj/machinery/atmospherics/pipe/smart/simple/scrubbers/hidden{
dir = 5
diff --git a/_maps/RandomRuins/SpaceRuins/spacehotel_skyrat.dmm b/_maps/RandomRuins/SpaceRuins/spacehotel_skyrat.dmm
index 8bda7e70f3a..43334c57b9b 100644
--- a/_maps/RandomRuins/SpaceRuins/spacehotel_skyrat.dmm
+++ b/_maps/RandomRuins/SpaceRuins/spacehotel_skyrat.dmm
@@ -6958,7 +6958,7 @@
/area/ruin/space/has_grav/hotel)
"Ps" = (
/obj/structure/table,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/turf/open/floor/iron/showroomfloor,
/area/ruin/space/has_grav/hotel)
"Pw" = (
@@ -7370,10 +7370,10 @@
/turf/open/floor/carpet/neon/simple/black/nodots,
/area/ruin/space/has_grav/hotel/guestroom/room_1)
"Sb" = (
-/obj/machinery/oven,
/obj/effect/turf_decal/siding/dark_green{
dir = 1
},
+/obj/machinery/oven/range,
/turf/open/floor/iron/cafeteria,
/area/ruin/space/has_grav/hotel/bar)
"Se" = (
@@ -7837,7 +7837,9 @@
dir = 4;
id = "garbage"
},
-/obj/machinery/recycler,
+/obj/machinery/recycler{
+ dir = 8
+ },
/turf/open/floor/plating,
/area/ruin/space/has_grav/hotel/workroom)
"VQ" = (
diff --git a/_maps/RandomRuins/SpaceRuins/the_faceoff.dmm b/_maps/RandomRuins/SpaceRuins/the_faceoff.dmm
index 08f2fe4d8f4..2560cefa8a1 100644
--- a/_maps/RandomRuins/SpaceRuins/the_faceoff.dmm
+++ b/_maps/RandomRuins/SpaceRuins/the_faceoff.dmm
@@ -735,7 +735,7 @@
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/stripes/full,
-/mob/living/simple_animal/hostile/mining_drone,
+/mob/living/basic/mining_drone,
/obj/item/grenade/c4,
/turf/open/misc/asteroid/basalt/airless,
/area/ruin/space)
diff --git a/_maps/RandomRuins/SpaceRuins/the_outlet.dmm b/_maps/RandomRuins/SpaceRuins/the_outlet.dmm
index 1ed37f9df00..6b0f009dcc6 100644
--- a/_maps/RandomRuins/SpaceRuins/the_outlet.dmm
+++ b/_maps/RandomRuins/SpaceRuins/the_outlet.dmm
@@ -704,7 +704,7 @@
/area/ruin/space/has_grav/the_outlet/employeesection)
"rF" = (
/obj/structure/table/reinforced/rglass,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/item/reagent_containers/syringe/lethal/execution,
/turf/open/floor/iron/freezer,
/area/ruin/space/has_grav/the_outlet/researchrooms)
diff --git a/_maps/RandomRuins/SpaceRuins/whiteshipruin_box.dmm b/_maps/RandomRuins/SpaceRuins/whiteshipruin_box.dmm
index 76181cecd81..602aa1a273b 100644
--- a/_maps/RandomRuins/SpaceRuins/whiteshipruin_box.dmm
+++ b/_maps/RandomRuins/SpaceRuins/whiteshipruin_box.dmm
@@ -492,7 +492,7 @@
/turf/open/misc/asteroid/airless,
/area/ruin/space/has_grav/whiteship/box)
"nz" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/mineral/titanium/white/airless,
/area/ruin/space/has_grav/whiteship/box)
@@ -515,7 +515,7 @@
/turf/open/floor/carpet,
/area/ruin/space/has_grav/whiteship/box)
"oe" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/siding/yellow{
dir = 6
},
diff --git a/_maps/RandomRuins/SpaceRuins/whiteshipruin_box_skyrat.dmm b/_maps/RandomRuins/SpaceRuins/whiteshipruin_box_skyrat.dmm
index bcd73158470..c6de835f18a 100644
--- a/_maps/RandomRuins/SpaceRuins/whiteshipruin_box_skyrat.dmm
+++ b/_maps/RandomRuins/SpaceRuins/whiteshipruin_box_skyrat.dmm
@@ -505,7 +505,7 @@
/turf/open/floor/iron/shuttle/cargo,
/area/ruin/space/has_grav/whiteship/box)
"nz" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/mineral/titanium/white/airless,
/area/ruin/space/has_grav/whiteship/box)
@@ -528,7 +528,7 @@
/turf/open/floor/carpet,
/area/ruin/space/has_grav/whiteship/box)
"oe" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/siding/yellow{
dir = 6
},
diff --git a/_maps/RandomZLevels/blackmesa.dmm b/_maps/RandomZLevels/blackmesa.dmm
index 07f0283bb95..b9887279a16 100644
--- a/_maps/RandomZLevels/blackmesa.dmm
+++ b/_maps/RandomZLevels/blackmesa.dmm
@@ -7289,7 +7289,7 @@
/turf/open/floor/iron/dark/textured_large,
/area/awaymission/black_mesa/black_ops_bus)
"hhL" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/structure/curtain,
/turf/open/floor/iron/white,
/area/awaymission/black_mesa/hecu_zone_camp)
@@ -7444,12 +7444,12 @@
/turf/open/floor/iron/smooth_large,
/area/awaymission/black_mesa/high_security_surgery)
"hzh" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/structure/curtain,
/turf/open/floor/iron/textured_large,
/area/awaymission/black_mesa/hecu_zone_infirmary)
"hzj" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/structure/curtain,
/obj/effect/mob_spawn/corpse/human/scientist_zombie,
/turf/open/floor/iron/smooth_large,
@@ -7852,7 +7852,7 @@
/area/awaymission/black_mesa/employee_dorm_room)
"iqd" = (
/obj/machinery/light/cold/directional/west,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/structure/curtain,
/turf/open/floor/iron/smooth_large,
/area/awaymission/black_mesa/deep_sci_medbay)
@@ -7939,7 +7939,7 @@
/turf/open/floor/iron/smooth_large,
/area/awaymission/black_mesa/entrance_internal_hall)
"ixj" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/structure/curtain,
/obj/effect/mob_spawn/corpse/human/scientist_zombie,
/turf/open/floor/iron/textured_half,
@@ -8311,7 +8311,7 @@
/turf/open/floor/plating/cobblestone,
/area/awaymission/black_mesa/hecu_zone_camp)
"jfP" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/structure/curtain,
/turf/open/floor/iron/textured_half,
/area/awaymission/black_mesa/hecu_zone_infirmary)
@@ -13175,7 +13175,7 @@
/turf/open/floor/iron/dark,
/area/awaymission/black_mesa/xen/acid_lake)
"syy" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/structure/curtain,
/obj/effect/mob_spawn/corpse/human/engineer,
/turf/open/floor/iron/smooth_large,
@@ -14741,7 +14741,7 @@
/area/awaymission/black_mesa/resonant_chamber)
"vEa" = (
/obj/structure/table,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/turf/open/floor/iron/smooth_large,
/area/awaymission/black_mesa/deep_sci_medbay)
"vEe" = (
@@ -15697,7 +15697,7 @@
/turf/open/floor/iron/textured_half,
/area/awaymission/black_mesa/hecu_zone_infirmary)
"xnW" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/structure/curtain,
/turf/open/floor/iron/smooth_large,
/area/awaymission/black_mesa/deep_sci_medbay)
@@ -15753,7 +15753,7 @@
/turf/open/floor/iron/dark/textured_large,
/area/awaymission/black_mesa/black_ops_bus)
"xww" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/structure/curtain,
/obj/effect/mob_spawn/corpse/human/scientist_zombie,
/turf/open/floor/iron/textured_large,
diff --git a/_maps/RandomZLevels/caves.dmm b/_maps/RandomZLevels/caves.dmm
index 697b0f4feef..a1e4de62b48 100644
--- a/_maps/RandomZLevels/caves.dmm
+++ b/_maps/RandomZLevels/caves.dmm
@@ -1206,7 +1206,7 @@
"he" = (
/obj/structure/window/spawner/directional/west,
/obj/structure/window/spawner/directional/south,
-/mob/living/simple_animal/hostile/mining_drone,
+/mob/living/basic/mining_drone,
/turf/open/floor/plating,
/area/awaymission/caves/listeningpost)
"hq" = (
@@ -1728,7 +1728,7 @@
/area/awaymission/caves/bmp_asteroid/level_three)
"IH" = (
/obj/structure/window/spawner/directional/west,
-/mob/living/simple_animal/hostile/mining_drone,
+/mob/living/basic/mining_drone,
/turf/open/floor/plating,
/area/awaymission/caves/listeningpost)
"IN" = (
diff --git a/_maps/RandomZLevels/snowdin.dmm b/_maps/RandomZLevels/snowdin.dmm
index e464f86bc22..a643bde9e4c 100644
--- a/_maps/RandomZLevels/snowdin.dmm
+++ b/_maps/RandomZLevels/snowdin.dmm
@@ -8927,7 +8927,7 @@
/turf/open/floor/iron/dark,
/area/awaymission/snowdin/cave)
"EK" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/tile/neutral/half/contrasted{
dir = 4
},
diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm
index 748aa80de1d..21b1cddf818 100644
--- a/_maps/map_files/Birdshot/birdshot.dmm
+++ b/_maps/map_files/Birdshot/birdshot.dmm
@@ -916,6 +916,16 @@
/obj/machinery/door/firedoor,
/turf/open/floor/iron/textured_half,
/area/station/service/cafeteria)
+"asZ" = (
+/obj/structure/disposalpipe/trunk,
+/obj/structure/disposaloutlet{
+ dir = 1
+ },
+/obj/structure/window/reinforced/spawner/directional/south,
+/obj/structure/window/reinforced/spawner/directional/east,
+/obj/effect/turf_decal/stripes/box,
+/turf/open/floor/plating,
+/area/station/service/janitor)
"ata" = (
/obj/structure/flora/bush/flowers_yw/style_random,
/obj/machinery/light/small/directional/west,
@@ -1128,10 +1138,8 @@
/obj/effect/turf_decal/trimline/blue/filled/corner{
dir = 8
},
-/obj/structure/bed/pod{
- desc = "An old medical bed, just waiting for replacement with something up to date.";
- dir = 4;
- name = "medical bed"
+/obj/structure/bed/medical{
+ dir = 8
},
/obj/machinery/iv_drip,
/obj/effect/turf_decal/trimline/blue/corner{
@@ -1359,6 +1367,7 @@
/area/station/engineering/storage/tech)
"aCM" = (
/obj/effect/spawner/random/structure/crate_abandoned,
+/obj/structure/alien/weeds,
/turf/open/misc/asteroid,
/area/station/maintenance/starboard/greater)
"aCO" = (
@@ -1684,7 +1693,6 @@
dir = 4
},
/obj/effect/mapping_helpers/airlock/access/any/science/maintenance,
-/obj/effect/mapping_helpers/airlock/access/any/science/maintenance,
/obj/effect/mapping_helpers/airlock/unres{
dir = 4
},
@@ -2526,6 +2534,7 @@
pixel_x = -8;
pixel_y = 6
},
+/obj/structure/alien/weeds,
/turf/open/misc/asteroid,
/area/station/maintenance/starboard/greater)
"baW" = (
@@ -3140,6 +3149,12 @@
/obj/effect/mapping_helpers/airlock/access/any/medical/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/central)
+"bnr" = (
+/obj/structure/cable,
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/alien/weeds,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/greater)
"bnz" = (
/obj/machinery/light_switch/directional/south,
/obj/structure/cable,
@@ -3195,19 +3210,11 @@
/turf/open/floor/iron/white,
/area/station/science/robotics/augments)
"boX" = (
-/obj/structure/table,
-/obj/item/clothing/gloves/color/orange{
- pixel_x = 4;
- pixel_y = -2
+/obj/machinery/conveyor{
+ dir = 4;
+ id = "garbage"
},
-/obj/item/stack/tile/iron/base{
- pixel_y = 18
- },
-/obj/item/key/janitor{
- pixel_x = -3;
- pixel_y = 6
- },
-/turf/open/floor/iron/white/small,
+/turf/open/floor/plating,
/area/station/service/janitor)
"boY" = (
/obj/machinery/atmospherics/pipe/smart/simple/purple/visible,
@@ -3317,6 +3324,13 @@
/obj/structure/grille,
/turf/open/floor/plating,
/area/station/hallway/primary/port)
+"brz" = (
+/obj/effect/turf_decal/sand/plating,
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/alien/weeds,
+/obj/vehicle/ridden/scooter/skateboard/hoverboard,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/greater)
"brD" = (
/obj/machinery/airalarm/directional/west,
/obj/effect/turf_decal/tile/neutral{
@@ -3695,6 +3709,14 @@
/obj/effect/turf_decal/stripes/asteroid/end,
/turf/open/floor/circuit/green,
/area/station/science/robotics/mechbay)
+"byU" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/alien/egg/fake,
+/obj/structure/alien/weeds,
+/obj/effect/gibspawner,
+/turf/open/floor/wood,
+/area/station/maintenance/starboard/greater)
"byV" = (
/obj/effect/turf_decal/tile/yellow/opposingcorners,
/obj/item/radio/intercom/directional/west,
@@ -3709,9 +3731,11 @@
"bzn" = (
/obj/structure/cable,
/obj/effect/turf_decal/tile/yellow/opposingcorners,
-/obj/item/stack/sheet/plasteel/fifty,
/obj/machinery/firealarm/directional/east,
/obj/structure/rack,
+/obj/item/mod/module/plasma_stabilizer,
+/obj/item/mod/module/signlang_radio,
+/obj/item/mod/module/thermal_regulator,
/turf/open/floor/iron,
/area/station/engineering/atmospherics_engine)
"bzs" = (
@@ -3977,6 +4001,7 @@
"bDq" = (
/obj/structure/table,
/obj/item/shovel,
+/obj/structure/alien/weeds,
/turf/open/misc/asteroid,
/area/station/maintenance/starboard/greater)
"bDr" = (
@@ -4478,6 +4503,7 @@
/obj/structure/cable,
/obj/structure/broken_flooring/pile/directional/east,
/obj/effect/decal/cleanable/dirt,
+/obj/structure/alien/weeds,
/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"bNQ" = (
@@ -4628,6 +4654,11 @@
/obj/effect/spawner/random/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
+"bRm" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/alien/weeds,
+/turf/open/floor/wood,
+/area/station/maintenance/starboard/greater)
"bRo" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -4713,6 +4744,14 @@
/obj/structure/table/reinforced/titaniumglass,
/obj/effect/turf_decal/tile/yellow/opposingcorners,
/obj/item/hfr_box/core,
+/obj/item/hfr_box/corner,
+/obj/item/hfr_box/corner,
+/obj/item/hfr_box/corner,
+/obj/item/hfr_box/corner,
+/obj/item/hfr_box/body/waste_output,
+/obj/item/hfr_box/body/moderator_input,
+/obj/item/hfr_box/body/interface,
+/obj/item/hfr_box/body/fuel_input,
/turf/open/floor/iron,
/area/station/engineering/atmospherics_engine)
"bTv" = (
@@ -5328,7 +5367,7 @@
/area/station/maintenance/central/greater)
"ceK" = (
/obj/effect/turf_decal/tile/neutral/fourcorners,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/turf/open/floor/iron/dark,
/area/station/medical/medbay/central)
"ceZ" = (
@@ -5458,6 +5497,14 @@
},
/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,
@@ -5896,6 +5943,16 @@
/obj/machinery/air_sensor/incinerator_tank,
/turf/open/floor/engine,
/area/station/maintenance/disposal/incinerator)
+"cqS" = (
+/obj/machinery/conveyor{
+ dir = 4;
+ id = "garbage"
+ },
+/obj/effect/spawner/random/trash/garbage{
+ spawn_loot_count = 3
+ },
+/turf/open/floor/plating,
+/area/station/service/janitor)
"crm" = (
/obj/machinery/atmospherics/pipe/smart/simple/dark/visible{
dir = 4
@@ -6037,7 +6094,7 @@
/turf/open/floor/plating/rust,
/area/station/maintenance/department/engine/atmos)
"cvy" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/turf/open/floor/iron/dark,
/area/station/medical/medbay/lobby)
"cvH" = (
@@ -7639,7 +7696,11 @@
/obj/item/reagent_containers/cup/bucket,
/obj/item/mop,
/obj/structure/sink/kitchen/directional/east,
-/obj/machinery/airalarm/directional/west,
+/obj/machinery/airalarm/directional/south,
+/obj/machinery/button/door/directional/west{
+ pixel_y = 8;
+ id = "custodialshutters"
+ },
/turf/open/floor/iron/white/small,
/area/station/service/janitor)
"cZM" = (
@@ -8325,6 +8386,10 @@
},
/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";
@@ -8544,9 +8609,8 @@
/turf/open/floor/plating,
/area/station/maintenance/department/engine/atmos)
"dry" = (
-/obj/structure/bed/pod{
- desc = "An old medical bed, just waiting for replacement with something up to date.";
- name = "medical bed"
+/obj/structure/bed/medical{
+ dir = 4
},
/obj/item/bedsheet/medical,
/obj/machinery/light/small/directional/east,
@@ -9498,14 +9562,14 @@
name = "Privacy Bolts";
normaldoorcontrol = 1;
pixel_x = -32;
- pixel_y = 26;
+ pixel_y = 35;
specialfunctions = 4
},
/obj/machinery/button/door/directional/north{
id = "com_guest2";
name = "Privacy Shutters";
pixel_x = -32;
- pixel_y = 35
+ pixel_y = 26
},
/turf/open/floor/wood/large,
/area/station/command/corporate_suite)
@@ -9704,6 +9768,7 @@
/area/station/hallway/secondary/entry)
"dOb" = (
/obj/structure/broken_flooring/singular/directional/east,
+/obj/structure/alien/weeds,
/turf/open/floor/iron,
/area/station/maintenance/starboard/greater)
"dOd" = (
@@ -9969,6 +10034,8 @@
/obj/structure/broken_flooring/pile/directional/east,
/obj/effect/decal/cleanable/dirt,
/obj/machinery/light/small/directional/south,
+/obj/structure/alien/weeds,
+/obj/structure/alien/weeds,
/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"dTI" = (
@@ -10238,6 +10305,13 @@
dir = 9
},
/area/station/engineering/atmos)
+"dXO" = (
+/obj/effect/spawner/structure/window/reinforced/tinted,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/station/service/janitor)
"dXT" = (
/obj/machinery/atmospherics/pipe/smart/simple/yellow/visible{
dir = 4
@@ -10863,10 +10937,10 @@
/turf/open/floor/iron,
/area/station/security)
"ejn" = (
-/obj/structure/frame,
/obj/item/stack/cable_coil/five,
-/obj/item/circuitboard/computer/arcade,
/obj/effect/decal/cleanable/cobweb,
+/obj/effect/spawner/random/techstorage/arcade_boards,
+/obj/structure/frame/computer,
/turf/open/floor/eighties/red,
/area/station/service/abandoned_gambling_den/gaming)
"ejt" = (
@@ -12204,7 +12278,6 @@
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/landmark/navigate_destination/eva,
-/obj/machinery/status_display/ai/directional/east,
/turf/open/floor/iron,
/area/station/hallway/primary/fore)
"eFV" = (
@@ -12335,6 +12408,10 @@
/obj/structure/holosign/barrier/atmos/tram,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
+"eHN" = (
+/obj/structure/cable,
+/turf/open/floor/wood/tile,
+/area/station/maintenance/port/lesser)
"eHR" = (
/obj/machinery/atmospherics/pipe/smart/simple/cyan/visible,
/obj/effect/spawner/structure/window/reinforced,
@@ -12414,6 +12491,10 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/security/prison/rec)
+"eJH" = (
+/obj/structure/urinal/directional/west,
+/turf/open/misc/asteroid/airless,
+/area/space/nearstation)
"eJP" = (
/obj/machinery/mech_bay_recharge_port{
dir = 1
@@ -13009,6 +13090,7 @@
/obj/effect/turf_decal/sand/plating,
/obj/structure/table,
/obj/item/stack/ore/bananium,
+/obj/structure/alien/weeds,
/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"eUH" = (
@@ -13389,6 +13471,10 @@
/obj/structure/extinguisher_cabinet/directional/west,
/turf/open/floor/iron/smooth,
/area/station/service/greenroom)
+"fcq" = (
+/obj/structure/alien/weeds,
+/turf/open/misc/asteroid,
+/area/station/maintenance/starboard/greater)
"fcs" = (
/obj/effect/turf_decal/tile/yellow/opposingcorners,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
@@ -13474,6 +13560,13 @@
/obj/effect/turf_decal/sand/plating,
/turf/open/floor/plating/airless,
/area/space/nearstation)
+"ffD" = (
+/obj/machinery/conveyor/inverted{
+ dir = 10;
+ id = "garbage"
+ },
+/turf/open/floor/plating,
+/area/station/service/janitor)
"ffO" = (
/obj/machinery/atmospherics/pipe/smart/simple/green/visible,
/turf/open/floor/plating/airless,
@@ -13715,6 +13808,7 @@
/obj/item/mod/module/thermal_regulator,
/obj/effect/turf_decal/bot_white,
/obj/machinery/status_display/ai/directional/south,
+/obj/item/mod/module/signlang_radio,
/turf/open/floor/iron/small,
/area/station/medical/storage)
"fkt" = (
@@ -13730,6 +13824,11 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/dark,
/area/station/science/ordnance)
+"fkT" = (
+/obj/effect/turf_decal/sand/plating,
+/obj/structure/alien/weeds,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/greater)
"flg" = (
/obj/machinery/atmospherics/pipe/smart/simple/cyan/visible{
dir = 10
@@ -14320,6 +14419,7 @@
/obj/machinery/light/small/directional/east,
/obj/machinery/power/shieldwallgen/xenobiologyaccess,
/obj/effect/mapping_helpers/broken_floor,
+/obj/structure/cable/multilayer,
/turf/open/floor/plating,
/area/station/science/xenobiology)
"fuC" = (
@@ -15649,6 +15749,7 @@
/obj/effect/mapping_helpers/airlock/cyclelink_helper{
dir = 4
},
+/obj/structure/alien/weeds,
/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"fQi" = (
@@ -16217,6 +16318,7 @@
"gbD" = (
/obj/machinery/hydroponics/soil,
/obj/item/food/grown/mushroom/reishi,
+/obj/structure/alien/weeds,
/turf/open/misc/asteroid,
/area/station/maintenance/starboard/greater)
"gbH" = (
@@ -16583,16 +16685,10 @@
/turf/open/floor/circuit/green,
/area/station/ai_monitored/command/nuke_storage)
"ghW" = (
-/obj/structure/disposalpipe/trunk{
- dir = 8
+/obj/machinery/mineral/stacking_machine{
+ input_dir = 2
},
-/obj/structure/window/reinforced/spawner/directional/east,
-/obj/machinery/disposal/bin,
-/obj/effect/turf_decal/bot,
-/obj/effect/turf_decal/stripes/end{
- dir = 4
- },
-/turf/open/floor/iron/white/small,
+/turf/open/floor/plating,
/area/station/service/janitor)
"gic" = (
/obj/effect/turf_decal/siding/blue{
@@ -17142,7 +17238,7 @@
/obj/structure/disposalpipe/segment{
dir = 4
},
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/airalarm/directional/north,
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/turf/open/floor/iron/dark,
@@ -18540,6 +18636,14 @@
/obj/machinery/holopad,
/turf/open/floor/wood/tile,
/area/station/command/meeting_room)
+"gSk" = (
+/obj/structure/cable,
+/obj/effect/turf_decal/sand/plating,
+/obj/machinery/power/floodlight,
+/obj/structure/alien/weeds,
+/obj/effect/gibspawner/human,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/greater)
"gSD" = (
/obj/machinery/mass_driver/chapelgun{
dir = 8
@@ -19597,6 +19701,10 @@
pixel_x = 20;
pixel_y = 11
},
+/obj/item/mod/module/signlang_radio{
+ pixel_y = 2;
+ pixel_x = -2
+ },
/turf/open/floor/iron/small,
/area/station/security/office)
"hiV" = (
@@ -19627,7 +19735,7 @@
},
/area/station/engineering/atmos)
"hjx" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/stripes/line{
dir = 1
},
@@ -20133,18 +20241,21 @@
/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,
/turf/open/floor/plating,
/area/station/hallway/secondary/command)
-"hsX" = (
-/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)
"hsZ" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -20155,11 +20266,6 @@
/obj/structure/barricade/wooden,
/turf/open/floor/plating,
/area/station/security/tram)
-"htt" = (
-/obj/structure/rack,
-/obj/effect/spawner/random/maintenance/two,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"htI" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -20208,12 +20314,6 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/maintenance/department/science/xenobiology)
-"huc" = (
-/obj/effect/turf_decal/bot_white,
-/obj/structure/rack,
-/obj/item/electronics/apc,
-/turf/open/floor/iron/smooth_large,
-/area/station/cargo/warehouse)
"huh" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -20589,6 +20689,21 @@
/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,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"hzX" = (
/obj/machinery/door/airlock/external{
name = "Mining Dock Airlock"
@@ -20908,6 +21023,12 @@
/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
@@ -21582,19 +21703,12 @@
/turf/open/floor/iron,
/area/station/hallway/primary/fore)
"hTW" = (
+/obj/structure/window/reinforced/spawner/directional/north,
+/obj/vehicle/ridden/janicart,
/obj/effect/turf_decal/stripes/line{
- dir = 4
+ dir = 1
},
-/obj/effect/turf_decal/stripes/line{
- dir = 8
- },
-/obj/machinery/conveyor{
- dir = 1;
- id = "garbage";
- name = "trash belt"
- },
-/obj/machinery/recycler,
-/turf/open/floor/plating,
+/turf/open/floor/iron/white/small,
/area/station/service/janitor)
"hTZ" = (
/obj/structure/chair/sofa/bench/left{
@@ -23273,11 +23387,14 @@
"ixP" = (
/obj/structure/table,
/obj/machinery/firealarm/directional/south,
+/obj/item/restraints/legcuffs/beartrap,
+/obj/item/stack/tile/iron/base{
+ pixel_y = 18
+ },
/obj/item/grenade/chem_grenade/cleaner{
pixel_x = -7;
pixel_y = 12
},
-/obj/item/restraints/legcuffs/beartrap,
/turf/open/floor/iron,
/area/station/service/janitor)
"ixU" = (
@@ -23415,7 +23532,9 @@
/turf/open/floor/iron,
/area/station/security/brig/entrance)
"iAZ" = (
-/obj/structure/bed,
+/obj/structure/bed/medical/anchored{
+ dir = 4
+ },
/obj/item/bedsheet,
/obj/effect/turf_decal/siding/red{
dir = 5
@@ -23457,6 +23576,11 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/smooth,
/area/station/hallway/secondary/command)
+"iBE" = (
+/obj/effect/turf_decal/sand/plating,
+/obj/structure/cable,
+/turf/open/floor/wood/tile,
+/area/station/maintenance/port/lesser)
"iBV" = (
/obj/effect/turf_decal/stripes/white/line{
dir = 1
@@ -24434,13 +24558,6 @@
/obj/effect/decal/cleanable/cobweb/cobweb2,
/turf/open/floor/plating,
/area/station/service/abandoned_gambling_den)
-"iUG" = (
-/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)
"iUH" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/structure/table/reinforced/titaniumglass,
@@ -24694,7 +24811,7 @@
/obj/structure/railing{
dir = 5
},
-/obj/machinery/atmospherics/components/unary/passive_vent/layer2{
+/obj/machinery/atmospherics/components/unary/outlet_injector/layer2{
dir = 8
},
/turf/open/space/basic,
@@ -24839,6 +24956,10 @@
/obj/machinery/light/small/directional/north,
/turf/open/floor/plating,
/area/station/cargo/storage)
+"jaP" = (
+/obj/effect/mob_spawn/corpse/human/clown,
+/turf/open/floor/plating/airless,
+/area/station/science/ordnance/bomb)
"jaQ" = (
/turf/open/floor/catwalk_floor/iron_dark,
/area/station/security/processing)
@@ -24896,6 +25017,7 @@
/obj/effect/spawner/random/entertainment/plushie,
/obj/effect/spawner/random/entertainment/plushie,
/obj/effect/spawner/random/entertainment/plushie,
+/obj/structure/alien/weeds,
/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"jco" = (
@@ -25489,6 +25611,7 @@
/obj/effect/decal/cleanable/dirt,
/obj/structure/showcase/machinery/tv/broken,
/obj/effect/decal/cleanable/glass,
+/obj/structure/alien/weeds,
/turf/open/floor/wood,
/area/station/maintenance/starboard/greater)
"jpm" = (
@@ -25775,6 +25898,9 @@
},
/obj/structure/table,
/obj/effect/decal/cleanable/dirt,
+/obj/item/stack/package_wrap{
+ pixel_y = 5
+ },
/obj/item/storage/box/matches,
/turf/open/floor/iron,
/area/station/cargo/sorting)
@@ -27046,7 +27172,8 @@
/area/station/cargo/warehouse)
"jPq" = (
/obj/structure/disposalpipe/segment,
-/turf/closed/wall,
+/obj/effect/spawner/structure/window/reinforced/tinted,
+/turf/open/floor/plating,
/area/station/maintenance/fore/greater)
"jQo" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -27404,6 +27531,15 @@
/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;
@@ -27520,10 +27656,7 @@
/turf/open/floor/plating,
/area/station/maintenance/department/prison)
"jZK" = (
-/obj/structure/disposalpipe/segment{
- dir = 10
- },
-/obj/effect/decal/cleanable/dirt,
+/obj/structure/disposalpipe/junction/yjunction,
/turf/open/floor/iron,
/area/station/maintenance/hallway/abandoned_command)
"jZL" = (
@@ -27550,16 +27683,16 @@
/turf/open/floor/plating,
/area/station/maintenance/department/engine)
"kam" = (
-/obj/structure/cable,
-/obj/structure/table,
-/obj/machinery/power/apc/auto_name/directional/north,
-/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/cobweb,
-/obj/item/storage/box/mousetraps{
- pixel_x = -3;
- pixel_y = 8
+/obj/machinery/disposal/delivery_chute{
+ dir = 4
},
-/turf/open/floor/iron/white/small,
+/obj/structure/window/reinforced/spawner/directional/south,
+/obj/structure/disposalpipe/trunk{
+ dir = 8
+ },
+/obj/effect/turf_decal/stripes/box,
+/turf/open/floor/plating,
/area/station/service/janitor)
"kar" = (
/obj/structure/disposalpipe/segment,
@@ -27600,11 +27733,8 @@
/obj/structure/disposalpipe/trunk{
dir = 1
},
-/obj/effect/turf_decal/stripes/end{
- dir = 1
- },
/obj/machinery/disposal/delivery_chute,
-/obj/structure/sign/poster/official/random/directional/north,
+/obj/effect/turf_decal/stripes/box,
/turf/open/floor/plating,
/area/station/service/janitor)
"kaI" = (
@@ -27637,22 +27767,6 @@
/obj/structure/broken_flooring/corner/directional/south,
/turf/open/floor/plating,
/area/station/maintenance/hallway/abandoned_recreation)
-"kbc" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 4
- },
-/obj/machinery/door/window/left/directional/east{
- name = "Trash Chute";
- req_access = list("janitor")
- },
-/obj/machinery/conveyor_switch/oneway{
- dir = 4;
- id = "garbage";
- name = "trash chute"
- },
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/white/small,
-/area/station/service/janitor)
"kbE" = (
/obj/effect/decal/cleanable/blood/gibs/body,
/obj/machinery/light/small/broken/directional/north,
@@ -27829,11 +27943,6 @@
dir = 8
},
/area/station/hallway/secondary/dock)
-"kfA" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/spawner/random/structure/crate,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"kfC" = (
/obj/effect/spawner/random/engineering/atmospherics_portable,
/turf/open/floor/plating,
@@ -28020,10 +28129,8 @@
"kjh" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/turf_decal/stripes/line{
- dir = 4
- },
-/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/stripes/corner,
+/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/iron,
/area/station/maintenance/hallway/abandoned_command)
"kjl" = (
@@ -28131,9 +28238,8 @@
"kkD" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/light/small/directional/east,
/obj/effect/mapping_helpers/broken_floor,
-/obj/effect/turf_decal/stripes/corner,
-/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/station/maintenance/hallway/abandoned_command)
"kkL" = (
@@ -28805,6 +28911,7 @@
dir = 1
},
/obj/effect/decal/cleanable/blood/old,
+/obj/structure/alien/weeds,
/turf/open/floor/wood,
/area/station/maintenance/starboard/greater)
"kxp" = (
@@ -28956,15 +29063,6 @@
},
/turf/open/floor/iron/small,
/area/station/hallway/primary/central/fore)
-"kzF" = (
-/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)
"kzI" = (
/obj/effect/turf_decal/bot_white,
/obj/effect/spawner/random/structure/crate_empty,
@@ -29075,16 +29173,24 @@
/turf/open/floor/plating,
/area/station/maintenance/fore/lesser)
"kCN" = (
-/obj/machinery/holopad,
/obj/effect/decal/cleanable/dirt,
+/obj/machinery/door/window/left/directional/north{
+ name = "Trash Chute"
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 9
+ },
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/iron/white/small,
/area/station/service/janitor)
"kCP" = (
/obj/effect/turf_decal/stripes/line{
- dir = 5
+ dir = 1
},
-/obj/structure/window/reinforced/spawner/directional/east,
/obj/structure/mop_bucket/janitorialcart,
+/obj/machinery/door/window/left/directional/north{
+ name = "Trash Chute"
+ },
/turf/open/floor/iron/white/small,
/area/station/service/janitor)
"kCT" = (
@@ -29731,10 +29837,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/textured_half,
/area/station/cargo/miningoffice)
-"kOA" = (
-/obj/effect/spawner/random/structure/closet_maintenance,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"kOG" = (
/obj/structure/cable,
/obj/machinery/door/airlock/external{
@@ -30467,27 +30569,25 @@
/turf/open/floor/iron/small,
/area/station/engineering/atmos)
"lcW" = (
-/obj/structure/disposalpipe/segment{
- dir = 6
+/obj/structure/disposalpipe/sorting/mail{
+ dir = 1
},
+/obj/effect/mapping_helpers/mail_sorting/service/janitor_closet,
+/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/white/small,
/area/station/service/janitor)
"lde" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 6
+/obj/item/radio/intercom/directional/south,
+/obj/structure/disposalpipe/trunk{
+ dir = 8
},
-/obj/effect/turf_decal/stripes/corner{
+/obj/structure/disposaloutlet{
dir = 1
},
-/obj/machinery/conveyor{
- dir = 1;
- id = "garbage";
- name = "trash belt"
- },
-/obj/item/radio/intercom/directional/south,
-/turf/open/floor/plating,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/stripes/box,
+/turf/open/floor/iron/white/small,
/area/station/service/janitor)
"ldo" = (
/obj/structure/chair/comfy/brown{
@@ -31072,6 +31172,7 @@
/area/station/security/prison/workout)
"lkd" = (
/obj/structure/cable,
+/obj/structure/alien/weeds,
/turf/open/misc/asteroid,
/area/station/maintenance/starboard/greater)
"lku" = (
@@ -31169,10 +31270,8 @@
/area/station/cargo/sorting)
"llP" = (
/obj/structure/cable,
-/obj/structure/bed/pod{
- desc = "An old medical bed, just waiting for replacement with something up to date.";
- dir = 4;
- name = "medical bed"
+/obj/structure/bed/medical{
+ dir = 8
},
/obj/effect/turf_decal/trimline/blue/corner,
/obj/machinery/power/apc/auto_name/directional/south,
@@ -31254,6 +31353,10 @@
/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,
@@ -31795,6 +31898,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/structure/curtain/cloth,
/obj/effect/decal/cleanable/dirt,
+/obj/structure/cable,
/turf/open/floor/iron/textured_half,
/area/station/service/janitor)
"lyQ" = (
@@ -31819,16 +31923,6 @@
/obj/item/wrench,
/turf/open/floor/iron,
/area/station/security/tram)
-"lzn" = (
-/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)
"lzp" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -31960,6 +32054,8 @@
/obj/structure/sign/picture_frame/portrait{
pixel_x = -26
},
+/obj/structure/alien/resin/membrane,
+/obj/structure/alien/weeds,
/turf/open/floor/wood,
/area/station/maintenance/starboard/greater)
"lAS" = (
@@ -32855,14 +32951,12 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
/area/station/maintenance/starboard/central)
-"lQq" = (
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"lQu" = (
/obj/machinery/light/broken/directional/south,
/obj/effect/spawner/random/trash/bin,
/obj/effect/decal/cleanable/glass,
+/obj/structure/alien/resin/membrane,
+/obj/structure/alien/weeds,
/turf/open/floor/wood,
/area/station/maintenance/starboard/greater)
"lQA" = (
@@ -33610,6 +33704,11 @@
},
/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
+"mcl" = (
+/obj/structure/alien/weeds,
+/obj/effect/gibspawner/xeno,
+/turf/open/misc/asteroid,
+/area/station/maintenance/starboard/greater)
"mcn" = (
/obj/machinery/status_display/ai/directional/south,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
@@ -33845,14 +33944,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/central)
-"mhW" = (
-/obj/structure/cable,
-/obj/machinery/door/airlock{
- name = "Custodial Closet Maintenance"
- },
-/obj/effect/mapping_helpers/airlock/access/any/service/janitor,
-/turf/open/floor/plating,
-/area/station/maintenance/fore/greater)
"mhY" = (
/obj/structure/disposalpipe/segment,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -34046,6 +34137,11 @@
/obj/machinery/light/floor,
/turf/open/floor/iron/grimy,
/area/station/tcommsat/server)
+"mlm" = (
+/obj/structure/cable,
+/obj/structure/alien/weeds,
+/turf/open/floor/iron,
+/area/station/maintenance/starboard/greater)
"mlr" = (
/obj/structure/chair/office/light{
dir = 4
@@ -34543,6 +34639,9 @@
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/blood/old,
/obj/item/crowbar,
+/obj/structure/alien/egg/burst,
+/obj/structure/alien/weeds,
+/obj/effect/gibspawner,
/turf/open/floor/wood,
/area/station/maintenance/starboard/greater)
"mwy" = (
@@ -35016,15 +35115,15 @@
/turf/open/floor/iron/dark/smooth_corner,
/area/station/maintenance/starboard/greater)
"mEy" = (
-/obj/structure/disposalpipe/segment{
- dir = 6
+/obj/machinery/conveyor{
+ dir = 8;
+ id = "garbage"
},
-/obj/structure/cable,
-/obj/effect/turf_decal/stripes/line{
- dir = 1
+/obj/machinery/light/cold/directional/north,
+/obj/machinery/mineral/stacking_unit_console{
+ pixel_y = 27
},
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/white/small,
+/turf/open/floor/plating,
/area/station/service/janitor)
"mEB" = (
/obj/effect/spawner/structure/window,
@@ -35444,6 +35543,11 @@
},
/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,
@@ -35499,6 +35603,10 @@
/obj/effect/mapping_helpers/airlock/access/all/medical/general,
/turf/open/floor/iron/dark/small,
/area/station/medical/paramedic)
+"mMr" = (
+/obj/structure/alien/weeds,
+/turf/closed/wall,
+/area/station/maintenance/starboard/greater)
"mMt" = (
/obj/structure/cable,
/obj/structure/chair{
@@ -35886,6 +35994,7 @@
},
/obj/effect/mapping_helpers/airlock/access/any/service/maintenance,
/obj/effect/decal/cleanable/dirt,
+/obj/structure/alien/weeds,
/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"mUt" = (
@@ -36142,6 +36251,7 @@
/obj/machinery/door/airlock/public/glass{
name = "Old Dorms"
},
+/obj/structure/alien/weeds,
/turf/open/floor/wood,
/area/station/maintenance/starboard/greater)
"mZX" = (
@@ -36260,13 +36370,11 @@
/obj/effect/decal/cleanable/dirt,
/obj/structure/table/wood,
/obj/item/paper/calling_card,
+/obj/structure/alien/resin/membrane,
+/obj/structure/alien/weeds,
+/obj/structure/alien/weeds,
/turf/open/floor/wood,
/area/station/maintenance/starboard/greater)
-"ncf" = (
-/obj/structure/disposalpipe/segment,
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/white/small,
-/area/station/service/janitor)
"ncl" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -37173,6 +37281,10 @@
},
/turf/open/floor/iron,
/area/station/cargo/storage)
+"num" = (
+/obj/effect/turf_decal/sand/plating,
+/turf/closed/wall,
+/area/station/maintenance/port/lesser)
"nuo" = (
/obj/effect/turf_decal/tile/neutral/fourcorners,
/obj/effect/decal/cleanable/dirt,
@@ -37239,6 +37351,11 @@
/obj/machinery/firealarm/directional/south,
/turf/open/floor/carpet/blue,
/area/station/cargo/boutique)
+"nuY" = (
+/obj/structure/broken_flooring/pile/directional/east,
+/obj/structure/alien/weeds/node,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/greater)
"nvo" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -37339,7 +37456,9 @@
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/mapping_helpers/dead_body_placer,
+/obj/effect/mapping_helpers/dead_body_placer{
+ bodycount = 2
+ },
/turf/open/floor/iron/dark/small,
/area/station/medical/morgue)
"nxJ" = (
@@ -37772,20 +37891,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/white,
/area/station/science/cytology)
-"nEJ" = (
-/obj/effect/turf_decal/delivery,
-/obj/machinery/door/poddoor/shutters{
- dir = 8;
- id = "custodialshutters";
- name = "Custodial Closet Shutters"
- },
-/obj/machinery/button/door/directional/north{
- id = "custodialshutters";
- name = "shutters control";
- pixel_x = 8
- },
-/turf/open/floor/iron/large,
-/area/station/service/janitor)
"nEY" = (
/obj/structure/closet/firecloset,
/obj/effect/decal/cleanable/dirt,
@@ -37797,6 +37902,7 @@
/obj/machinery/door/airlock/highsecurity{
name = "Secure Tech Storage"
},
+/obj/effect/mapping_helpers/airlock/access/all/command/general,
/turf/open/floor/iron/textured_half,
/area/station/engineering/storage/tech)
"nFh" = (
@@ -37833,8 +37939,16 @@
/turf/open/floor/iron,
/area/station/maintenance/department/medical/central)
"nFA" = (
-/obj/structure/disposalpipe/segment,
-/obj/effect/landmark/start/janitor,
+/obj/structure/window/reinforced/spawner/directional/north,
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/conveyor_switch/oneway{
+ dir = 4;
+ id = "garbage";
+ name = "trash chute"
+ },
/turf/open/floor/iron/white/small,
/area/station/service/janitor)
"nFD" = (
@@ -38097,7 +38211,9 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/mapping_helpers/broken_floor,
-/obj/machinery/light/small/directional/east,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
/turf/open/floor/iron,
/area/station/maintenance/hallway/abandoned_command)
"nJU" = (
@@ -38988,10 +39104,6 @@
/obj/structure/steam_vent,
/turf/open/floor/plating/rust,
/area/station/maintenance/fore/greater)
-"odN" = (
-/obj/machinery/rnd/bepis,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"odP" = (
/obj/machinery/firealarm/directional/west,
/obj/effect/landmark/generic_maintenance_landmark,
@@ -39090,6 +39202,9 @@
},
/turf/open/floor/iron/smooth_large,
/area/station/maintenance/department/medical/central)
+"ofZ" = (
+/turf/closed/mineral/random/stationside,
+/area/station/maintenance/port/lesser)
"ogi" = (
/obj/effect/landmark/start/captain,
/obj/structure/cable,
@@ -39360,6 +39475,13 @@
/obj/machinery/firealarm/directional/east,
/turf/open/floor/iron/white/small,
/area/station/science/ordnance/storage)
+"oiU" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/alien/resin/membrane,
+/obj/structure/alien/weeds,
+/turf/open/floor/wood,
+/area/station/maintenance/starboard/greater)
"ojw" = (
/obj/item/kirbyplants/random,
/obj/effect/mapping_helpers/broken_floor,
@@ -39428,6 +39550,7 @@
"olm" = (
/obj/structure/table,
/obj/item/mining_voucher,
+/obj/structure/alien/weeds,
/turf/open/misc/asteroid,
/area/station/maintenance/starboard/greater)
"olI" = (
@@ -39525,14 +39648,19 @@
/turf/open/floor/iron/white/small,
/area/station/medical/cryo)
"onR" = (
-/obj/structure/disposalpipe/sorting/mail/flip{
+/obj/structure/disposalpipe/segment{
dir = 4
},
-/obj/effect/turf_decal/delivery/white{
- color = "#52B4E9"
+/obj/structure/table,
+/obj/item/clothing/gloves/color/orange{
+ pixel_x = 4;
+ pixel_y = -2
},
-/obj/vehicle/ridden/janicart,
-/obj/effect/mapping_helpers/mail_sorting/service/janitor_closet,
+/obj/item/key/janitor{
+ pixel_x = -3;
+ pixel_y = 6
+ },
+/obj/structure/cable,
/turf/open/floor/iron/white/small,
/area/station/service/janitor)
"onX" = (
@@ -39947,6 +40075,11 @@
/obj/structure/closet/emcloset,
/turf/open/floor/iron,
/area/station/maintenance/aft)
+"ovB" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/alien/weeds,
+/turf/open/floor/iron,
+/area/station/maintenance/starboard/greater)
"ovQ" = (
/obj/effect/turf_decal/stripes/line,
/turf/open/floor/iron,
@@ -40203,6 +40336,10 @@
/obj/effect/mapping_helpers/airlock/access/all/security/entrance,
/turf/open/floor/iron/textured_half,
/area/station/security/brig)
+"oBh" = (
+/obj/structure/alien/weeds/node,
+/turf/open/misc/asteroid,
+/area/station/maintenance/starboard/greater)
"oBm" = (
/obj/structure/chair/sofa/bench/left,
/obj/effect/turf_decal/tile/neutral/fourcorners,
@@ -40786,6 +40923,7 @@
"oNH" = (
/obj/structure/cable,
/obj/effect/decal/cleanable/dirt,
+/obj/structure/alien/weeds,
/turf/open/floor/iron,
/area/station/maintenance/starboard/greater)
"oNM" = (
@@ -41263,13 +41401,14 @@
"oWk" = (
/obj/structure/broken_flooring/singular/directional/east,
/obj/item/clothing/suit/caution,
+/obj/structure/alien/weeds,
/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"oWl" = (
/obj/machinery/door/airlock{
name = "Maintenance"
},
-/obj/effect/mapping_helpers/airlock/access/any/service/maintenance,
+/obj/effect/mapping_helpers/airlock/access/any/command/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/hallway/abandoned_command)
"oWr" = (
@@ -41730,6 +41869,13 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/iron/small,
/area/station/maintenance/port/lesser)
+"pfh" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/alien/weeds,
+/obj/effect/spawner/random/food_or_drink/soup,
+/obj/effect/gibspawner,
+/turf/open/floor/wood,
+/area/station/maintenance/starboard/greater)
"pfv" = (
/obj/structure/disposalpipe/trunk{
dir = 8
@@ -41771,6 +41917,8 @@
},
/obj/effect/mapping_helpers/airlock/abandoned,
/obj/structure/barricade/wooden/crude,
+/obj/effect/mapping_helpers/airlock/locked,
+/obj/effect/mapping_helpers/airlock/welded,
/turf/open/floor/iron/textured_half{
dir = 8
},
@@ -41893,6 +42041,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/decal/cleanable/dirt,
/obj/effect/landmark/start/janitor,
+/obj/structure/cable,
/turf/open/floor/iron,
/area/station/service/janitor)
"pil" = (
@@ -42014,6 +42163,13 @@
},
/turf/open/floor/iron,
/area/station/hallway/secondary/recreation)
+"pke" = (
+/obj/machinery/door/airlock/centcom{
+ name = "Disposals Access:"
+ },
+/obj/effect/mapping_helpers/airlock/access/any/service/janitor,
+/turf/open/floor/plating,
+/area/station/maintenance/fore/greater)
"pkh" = (
/obj/effect/spawner/random/decoration/showcase,
/obj/structure/window/spawner/directional/south,
@@ -42751,6 +42907,7 @@
/obj/structure/disposalpipe/segment,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/decal/cleanable/dirt,
+/obj/structure/cable,
/turf/open/floor/iron,
/area/station/service/janitor)
"pwA" = (
@@ -43299,6 +43456,7 @@
"pFk" = (
/obj/structure/broken_flooring/singular/directional/east,
/obj/effect/decal/cleanable/dirt,
+/obj/structure/alien/weeds,
/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"pFr" = (
@@ -43432,6 +43590,7 @@
"pHn" = (
/obj/structure/cable,
/obj/structure/broken_flooring/singular/directional/east,
+/obj/structure/alien/weeds,
/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"pHo" = (
@@ -43986,6 +44145,10 @@
},
/turf/open/floor/iron/dark/side,
/area/station/science/xenobiology)
+"pRb" = (
+/obj/item/computer_disk/virus/mime,
+/turf/closed/mineral/random/stationside,
+/area/space/nearstation)
"pRe" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/table/wood,
@@ -44168,7 +44331,7 @@
/area/station/maintenance/port/lesser)
"pTr" = (
/obj/structure/table,
-/obj/item/storage/backpack/duffelbag/med/surgery{
+/obj/item/surgery_tray/full{
pixel_y = -5
},
/obj/item/wirecutters{
@@ -44419,6 +44582,7 @@
/obj/machinery/door/airlock/centcom{
name = "Custodial Closet"
},
+/obj/structure/cable,
/turf/open/floor/iron/textured_half,
/area/station/service/janitor)
"pWZ" = (
@@ -48638,6 +48802,10 @@
},
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
+"roq" = (
+/obj/effect/turf_decal/sand/plating,
+/turf/open/floor/wood/tile,
+/area/station/maintenance/port/lesser)
"row" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/reagent_dispensers/plumbed,
@@ -48648,18 +48816,9 @@
/turf/open/floor/plating,
/area/station/maintenance/department/science/xenobiology)
"roB" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 4
- },
-/obj/effect/turf_decal/stripes/line{
- dir = 8
- },
-/obj/machinery/conveyor{
- dir = 1;
- id = "garbage";
- name = "trash belt"
- },
-/turf/open/floor/plating,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/delivery,
+/turf/open/floor/iron/white/small,
/area/station/service/janitor)
"roC" = (
/obj/structure/cable,
@@ -48925,9 +49084,8 @@
/turf/open/floor/iron,
/area/station/hallway/secondary/recreation)
"rsz" = (
-/obj/structure/bed/pod{
- desc = "An old medical bed, just waiting for replacement with something up to date.";
- name = "medical bed"
+/obj/structure/bed/medical{
+ dir = 4
},
/obj/item/bedsheet/medical,
/obj/machinery/light/small/directional/east,
@@ -49625,6 +49783,8 @@
"rEb" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/landmark/generic_maintenance_landmark,
+/obj/structure/alien/gelpod,
+/obj/structure/alien/weeds,
/turf/open/floor/wood,
/area/station/maintenance/starboard/greater)
"rEt" = (
@@ -50976,6 +51136,7 @@
/obj/effect/spawner/random/trash/food_packaging,
/obj/effect/spawner/random/trash/cigbutt,
/obj/effect/decal/cleanable/dirt,
+/obj/structure/alien/weeds,
/turf/open/floor/iron,
/area/station/maintenance/starboard/greater)
"rZH" = (
@@ -51018,20 +51179,26 @@
/turf/open/floor/iron/white/small,
/area/station/service/hydroponics)
"saD" = (
-/obj/structure/disposalpipe/trunk{
- dir = 8
- },
-/obj/effect/turf_decal/stripes/end{
- dir = 8
- },
-/obj/structure/disposaloutlet{
- dir = 4
- },
-/obj/structure/window/reinforced/spawner/directional/north,
-/obj/structure/window/reinforced/spawner/directional/west,
/obj/machinery/camera/directional/south,
/obj/machinery/light/small/directional/south,
-/turf/open/floor/plating,
+/obj/machinery/power/apc/auto_name/directional/south,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/structure/table,
+/obj/item/storage/box/mousetraps{
+ pixel_x = -3;
+ pixel_y = 8
+ },
+/obj/item/restraints/legcuffs/beartrap{
+ pixel_x = 8;
+ pixel_y = 13
+ },
+/obj/item/flashlight{
+ pixel_y = 4
+ },
+/obj/structure/cable,
+/turf/open/floor/iron/white/small,
/area/station/service/janitor)
"saY" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -53179,6 +53346,8 @@
"sKS" = (
/obj/structure/sign/poster/official/pda_ad/directional/north,
/obj/structure/tank_holder/extinguisher,
+/obj/structure/alien/weeds,
+/obj/effect/gibspawner,
/turf/open/floor/wood,
/area/station/maintenance/starboard/greater)
"sKX" = (
@@ -53277,13 +53446,13 @@
/area/station/maintenance/port/greater)
"sMT" = (
/obj/structure/table,
-/obj/item/roller{
+/obj/item/emergency_bed{
pixel_y = 14
},
-/obj/item/roller{
+/obj/item/emergency_bed{
pixel_y = 18
},
-/obj/item/roller{
+/obj/item/emergency_bed{
pixel_y = 25
},
/obj/item/wheelchair{
@@ -53460,6 +53629,7 @@
/obj/item/stack/ore/iron{
amount = 25
},
+/obj/structure/alien/weeds,
/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"sQA" = (
@@ -54516,6 +54686,7 @@
/obj/item/stack/ore/glass{
amount = 20
},
+/obj/structure/alien/weeds,
/turf/open/misc/asteroid,
/area/station/maintenance/starboard/greater)
"tiQ" = (
@@ -55184,6 +55355,7 @@
/area/station/command/heads_quarters/captain/private)
"tvZ" = (
/obj/effect/spawner/random/trash,
+/obj/structure/cable,
/turf/open/floor/plating,
/area/station/maintenance/port/lesser)
"twf" = (
@@ -55362,10 +55534,6 @@
/obj/effect/mapping_helpers/airlock/access/all/command/captain,
/turf/open/floor/plating,
/area/station/maintenance/hallway/abandoned_command)
-"tyv" = (
-/obj/machinery/lapvend,
-/turf/open/floor/iron/white,
-/area/station/hallway/primary/starboard)
"tyx" = (
/obj/structure/disposalpipe/segment{
dir = 6
@@ -55389,6 +55557,11 @@
dir = 4
},
/area/station/science/ordnance/testlab)
+"tzo" = (
+/obj/structure/alien/egg/burst,
+/obj/structure/alien/weeds,
+/turf/open/misc/asteroid,
+/area/station/maintenance/starboard/greater)
"tzq" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -55430,21 +55603,11 @@
/turf/open/floor/plating,
/area/station/science/lobby)
"tzD" = (
-/obj/structure/cable,
-/obj/effect/turf_decal/stripes/corner{
- dir = 4
+/obj/machinery/conveyor{
+ dir = 8;
+ id = "garbage"
},
-/obj/structure/table,
-/obj/item/restraints/legcuffs/beartrap{
- pixel_x = 8;
- pixel_y = 13
- },
-/obj/item/flashlight{
- pixel_y = 4
- },
-/obj/machinery/light/cold/directional/north,
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/white/small,
+/turf/open/floor/plating,
/area/station/service/janitor)
"tzF" = (
/obj/structure/cable,
@@ -55688,6 +55851,13 @@
/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)
@@ -56792,6 +56962,11 @@
dir = 1
},
/area/station/hallway/secondary/exit/departure_lounge)
+"tXl" = (
+/obj/effect/turf_decal/sand/plating,
+/obj/structure/table/bronze,
+/turf/open/floor/wood/tile,
+/area/station/maintenance/port/lesser)
"tXw" = (
/obj/structure/disposalpipe/segment{
dir = 9
@@ -57486,6 +57661,10 @@
/obj/machinery/iv_drip,
/turf/open/floor/iron/small,
/area/station/medical/morgue)
+"uhq" = (
+/obj/structure/chair/bronze,
+/turf/open/floor/wood/tile,
+/area/station/maintenance/port/lesser)
"uhu" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/turf_decal/tile/blue{
@@ -57609,13 +57788,6 @@
/obj/effect/turf_decal/trimline/neutral/line,
/turf/open/floor/iron,
/area/station/hallway/primary/starboard)
-"ujl" = (
-/obj/structure/disposalpipe/segment,
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
- dir = 8
- },
-/turf/open/floor/iron/white/small,
-/area/station/service/janitor)
"ujq" = (
/obj/structure/disposalpipe/segment,
/obj/structure/closet/emcloset,
@@ -57704,6 +57876,12 @@
/area/station/security/checkpoint/science)
"ukW" = (
/obj/effect/decal/cleanable/dirt,
+/obj/structure/disposalpipe/segment{
+ dir = 5
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
/turf/open/floor/iron/white/small,
/area/station/service/janitor)
"ulb" = (
@@ -57736,18 +57914,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/circuit,
/area/station/tcommsat/server)
-"ulM" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 4
- },
-/obj/machinery/mineral/stacking_machine{
- input_dir = 2
- },
-/obj/effect/turf_decal/stripes/line{
- dir = 8
- },
-/turf/open/floor/iron/white/small,
-/area/station/service/janitor)
"ulO" = (
/turf/open/floor/plating,
/area/station/maintenance/department/medical/central)
@@ -57810,14 +57976,6 @@
/obj/machinery/firealarm/directional/west,
/turf/open/floor/iron,
/area/station/hallway/primary/central/fore)
-"unz" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/structure/cable,
-/obj/structure/extinguisher_cabinet/directional/north,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"unK" = (
/obj/structure/rack,
/obj/effect/spawner/random/maintenance,
@@ -58000,6 +58158,13 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/central)
+"uqU" = (
+/obj/structure/cable,
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/trap/stun,
+/obj/structure/alien/weeds,
+/turf/open/floor/iron,
+/area/station/maintenance/starboard/greater)
"urd" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -58356,6 +58521,7 @@
/area/station/medical/pharmacy)
"uxL" = (
/obj/structure/broken_flooring/pile/directional/east,
+/obj/structure/trap/stun,
/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"uya" = (
@@ -58500,9 +58666,8 @@
/turf/open/floor/wood/tile,
/area/station/service/bar)
"uAH" = (
-/obj/structure/bed/pod{
- desc = "An old medical bed, just waiting for replacement with something up to date.";
- name = "medical bed"
+/obj/structure/bed/medical{
+ dir = 4
},
/obj/effect/turf_decal/tile/blue/fourcorners,
/obj/item/bedsheet/medical,
@@ -59375,7 +59540,7 @@
/turf/open/floor/iron/dark,
/area/station/medical/pharmacy)
"uQf" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/structure/extinguisher_cabinet/directional/west,
/obj/item/radio/intercom/directional/north,
/turf/open/floor/iron/dark,
@@ -60476,6 +60641,13 @@
/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,
@@ -60527,6 +60699,7 @@
/obj/structure/cable,
/obj/effect/turf_decal/sand/plating,
/obj/machinery/power/floodlight,
+/obj/structure/alien/weeds,
/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"vjx" = (
@@ -60864,8 +61037,8 @@
/area/station/service/chapel/office)
"vnq" = (
/obj/structure/cable,
-/obj/structure/bed{
- dir = 4
+/obj/structure/bed/medical/anchored{
+ dir = 8
},
/obj/item/bedsheet{
dir = 1
@@ -61610,6 +61783,7 @@
/obj/item/cultivator/rake,
/obj/machinery/light/small/directional/west,
/obj/effect/decal/cleanable/dirt,
+/obj/structure/alien/weeds,
/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"vzy" = (
@@ -61725,6 +61899,9 @@
},
/turf/open/misc/sandy_dirt,
/area/station/security/tram)
+"vAD" = (
+/turf/open/floor/wood/tile,
+/area/station/maintenance/port/lesser)
"vAK" = (
/obj/machinery/door/airlock{
name = "Maintenance"
@@ -62423,6 +62600,7 @@
/area/station/medical/pharmacy)
"vMr" = (
/obj/effect/turf_decal/sand/plating,
+/obj/structure/alien/weeds,
/turf/open/misc/asteroid,
/area/station/maintenance/starboard/greater)
"vMs" = (
@@ -62590,6 +62768,11 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/closed/wall/r_wall,
/area/station/hallway/secondary/spacebridge)
+"vPJ" = (
+/obj/structure/broken_flooring/singular/directional/east,
+/obj/structure/alien/weeds,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/greater)
"vPK" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -63734,6 +63917,10 @@
/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{
@@ -63849,8 +64036,14 @@
/turf/open/floor/grass,
/area/station/service/hydroponics/garden/monastery)
"wjM" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/decal/cleanable/dirt,
+/obj/structure/disposalpipe/segment{
+ dir = 10
+ },
+/obj/effect/turf_decal/stripes/corner{
+ dir = 1
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/white/small,
/area/station/service/janitor)
"wjY" = (
@@ -64972,6 +65165,9 @@
/obj/machinery/duct,
/turf/open/floor/plating,
/area/station/maintenance/fore/greater)
+"wBQ" = (
+/turf/open/space/basic,
+/area/station/construction/mining)
"wCa" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
@@ -64996,6 +65192,10 @@
},
/turf/open/floor/iron/dark/small,
/area/station/medical/chemistry)
+"wCz" = (
+/obj/machinery/computer/arcade/orion_trail/kobayashi,
+/turf/open/floor/wood/tile,
+/area/station/maintenance/port/lesser)
"wCH" = (
/obj/effect/turf_decal/stripes/white/line{
dir = 9
@@ -65173,6 +65373,7 @@
/obj/effect/turf_decal/sand/plating,
/obj/structure/table,
/obj/item/storage/belt/mining,
+/obj/structure/alien/weeds,
/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"wFQ" = (
@@ -65507,6 +65708,8 @@
/turf/open/floor/iron,
/area/station/engineering/atmos/storage/gas)
"wKG" = (
+/obj/structure/alien/resin/wall,
+/obj/structure/alien/weeds,
/turf/open/floor/wood,
/area/station/maintenance/starboard/greater)
"wKT" = (
@@ -65842,6 +66045,13 @@
/obj/effect/turf_decal/bot,
/turf/open/floor/iron/dark/small,
/area/station/security/detectives_office)
+"wPu" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/alien/weeds,
+/obj/effect/gibspawner,
+/turf/open/floor/wood,
+/area/station/maintenance/starboard/greater)
"wPK" = (
/obj/effect/turf_decal/tile/neutral/fourcorners,
/obj/structure/chair/office/light{
@@ -66044,6 +66254,7 @@
/obj/machinery/door/airlock/highsecurity{
name = "Secure Tech Storage"
},
+/obj/effect/mapping_helpers/airlock/access/all/command/general,
/turf/open/floor/iron/textured_half,
/area/station/engineering/storage/tech)
"wSL" = (
@@ -66081,6 +66292,11 @@
/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,
@@ -67449,6 +67665,7 @@
/obj/machinery/light/small/directional/east,
/obj/machinery/power/shieldwallgen/xenobiologyaccess,
/obj/effect/decal/cleanable/dirt,
+/obj/structure/cable/multilayer,
/turf/open/floor/plating,
/area/station/science/xenobiology)
"xlP" = (
@@ -68993,16 +69210,6 @@
},
/turf/open/floor/iron/terracotta/small,
/area/station/security/checkpoint/escape)
-"xHm" = (
-/obj/structure/cable,
-/obj/effect/spawner/structure/window/reinforced,
-/obj/machinery/door/poddoor/shutters/preopen{
- dir = 8;
- id = "com_guest";
- name = "Privacy Shutter"
- },
-/turf/open/floor/plating,
-/area/station/command/corporate_suite)
"xHv" = (
/obj/structure/disposalpipe/trunk{
dir = 8
@@ -69392,10 +69599,12 @@
/turf/open/floor/iron/dark/smooth_large,
/area/station/command/bridge)
"xMo" = (
-/obj/structure/frame,
/obj/item/stack/cable_coil/five,
-/obj/item/circuitboard/computer/arcade,
/obj/effect/decal/cleanable/glass,
+/obj/effect/spawner/random/techstorage/arcade_boards,
+/obj/structure/frame/computer{
+ dir = 1
+ },
/turf/open/floor/eighties/red,
/area/station/service/abandoned_gambling_den/gaming)
"xMr" = (
@@ -69769,7 +69978,7 @@
"xRl" = (
/obj/structure/cable,
/obj/machinery/iv_drip,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/power/apc/auto_name/directional/south,
/obj/effect/turf_decal/siding/red,
/turf/open/floor/iron/white,
@@ -70348,6 +70557,12 @@
/obj/effect/spawner/structure/window,
/turf/open/floor/plating,
/area/station/security/processing)
+"xYz" = (
+/obj/structure/alien/weeds,
+/obj/structure/alien/weeds,
+/obj/effect/gibspawner/human,
+/turf/open/misc/asteroid,
+/area/station/maintenance/starboard/greater)
"xYD" = (
/turf/open/floor/grass,
/area/station/service/hydroponics/garden/monastery)
@@ -70501,7 +70716,7 @@
/obj/effect/turf_decal/siding/white,
/obj/machinery/light/small/directional/south,
/obj/structure/table/reinforced,
-/obj/item/storage/backpack/duffelbag/coroner/surgery,
+/obj/item/surgery_tray/full/morgue,
/turf/open/floor/iron/small,
/area/station/medical/morgue)
"yaL" = (
@@ -71357,6 +71572,12 @@
/obj/effect/spawner/structure/window,
/turf/open/floor/plating,
/area/station/commons/fitness/locker_room)
+"yma" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/alien/resin/wall,
+/obj/structure/alien/weeds,
+/turf/open/floor/wood,
+/area/station/maintenance/starboard/greater)
"ymd" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -81037,7 +81258,7 @@ dDB
dDB
blb
dDB
-dDB
+wBQ
dDB
blb
dDB
@@ -81554,10 +81775,10 @@ tYT
cCE
tYT
fEC
-aJq
-aJq
-tYT
-tYT
+ofZ
+ofZ
+fEC
+fEC
dDB
dDB
dDB
@@ -81811,11 +82032,11 @@ qkK
cFS
qkK
fEC
-aJq
-aJq
-vmL
-tYT
-tYT
+wCz
+vAD
+roq
+fEC
+fEC
tYT
tYT
aJq
@@ -82068,11 +82289,11 @@ kCo
peR
dyW
fEC
-aJq
-tYT
-tYT
-vmL
-tYT
+eHN
+vAD
+vAD
+roq
+fEC
vmL
aJq
aJq
@@ -82325,12 +82546,11 @@ qXB
tmT
qXB
fEC
-aJq
-tYT
-vmL
-tYT
-vmL
-aJq
+eHN
+uhq
+tXl
+vAD
+num
aJq
aJq
aJq
@@ -82339,6 +82559,7 @@ aJq
aJq
aJq
aJq
+pRb
dDB
dDB
dDB
@@ -82582,12 +82803,11 @@ hbm
aZw
vSW
fEC
-vmL
-tYT
-vmL
-vmL
-gcs
-aJq
+iBE
+uhq
+tXl
+roq
+fEC
aJq
aJq
aJq
@@ -82596,6 +82816,7 @@ aJq
aJq
aJq
aJq
+pRb
aJq
aJq
aJq
@@ -82782,7 +83003,7 @@ uzJ
mQh
nJU
ppk
-odN
+lnT
ovQ
oRr
poM
@@ -82837,14 +83058,13 @@ qVP
wmV
cpH
tqo
-tqo
+hzV
+eHN
+iBE
+roq
+roq
+roq
fEC
-vmL
-vmL
-vmL
-vmL
-gcs
-aJq
aJq
aJq
aJq
@@ -82853,6 +83073,7 @@ aJq
aJq
aJq
aJq
+pRb
aJq
aJq
aJq
@@ -83094,7 +83315,7 @@ qVP
fEC
cpH
fEC
-tqo
+hzV
fEC
qVP
fNu
@@ -83283,14 +83504,14 @@ gOK
slY
hfc
slY
-hsX
+viR
jBb
kPW
kwY
-lQq
-kOA
+whS
+dmz
slY
-lzn
+hzN
lRc
moz
kee
@@ -83351,7 +83572,7 @@ qVP
nHu
dpt
tvZ
-tqo
+hzV
efr
qVP
ets
@@ -83540,14 +83761,14 @@ gPN
gZk
iNE
ueX
-htt
+mLx
kwY
slY
slY
kwY
slY
slY
-kzF
+jXE
lTv
oem
oem
@@ -83800,10 +84021,10 @@ jCo
hff
jCo
slY
-kfA
-lQq
+wTn
+whS
kPW
-iUG
+tDm
jkS
lTN
mRD
@@ -84061,7 +84282,7 @@ slY
slY
slY
slY
-unz
+ciL
lUz
ohj
ohj
@@ -84311,7 +84532,7 @@ sNz
hyO
roi
slY
-huc
+hFm
hAN
jMb
kzI
@@ -97930,7 +98151,7 @@ qjy
vPP
otX
hei
-xHm
+hei
vPP
hxJ
jVe
@@ -103595,9 +103816,9 @@ sOs
xmO
lKn
nFW
+dXO
sRL
sRL
-nEJ
nVX
sRL
sRL
@@ -103854,10 +104075,10 @@ sHe
nFW
kam
boX
-kBH
+asZ
ukW
cZL
-xVV
+sRL
dCH
ixP
sRL
@@ -104108,9 +104329,9 @@ kCW
xID
xmO
sHs
-nFW
+pke
tzD
-ukW
+cqS
kCN
wjM
lcW
@@ -104365,11 +104586,11 @@ rIJ
rAG
xmO
sHe
-mhW
+nFW
mEy
-ncf
+hsK
nFA
-ujl
+kBH
onR
xVV
lOt
@@ -104624,9 +104845,9 @@ xmO
qzO
nFW
ghW
-ulM
+boX
kCP
-kbc
+kBH
saD
sRL
sRL
@@ -104881,7 +105102,7 @@ sJR
sIA
jPq
kaF
-roB
+ffD
hTW
roB
lde
@@ -105137,10 +105358,10 @@ xmO
jsn
sIS
nFW
+sRL
+sRL
xVV
-xVV
-xVV
-xVV
+sRL
xVV
sRL
bFg
@@ -111588,7 +111809,7 @@ rVX
stP
wbu
tbD
-tyv
+ygu
xdc
ugC
xSZ
@@ -123072,7 +123293,7 @@ atE
atE
atG
axq
-axq
+jaP
aMa
aPx
atE
@@ -126002,8 +126223,8 @@ cCl
cCl
oGQ
oGQ
-oGQ
-oGQ
+bnr
+bnr
qkp
rfZ
sEB
@@ -126260,7 +126481,7 @@ ylD
ylD
ylD
mUn
-ylD
+mMr
ylD
rhL
rTq
@@ -126511,11 +126732,11 @@ eDI
xZy
ylD
jmd
-sCH
+bRm
wKG
lAO
ncb
-ylD
+mMr
oNH
pFk
ylD
@@ -126523,8 +126744,8 @@ rir
sIZ
sEB
bGi
-ylD
-vlb
+mMr
+vPJ
dTB
ylD
pdt
@@ -126770,19 +126991,19 @@ ylD
joS
kxm
rEb
-nhB
-nhB
+oiU
+oiU
mZA
-oNH
+uqU
naC
ylD
rlg
tTA
bAI
fbj
-ylD
-uxL
-xlx
+mMr
+nuY
+ovB
ylD
ylD
ylD
@@ -127025,11 +127246,11 @@ lgf
xZy
ylD
sKS
-nhB
-sCH
+wPu
+yma
lQu
-ylD
-ylD
+mMr
+mMr
oWk
qHt
ylD
@@ -127037,9 +127258,9 @@ ylD
ylD
ylD
ylD
-ylD
+mMr
dOb
-xlx
+ovB
cFq
xZy
xZy
@@ -127281,13 +127502,13 @@ wdk
goZ
fmq
ylD
-nhB
-sCH
+byU
+pfh
mwx
wgF
ylD
rZG
-xlx
+ovB
bNP
fii
fNv
@@ -127546,7 +127767,7 @@ ylD
xcH
xmg
pHn
-qHt
+mlm
vlb
xgz
iKo
@@ -127557,7 +127778,7 @@ jxD
ylD
hqH
vzv
-wyj
+brz
cgM
ylD
wyj
@@ -127813,7 +128034,7 @@ ylD
ylD
ylD
aEB
-cgM
+tzo
vMr
gbD
ylD
@@ -128059,10 +128280,10 @@ tZt
ylD
wFz
baE
-cgM
+fcq
lkd
-lgf
-cgM
+fkT
+fcq
sQv
xwd
wdk
@@ -128315,8 +128536,8 @@ ylD
ylD
ylD
olm
-cgM
-lgf
+fcq
+fkT
jcm
lkd
lkd
@@ -128571,15 +128792,15 @@ cgM
lnI
cgM
cgM
-cgM
-cgM
-cgM
-cgM
+fcq
+fcq
+mcl
+xYz
lkd
-cgM
-lgf
-cgM
-cgM
+fcq
+fkT
+fcq
+fcq
cgM
wdk
wdk
@@ -128828,17 +129049,17 @@ wdk
wdk
lhQ
lgf
-lgf
-cgM
-cgM
-cgM
-vjp
-cgM
-cgM
-cgM
-cgM
-cgM
-cgM
+fkT
+mcl
+mcl
+xYz
+gSk
+fcq
+oBh
+fcq
+fcq
+fcq
+fcq
wdk
wdk
wdk
@@ -129087,14 +129308,14 @@ wdk
wdk
wdk
wdk
-cgM
-cgM
+fcq
+fcq
tiN
aCM
bDq
eUF
jar
-ylD
+mMr
fPR
ylD
aJq
@@ -129865,9 +130086,9 @@ aJq
tYT
tYT
tYT
+eJH
tYT
-tYT
-tYT
+eJH
tYT
aJq
aJq
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index 9bb336d23d3..15c9aae2b71 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -2533,7 +2533,6 @@
/turf/open/space,
/area/space/nearstation)
"aFs" = (
-/obj/machinery/lapvend,
/obj/effect/turf_decal/trimline/blue/filled/warning{
dir = 4
},
@@ -6286,8 +6285,8 @@
/turf/open/floor/iron,
/area/station/science/robotics/lab)
"bBG" = (
-/obj/structure/bed{
- dir = 4
+/obj/structure/bed/medical/anchored{
+ dir = 8
},
/obj/item/bedsheet/medical{
dir = 4
@@ -7909,7 +7908,9 @@
/obj/effect/turf_decal/trimline/neutral/mid_joiner{
dir = 4
},
-/obj/structure/bed,
+/obj/structure/bed/medical/anchored{
+ dir = 4
+ },
/obj/item/bedsheet/medical,
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
@@ -8178,14 +8179,14 @@
/turf/open/floor/iron,
/area/station/commons/fitness/recreation)
"bWw" = (
-/obj/machinery/button/flasher{
- id = "Cell 6";
- name = "Prisoner Flash";
- pixel_x = -25
- },
/obj/effect/turf_decal/tile/red{
dir = 4
},
+/obj/machinery/status_display/door_timer{
+ id = "Isolation_Cell";
+ name = "Isolation Cell";
+ pixel_x = -32
+ },
/turf/open/floor/iron,
/area/station/security/execution/transfer)
"bWD" = (
@@ -9197,7 +9198,7 @@
/area/station/medical/psychology)
"ckB" = (
/obj/structure/closet/secure_closet/hop,
-/obj/item/clothing/suit/costume/ianshirt,
+/obj/item/clothing/suit/costume/wellworn_shirt/graphic/ian,
/obj/item/bedsheet/ian,
/turf/open/floor/iron/grimy,
/area/station/command/heads_quarters/hop)
@@ -14308,7 +14309,7 @@
/turf/open/floor/iron/dark,
/area/station/service/theater)
"dxo" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/item/radio/intercom/directional/south,
/obj/effect/turf_decal/trimline/blue/filled/line,
/turf/open/floor/iron/white,
@@ -15844,7 +15845,7 @@
/area/station/cargo/lobby)
"dRQ" = (
/obj/structure/table/glass,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/structure/window/reinforced/spawner/directional/west,
/obj/item/clothing/gloves/latex,
/obj/item/clothing/suit/apron/surgical,
@@ -17317,7 +17318,9 @@
dir = 4;
id = "garbage"
},
-/obj/machinery/recycler,
+/obj/machinery/recycler{
+ dir = 8
+ },
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/stripes/line,
/turf/open/floor/plating,
@@ -22258,7 +22261,7 @@
/area/station/security/checkpoint/supply)
"fym" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/trimline/green/filled/line{
dir = 1
},
@@ -23596,6 +23599,7 @@
dir = 5
},
/obj/item/radio/intercom/directional/south,
+/obj/item/mod/module/signlang_radio,
/turf/open/floor/iron/dark,
/area/station/security/office)
"fQF" = (
@@ -24094,11 +24098,11 @@
/obj/effect/turf_decal/stripes/line{
dir = 1
},
-/obj/effect/mapping_helpers/airlock/access/any/engineering/maintenance/departmental,
/obj/effect/mapping_helpers/airlock/unres{
dir = 1
},
/obj/machinery/atmospherics/pipe/layer_manifold/supply/hidden,
+/obj/effect/mapping_helpers/airlock/access/all/engineering/atmos,
/turf/open/floor/iron,
/area/station/maintenance/department/electrical)
"fXk" = (
@@ -25396,12 +25400,12 @@
/obj/effect/turf_decal/stripes/line{
dir = 1
},
-/obj/effect/mapping_helpers/airlock/access/any/engineering/maintenance/departmental,
/obj/effect/mapping_helpers/airlock/unres{
dir = 1
},
/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/engineering/general,
/turf/open/floor/iron,
/area/station/maintenance/department/electrical)
"gmE" = (
@@ -27895,16 +27899,6 @@
},
/turf/open/floor/iron,
/area/station/maintenance/central)
-"gQw" = (
-/obj/machinery/airalarm/directional/south,
-/obj/effect/turf_decal/bot,
-/obj/item/computer_disk/engineering,
-/obj/item/computer_disk/engineering,
-/obj/item/computer_disk/engineering,
-/obj/structure/rack,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron/dark,
-/area/station/command/heads_quarters/ce)
"gQz" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/structure/cable,
@@ -28131,7 +28125,7 @@
/area/station/medical/cryo)
"gTH" = (
/obj/machinery/flasher/directional/south{
- id = "Cell 6"
+ id = "Isolation_Cell"
},
/obj/machinery/light/small/broken/directional/south,
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
@@ -30051,7 +30045,7 @@
/turf/open/floor/iron/dark,
/area/station/security/warden)
"huR" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/trimline/blue/filled/line,
/turf/open/floor/iron/white,
/area/station/medical/medbay/lobby)
@@ -38916,7 +38910,9 @@
/turf/open/floor/iron,
/area/station/cargo/office)
"jFJ" = (
-/obj/structure/bed,
+/obj/structure/bed/medical/anchored{
+ dir = 4
+ },
/obj/item/bedsheet/medical,
/obj/structure/sign/nanotrasen{
pixel_x = 32
@@ -39899,10 +39895,10 @@
"jRJ" = (
/obj/machinery/defibrillator_mount/directional/south,
/obj/item/radio/intercom/directional/west,
-/obj/item/roller{
+/obj/item/emergency_bed{
pixel_y = 6
},
-/obj/item/roller{
+/obj/item/emergency_bed{
pixel_y = 11
},
/obj/structure/table/reinforced/rglass,
@@ -47742,8 +47738,8 @@
/turf/open/floor/iron,
/area/station/security/checkpoint/escape)
"lQj" = (
-/obj/structure/bed{
- dir = 4
+/obj/structure/bed/medical{
+ dir = 8
},
/obj/item/clothing/suit/jacket/straight_jacket,
/obj/item/clothing/mask/muzzle,
@@ -48393,7 +48389,7 @@
/turf/open/floor/iron,
/area/station/maintenance/port/fore)
"mbA" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/newscaster/directional/south,
/obj/effect/turf_decal/trimline/blue/filled/line,
/obj/machinery/light/directional/south,
@@ -52514,7 +52510,7 @@
dir = 4
},
/obj/structure/table/reinforced,
-/obj/item/storage/backpack/duffelbag/coroner/surgery,
+/obj/item/surgery_tray/full/morgue,
/obj/effect/turf_decal/tile/dark_blue/half/contrasted{
dir = 4
},
@@ -58439,6 +58435,16 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/engineering/atmos)
+"oIL" = (
+/obj/machinery/airalarm/directional/south,
+/obj/effect/turf_decal/bot,
+/obj/item/computer_disk/engineering,
+/obj/item/computer_disk/engineering,
+/obj/item/computer_disk/engineering,
+/obj/structure/rack,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron/dark,
+/area/station/command/heads_quarters/ce)
"oIU" = (
/obj/structure/cable,
/obj/effect/spawner/structure/window/reinforced,
@@ -58813,7 +58819,7 @@
/area/station/commons/locker)
"oOz" = (
/obj/structure/extinguisher_cabinet/directional/north,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/item/restraints/handcuffs,
/obj/effect/turf_decal/trimline/green/filled/line{
dir = 9
@@ -59358,7 +59364,7 @@
},
/area/station/service/chapel)
"oVI" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/delivery,
/turf/open/floor/iron,
@@ -59413,7 +59419,7 @@
/obj/effect/turf_decal/trimline/neutral/mid_joiner{
dir = 8
},
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/security/medical)
@@ -61090,6 +61096,7 @@
/obj/machinery/power/apc/auto_name/directional/east,
/obj/item/mod/module/tether,
/obj/item/mod/module/tether,
+/obj/item/stack/sheet/plasteel/fifty,
/turf/open/floor/iron,
/area/station/engineering/storage)
"ptC" = (
@@ -64488,7 +64495,7 @@
/turf/closed/wall/r_wall,
/area/station/science/ordnance/storage)
"qgp" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/item/bot_assembly/medbot,
/turf/open/floor/plating,
/area/station/medical/abandoned)
@@ -68167,9 +68174,8 @@
/turf/open/floor/iron,
/area/station/hallway/secondary/entry)
"rff" = (
-/obj/structure/bed/pod{
- desc = "An old medical bed, just waiting for replacement with something up to date.";
- name = "medical bed"
+/obj/structure/bed/medical{
+ dir = 4
},
/obj/structure/window/reinforced/spawner/directional/east,
/obj/effect/turf_decal/tile/blue/fourcorners,
@@ -68740,9 +68746,9 @@
/obj/effect/turf_decal/stripes/line{
dir = 1
},
-/obj/effect/mapping_helpers/airlock/access/any/engineering/maintenance/departmental,
/obj/effect/mapping_helpers/airlock/unres,
/obj/structure/cable,
+/obj/effect/mapping_helpers/airlock/access/all/engineering/general,
/turf/open/floor/iron,
/area/station/maintenance/department/electrical)
"rly" = (
@@ -70229,7 +70235,7 @@
/area/station/engineering/atmos/pumproom)
"rFm" = (
/obj/structure/window/reinforced/spawner/directional/south,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/effect/turf_decal/siding/dark_blue,
/obj/effect/turf_decal/tile/dark_blue/half/contrasted,
@@ -77237,7 +77243,7 @@
/area/station/engineering/atmos)
"tsx" = (
/obj/structure/table/glass,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/item/clothing/gloves/latex,
/obj/item/clothing/suit/apron/surgical,
/obj/effect/turf_decal/tile/neutral/fourcorners,
@@ -78409,7 +78415,6 @@
/area/station/medical/morgue)
"tGm" = (
/obj/structure/table/reinforced,
-/obj/item/stack/sheet/plasteel/fifty,
/obj/item/stack/sheet/rglass{
amount = 50;
pixel_x = 2;
@@ -78424,6 +78429,7 @@
/obj/item/mod/module/plasma_stabilizer,
/obj/item/mod/module/thermal_regulator,
/obj/item/mod/module/magboot,
+/obj/item/mod/module/signlang_radio,
/turf/open/floor/iron,
/area/station/engineering/storage)
"tGq" = (
@@ -80977,11 +80983,11 @@
/obj/effect/turf_decal/stripes/line{
dir = 1
},
-/obj/effect/mapping_helpers/airlock/access/any/engineering/maintenance/departmental,
/obj/effect/mapping_helpers/airlock/unres{
dir = 1
},
/obj/machinery/atmospherics/pipe/layer_manifold/scrubbers/hidden,
+/obj/effect/mapping_helpers/airlock/access/all/engineering/atmos,
/turf/open/floor/iron,
/area/station/maintenance/department/electrical)
"umM" = (
@@ -81533,7 +81539,7 @@
/turf/open/floor/iron/white,
/area/station/science/lab)
"uue" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/effect/turf_decal/tile/blue/opposingcorners,
/turf/open/floor/iron,
@@ -85138,7 +85144,7 @@
/turf/open/floor/iron,
/area/station/engineering/atmos/storage/gas)
"vnB" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/machinery/camera/directional/east{
c_tag = "Medbay - Operating Room";
@@ -85556,7 +85562,7 @@
/turf/open/floor/iron,
/area/station/science/research/abandoned)
"vtt" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/effect/turf_decal/tile/red/half/contrasted{
dir = 4
@@ -93154,7 +93160,9 @@
/turf/open/floor/iron,
/area/station/engineering/atmos)
"xqc" = (
-/obj/structure/bed,
+/obj/structure/bed/medical{
+ dir = 4
+ },
/obj/item/clothing/suit/jacket/straight_jacket,
/obj/item/clothing/mask/muzzle,
/obj/item/clothing/glasses/blindfold,
@@ -93291,7 +93299,7 @@
"xsj" = (
/obj/machinery/power/apc/auto_name/directional/west,
/obj/structure/cable,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/effect/turf_decal/tile/red/anticorner/contrasted{
dir = 1
@@ -93501,6 +93509,7 @@
dir = 1
},
/obj/machinery/digital_clock/directional/south,
+/obj/item/mod/module/signlang_radio,
/turf/open/floor/iron,
/area/station/medical/storage)
"xtZ" = (
@@ -119271,7 +119280,7 @@ ylf
ylf
ylf
eDp
-gQw
+oIL
gAw
phn
gAw
diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
index cf0cd03c97a..f3ff89fcc80 100644
--- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm
+++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
@@ -36,11 +36,13 @@
/obj/structure/flora/bush/flowers_pp/style_random,
/turf/open/floor/grass,
/area/station/security/prison/safe)
-"aaT" = (
-/obj/structure/table/wood,
-/obj/item/flashlight/lamp/green,
-/turf/open/floor/carpet/red,
-/area/station/commons/vacant_room/office)
+"aaW" = (
+/obj/machinery/camera/directional/south{
+ c_tag = "Port Hallway West"
+ },
+/obj/effect/turf_decal/tile/green,
+/turf/open/floor/iron,
+/area/station/hallway/primary/port)
"aaX" = (
/obj/structure/chair/sofa/bench/right,
/turf/open/misc/asteroid/snow/icemoon,
@@ -54,12 +56,12 @@
"abe" = (
/turf/open/floor/engine,
/area/station/science/xenobiology)
-"abu" = (
-/obj/effect/turf_decal/stripes/corner{
- dir = 8
+"abv" = (
+/obj/effect/turf_decal/loading_area{
+ dir = 1
},
-/obj/effect/turf_decal/stripes/corner,
-/turf/open/floor/iron,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron/dark,
/area/station/hallway/secondary/entry)
"abz" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
@@ -103,10 +105,6 @@
/obj/structure/table/wood,
/turf/open/floor/wood,
/area/station/maintenance/port/aft)
-"ack" = (
-/obj/structure/closet/emcloset,
-/turf/open/floor/plating,
-/area/station/hallway/secondary/entry)
"acr" = (
/obj/structure/table/wood,
/obj/effect/spawner/random/entertainment/gambling,
@@ -145,16 +143,20 @@
/obj/effect/turf_decal/tile/blue/full,
/turf/open/floor/iron/large,
/area/station/medical/treatment_center)
+"adq" = (
+/obj/machinery/door/airlock/maintenance,
+/obj/effect/mapping_helpers/airlock/unres{
+ dir = 4
+ },
+/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"adD" = (
/obj/structure/railing/corner{
dir = 8
},
/turf/open/lava/plasma/ice_moon,
/area/icemoon/underground/explored)
-"adW" = (
-/obj/machinery/light/directional/south,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"adY" = (
/obj/structure/cable,
/obj/effect/spawner/structure/window/reinforced,
@@ -169,6 +171,15 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/wood,
/area/station/maintenance/aft/lesser)
+"ael" = (
+/obj/effect/turf_decal/siding/thinplating_new/corner{
+ dir = 8
+ },
+/obj/effect/turf_decal/siding/thinplating_new{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
"aen" = (
/obj/machinery/atmospherics/pipe/smart/simple/green/visible{
dir = 5
@@ -290,12 +301,6 @@
/obj/structure/table/wood,
/turf/open/floor/wood/tile,
/area/station/service/theater)
-"agh" = (
-/obj/effect/landmark/start/hangover,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/obj/effect/turf_decal/tile/neutral,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"agk" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -339,6 +344,10 @@
/obj/effect/turf_decal/tile/red/half/contrasted,
/turf/open/floor/iron/dark/textured,
/area/station/ai_monitored/security/armory)
+"agG" = (
+/obj/structure/sign/poster/official/random/directional/east,
+/turf/open/floor/iron/grimy,
+/area/station/hallway/secondary/entry)
"agI" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -418,6 +427,14 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/iron/dark,
/area/station/service/chapel)
+"aiA" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/effect/spawner/random/trash/mess,
+/obj/effect/decal/cleanable/dirt/dust,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"aiH" = (
/obj/structure/table,
/obj/item/folder/white,
@@ -537,6 +554,13 @@
/obj/structure/chair/stool/directional/east,
/turf/open/floor/iron,
/area/station/commons/dorms)
+"akK" = (
+/obj/effect/turf_decal/siding/wood{
+ dir = 1
+ },
+/obj/effect/decal/cleanable/dirt/dust,
+/turf/open/floor/iron/grimy,
+/area/station/commons/vacant_room/office)
"akL" = (
/obj/effect/turf_decal/bot{
dir = 1
@@ -594,6 +618,13 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/wood,
/area/station/security/prison/rec)
+"alD" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 1
+ },
+/obj/effect/turf_decal/siding/thinplating_new/corner,
+/turf/open/floor/iron/large,
+/area/station/hallway/secondary/entry)
"alK" = (
/obj/machinery/power/apc/auto_name/directional/east,
/obj/machinery/power/port_gen/pacman,
@@ -725,13 +756,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/carpet,
/area/station/command/heads_quarters/captain)
-"anG" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/turf_decal/tile/neutral/half/contrasted{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"anK" = (
/obj/effect/turf_decal/trimline/green/filled/line{
dir = 4
@@ -765,6 +789,14 @@
/obj/machinery/light/floor,
/turf/open/floor/iron,
/area/station/command/bridge)
+"aol" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/disposalpipe/segment,
+/obj/machinery/firealarm/directional/east,
+/turf/open/floor/iron,
+/area/station/command/heads_quarters/hop)
"aoo" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -793,11 +825,6 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/commons/dorms)
-"aoK" = (
-/obj/structure/table,
-/obj/item/toy/cards/deck,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"aoP" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/public/glass{
@@ -840,6 +867,15 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/dark,
/area/station/ai_monitored/turret_protected/aisat/service)
+"apq" = (
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/siding/thinplating_new/corner{
+ dir = 8
+ },
+/obj/item/radio/intercom/directional/east,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"apt" = (
/obj/effect/turf_decal/trimline/green/filled/corner{
dir = 4
@@ -855,17 +891,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/medbay/aft)
-"apz" = (
-/obj/structure/table/wood,
-/obj/item/storage/fancy/cigarettes{
- pixel_y = 2
- },
-/obj/item/lighter/greyscale{
- pixel_x = 4;
- pixel_y = 2
- },
-/turf/open/floor/iron/grimy,
-/area/station/hallway/secondary/entry)
"apB" = (
/obj/effect/spawner/structure/window/hollow/reinforced/middle{
dir = 4
@@ -934,14 +959,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/virology)
-"aqy" = (
-/obj/machinery/door/airlock/external,
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
- dir = 4
- },
-/obj/effect/mapping_helpers/airlock/access/all/engineering/external,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"aqB" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -964,17 +981,6 @@
},
/turf/open/floor/iron,
/area/station/commons/vacant_room/commissary)
-"aqT" = (
-/obj/machinery/conveyor{
- dir = 8;
- id = "garbage"
- },
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/structure/disposalpipe/segment,
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"arb" = (
/obj/structure/table,
/obj/item/folder/red,
@@ -1019,11 +1025,13 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/security/office)
-"arO" = (
-/obj/structure/table,
-/obj/effect/spawner/random/entertainment/dice,
+"arG" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/airalarm/directional/east,
+/obj/structure/cable,
/turf/open/floor/iron,
-/area/station/commons/locker)
+/area/station/hallway/secondary/entry)
"arT" = (
/obj/machinery/computer/security/labor{
dir = 4
@@ -1051,16 +1059,16 @@
/obj/effect/spawner/random/maintenance/two,
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
-"asp" = (
-/obj/machinery/camera/directional/south{
- c_tag = "Port Hallway Center"
- },
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+"asm" = (
+/obj/structure/chair/sofa/bench/right{
dir = 1
},
-/obj/machinery/light/directional/south,
-/turf/open/floor/iron,
-/area/station/hallway/primary/port)
+/obj/effect/turf_decal/stripes/line,
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/turf/open/floor/iron/white/corner,
+/area/station/hallway/secondary/entry)
"asy" = (
/obj/effect/turf_decal/stripes/line{
dir = 6
@@ -1095,12 +1103,6 @@
/obj/effect/turf_decal/tile/yellow/opposingcorners,
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/project)
-"asO" = (
-/obj/structure/chair/stool/directional/north,
-/obj/effect/decal/cleanable/dirt,
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
-/turf/open/floor/iron,
-/area/station/maintenance/port/fore)
"asZ" = (
/obj/machinery/door/airlock/research{
name = "Robotics Lab"
@@ -1159,11 +1161,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/virology)
-"atn" = (
-/obj/structure/frame/computer,
-/obj/structure/sign/poster/official/help_others/directional/north,
-/turf/open/floor/iron,
-/area/station/maintenance/port/fore)
"atv" = (
/obj/item/radio/intercom/directional/south,
/turf/open/floor/iron,
@@ -1208,13 +1205,27 @@
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 4
+ },
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 8
+ },
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron/dark/textured,
/area/station/hallway/primary/port)
"aud" = (
/obj/structure/closet/secure_closet/miner,
/obj/machinery/light/directional/east,
/turf/open/floor/iron,
/area/station/cargo/miningdock)
+"aui" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 4
+ },
+/obj/structure/cable,
+/turf/open/floor/iron/large,
+/area/station/hallway/secondary/entry)
"aus" = (
/obj/effect/turf_decal/stripes/corner{
dir = 8
@@ -1320,20 +1331,6 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/ai_monitored/security/armory/upper)
-"awh" = (
-/obj/effect/decal/cleanable/blood/gibs/old,
-/obj/effect/mapping_helpers/burnt_floor,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
-"awk" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/neutral/half/contrasted{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"awn" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -1359,7 +1356,9 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/structure/cable,
-/obj/structure/disposalpipe/segment,
+/obj/structure/disposalpipe/junction{
+ dir = 4
+ },
/turf/open/floor/iron,
/area/station/hallway/primary/port)
"awK" = (
@@ -1390,6 +1389,18 @@
/obj/machinery/light/small/directional/north,
/turf/open/floor/iron/dark,
/area/station/security/courtroom)
+"awR" = (
+/obj/machinery/conveyor{
+ id = "garbage";
+ dir = 1
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/stripes/line{
+ dir = 4
+ },
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"axb" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 4
@@ -1587,6 +1598,23 @@
/obj/effect/mapping_helpers/airlock/access/all/engineering/engine_equipment,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
+"azN" = (
+/obj/structure/rack,
+/obj/item/tank/internals/emergency_oxygen{
+ pixel_x = 5;
+ pixel_y = -2
+ },
+/obj/item/tank/internals/emergency_oxygen{
+ pixel_y = 3
+ },
+/obj/item/tank/internals/emergency_oxygen,
+/obj/item/clothing/mask/gas,
+/obj/item/clothing/mask/gas,
+/obj/item/radio/intercom/directional/west,
+/obj/structure/cable,
+/obj/effect/turf_decal/delivery/red,
+/turf/open/floor/iron/dark/textured,
+/area/station/hallway/secondary/entry)
"azU" = (
/obj/structure/table/reinforced,
/obj/machinery/door/poddoor/shutters/preopen{
@@ -1638,12 +1666,6 @@
},
/turf/open/floor/circuit/red,
/area/station/ai_monitored/turret_protected/ai_upload)
-"aAu" = (
-/obj/machinery/light/directional/west,
-/obj/structure/closet/wardrobe/grey,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"aAv" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -1685,6 +1707,20 @@
"aBR" = (
/turf/open/genturf/blue,
/area/icemoon/surface/outdoors/noruins)
+"aBT" = (
+/obj/machinery/door/airlock/external,
+/obj/effect/mapping_helpers/airlock/cyclelink_helper{
+ dir = 4
+ },
+/obj/effect/mapping_helpers/airlock/access/all/engineering/external,
+/turf/open/floor/plating,
+/area/station/commons/dorms/laundry)
+"aBX" = (
+/obj/effect/spawner/structure/window/hollow/reinforced/middle{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"aCb" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -1731,18 +1767,14 @@
},
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/underground/explored)
-"aCJ" = (
-/obj/effect/turf_decal/siding/wood{
+"aCU" = (
+/obj/effect/spawner/random/maintenance,
+/obj/structure/disposalpipe/segment{
dir = 4
},
-/turf/open/floor/wood,
-/area/station/commons/vacant_room/office)
-"aCW" = (
-/obj/structure/chair/office{
- dir = 1
- },
-/turf/open/floor/iron/grimy,
-/area/station/commons/vacant_room/office)
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"aCX" = (
/obj/structure/table,
/obj/item/stock_parts/subspace/filter,
@@ -1760,10 +1792,13 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/wood,
/area/station/service/library)
-"aDx" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
+"aDy" = (
+/obj/machinery/light/directional/south,
+/obj/effect/spawner/random/vending/colavend,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/structure/sign/poster/official/random/directional/south,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"aDJ" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -1771,13 +1806,6 @@
/obj/effect/landmark/start/prisoner,
/turf/open/floor/iron/dark/side,
/area/station/security/prison)
-"aDN" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/turf_decal/tile/blue{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"aDZ" = (
/obj/structure/sign/warning/secure_area/directional/east,
/obj/machinery/door/firedoor,
@@ -1872,12 +1900,6 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/ai_monitored/turret_protected/aisat/atmos)
-"aFr" = (
-/obj/effect/spawner/structure/window/hollow/reinforced/middle{
- dir = 1
- },
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"aFt" = (
/obj/machinery/dna_scannernew,
/turf/open/floor/iron/dark,
@@ -1911,6 +1933,17 @@
},
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/underground/explored)
+"aFH" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/turf_decal/siding/green/corner{
+ dir = 1
+ },
+/obj/structure/disposalpipe/segment{
+ dir = 10
+ },
+/turf/open/floor/iron,
+/area/station/service/hydroponics/garden)
"aFJ" = (
/obj/structure/disposalpipe/segment{
dir = 5
@@ -1968,16 +2001,6 @@
/obj/effect/turf_decal/tile/brown/anticorner/contrasted,
/turf/open/floor/iron,
/area/station/cargo/office)
-"aHL" = (
-/obj/machinery/door/airlock/maintenance,
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/mapping_helpers/airlock/unres{
- dir = 1
- },
-/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"aHT" = (
/turf/closed/wall,
/area/station/security/checkpoint/science)
@@ -2190,6 +2213,16 @@
/obj/structure/altar_of_gods,
/turf/open/floor/iron/dark,
/area/station/service/chapel)
+"aLz" = (
+/obj/machinery/conveyor{
+ id = "garbage"
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"aLA" = (
/obj/structure/cable,
/obj/machinery/door/poddoor/preopen{
@@ -2207,18 +2240,18 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/visible,
/turf/open/floor/iron,
/area/station/maintenance/disposal/incinerator)
-"aLK" = (
-/obj/machinery/power/apc/auto_name/directional/east,
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/blue{
- dir = 4
- },
-/turf/open/floor/iron/white/corner,
-/area/station/hallway/secondary/entry)
"aLM" = (
/obj/machinery/shower/directional/south,
/turf/open/floor/iron/showroomfloor,
/area/station/security/prison/toilet)
+"aLO" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/turf_decal/siding/wood/corner{
+ dir = 8
+ },
+/obj/structure/sign/clock/directional/east,
+/turf/open/floor/wood,
+/area/station/commons/vacant_room/office)
"aLV" = (
/obj/machinery/bluespace_vendor/directional/south,
/turf/open/floor/iron,
@@ -2340,28 +2373,17 @@
/obj/machinery/portable_atmospherics/canister/oxygen,
/turf/open/floor/plating,
/area/mine/eva/lower)
-"aNz" = (
-/obj/item/reagent_containers/spray/plantbgone,
-/obj/item/reagent_containers/spray/pestspray{
- pixel_x = 3;
- pixel_y = 4
- },
-/obj/item/reagent_containers/cup/bottle/nutrient/ez,
-/obj/item/reagent_containers/cup/bottle/nutrient/rh{
- pixel_x = 2;
- pixel_y = 1
- },
-/obj/structure/table/glass,
-/obj/effect/turf_decal/tile/green/anticorner/contrasted{
- dir = 1
- },
-/turf/open/floor/iron/dark,
-/area/station/service/hydroponics/garden)
"aNR" = (
/obj/machinery/smartfridge,
/obj/machinery/door/firedoor,
/turf/open/floor/iron,
/area/station/service/bar/backroom)
+"aOa" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/decal/cleanable/dirt/dust,
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"aOd" = (
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
@@ -2459,13 +2481,6 @@
"aPD" = (
/turf/closed/wall/r_wall,
/area/station/engineering/storage_shared)
-"aPI" = (
-/obj/machinery/door/firedoor,
-/obj/machinery/door/airlock/public/glass{
- name = "Arrivals"
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"aPM" = (
/obj/effect/turf_decal/siding/wood{
dir = 8
@@ -2503,14 +2518,6 @@
},
/turf/open/floor/iron/dark/textured,
/area/station/ai_monitored/security/armory/upper)
-"aQb" = (
-/obj/structure/closet/secure_closet/personal{
- anchored = 1
- },
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/obj/machinery/light/directional/south,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"aQe" = (
/obj/item/clothing/shoes/jackboots,
/turf/open/floor/plating,
@@ -2594,8 +2601,8 @@
/obj/effect/turf_decal/trimline/green/filled/line{
dir = 6
},
-/obj/structure/bed{
- dir = 4
+/obj/structure/bed/medical/anchored{
+ dir = 8
},
/obj/item/bedsheet/medical{
dir = 4
@@ -2690,11 +2697,25 @@
/obj/effect/turf_decal/box,
/turf/open/floor/iron/dark,
/area/station/science/ordnance/office)
+"aSC" = (
+/obj/structure/window/spawner/directional/south,
+/obj/item/radio/intercom/directional/west,
+/obj/effect/turf_decal/tile/brown/half/contrasted,
+/obj/structure/railing/corner,
+/turf/open/floor/iron/dark,
+/area/station/maintenance/disposal)
"aSH" = (
/obj/machinery/flasher/portable,
/obj/effect/turf_decal/tile/red/half/contrasted,
/turf/open/floor/iron/dark/textured,
/area/station/ai_monitored/security/armory/upper)
+"aSI" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"aSS" = (
/obj/effect/turf_decal/trimline/dark_red/end,
/obj/machinery/meter,
@@ -2804,6 +2825,17 @@
},
/turf/open/floor/iron/white,
/area/station/medical/treatment_center)
+"aUi" = (
+/obj/structure/table,
+/obj/item/storage/briefcase{
+ pixel_y = 3;
+ pixel_x = 2
+ },
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/item/storage/wallet,
+/obj/item/storage/wallet,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"aUj" = (
/turf/closed/wall/r_wall,
/area/station/engineering/storage)
@@ -2815,17 +2847,12 @@
/obj/effect/spawner/random/trash/mess,
/turf/open/floor/plating,
/area/station/maintenance/starboard/upper)
-"aUr" = (
-/obj/effect/turf_decal/bot,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+"aUm" = (
/obj/structure/cable,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
-"aUv" = (
-/obj/machinery/atmospherics/pipe/layer_manifold/supply/hidden,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/plating,
-/area/station/maintenance/starboard/aft)
+/area/station/maintenance/port/fore)
"aUA" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 4
@@ -2883,6 +2910,14 @@
/obj/machinery/light/small/directional/west,
/turf/open/floor/iron/grimy,
/area/station/service/bar/atrium)
+"aVb" = (
+/obj/effect/turf_decal/siding/wood{
+ dir = 1
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/wood,
+/area/station/commons/vacant_room/office)
"aVe" = (
/obj/machinery/door/airlock/maintenance{
name = "Mining Station Maintenance"
@@ -3003,12 +3038,6 @@
},
/turf/open/floor/iron,
/area/station/ai_monitored/security/armory/upper)
-"aWs" = (
-/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/incinerator_ordmix{
- dir = 8
- },
-/turf/open/floor/engine,
-/area/station/science/ordnance/burnchamber)
"aWD" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -3025,6 +3054,13 @@
/obj/machinery/light/small/directional/south,
/turf/open/floor/wood/parquet,
/area/station/service/bar/atrium)
+"aWN" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
+/obj/effect/turf_decal/siding/thinplating_new/corner{
+ dir = 1
+ },
+/turf/open/floor/iron/large,
+/area/station/hallway/secondary/entry)
"aWS" = (
/obj/structure/table,
/obj/item/storage/box/donkpockets/donkpocketberry,
@@ -3041,12 +3077,6 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/mine/laborcamp/security)
-"aWX" = (
-/obj/structure/chair/comfy/beige{
- dir = 8
- },
-/turf/open/floor/iron/grimy,
-/area/station/hallway/secondary/entry)
"aXY" = (
/obj/structure/rack,
/obj/item/circuitboard/machine/monkey_recycler,
@@ -3141,6 +3171,25 @@
},
/turf/closed/wall/r_wall,
/area/station/engineering/supermatter/room)
+"aZK" = (
+/obj/effect/turf_decal/stripes/line,
+/obj/structure/table,
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/obj/item/lighter/greyscale{
+ pixel_x = 4;
+ pixel_y = 2
+ },
+/obj/effect/spawner/random/entertainment/cigarette_pack{
+ pixel_x = 7
+ },
+/obj/item/reagent_containers/cup/soda_cans/sol_dry{
+ pixel_y = 4;
+ pixel_x = -7
+ },
+/turf/open/floor/iron/white/corner,
+/area/station/hallway/secondary/entry)
"aZL" = (
/obj/item/kirbyplants/random,
/obj/machinery/firealarm/directional/south,
@@ -3204,6 +3253,14 @@
/obj/structure/sign/poster/contraband/random/directional/south,
/turf/open/floor/iron,
/area/station/maintenance/starboard/fore)
+"bar" = (
+/obj/effect/turf_decal/tile/blue/opposingcorners{
+ dir = 1
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/iron/cafeteria,
+/area/station/commons/dorms/laundry)
"baA" = (
/obj/structure/cable,
/obj/machinery/camera/directional/east{
@@ -3299,12 +3356,6 @@
/obj/effect/turf_decal/tile/red,
/turf/open/floor/iron/textured,
/area/station/security/brig)
-"bcn" = (
-/obj/effect/turf_decal/tile/neutral{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"bcx" = (
/obj/machinery/door/airlock/maintenance{
name = "Quartermaster Office Maintenance"
@@ -3469,6 +3520,22 @@
name = "hyper-reinforced wall"
},
/area/station/science/ordnance/bomb)
+"bfa" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 5
+ },
+/obj/structure/industrial_lift{
+ radial_travel = 0
+ },
+/obj/structure/railing{
+ dir = 5
+ },
+/obj/machinery/elevator_control_panel/directional/north{
+ linked_elevator_id = "publicElevator";
+ preset_destination_names = list("3"="Icemoon Level","4"="Station Level")
+ },
+/turf/open/floor/plating/elevatorshaft,
+/area/mine/storage)
"bff" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/iron,
@@ -3654,26 +3721,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply,
/turf/open/floor/iron/white,
/area/station/medical/virology)
-"bhK" = (
-/obj/structure/table,
-/obj/item/folder/blue{
- pixel_x = -6;
- pixel_y = 3
- },
-/obj/item/pen{
- pixel_x = -1;
- pixel_y = 1
- },
-/obj/item/paper_bin/carbon{
- pixel_x = 5;
- pixel_y = 18
- },
-/obj/item/stamp/head/hop{
- pixel_x = 8;
- pixel_y = 5
- },
-/turf/open/floor/iron,
-/area/station/command/heads_quarters/hop)
"bhV" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -3807,6 +3854,20 @@
dir = 4
},
/area/station/security/prison)
+"bjv" = (
+/obj/machinery/door/airlock/maintenance,
+/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/mapping_helpers/airlock/unres{
+ dir = 8
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"bjN" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -3814,6 +3875,12 @@
/obj/machinery/power/apc/auto_name/directional/west,
/turf/open/floor/iron/dark,
/area/mine/mechbay)
+"bjQ" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 8
+ },
+/turf/open/floor/iron/large,
+/area/station/commons/locker)
"bjU" = (
/obj/effect/turf_decal/trimline/yellow/filled/line{
dir = 4
@@ -3866,10 +3933,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/station/science/explab)
-"bkK" = (
-/obj/machinery/requests_console/auto_name/directional/east,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"bkS" = (
/obj/machinery/bci_implanter,
/turf/open/floor/iron/white/side{
@@ -3932,11 +3995,6 @@
"bln" = (
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors/nospawn)
-"blq" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"blA" = (
/obj/machinery/hydroponics/soil,
/obj/machinery/light/directional/west,
@@ -4004,15 +4062,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central)
-"bmK" = (
-/obj/structure/cable,
-/obj/structure/disposalpipe/junction/flip{
- dir = 1
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"bmM" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/cable,
@@ -4107,6 +4156,19 @@
},
/turf/open/floor/iron,
/area/station/science/ordnance)
+"bod" = (
+/obj/structure/closet/crate/wooden,
+/obj/item/camera_film{
+ pixel_x = -4;
+ pixel_y = 4
+ },
+/obj/item/camera,
+/obj/effect/turf_decal/siding/wood{
+ dir = 1
+ },
+/obj/structure/sign/poster/contraband/the_griffin/directional/south,
+/turf/open/floor/iron/grimy,
+/area/station/commons/vacant_room/office)
"bol" = (
/turf/open/floor/iron/dark/textured,
/area/station/security/prison)
@@ -4120,11 +4182,6 @@
/obj/structure/closet/firecloset,
/turf/open/floor/plating,
/area/station/service/kitchen/coldroom)
-"boL" = (
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"boO" = (
/obj/structure/chair/sofa/left/brown{
dir = 8
@@ -4137,6 +4194,18 @@
/obj/machinery/atmospherics/pipe/layer_manifold/supply/visible,
/turf/closed/wall/r_wall,
/area/station/maintenance/department/medical/central)
+"boS" = (
+/obj/structure/disposaloutlet{
+ dir = 4
+ },
+/obj/structure/disposalpipe/trunk{
+ dir = 8
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"boV" = (
/obj/machinery/hydroponics/constructable,
/obj/effect/turf_decal/trimline/green/filled/line{
@@ -4160,6 +4229,15 @@
/obj/effect/turf_decal/tile/red/anticorner/contrasted,
/turf/open/floor/iron,
/area/station/command/bridge)
+"bpm" = (
+/obj/effect/turf_decal/tile/red/anticorner/contrasted{
+ dir = 4
+ },
+/obj/structure/closet/secure_closet/security,
+/obj/machinery/power/apc/auto_name/directional/east,
+/obj/structure/cable,
+/turf/open/floor/iron/dark,
+/area/station/security/checkpoint/customs/auxiliary)
"bpn" = (
/obj/effect/turf_decal/trimline/neutral/corner{
dir = 8
@@ -4184,6 +4262,12 @@
/obj/machinery/chem_master/condimaster,
/turf/open/floor/iron/kitchen/diagonal,
/area/station/service/kitchen)
+"bpK" = (
+/obj/machinery/door/airlock/maintenance,
+/obj/effect/mapping_helpers/airlock/unres,
+/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"bpL" = (
/obj/structure/noticeboard/directional/west,
/turf/open/floor/engine/cult,
@@ -4321,6 +4405,10 @@
dir = 5
},
/area/station/service/chapel)
+"brM" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"brY" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
@@ -4362,11 +4450,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/break_room)
-"bsq" = (
-/obj/machinery/hydroponics/soil,
-/obj/structure/sign/poster/contraband/kudzu/directional/west,
-/turf/open/floor/grass,
-/area/station/service/hydroponics/garden)
"bst" = (
/obj/effect/turf_decal/trimline/neutral/filled/line{
dir = 6
@@ -4406,6 +4489,14 @@
},
/turf/open/floor/iron/dark,
/area/station/science/genetics)
+"bsO" = (
+/obj/effect/turf_decal/box,
+/obj/structure/closet/crate,
+/obj/effect/spawner/random/maintenance/two,
+/obj/item/wrench,
+/obj/effect/decal/cleanable/cobweb/cobweb2,
+/turf/open/floor/iron/dark,
+/area/station/maintenance/port/greater)
"bta" = (
/obj/structure/chair/sofa/bench/right{
dir = 8
@@ -4422,6 +4513,18 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/central)
+"btm" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/structure/sign/warning/directional/north,
+/obj/structure/cable,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"btp" = (
/obj/effect/turf_decal/siding/white{
dir = 1
@@ -4467,6 +4570,12 @@
"btU" = (
/turf/closed/wall,
/area/station/medical/morgue)
+"btW" = (
+/obj/structure/cable,
+/turf/open/floor/iron/white/corner{
+ dir = 1
+ },
+/area/station/hallway/secondary/entry)
"bub" = (
/obj/machinery/vending/cola/red,
/obj/machinery/light/warm/directional/north,
@@ -4501,6 +4610,13 @@
},
/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
+"buF" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/structure/chair/sofa/bench/left{
+ dir = 1
+ },
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"buW" = (
/obj/structure/lattice,
/obj/structure/sign/warning/directional/south,
@@ -4524,6 +4640,21 @@
},
/turf/open/openspace,
/area/station/medical/treatment_center)
+"bvg" = (
+/obj/structure/railing{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/blue/half/contrasted{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral/half/contrasted{
+ dir = 8
+ },
+/obj/effect/turf_decal/siding/thinplating/corner{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/commons/locker)
"bvj" = (
/obj/structure/table,
/obj/item/paper_bin,
@@ -4531,6 +4662,12 @@
/obj/effect/turf_decal/tile/red,
/turf/open/floor/iron,
/area/mine/laborcamp/security)
+"bvq" = (
+/obj/effect/turf_decal/bot,
+/obj/machinery/light/directional/north,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"bvr" = (
/obj/machinery/light_switch/directional/west,
/obj/machinery/autolathe,
@@ -4605,6 +4742,18 @@
},
/turf/open/floor/wood,
/area/station/service/library)
+"bwn" = (
+/obj/effect/turf_decal/tile/blue,
+/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{
+ dir = 6
+ },
+/turf/open/floor/iron/white/corner{
+ dir = 8
+ },
+/area/station/hallway/secondary/entry)
"bwr" = (
/obj/machinery/light_switch/directional/east,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -4696,6 +4845,14 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/mine/laborcamp)
+"byd" = (
+/obj/effect/turf_decal/tile/red/half/contrasted,
+/obj/machinery/light_switch/directional/south,
+/obj/machinery/camera/directional/south{
+ c_tag = "Customs Security Checkpoint"
+ },
+/turf/open/floor/iron/dark,
+/area/station/security/checkpoint/customs/auxiliary)
"byk" = (
/obj/structure/sign/painting/library{
pixel_y = 32
@@ -4727,6 +4884,12 @@
/obj/item/kirbyplants/random,
/turf/open/floor/iron/white,
/area/station/security/prison/safe)
+"byv" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/item/trash/semki,
+/obj/item/trash/semki,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"byx" = (
/obj/machinery/computer/security/telescreen/entertainment/directional/north,
/obj/structure/cable,
@@ -4763,14 +4926,14 @@
/obj/effect/turf_decal/tile/blue,
/turf/open/floor/iron,
/area/station/hallway/primary/central)
-"bzh" = (
-/obj/machinery/door/airlock/maintenance{
- name = "Cargo Bay Maintenance"
+"bzg" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
},
-/obj/structure/cable,
-/obj/effect/mapping_helpers/airlock/access/all/supply/general,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"bzn" = (
/obj/machinery/door/airlock{
name = "Kitchen Access"
@@ -4854,15 +5017,24 @@
/obj/machinery/firealarm/directional/west,
/turf/open/floor/carpet,
/area/station/security/prison/rec)
-"bAp" = (
+"bAo" = (
/obj/effect/turf_decal/tile/blue{
- dir = 4
- },
-/obj/machinery/light/directional/north,
-/turf/open/floor/iron/white/corner{
dir = 1
},
+/obj/machinery/airalarm/directional/north,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
/area/station/hallway/secondary/entry)
+"bAB" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/hallway/primary/port)
"bAF" = (
/turf/open/floor/iron/chapel{
dir = 1
@@ -4886,12 +5058,13 @@
/obj/item/clothing/gloves/color/yellow,
/obj/structure/cable,
/obj/item/mod/module/plasma_stabilizer,
-/obj/item/mod/module/thermal_regulator,
/obj/item/stock_parts/cell/emproof{
pixel_x = -4;
pixel_y = -1
},
/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/item/mod/module/signlang_radio,
+/obj/item/mod/module/thermal_regulator,
/turf/open/floor/iron/dark,
/area/station/engineering/engine_smes)
"bAR" = (
@@ -4922,6 +5095,13 @@
/obj/effect/turf_decal/stripes/line,
/turf/open/floor/iron,
/area/station/hallway/secondary/exit/departure_lounge)
+"bBb" = (
+/obj/structure/railing{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/aft)
"bBd" = (
/obj/effect/turf_decal/siding/yellow{
dir = 6
@@ -4930,29 +5110,6 @@
/obj/machinery/light/floor,
/turf/open/floor/iron,
/area/station/engineering/lobby)
-"bBe" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/hallway/primary/port)
-"bBn" = (
-/obj/machinery/door/airlock/security/glass{
- id_tag = "permainner";
- name = "Permabrig Transfer"
- },
-/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
- cycle_id = "perma-entrance"
- },
-/obj/machinery/door/firedoor,
-/turf/open/floor/iron/dark/textured,
-/area/station/security/execution/transfer)
-"bBr" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/closed/wall,
-/area/station/maintenance/port/fore)
"bBw" = (
/obj/item/trash/sosjerky,
/turf/open/floor/plating,
@@ -5014,11 +5171,6 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/command/heads_quarters/cmo)
-"bCl" = (
-/obj/machinery/door/firedoor,
-/obj/effect/landmark/navigate_destination,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"bCp" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -5072,6 +5224,10 @@
/obj/item/storage/box/monkeycubes,
/turf/open/floor/iron,
/area/station/science/xenobiology)
+"bCQ" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"bCT" = (
/obj/effect/turf_decal/trimline/dark_red/arrow_ccw{
dir = 1
@@ -5110,11 +5266,6 @@
/obj/machinery/light/small/directional/north,
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
-"bDp" = (
-/obj/item/airlock_painter,
-/obj/structure/closet,
-/turf/open/misc/asteroid/snow/icemoon,
-/area/icemoon/surface/outdoors/nospawn)
"bDu" = (
/turf/closed/wall/r_wall,
/area/station/security/lockers)
@@ -5175,18 +5326,28 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/orange/visible,
/turf/open/floor/plating,
/area/station/engineering/supermatter/room)
-"bDZ" = (
-/obj/structure/cable,
-/obj/structure/disposalpipe/segment,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"bEa" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/general/visible,
/obj/effect/landmark/event_spawn,
/turf/open/floor/iron/dark,
/area/station/engineering/supermatter/room)
+"bEd" = (
+/obj/machinery/conveyor_switch/oneway{
+ dir = 8;
+ id = "garbage";
+ name = "disposal conveyor";
+ pixel_y = 5;
+ pixel_x = -5
+ },
+/obj/structure/railing/corner,
+/obj/effect/turf_decal/box/corners{
+ dir = 8
+ },
+/obj/effect/turf_decal/tile/brown/half/contrasted{
+ dir = 4
+ },
+/turf/open/floor/iron/dark,
+/area/station/maintenance/disposal)
"bEf" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -5292,14 +5453,6 @@
/obj/machinery/light/small/directional/south,
/turf/open/floor/engine/n2,
/area/station/engineering/atmos)
-"bFe" = (
-/obj/machinery/door/airlock/maintenance{
- name = "Security Maintenance"
- },
-/obj/structure/cable,
-/obj/effect/mapping_helpers/airlock/access/all/security/general,
-/turf/open/floor/plating,
-/area/station/security/checkpoint/customs/auxiliary)
"bFq" = (
/obj/effect/spawner/random/structure/crate,
/turf/open/floor/plating,
@@ -5314,22 +5467,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/secondary/exit/departure_lounge)
-"bFL" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/turf_decal/tile/blue{
- dir = 4
- },
-/turf/open/floor/iron/cafeteria,
-/area/station/hallway/secondary/entry)
-"bFP" = (
-/obj/machinery/camera/directional/south,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/turf_decal/tile/blue{
- dir = 8
- },
-/turf/open/floor/iron/white/corner,
-/area/station/hallway/secondary/entry)
"bFS" = (
/obj/item/crowbar/red,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -5371,29 +5508,11 @@
},
/turf/open/floor/iron,
/area/station/command/bridge)
-"bGn" = (
-/obj/machinery/door/airlock/engineering{
- name = "Auxillary Base Construction"
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/cable,
-/obj/effect/mapping_helpers/airlock/access/all/engineering/aux_base,
-/turf/open/floor/iron,
-/area/station/construction/mining/aux_base)
"bGA" = (
/obj/effect/spawner/structure/window,
/obj/structure/sign/departments/xenobio/directional/south,
/turf/open/floor/plating,
/area/station/science/xenobiology)
-"bGL" = (
-/obj/item/radio/intercom/directional/south,
-/obj/structure/chair{
- dir = 1
- },
-/obj/effect/turf_decal/stripes/line,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"bGP" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/obj/effect/turf_decal/tile/brown/half/contrasted{
@@ -5491,25 +5610,43 @@
dir = 4
},
/area/station/ai_monitored/command/storage/eva)
-"bIq" = (
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
- dir = 1
+"bId" = (
+/obj/machinery/atmospherics/pipe/smart/simple/dark/visible{
+ dir = 4
},
-/obj/effect/turf_decal/tile/blue/opposingcorners{
- dir = 1
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
},
-/turf/open/floor/iron/cafeteria,
-/area/station/commons/dorms/laundry)
+/obj/machinery/door/firedoor/heavy,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/iron/dark,
+/area/station/science/ordnance)
+"bIl" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 4
+ },
+/obj/effect/landmark/generic_maintenance_landmark,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/pink/visible,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
+"bIo" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/railing/corner/end/flip{
+ dir = 8
+ },
+/obj/structure/railing/corner/end{
+ dir = 4
+ },
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"bIt" = (
/obj/structure/rack,
/obj/effect/decal/cleanable/cobweb/cobweb2,
/obj/effect/spawner/random/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
-"bIB" = (
-/obj/effect/spawner/random/vending/snackvend,
-/turf/open/floor/iron/dark,
-/area/station/hallway/secondary/entry)
"bID" = (
/turf/closed/wall/r_wall,
/area/station/engineering/lobby)
@@ -5604,6 +5741,17 @@
/obj/machinery/light/directional/south,
/turf/open/floor/iron,
/area/mine/laborcamp)
+"bJA" = (
+/obj/effect/turf_decal/siding/wood{
+ dir = 1
+ },
+/obj/effect/turf_decal/siding/wood,
+/obj/machinery/door/firedoor,
+/obj/machinery/door/airlock/multi_tile/public/glass{
+ name = "The Girly Boar"
+ },
+/turf/open/floor/iron/dark/textured_half,
+/area/station/service/bar/atrium)
"bJD" = (
/obj/machinery/atmospherics/components/trinary/filter/atmos/n2{
dir = 4
@@ -5630,14 +5778,6 @@
},
/turf/open/floor/wood,
/area/station/service/library)
-"bJZ" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 1
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/decal/cleanable/generic,
-/turf/open/floor/iron/dark,
-/area/station/maintenance/disposal)
"bKm" = (
/obj/machinery/vending/assist,
/obj/structure/sign/poster/random/directional/west,
@@ -5654,6 +5794,15 @@
/obj/effect/mapping_helpers/airlock/access/any/supply/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
+"bKA" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/cable,
+/obj/machinery/door/airlock/grunge{
+ name = "Vacant Office A"
+ },
+/turf/open/floor/iron/dark,
+/area/station/commons/vacant_room/office)
"bKI" = (
/obj/structure/window/reinforced/spawner/directional/north,
/obj/machinery/disposal/bin,
@@ -5707,6 +5856,10 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/wood,
/area/station/maintenance/fore)
+"bLs" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
+/turf/open/floor/iron/dark/smooth_large,
+/area/station/hallway/secondary/entry)
"bLz" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -5911,10 +6064,6 @@
},
/turf/open/floor/plating,
/area/mine/living_quarters)
-"bOL" = (
-/obj/machinery/vending/coffee,
-/turf/open/floor/iron/dark,
-/area/station/hallway/secondary/entry)
"bOO" = (
/obj/effect/turf_decal/trimline/yellow/filled/corner{
dir = 8
@@ -5979,6 +6128,15 @@
},
/turf/open/floor/iron/dark,
/area/station/commons/storage/primary)
+"bPs" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/effect/spawner/structure/window/hollow/reinforced/middle{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"bPt" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -6009,12 +6167,6 @@
/obj/effect/turf_decal/tile/green/full,
/turf/open/floor/iron/dark/smooth_large,
/area/station/medical/virology)
-"bPP" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"bPV" = (
/obj/item/kirbyplants/random/dead,
/turf/open/floor/plating/snowed/icemoon,
@@ -6114,15 +6266,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/maintenance/department/cargo)
-"bRt" = (
-/obj/machinery/door/airlock/external{
- name = "Escape Pod Two"
- },
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
- dir = 8
- },
-/turf/open/floor/plating,
-/area/station/hallway/secondary/entry)
"bRz" = (
/obj/machinery/hydroponics/soil{
pixel_y = 8
@@ -6291,12 +6434,27 @@
},
/turf/open/floor/engine,
/area/station/science/xenobiology)
+"bUW" = (
+/obj/effect/turf_decal/tile/blue/opposingcorners{
+ dir = 1
+ },
+/obj/machinery/newscaster/directional/north,
+/obj/structure/chair/stool/directional/south,
+/turf/open/floor/iron/cafeteria,
+/area/station/commons/dorms/laundry)
"bVe" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 1
},
/turf/open/floor/iron/white/smooth_large,
/area/station/medical/chemistry)
+"bVn" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/structure/sign/poster/contraband/random/directional/east,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"bVp" = (
/obj/effect/turf_decal/trimline/blue/filled/line,
/obj/structure/closet/secure_closet/medical3,
@@ -6439,6 +6597,15 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/engineering/engine_smes)
+"bXx" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/obj/structure/cable,
+/turf/open/floor/iron/white/corner{
+ dir = 1
+ },
+/area/station/hallway/secondary/entry)
"bXy" = (
/turf/open/openspace,
/area/station/ai_monitored/security/armory/upper)
@@ -6507,6 +6674,16 @@
},
/turf/open/floor/engine,
/area/station/engineering/supermatter)
+"bYz" = (
+/obj/machinery/conveyor{
+ dir = 8;
+ id = "garbage"
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"bYB" = (
/obj/structure/table,
/obj/item/storage/box/hug{
@@ -6584,13 +6761,6 @@
},
/turf/open/floor/iron/smooth_half,
/area/station/command/heads_quarters/rd)
-"bZf" = (
-/obj/machinery/atmospherics/pipe/smart/simple/dark/visible{
- dir = 5
- },
-/obj/machinery/igniter/incinerator_atmos,
-/turf/open/floor/engine/vacuum,
-/area/station/maintenance/disposal/incinerator)
"bZg" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -6650,11 +6820,25 @@
/mob/living/carbon/human/species/monkey,
/turf/open/floor/engine,
/area/station/science/genetics)
+"caH" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
+/turf/open/floor/iron/large,
+/area/station/hallway/primary/port)
"caU" = (
/obj/structure/sign/warning/cold_temp/directional/south,
/obj/structure/sign/warning/gas_mask/directional/north,
/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
+"caX" = (
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 9
+ },
+/obj/structure/marker_beacon/burgundy,
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"caY" = (
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/wood,
@@ -6785,6 +6969,14 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/engineering/storage_shared)
+"ccB" = (
+/obj/structure/disposalpipe/sorting/mail/flip{
+ dir = 4
+ },
+/obj/effect/mapping_helpers/mail_sorting/supply/disposals,
+/obj/effect/decal/cleanable/dirt/dust,
+/turf/open/floor/catwalk_floor/iron_smooth,
+/area/station/maintenance/port/lesser)
"ccQ" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -6794,6 +6986,17 @@
},
/turf/open/floor/iron/white,
/area/station/science/xenobiology)
+"ccS" = (
+/obj/effect/turf_decal/siding/thinplating_new{
+ dir = 4
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/turf/open/floor/iron/white/side{
+ dir = 8
+ },
+/area/station/hallway/secondary/entry)
"ccT" = (
/obj/structure/extinguisher_cabinet/directional/north,
/turf/open/floor/iron/dark/smooth_edge,
@@ -6865,17 +7068,6 @@
},
/turf/open/floor/iron,
/area/station/maintenance/starboard/aft)
-"ceh" = (
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
- dir = 4
- },
-/obj/effect/turf_decal/tile/blue{
- dir = 4
- },
-/turf/open/floor/iron/white/corner{
- dir = 1
- },
-/area/station/hallway/secondary/entry)
"cek" = (
/obj/structure/grille,
/turf/open/misc/asteroid/snow/icemoon,
@@ -6922,6 +7114,18 @@
/obj/effect/turf_decal/siding/white,
/turf/open/floor/iron/smooth,
/area/mine/mechbay)
+"ceY" = (
+/obj/machinery/door/poddoor/preopen{
+ id = "Disposal Exit";
+ name = "Disposal Exit Vent"
+ },
+/obj/machinery/conveyor{
+ id = "garbage";
+ dir = 1
+ },
+/obj/effect/turf_decal/stripes/red/box,
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"cfe" = (
/obj/structure/cable,
/obj/machinery/holopad/secure,
@@ -6971,12 +7175,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central)
-"cfB" = (
-/obj/structure/chair/office{
- dir = 8
- },
-/turf/open/floor/carpet/red,
-/area/station/commons/vacant_room/office)
"cfC" = (
/obj/machinery/atmospherics/pipe/bridge_pipe/cyan/visible,
/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible{
@@ -7140,6 +7338,16 @@
/obj/item/flashlight/lamp,
/turf/open/floor/wood/large,
/area/mine/eva/lower)
+"chP" = (
+/obj/structure/sign/nanotrasen{
+ pixel_x = -32
+ },
+/obj/structure/marker_beacon/burgundy,
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 5
+ },
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"chQ" = (
/obj/effect/turf_decal/stripes/asteroid/line{
dir = 1
@@ -7200,6 +7408,13 @@
},
/turf/open/floor/iron/smooth_half,
/area/station/security/brig/upper)
+"ciH" = (
+/obj/effect/turf_decal/tile/blue/opposingcorners{
+ dir = 1
+ },
+/obj/structure/sign/poster/official/random/directional/south,
+/turf/open/floor/iron/cafeteria,
+/area/station/commons/dorms/laundry)
"ciI" = (
/obj/item/radio/intercom/directional/west,
/obj/effect/turf_decal/tile/neutral/opposingcorners,
@@ -7245,13 +7460,6 @@
/obj/effect/spawner/random/contraband/permabrig_gear,
/turf/open/floor/iron/grimy,
/area/station/security/prison/work)
-"cjG" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/yellow/half/contrasted,
-/turf/open/floor/iron,
-/area/station/construction/mining/aux_base)
"cjI" = (
/obj/effect/turf_decal/stripes/line{
dir = 10
@@ -7302,7 +7510,9 @@
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/disposalpipe/segment,
+/obj/structure/disposalpipe/segment{
+ dir = 9
+ },
/turf/open/floor/iron,
/area/station/hallway/primary/port)
"cks" = (
@@ -7402,6 +7612,14 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/carpet/blue,
/area/station/security/prison/work)
+"clT" = (
+/obj/item/kirbyplants/random,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/siding/white{
+ dir = 1
+ },
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"clV" = (
/obj/structure/disposalpipe/segment,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -7425,11 +7643,6 @@
/obj/structure/closet/firecloset,
/turf/open/floor/plating,
/area/station/maintenance/aft/lesser)
-"cmm" = (
-/obj/structure/chair/office,
-/obj/effect/turf_decal/tile/red/half/contrasted,
-/turf/open/floor/iron,
-/area/station/security/checkpoint/customs/auxiliary)
"cmq" = (
/obj/machinery/door/airlock/external{
name = "External Access"
@@ -7501,6 +7714,19 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/morgue)
+"cmT" = (
+/obj/effect/turf_decal/tile/brown/anticorner/contrasted{
+ dir = 4
+ },
+/turf/open/floor/iron/dark,
+/area/station/maintenance/disposal)
+"cmV" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/obj/structure/cable,
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
"cmX" = (
/obj/effect/spawner/random/structure/crate,
/obj/effect/mapping_helpers/broken_floor,
@@ -7582,29 +7808,6 @@
},
/turf/open/floor/iron,
/area/station/command/heads_quarters/qm)
-"coa" = (
-/obj/machinery/door/airlock/maintenance,
-/obj/structure/disposalpipe/segment,
-/obj/structure/cable,
-/obj/effect/mapping_helpers/airlock/unres,
-/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
-"coB" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
- dir = 8
- },
-/turf/open/floor/iron/large,
-/area/station/security/checkpoint/customs/auxiliary)
-"coH" = (
-/obj/structure/railing{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/plating,
-/area/station/maintenance/starboard/aft)
"coL" = (
/obj/structure/reagent_dispensers/water_cooler,
/obj/structure/cable,
@@ -7613,6 +7816,15 @@
},
/turf/open/floor/iron,
/area/station/commons/fitness)
+"coT" = (
+/obj/structure/table,
+/obj/item/storage/wallet,
+/obj/item/storage/wallet{
+ pixel_y = 3;
+ pixel_x = 4
+ },
+/turf/open/floor/plastic,
+/area/station/commons/dorms/laundry)
"cpe" = (
/obj/machinery/atmospherics/components/tank/air{
dir = 8
@@ -7628,13 +7840,6 @@
},
/turf/open/floor/iron/white,
/area/station/science/xenobiology)
-"cpj" = (
-/obj/structure/disposalpipe/segment{
- dir = 9
- },
-/obj/structure/cable,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"cpl" = (
/obj/machinery/camera/directional/south{
c_tag = "Atmospherics Storage Room - East"
@@ -7777,13 +7982,6 @@
/obj/effect/turf_decal/tile/red/half/contrasted,
/turf/open/floor/iron/dark/textured,
/area/station/ai_monitored/security/armory/upper)
-"crc" = (
-/obj/machinery/camera/directional/south,
-/obj/effect/turf_decal/tile/blue{
- dir = 8
- },
-/turf/open/floor/iron/white/corner,
-/area/station/hallway/secondary/entry)
"crg" = (
/obj/machinery/door/morgue{
name = "Confession Booth"
@@ -7800,6 +7998,19 @@
/obj/machinery/vending/wardrobe/law_wardrobe,
/turf/open/floor/wood,
/area/station/service/lawoffice)
+"crT" = (
+/obj/effect/spawner/random/structure/chair_flipped,
+/obj/effect/spawner/random/trash/bacteria,
+/obj/structure/sign/poster/ripped/directional/west,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
+"cse" = (
+/obj/machinery/door/airlock/maintenance{
+ name = "Cargo Bay Maintenance"
+ },
+/obj/effect/mapping_helpers/airlock/access/all/supply/general,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"csf" = (
/obj/structure/table,
/obj/effect/turf_decal/siding/red{
@@ -7908,6 +8119,10 @@
/obj/structure/tank_holder/anesthetic,
/turf/open/floor/iron/dark,
/area/station/science/robotics/lab)
+"cuc" = (
+/obj/effect/turf_decal/siding/thinplating_new,
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
"cum" = (
/obj/effect/spawner/structure/window/hollow/reinforced/middle{
dir = 1
@@ -7935,6 +8150,16 @@
},
/turf/open/floor/iron/dark/textured,
/area/station/security/prison/rec)
+"cut" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/light_switch/directional/west,
+/obj/effect/turf_decal/siding/wood/corner{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/light/small/directional/west,
+/turf/open/floor/wood,
+/area/station/commons/vacant_room/office)
"cuJ" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 4
@@ -8071,6 +8296,10 @@
/obj/structure/disposalpipe/trunk,
/turf/open/floor/iron,
/area/station/service/theater)
+"cwe" = (
+/obj/effect/turf_decal/tile/yellow,
+/turf/open/floor/iron,
+/area/station/maintenance/port/fore)
"cwh" = (
/obj/structure/plaque/static_plaque/golden/commission/icebox{
pixel_y = 29
@@ -8122,11 +8351,6 @@
/obj/effect/turf_decal/tile/blue/full,
/turf/open/floor/iron/dark/smooth_large,
/area/station/medical/storage)
-"cwK" = (
-/obj/structure/tank_holder/extinguisher,
-/obj/effect/mapping_helpers/burnt_floor,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"cwO" = (
/obj/item/radio/intercom/directional/north,
/turf/open/floor/iron,
@@ -8152,7 +8376,7 @@
anchored = 1
},
/obj/item/clothing/under/pants/track,
-/obj/item/clothing/suit/costume/ianshirt,
+/obj/item/clothing/suit/costume/wellworn_shirt/graphic/ian,
/turf/open/floor/iron,
/area/station/maintenance/starboard/fore)
"cxz" = (
@@ -8196,16 +8420,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply,
/turf/open/floor/iron/white,
/area/station/medical/virology)
-"cya" = (
-/obj/machinery/door/airlock/maintenance,
-/obj/effect/mapping_helpers/airlock/abandoned,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/mapping_helpers/airlock/unres{
- dir = 4
- },
-/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"cyh" = (
/obj/structure/cable,
/obj/effect/spawner/structure/window/reinforced,
@@ -8218,15 +8432,15 @@
/obj/effect/turf_decal/tile/blue/full,
/turf/open/floor/iron/large,
/area/station/medical/treatment_center)
-"cyF" = (
-/obj/structure/table/wood,
-/obj/machinery/recharger,
-/obj/item/coin/plasma{
- pixel_x = -6;
- pixel_y = 13
+"cyA" = (
+/obj/machinery/door/airlock/maintenance,
+/obj/effect/mapping_helpers/airlock/unres{
+ dir = 4
},
-/turf/open/floor/wood,
-/area/station/command/heads_quarters/captain)
+/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
+/obj/effect/spawner/random/structure/barricade,
+/turf/open/floor/plating,
+/area/station/commons/vacant_room/office)
"cyG" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -8283,6 +8497,13 @@
},
/turf/open/floor/iron,
/area/station/hallway/secondary/exit/departure_lounge)
+"cyV" = (
+/obj/structure/chair/stool/directional/west,
+/obj/effect/turf_decal/tile/yellow{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/maintenance/port/fore)
"cyX" = (
/obj/machinery/recharge_station,
/obj/item/radio/intercom/directional/west,
@@ -8322,15 +8543,6 @@
/obj/effect/mapping_helpers/airlock/access/all/supply/mining_station,
/turf/open/floor/iron/smooth,
/area/mine/eva)
-"czs" = (
-/obj/structure/table,
-/obj/item/clothing/head/soft/grey{
- pixel_x = -2;
- pixel_y = 3
- },
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"czv" = (
/obj/machinery/conveyor_switch/oneway{
dir = 8;
@@ -8338,6 +8550,26 @@
},
/turf/open/floor/iron,
/area/station/cargo/storage)
+"czz" = (
+/obj/machinery/computer/pod/old/mass_driver_controller/trash{
+ pixel_x = -24;
+ pixel_y = -6
+ },
+/obj/machinery/button/door/directional/west{
+ id = "Disposal Exit";
+ name = "Disposal Vent Control";
+ pixel_y = 4;
+ req_access = list("maint_tunnels")
+ },
+/obj/structure/chair/stool/directional/south{
+ dir = 4
+ },
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/turf_decal/tile/brown/half/contrasted{
+ dir = 8
+ },
+/turf/open/floor/iron/dark,
+/area/station/maintenance/disposal)
"czD" = (
/turf/closed/wall,
/area/mine/laborcamp/security)
@@ -8375,14 +8607,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/medbay/lobby)
-"czV" = (
-/obj/machinery/door/airlock/external,
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
- dir = 8
- },
-/obj/effect/mapping_helpers/airlock/access/all/engineering/external,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"czW" = (
/obj/structure/weightmachine,
/obj/effect/turf_decal/box,
@@ -8405,12 +8629,6 @@
dir = 1
},
/area/station/hallway/primary/starboard)
-"cAl" = (
-/obj/effect/turf_decal/tile/red/half/contrasted{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/security/checkpoint/customs/auxiliary)
"cAo" = (
/obj/machinery/airalarm/directional/west,
/obj/structure/closet/toolcloset,
@@ -8429,14 +8647,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply,
/turf/open/floor/iron/white,
/area/station/medical/virology)
-"cAs" = (
-/obj/structure/cable,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"cAu" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/trimline/dark_red/arrow_ccw{
@@ -8760,6 +8970,11 @@
/obj/structure/grille/broken,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/morgue)
+"cEG" = (
+/obj/effect/spawner/random/trash/cigbutt,
+/obj/effect/spawner/random/trash/cigbutt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"cEL" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -8890,6 +9105,13 @@
},
/turf/open/floor/iron,
/area/station/engineering/atmos)
+"cHs" = (
+/obj/structure/disposalpipe/segment{
+ dir = 10
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"cHy" = (
/obj/structure/cable,
/obj/structure/railing,
@@ -8944,6 +9166,13 @@
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/turf/open/floor/iron,
/area/station/cargo/storage)
+"cIa" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/machinery/digital_clock/directional/east,
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
"cIc" = (
/turf/closed/wall,
/area/station/security/prison/work)
@@ -8967,12 +9196,6 @@
/obj/item/coin/diamond,
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
-"cIu" = (
-/obj/structure/table,
-/obj/item/toy/gun,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"cIK" = (
/obj/structure/table/wood,
/obj/item/pai_card,
@@ -9050,6 +9273,12 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
+"cKe" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/pink,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"cKk" = (
/obj/machinery/status_display/evac/directional/north,
/obj/machinery/light/directional/north,
@@ -9062,13 +9291,6 @@
/mob/living/simple_animal/bot/secbot/beepsky,
/turf/open/floor/plating,
/area/station/maintenance/fore)
-"cKp" = (
-/obj/machinery/door/airlock/multi_tile/public/glass{
- name = "Hydroponics"
- },
-/obj/effect/mapping_helpers/airlock/access/all/service/hydroponics,
-/turf/open/floor/iron/textured_half,
-/area/station/service/hydroponics)
"cKq" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -9087,19 +9309,33 @@
},
/turf/open/floor/engine,
/area/station/science/xenobiology)
+"cKB" = (
+/obj/machinery/atmospherics/components/unary/portables_connector/visible{
+ dir = 4
+ },
+/obj/machinery/portable_atmospherics/canister/air,
+/obj/effect/turf_decal/stripes/line,
+/obj/effect/turf_decal/tile/yellow{
+ dir = 1
+ },
+/turf/open/floor/iron/checker{
+ dir = 8
+ },
+/area/station/maintenance/port/fore)
+"cKD" = (
+/obj/structure/closet,
+/obj/effect/spawner/random/maintenance,
+/obj/item/stock_parts/water_recycler,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"cKF" = (
/obj/structure/bookcase/random/reference,
/turf/open/floor/carpet/blue,
/area/station/medical/psychology)
-"cKM" = (
-/obj/structure/cable,
-/obj/structure/sign/poster/random/directional/south,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"cLf" = (
/obj/effect/decal/cleanable/blood/bubblegum,
/obj/effect/turf_decal/tile/neutral/fourcorners,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/turf/open/floor/iron/dark,
/area/station/medical/morgue)
@@ -9142,14 +9378,6 @@
},
/turf/open/floor/iron,
/area/station/engineering/lobby)
-"cLy" = (
-/obj/machinery/atmospherics/components/unary/portables_connector/visible{
- dir = 8
- },
-/obj/effect/turf_decal/stripes/line,
-/obj/structure/closet/cardboard,
-/turf/open/floor/iron,
-/area/station/maintenance/port/fore)
"cLB" = (
/obj/machinery/computer/prisoner/gulag_teleporter_computer{
dir = 4
@@ -9183,11 +9411,6 @@
},
/turf/open/floor/wood,
/area/station/service/library)
-"cLM" = (
-/obj/machinery/meter,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/pink/hidden,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"cLN" = (
/turf/open/floor/iron,
/area/station/hallway/primary/aft)
@@ -9346,11 +9569,6 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/engine,
/area/station/science/xenobiology)
-"cNQ" = (
-/obj/structure/closet/wardrobe/grey,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"cNS" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/public/glass{
@@ -9359,7 +9577,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/landmark/navigate_destination,
-/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/textured,
/area/station/service/hydroponics/garden)
"cOa" = (
@@ -9439,12 +9656,17 @@
},
/turf/open/floor/iron,
/area/station/security/prison/workout)
-"cQb" = (
-/obj/machinery/light_switch/directional/north,
-/obj/machinery/vending/autodrobe/all_access,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/commons/locker)
+"cQa" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/sign/nanotrasen{
+ pixel_x = 32
+ },
+/turf/open/floor/iron/white/corner,
+/area/station/hallway/secondary/entry)
"cQc" = (
/obj/structure/table/wood,
/obj/item/reagent_containers/cup/rag,
@@ -9470,6 +9692,21 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/security/checkpoint/supply)
+"cQi" = (
+/obj/machinery/disposal/delivery_chute{
+ dir = 4
+ },
+/obj/structure/disposalpipe/trunk{
+ dir = 8
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 5
+ },
+/obj/machinery/door/window/left/directional/east{
+ name = "Loop Chute Access"
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"cQs" = (
/obj/structure/table,
/obj/item/computer_disk{
@@ -9571,30 +9808,10 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden,
/turf/closed/wall,
/area/station/engineering/atmos)
-"cRS" = (
-/obj/structure/table,
-/obj/item/storage/box/lights/mixed,
-/obj/item/pipe_dispenser,
-/obj/machinery/button/door/directional/east{
- id = "aux_base_shutters";
- name = "Public Shutters Control";
- req_access = list("aux_base")
- },
-/obj/effect/turf_decal/tile/yellow/anticorner/contrasted,
-/obj/machinery/mining_weather_monitor/directional/south,
-/turf/open/floor/iron,
-/area/station/construction/mining/aux_base)
"cRX" = (
/obj/machinery/processor,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
-"cSb" = (
-/obj/structure/closet/emcloset,
-/obj/effect/turf_decal/stripes/line{
- dir = 10
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"cSc" = (
/obj/structure/flora/bush/flowers_pp/style_random,
/obj/structure/closet/crate{
@@ -9611,6 +9828,17 @@
/obj/item/queen_bee/bought,
/turf/open/floor/grass,
/area/station/service/hydroponics)
+"cSe" = (
+/obj/structure/table,
+/obj/item/flashlight{
+ pixel_x = 1;
+ pixel_y = 5
+ },
+/obj/item/wirecutters,
+/obj/effect/turf_decal/tile/neutral/anticorner/contrasted,
+/obj/machinery/status_display/evac/directional/east,
+/turf/open/floor/iron/dark,
+/area/station/commons/storage/primary)
"cSj" = (
/obj/effect/turf_decal/weather/snow/corner,
/turf/open/misc/dirt{
@@ -9655,10 +9883,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible,
/turf/open/floor/engine,
/area/station/engineering/supermatter/room)
-"cSM" = (
-/obj/machinery/door/firedoor,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"cSP" = (
/obj/machinery/camera/directional/east{
c_tag = "Aft Primary Hallway South";
@@ -9675,6 +9899,12 @@
},
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
+"cTh" = (
+/obj/structure/table/wood,
+/obj/item/paper_bin,
+/obj/item/pen,
+/turf/open/floor/iron/grimy,
+/area/station/commons/vacant_room/office)
"cTs" = (
/obj/machinery/door/firedoor,
/obj/structure/cable,
@@ -9699,6 +9929,14 @@
},
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
+"cTD" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 8
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/wood/large,
+/area/station/commons/vacant_room/office)
"cTJ" = (
/obj/structure/cable,
/obj/machinery/light_switch/directional/south{
@@ -9710,14 +9948,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/cryo)
-"cTK" = (
-/obj/structure/table,
-/obj/effect/spawner/random/maintenance/two,
-/obj/effect/decal/cleanable/dirt,
-/obj/item/stock_parts/capacitor,
-/obj/structure/sign/poster/random/directional/north,
-/turf/open/floor/iron,
-/area/station/maintenance/port/fore)
"cTV" = (
/obj/effect/turf_decal/box/white{
color = "#52B4E9"
@@ -9725,6 +9955,15 @@
/obj/machinery/holopad,
/turf/open/floor/iron/white,
/area/station/medical/medbay/central)
+"cUd" = (
+/obj/machinery/door/airlock/maintenance{
+ name = "Locker Room Maintenance"
+ },
+/obj/effect/mapping_helpers/airlock/unres,
+/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"cUt" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -9737,10 +9976,6 @@
},
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
-"cUy" = (
-/obj/machinery/space_heater,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"cUF" = (
/obj/machinery/camera/directional/west{
c_tag = "Aft Primary Hallway North"
@@ -9772,13 +10007,6 @@
},
/turf/open/floor/iron/grimy,
/area/station/security/detectives_office)
-"cVq" = (
-/obj/structure/rack,
-/obj/effect/spawner/random/clothing/costume,
-/obj/item/crowbar,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"cVz" = (
/obj/effect/turf_decal/stripes/corner{
dir = 4
@@ -9798,10 +10026,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/mine/laborcamp)
-"cWn" = (
-/obj/structure/reagent_dispensers/watertank,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"cWq" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/obj/effect/turf_decal/tile/green/half/contrasted{
@@ -9985,16 +10209,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/plating,
/area/station/maintenance/aft/lesser)
-"cYX" = (
-/obj/structure/cable,
-/obj/structure/disposalpipe/segment{
- dir = 5
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/light/small/dim/directional/west,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"cYY" = (
/obj/structure/railing{
dir = 8
@@ -10085,6 +10299,14 @@
},
/turf/open/floor/iron/dark,
/area/station/service/chapel)
+"dak" = (
+/obj/item/clothing/suit/apron/surgical,
+/obj/effect/mapping_helpers/broken_floor,
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 8
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"dal" = (
/obj/structure/table/wood,
/obj/machinery/libraryscanner{
@@ -10267,6 +10489,17 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/mix)
+"dcG" = (
+/obj/effect/turf_decal/stripes/corner{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/turf/open/floor/iron/white/corner{
+ dir = 8
+ },
+/area/station/hallway/secondary/entry)
"dcO" = (
/obj/machinery/camera/directional/east{
c_tag = "Engineering Emitter Room Starboard";
@@ -10283,6 +10516,12 @@
/obj/structure/sign/poster/official/random/directional/west,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
+"dcW" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"dcX" = (
/obj/structure/rack,
/obj/item/clothing/suit/hooded/wintercoat/security{
@@ -10326,10 +10565,6 @@
/obj/effect/landmark/start/hangover/closet,
/turf/open/floor/wood,
/area/station/commons/dorms)
-"ddt" = (
-/obj/machinery/status_display/evac/directional/east,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"ddu" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 8
@@ -10344,6 +10579,13 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/showroomfloor,
/area/station/security/prison/toilet)
+"ddA" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/machinery/atmospherics/components/binary/pump/on/supply/hidden/layer4{
+ dir = 8
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/aft/greater)
"ddZ" = (
/obj/structure/cable,
/obj/effect/turf_decal/siding/green{
@@ -10421,11 +10663,6 @@
},
/turf/open/floor/glass/reinforced,
/area/station/science/xenobiology)
-"dfj" = (
-/obj/effect/landmark/event_spawn,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"dfq" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible,
/turf/closed/wall/r_wall,
@@ -10464,13 +10701,6 @@
/obj/machinery/firealarm/directional/north,
/turf/open/floor/iron,
/area/station/cargo/storage)
-"dgk" = (
-/obj/effect/spawner/random/vending/snackvend,
-/obj/effect/turf_decal/stripes/line{
- dir = 9
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"dgl" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 8
@@ -10535,12 +10765,6 @@
},
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/underground/explored)
-"dhJ" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"dhL" = (
/obj/machinery/computer/upload/ai{
dir = 1
@@ -10640,7 +10864,7 @@
pixel_x = -4;
pixel_y = 3
},
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/effect/turf_decal/tile/blue/half/contrasted{
dir = 1
},
@@ -10658,6 +10882,7 @@
"djr" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/disposalpipe/segment,
/turf/open/floor/iron,
/area/station/hallway/primary/port)
"djB" = (
@@ -10761,12 +10986,6 @@
/obj/effect/turf_decal/stripes/line,
/turf/open/floor/iron/white,
/area/station/science/xenobiology)
-"dkN" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"dkO" = (
/obj/effect/landmark/start/hangover,
/obj/structure/chair/stool/directional/north,
@@ -10833,6 +11052,22 @@
/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/science/xenobiology)
+"dmk" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/railing{
+ dir = 8
+ },
+/obj/effect/turf_decal/tile/blue/half/contrasted{
+ dir = 8
+ },
+/obj/effect/turf_decal/tile/neutral/half/contrasted{
+ dir = 4
+ },
+/obj/effect/turf_decal/siding/thinplating/corner{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/commons/locker)
"dms" = (
/obj/structure/closet/crate,
/turf/open/floor/plating,
@@ -10899,15 +11134,6 @@
"dnq" = (
/turf/open/floor/iron,
/area/station/hallway/primary/central)
-"dnD" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron/white/corner{
- dir = 1
- },
-/area/station/hallway/secondary/entry)
"dnL" = (
/obj/machinery/portable_atmospherics/canister/air,
/turf/open/floor/plating,
@@ -11002,14 +11228,14 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/wood/large,
/area/mine/eva/lower)
-"doT" = (
-/obj/item/assembly/timer{
- pixel_x = -3;
- pixel_y = 15
+"doW" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/turf_decal/tile/green/half/contrasted{
+ dir = 1
},
-/obj/structure/table,
-/turf/open/floor/wood,
-/area/station/command/meeting_room)
+/turf/open/floor/iron,
+/area/station/hallway/primary/port)
"dpc" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/command/glass{
@@ -11051,6 +11277,22 @@
/obj/effect/spawner/random/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/central/greater)
+"dpU" = (
+/obj/effect/turf_decal/tile/blue,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
+"dpZ" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/sign/warning/docking/directional/south,
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/disposalpipe/segment{
+ dir = 5
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"dqd" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -11236,6 +11478,15 @@
},
/turf/open/floor/iron,
/area/station/command/heads_quarters/qm)
+"dsg" = (
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 10
+ },
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 1
+ },
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"dsj" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/firealarm/directional/south,
@@ -11278,6 +11529,16 @@
},
/turf/open/floor/iron,
/area/station/hallway/secondary/service)
+"dsR" = (
+/obj/machinery/conveyor/inverted{
+ dir = 10;
+ id = "garbage"
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 6
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"dsT" = (
/obj/effect/turf_decal/stripes/line{
dir = 8
@@ -11357,17 +11618,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/white,
/area/station/science/xenobiology)
-"dtY" = (
-/obj/machinery/camera/directional/north{
- c_tag = "Arrivals Bay 1"
- },
-/obj/effect/turf_decal/tile/blue{
- dir = 4
- },
-/turf/open/floor/iron/white/corner{
- dir = 1
- },
-/area/station/hallway/secondary/entry)
"duh" = (
/turf/closed/wall/r_wall,
/area/station/engineering/transit_tube)
@@ -11417,13 +11667,6 @@
},
/turf/open/floor/iron,
/area/station/service/hydroponics)
-"duW" = (
-/obj/effect/spawner/random/structure/crate,
-/obj/structure/disposalpipe/segment{
- dir = 5
- },
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"duZ" = (
/obj/machinery/door/airlock/engineering{
name = "Utilities Closet"
@@ -11439,6 +11682,20 @@
dir = 1
},
/area/mine/eva)
+"dvf" = (
+/obj/machinery/light/directional/south,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/camera/directional/south{
+ c_tag = "Arrivals Lobby South"
+ },
+/obj/machinery/newscaster/directional/south,
+/obj/effect/landmark/start/hangover,
+/obj/effect/landmark/start/assistant,
+/obj/structure/chair/sofa/bench{
+ dir = 1
+ },
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"dvi" = (
/obj/structure/flora/grass/both/style_random,
/obj/structure/railing,
@@ -11459,12 +11716,14 @@
/obj/machinery/light/directional/west,
/turf/open/floor/iron,
/area/station/hallway/primary/central/fore)
-"dvR" = (
-/obj/structure/cable,
-/obj/structure/chair/stool/directional/south,
-/obj/effect/landmark/start/assistant,
-/turf/open/floor/iron,
-/area/station/commons/locker)
+"dvO" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/turf/open/floor/iron/white/corner,
+/area/station/hallway/secondary/entry)
"dvS" = (
/turf/open/floor/iron/recharge_floor,
/area/station/maintenance/department/electrical)
@@ -11472,6 +11731,21 @@
/obj/structure/flora/tree/dead/style_random,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors/nospawn)
+"dwb" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/structure/cable,
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
+"dwo" = (
+/obj/structure/disposalpipe/segment{
+ dir = 6
+ },
+/obj/structure/lattice/catwalk,
+/obj/effect/decal/cleanable/cobweb,
+/turf/open/openspace/icemoon/keep_below,
+/area/station/maintenance/port/lesser)
"dww" = (
/obj/structure/disposalpipe/segment{
dir = 9
@@ -11488,6 +11762,12 @@
/obj/machinery/power/energy_accumulator/grounding_rod/anchored,
/turf/open/floor/engine,
/area/station/engineering/supermatter)
+"dwI" = (
+/obj/structure/table,
+/obj/effect/spawner/random/entertainment/wallet_storage,
+/obj/effect/spawner/random/clothing/kittyears_or_rabbitears,
+/turf/open/floor/plastic,
+/area/station/commons/dorms/laundry)
"dwS" = (
/obj/machinery/status_display/door_timer{
id = "Cell 3";
@@ -11529,14 +11809,6 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/wood,
/area/station/commons/dorms)
-"dxj" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
- dir = 1
- },
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/obj/effect/turf_decal/tile/neutral,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"dxm" = (
/obj/structure/rack,
/obj/item/clothing/suit/toggle/labcoat,
@@ -11563,6 +11835,11 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
+"dxu" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/iron,
+/area/station/maintenance/port/fore)
"dxA" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -11571,6 +11848,13 @@
},
/turf/open/floor/iron,
/area/station/engineering/lobby)
+"dxE" = (
+/obj/structure/disposalpipe/segment,
+/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/iron_smooth,
+/area/station/maintenance/port/lesser)
"dxJ" = (
/obj/structure/table,
/obj/item/crowbar/red,
@@ -11596,13 +11880,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/aft)
-"dxV" = (
-/obj/structure/rack,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"dyf" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -11693,15 +11970,6 @@
/obj/structure/closet/firecloset,
/turf/open/floor/iron/dark,
/area/mine/eva/lower)
-"dzX" = (
-/obj/machinery/vending/wardrobe/sec_wardrobe,
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/red/half/contrasted{
- dir = 1
- },
-/obj/item/radio/intercom/directional/north,
-/turf/open/floor/iron,
-/area/station/security/checkpoint/customs/auxiliary)
"dAc" = (
/obj/item/radio/intercom/directional/north,
/obj/item/storage/belt/utility{
@@ -11753,14 +12021,6 @@
dir = 5
},
/area/station/command/heads_quarters/rd)
-"dAO" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
-/obj/effect/turf_decal/siding/wood{
- dir = 1
- },
-/obj/effect/turf_decal/siding/wood,
-/turf/open/floor/wood,
-/area/station/commons/vacant_room/office)
"dAP" = (
/obj/structure/cable,
/obj/structure/chair{
@@ -11771,14 +12031,6 @@
},
/turf/open/floor/plating,
/area/station/maintenance/aft/greater)
-"dAT" = (
-/obj/structure/disposalpipe/segment{
- dir = 10
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"dAZ" = (
/turf/closed/wall/r_wall,
/area/station/security/prison/visit)
@@ -11786,15 +12038,6 @@
/obj/machinery/telecomms/server/presets/medical,
/turf/open/floor/iron/dark/telecomms,
/area/station/tcommsat/server)
-"dBj" = (
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
- dir = 1
- },
-/obj/machinery/door/airlock/external{
- name = "Port Docking Bay 4"
- },
-/turf/open/floor/plating,
-/area/station/hallway/secondary/entry)
"dBp" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -11816,6 +12059,13 @@
/obj/machinery/firealarm/directional/south,
/turf/open/floor/iron/checker,
/area/station/commons/storage/emergency/port)
+"dBJ" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"dBK" = (
/obj/machinery/disposal/bin,
/obj/machinery/light/directional/south,
@@ -12011,17 +12261,6 @@
/obj/effect/turf_decal/tile/blue/half/contrasted,
/turf/open/floor/iron,
/area/station/command/bridge)
-"dEL" = (
-/obj/machinery/camera/directional/east{
- c_tag = "Arrivals Bay 1 Hallway"
- },
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/blue{
- dir = 4
- },
-/obj/machinery/light/directional/east,
-/turf/open/floor/iron/white/corner,
-/area/station/hallway/secondary/entry)
"dEQ" = (
/obj/machinery/camera/directional/east{
c_tag = "Public Mining Ladder"
@@ -12031,6 +12270,18 @@
},
/turf/open/floor/iron/dark,
/area/station/commons/storage/mining)
+"dER" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 8
+ },
+/obj/machinery/light/directional/north,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/tile/brown/half/contrasted{
+ dir = 1
+ },
+/obj/structure/cable,
+/turf/open/floor/iron/dark,
+/area/station/maintenance/disposal)
"dEV" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -12177,6 +12428,12 @@
initial_gas_mix = "o2=22;n2=82;TEMP=293.15"
},
/area/station/security/prison/rec)
+"dHk" = (
+/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/iron_smooth,
+/area/station/maintenance/port/lesser)
"dHl" = (
/obj/structure/rack,
/obj/item/crowbar/red,
@@ -12191,12 +12448,6 @@
},
/turf/open/floor/iron/dark/textured_edge,
/area/station/security/prison)
-"dHG" = (
-/obj/structure/chair/comfy/beige{
- dir = 1
- },
-/turf/open/floor/iron/grimy,
-/area/station/hallway/secondary/entry)
"dHJ" = (
/obj/structure/cable/multilayer/multiz,
/obj/effect/turf_decal/stripes/line,
@@ -12281,6 +12532,12 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply,
/turf/open/floor/iron/dark,
/area/station/medical/virology)
+"dJk" = (
+/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/incinerator_ordmix{
+ dir = 8
+ },
+/turf/open/floor/engine,
+/area/station/science/ordnance/burnchamber)
"dJx" = (
/obj/structure/cable,
/obj/effect/spawner/structure/window/reinforced,
@@ -12297,6 +12554,12 @@
/obj/machinery/air_sensor/ordnance_freezer_chamber,
/turf/open/floor/iron/dark/airless,
/area/station/science/ordnance/freezerchamber)
+"dJY" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
"dJZ" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -12325,13 +12588,6 @@
/obj/effect/turf_decal/tile/yellow,
/turf/open/floor/iron,
/area/station/tcommsat/computer)
-"dKl" = (
-/obj/structure/chair/stool/directional/west,
-/obj/effect/turf_decal/tile/blue/opposingcorners{
- dir = 1
- },
-/turf/open/floor/iron/cafeteria,
-/area/station/commons/dorms/laundry)
"dKt" = (
/obj/machinery/door/airlock/external,
/obj/effect/turf_decal/weather/snow/corner{
@@ -12432,18 +12688,6 @@
},
/turf/open/floor/engine,
/area/station/science/xenobiology)
-"dLv" = (
-/obj/docking_port/stationary{
- dir = 8;
- dwidth = 3;
- height = 15;
- name = "arrivals";
- roundstart_template = /datum/map_template/shuttle/arrival/box;
- shuttle_id = "arrival_stationary";
- width = 7
- },
-/turf/open/misc/asteroid/snow/icemoon,
-/area/icemoon/surface/outdoors/nospawn)
"dLH" = (
/obj/structure/fence{
dir = 1
@@ -12519,6 +12763,14 @@
},
/turf/open/floor/iron,
/area/station/command/bridge)
+"dNl" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/siding/thinplating{
+ dir = 1
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plastic,
+/area/station/commons/dorms/laundry)
"dNt" = (
/obj/structure/disposalpipe/segment{
dir = 5
@@ -12667,6 +12919,16 @@
/obj/effect/mapping_helpers/airlock/access/any/service/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
+"dPX" = (
+/obj/structure/sign/warning/docking/directional/east,
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 10
+ },
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 4
+ },
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"dQd" = (
/obj/machinery/door/airlock/maintenance{
name = "Mining Station Maintenance"
@@ -12753,16 +13015,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/mine/laborcamp)
-"dRm" = (
-/obj/structure/disposaloutlet{
- dir = 4
- },
-/obj/effect/turf_decal/stripes/line{
- dir = 4
- },
-/obj/structure/disposalpipe/trunk,
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"dRz" = (
/obj/effect/turf_decal/trimline/green/filled/line,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -12777,17 +13029,6 @@
dir = 1
},
/area/station/command/gateway)
-"dRF" = (
-/obj/machinery/atmospherics/pipe/smart/simple/dark/visible{
- dir = 4
- },
-/obj/effect/turf_decal/stripes/line{
- dir = 8
- },
-/obj/machinery/door/firedoor/heavy,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron/dark,
-/area/station/science/ordnance)
"dSj" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 4
@@ -12863,6 +13104,7 @@
/area/station/service/chapel)
"dTD" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/disposalpipe/segment,
/turf/open/floor/iron,
/area/station/commons/storage/primary)
"dTF" = (
@@ -12956,10 +13198,10 @@
/obj/machinery/light_switch/directional/south,
/turf/open/floor/wood,
/area/station/security/courtroom)
-"dVj" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+"dVb" = (
+/obj/structure/table,
+/obj/item/toy/cards/deck,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron,
/area/station/commons/locker)
"dVq" = (
@@ -12967,6 +13209,15 @@
/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,
@@ -12994,10 +13245,28 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/smooth,
/area/station/engineering/lobby)
+"dVX" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/sign/poster/contraband/random/directional/east,
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 8
+ },
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/machinery/light/small/directional/east,
+/turf/open/floor/wood/large,
+/area/station/commons/vacant_room/office)
"dWf" = (
/obj/item/trash/pistachios,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
+"dWl" = (
+/obj/structure/closet/emcloset,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/status_display/evac/directional/north,
+/obj/effect/turf_decal/siding/white,
+/obj/effect/landmark/start/hangover/closet,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"dWn" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/obj/machinery/camera/directional/north{
@@ -13012,6 +13281,21 @@
/obj/item/shovel/spade,
/turf/open/floor/grass,
/area/station/security/prison/garden)
+"dWP" = (
+/obj/structure/table/wood,
+/obj/item/pen/red{
+ pixel_x = -1;
+ pixel_y = 5
+ },
+/obj/item/reagent_containers/cup/glass/mug/britcup{
+ pixel_x = 8;
+ pixel_y = 1
+ },
+/obj/item/pen/blue{
+ pixel_y = -2
+ },
+/turf/open/floor/iron/grimy,
+/area/station/commons/vacant_room/office)
"dWX" = (
/obj/machinery/modular_computer/preset/engineering,
/obj/effect/turf_decal/tile/brown/anticorner/contrasted{
@@ -13062,7 +13346,7 @@
network = list("ss13","medbay");
pixel_x = 22
},
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/effect/turf_decal/tile/blue/half/contrasted{
dir = 1
},
@@ -13092,18 +13376,20 @@
/obj/item/radio/intercom/directional/east,
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/hfr_room)
-"dXT" = (
-/obj/structure/cable,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"dXU" = (
/obj/effect/decal/cleanable/generic,
/obj/machinery/light/small/directional/south,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/central)
+"dYj" = (
+/obj/machinery/airalarm/directional/north,
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
+"dYq" = (
+/turf/open/floor/plating,
+/area/station/commons/dorms/laundry)
"dYr" = (
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/dark,
@@ -13120,6 +13406,11 @@
},
/turf/open/floor/iron,
/area/mine/production)
+"dYC" = (
+/obj/structure/closet/firecloset,
+/obj/effect/spawner/random/maintenance,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"dYI" = (
/obj/machinery/atmospherics/pipe/smart/simple/dark/visible{
dir = 4
@@ -13154,12 +13445,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/checker,
/area/station/maintenance/port/fore)
-"dZj" = (
-/obj/effect/decal/cleanable/oil,
-/obj/machinery/power/apc/auto_name/directional/east,
-/obj/structure/cable,
-/turf/open/floor/iron/dark,
-/area/station/maintenance/disposal)
"dZq" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 4
@@ -13178,12 +13463,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
/area/station/commons/fitness)
-"dZG" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/holopad,
-/obj/effect/landmark/event_spawn,
-/turf/open/floor/iron/large,
-/area/station/security/checkpoint/customs/auxiliary)
"dZJ" = (
/obj/machinery/seed_extractor,
/obj/machinery/status_display/evac/directional/north,
@@ -13255,6 +13534,11 @@
/obj/item/radio/intercom/directional/east,
/turf/open/floor/engine,
/area/station/engineering/supermatter/room)
+"eae" = (
+/obj/structure/sign/poster/contraband/random/directional/north,
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"eag" = (
/obj/structure/chair/stool/directional/north,
/obj/effect/landmark/start/scientist,
@@ -13303,12 +13587,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/secondary/service)
-"eaS" = (
-/obj/effect/turf_decal/tile/red/half/contrasted{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/security/checkpoint/customs/auxiliary)
"ebb" = (
/obj/structure/extinguisher_cabinet/directional/north,
/turf/open/floor/iron,
@@ -13343,6 +13621,19 @@
initial_gas_mix = "ICEMOON_ATMOS"
},
/area/icemoon/underground/explored)
+"ebC" = (
+/obj/machinery/recycler{
+ dir = 8
+ },
+/obj/machinery/conveyor{
+ dir = 4;
+ id = "garbage"
+ },
+/obj/structure/sign/warning/secure_area/directional/south,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/stripes/line,
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"ebK" = (
/obj/structure/window/reinforced/spawner/directional/north,
/obj/structure/rack,
@@ -13400,6 +13691,13 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/engineering/storage/tech)
+"ecU" = (
+/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,
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
"ecZ" = (
/obj/structure/table,
/obj/effect/turf_decal/tile/neutral/diagonal_edge,
@@ -13454,6 +13752,12 @@
/obj/machinery/light/directional/west,
/turf/open/floor/iron/grimy,
/area/station/commons/lounge)
+"edN" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/disposalpipe/segment,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"edT" = (
/obj/structure/grille/broken,
/turf/open/floor/plating,
@@ -13471,6 +13775,14 @@
/obj/item/clothing/head/costume/fancy,
/turf/open/floor/iron/dark/textured,
/area/station/security/prison)
+"eeq" = (
+/obj/structure/table,
+/obj/item/hand_tele{
+ pixel_x = 3;
+ pixel_y = 13
+ },
+/turf/open/floor/iron,
+/area/station/command/teleporter)
"eeD" = (
/obj/machinery/light/directional/west,
/turf/open/floor/iron/dark/textured,
@@ -13554,6 +13866,10 @@
/obj/item/food/grown/harebell,
/turf/open/floor/iron/chapel,
/area/station/service/chapel)
+"efI" = (
+/obj/structure/lattice,
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"efK" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 9
@@ -13567,11 +13883,6 @@
initial_gas_mix = "ICEMOON_ATMOS"
},
/area/icemoon/underground/explored)
-"efP" = (
-/obj/item/radio/intercom/directional/south,
-/obj/effect/turf_decal/stripes/line,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"efV" = (
/obj/effect/turf_decal/delivery,
/obj/structure/cable,
@@ -13620,10 +13931,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/ai_monitored/command/nuke_storage)
-"egK" = (
-/obj/machinery/firealarm/directional/south,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"egL" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 8
@@ -13640,6 +13947,17 @@
/obj/effect/turf_decal/stripes/line,
/turf/open/floor/plating,
/area/station/maintenance/starboard/upper)
+"egT" = (
+/obj/item/circuitboard/machine/stasis,
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 8
+ },
+/obj/item/wrench/medical,
+/obj/effect/mapping_helpers/broken_floor,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/decal/cleanable/blood/gibs/old,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"egV" = (
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
@@ -13664,13 +13982,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/starboard)
-"ehc" = (
-/obj/machinery/airalarm/directional/west,
-/obj/effect/turf_decal/tile/blue/opposingcorners{
- dir = 1
- },
-/turf/open/floor/iron/cafeteria,
-/area/station/commons/dorms/laundry)
"ehd" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -13840,13 +14151,6 @@
},
/turf/open/floor/plating,
/area/station/engineering/lobby)
-"ejW" = (
-/obj/structure/chair/comfy/beige{
- dir = 1
- },
-/obj/effect/landmark/start/assistant,
-/turf/open/floor/iron/grimy,
-/area/station/hallway/secondary/entry)
"ejX" = (
/turf/open/floor/plating,
/area/station/security/prison/safe)
@@ -13880,6 +14184,12 @@
},
/turf/open/floor/plating,
/area/station/medical/chemistry)
+"ekn" = (
+/obj/structure/disposalpipe/segment{
+ dir = 10
+ },
+/turf/open/floor/iron,
+/area/station/commons/storage/primary)
"ekq" = (
/obj/effect/spawner/random/structure/crate,
/obj/effect/mapping_helpers/burnt_floor,
@@ -13932,17 +14242,15 @@
dir = 8
},
/area/station/science/explab)
-"elr" = (
-/obj/machinery/mineral/stacking_unit_console,
-/turf/closed/wall,
-/area/station/maintenance/port/greater)
-"elu" = (
-/obj/effect/spawner/random/structure/steam_vent,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"elw" = (
/turf/closed/wall/r_wall,
/area/station/maintenance/starboard/upper)
+"elT" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/layer2{
+ dir = 8
+ },
+/turf/open/floor/engine/vacuum,
+/area/station/maintenance/disposal/incinerator)
"elU" = (
/obj/structure/window/reinforced/spawner/directional/west,
/obj/effect/turf_decal/tile/blue/opposingcorners{
@@ -13961,14 +14269,6 @@
dir = 6
},
/area/station/command/heads_quarters/rd)
-"emL" = (
-/obj/machinery/door/firedoor,
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/blue{
- dir = 4
- },
-/turf/open/floor/iron/white/corner,
-/area/station/hallway/secondary/entry)
"emM" = (
/obj/machinery/door/window/brigdoor/security/cell{
dir = 8;
@@ -13980,13 +14280,6 @@
dir = 1
},
/area/station/security/brig)
-"emO" = (
-/obj/structure/extinguisher_cabinet/directional/north,
-/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/hallway/secondary/entry)
"ena" = (
/obj/structure/lattice/catwalk,
/obj/structure/railing{
@@ -14022,9 +14315,6 @@
/obj/effect/mapping_helpers/airlock/unres{
dir = 4
},
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
/turf/open/floor/plating,
/area/station/commons/storage/primary)
"enR" = (
@@ -14059,14 +14349,12 @@
/obj/effect/spawner/structure/window,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/morgue)
-"eov" = (
-/obj/item/radio/off,
-/obj/item/crowbar,
-/obj/item/assembly/flash/handheld,
-/obj/structure/table,
-/obj/effect/turf_decal/tile/red/anticorner/contrasted,
-/turf/open/floor/iron,
-/area/station/security/checkpoint/customs/auxiliary)
+"eoy" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/catwalk_floor/iron_smooth,
+/area/station/maintenance/port/lesser)
"eoD" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible{
@@ -14110,6 +14398,15 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/hfr_room)
+"eoY" = (
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/power/apc/auto_name/directional/east,
+/obj/effect/turf_decal/siding/thinplating_new{
+ dir = 8
+ },
+/turf/open/floor/iron,
+/area/station/commons/locker)
"epd" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/cable,
@@ -14150,6 +14447,10 @@
dir = 8
},
/area/station/science/ordnance/office)
+"eqn" = (
+/obj/structure/sign/warning/docking/directional/east,
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"eqp" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -14241,6 +14542,7 @@
dir = 4
},
/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
"erl" = (
@@ -14260,15 +14562,18 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/white,
/area/station/science/genetics)
+"erw" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/turf_decal/tile/brown,
+/obj/structure/cable,
+/turf/open/floor/iron/dark,
+/area/station/maintenance/disposal)
"erA" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/light_switch/directional/east,
/turf/open/floor/iron,
/area/station/construction)
-"erE" = (
-/obj/machinery/vending/coffee,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"erH" = (
/obj/structure/disposalpipe/trunk{
dir = 8
@@ -14295,11 +14600,14 @@
/obj/machinery/light/small/directional/west,
/turf/open/floor/iron/white,
/area/station/hallway/secondary/exit/departure_lounge)
-"erJ" = (
-/obj/structure/table,
-/obj/item/lipstick/random,
-/turf/open/floor/iron,
-/area/station/commons/locker)
+"erK" = (
+/obj/effect/spawner/structure/window,
+/obj/machinery/door/poddoor/shutters{
+ id = "vacantofficemaintshutter";
+ name = "Privacy Shutters"
+ },
+/turf/open/floor/plating,
+/area/station/commons/vacant_room/office)
"erN" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -14329,12 +14637,6 @@
},
/turf/open/floor/iron/dark,
/area/station/cargo/miningdock)
-"esj" = (
-/obj/structure/cable,
-/obj/machinery/power/apc/auto_name/directional/south,
-/obj/machinery/light_switch/directional/west,
-/turf/open/floor/wood,
-/area/station/commons/vacant_room/office)
"esn" = (
/obj/effect/landmark/start/bartender,
/turf/open/floor/wood,
@@ -14359,12 +14661,6 @@
},
/turf/open/floor/iron,
/area/station/service/hydroponics/garden)
-"esB" = (
-/obj/effect/turf_decal/tile/neutral/half/contrasted{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/service/hydroponics/garden)
"esC" = (
/obj/machinery/portable_atmospherics/canister/air,
/obj/effect/decal/cleanable/dirt,
@@ -14411,10 +14707,6 @@
/obj/machinery/airalarm/directional/west,
/turf/open/floor/iron,
/area/station/security/prison/workout)
-"etx" = (
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
-/turf/open/floor/iron,
-/area/station/hallway/primary/port)
"etA" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -14461,6 +14753,10 @@
/obj/effect/turf_decal/tile/bar/opposingcorners,
/turf/open/floor/iron,
/area/station/hallway/secondary/service)
+"etY" = (
+/obj/machinery/light_switch/directional/north,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"euc" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 4
@@ -14502,6 +14798,10 @@
/obj/item/storage/toolbox/mechanical,
/turf/open/floor/iron/smooth,
/area/mine/eva)
+"euI" = (
+/obj/structure/statue/snow/snowman,
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/underground/explored)
"euM" = (
/obj/effect/turf_decal/stripes/line{
dir = 6
@@ -14618,17 +14918,6 @@
/obj/item/radio/intercom/directional/west,
/turf/open/floor/plating,
/area/station/medical/treatment_center)
-"exl" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 10
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
-"exo" = (
-/obj/structure/sink/directional/west,
-/obj/structure/sign/poster/official/cleanliness/directional/east,
-/turf/open/floor/iron,
-/area/station/maintenance/port/fore)
"exq" = (
/obj/effect/turf_decal/trimline/neutral/warning,
/obj/effect/turf_decal/trimline/neutral/mid_joiner,
@@ -14696,19 +14985,44 @@
/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/medical/pharmacy)
-"eye" = (
-/obj/effect/turf_decal/siding/wood{
+"eyf" = (
+/obj/machinery/door/firedoor,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/door/airlock/public/glass{
+ name = "Arrivals"
+ },
+/obj/structure/cable,
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 4
+ },
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 8
+ },
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/iron/dark/textured,
+/area/station/hallway/secondary/entry)
+"eyj" = (
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/turf/open/floor/iron/white/corner{
dir = 1
},
-/obj/effect/turf_decal/siding/wood/corner,
-/turf/open/floor/wood,
-/area/station/commons/vacant_room/office)
-"eyD" = (
-/obj/effect/spawner/structure/window/hollow/directional{
+/area/station/hallway/secondary/entry)
+"eyk" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/status_display/evac/directional/south,
+/obj/effect/turf_decal/siding/white{
dir = 1
},
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
+/obj/structure/closet/firecloset,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"eyU" = (
/obj/structure/closet/crate/coffin,
/obj/machinery/light/small/red/directional/south,
@@ -15231,13 +15545,6 @@
/obj/item/clothing/under/costume/jabroni,
/turf/open/floor/iron,
/area/station/maintenance/starboard/fore)
-"eHK" = (
-/obj/item/radio/intercom/directional/south,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/cable,
-/turf/open/floor/iron/smooth,
-/area/station/security/execution/transfer)
"eHT" = (
/obj/structure/cable,
/obj/effect/spawner/random/structure/steam_vent,
@@ -15426,6 +15733,11 @@
/obj/structure/chair/stool/directional/west,
/turf/open/floor/iron,
/area/station/commons/dorms)
+"eKN" = (
+/obj/structure/disposalpipe/segment,
+/obj/structure/lattice/catwalk,
+/turf/open/openspace/icemoon/keep_below,
+/area/station/maintenance/port/lesser)
"eKW" = (
/obj/effect/turf_decal/trimline/yellow/filled/corner{
dir = 4
@@ -15461,16 +15773,6 @@
dir = 5
},
/area/station/science/research)
-"eLt" = (
-/obj/structure/sign/map/left{
- pixel_y = 32
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/cable,
-/obj/machinery/light/directional/north,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"eLx" = (
/obj/effect/landmark/start/bartender,
/obj/machinery/duct,
@@ -15507,22 +15809,6 @@
},
/turf/open/floor/plating,
/area/station/engineering/atmos)
-"eMu" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/disposalpipe/segment{
- dir = 6
- },
-/turf/open/floor/iron,
-/area/station/service/hydroponics/garden)
-"eMF" = (
-/obj/machinery/door/firedoor,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/turf_decal/tile/neutral{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"eMG" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -15536,6 +15822,7 @@
"eMH" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/landmark/start/assistant,
+/obj/structure/disposalpipe/segment,
/turf/open/floor/iron,
/area/station/commons/storage/primary)
"eMK" = (
@@ -15609,10 +15896,6 @@
},
/turf/open/floor/plating,
/area/station/maintenance/fore)
-"eNA" = (
-/obj/structure/cable,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"eNC" = (
/obj/machinery/status_display/evac/directional/west,
/obj/item/kirbyplants/random,
@@ -15729,6 +16012,16 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/hallway/secondary/exit/departure_lounge)
+"ePn" = (
+/obj/structure/closet,
+/obj/item/clothing/under/suit/black/skirt,
+/obj/item/clothing/under/suit/black,
+/obj/machinery/newscaster/directional/east,
+/obj/effect/turf_decal/tile/blue/opposingcorners{
+ dir = 1
+ },
+/turf/open/floor/iron/cafeteria,
+/area/station/commons/dorms/laundry)
"ePr" = (
/turf/open/floor/carpet/royalblue,
/area/station/command/heads_quarters/hos)
@@ -15807,21 +16100,20 @@
},
/turf/open/floor/iron/grimy,
/area/station/ai_monitored/turret_protected/aisat_interior)
-"eRK" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/disposalpipe/junction/yjunction{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/hallway/primary/port)
"eRO" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/showroomfloor,
/area/station/security/warden)
+"eRZ" = (
+/obj/structure/table,
+/obj/item/papercutter{
+ pixel_x = 8;
+ pixel_y = 6
+ },
+/turf/open/floor/iron,
+/area/station/command/heads_quarters/hop)
"eSg" = (
/turf/open/floor/plating,
/area/station/maintenance/solars/port/fore)
@@ -15904,6 +16196,12 @@
/obj/effect/turf_decal/bot,
/turf/open/floor/iron/large,
/area/station/engineering/main)
+"eTC" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"eTM" = (
/obj/effect/turf_decal/trimline/blue/corner,
/obj/effect/turf_decal/trimline/blue/corner,
@@ -15952,6 +16250,17 @@
},
/turf/open/floor/iron/kitchen/diagonal,
/area/station/service/kitchen)
+"eUA" = (
+/obj/structure/cable,
+/obj/effect/turf_decal/siding/green/corner{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/service/hydroponics/garden)
"eUB" = (
/obj/structure/table,
/obj/item/flashlight{
@@ -16053,13 +16362,11 @@
/obj/effect/mapping_helpers/airlock/access/all/supply/shipping,
/turf/open/floor/iron,
/area/station/cargo/sorting)
-"eVn" = (
-/obj/structure/closet/emcloset,
-/obj/effect/turf_decal/stripes/line{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
+"eVp" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"eVC" = (
/obj/machinery/atmospherics/pipe/smart/simple/yellow/visible{
dir = 9
@@ -16189,11 +16496,6 @@
},
/turf/open/floor/iron,
/area/station/cargo/storage)
-"eXk" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/pink/hidden,
-/obj/machinery/airalarm/directional/north,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"eXH" = (
/turf/closed/wall/r_wall,
/area/station/medical/chemistry)
@@ -16317,24 +16619,10 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/plating,
/area/station/maintenance/aft/greater)
-"eZw" = (
-/obj/machinery/atmospherics/components/unary/portables_connector/visible{
- dir = 1
- },
-/obj/effect/turf_decal/stripes/end,
-/turf/open/floor/iron,
-/area/station/maintenance/port/fore)
"eZz" = (
/obj/item/storage/fancy/cigarettes/cigpack_mindbreaker,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/underground/explored)
-"eZJ" = (
-/obj/machinery/mineral/stacking_machine{
- input_dir = 1;
- stack_amt = 10
- },
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"eZL" = (
/obj/effect/turf_decal/tile/blue/half/contrasted{
dir = 8
@@ -16439,16 +16727,10 @@
/obj/machinery/newscaster/directional/north,
/turf/open/floor/wood,
/area/station/command/meeting_room)
-"fbK" = (
-/obj/structure/cable,
-/obj/structure/railing/corner{
- dir = 8
- },
-/obj/effect/turf_decal/tile/blue{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/commons/locker)
+"fbY" = (
+/obj/effect/spawner/random/trash/hobo_squat,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"fca" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -16548,17 +16830,20 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/maintenance/department/chapel)
-"fdO" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"fdP" = (
/obj/structure/bonfire,
/obj/item/melee/roastingstick,
/turf/open/floor/plating/snowed/smoothed/icemoon,
/area/icemoon/underground/explored)
+"fdX" = (
+/obj/item/toy/cards/deck{
+ pixel_y = 13;
+ pixel_x = -9
+ },
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/decal/cleanable/generic,
+/turf/open/floor/plating,
+/area/station/commons/dorms/laundry)
"fdY" = (
/obj/machinery/atmospherics/pipe/layer_manifold/scrubbers/hidden,
/turf/closed/wall,
@@ -16634,6 +16919,13 @@
/obj/structure/sign/poster/official/random/directional/east,
/turf/open/floor/wood,
/area/station/service/library)
+"fgo" = (
+/obj/effect/spawner/random/trash/mess,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"fgs" = (
/obj/effect/spawner/random/trash/grille_or_waste,
/turf/open/floor/plating,
@@ -16705,11 +16997,6 @@
/obj/structure/chair/sofa/bench/left,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors/nospawn)
-"fhL" = (
-/obj/item/clothing/suit/apron/surgical,
-/obj/effect/mapping_helpers/broken_floor,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"fhU" = (
/obj/structure/cable,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
@@ -16777,6 +17064,13 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden,
/turf/closed/wall/r_wall,
/area/station/maintenance/disposal/incinerator)
+"fiv" = (
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 6
+ },
+/obj/structure/marker_beacon/burgundy,
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"fiA" = (
/obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible,
/turf/open/floor/iron/dark,
@@ -16905,6 +17199,10 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/kitchen/diagonal,
/area/station/service/kitchen)
+"fkt" = (
+/obj/structure/disposalpipe/segment,
+/turf/open/floor/plating/icemoon,
+/area/station/maintenance/port/lesser)
"fkF" = (
/obj/item/weldingtool,
/turf/open/floor/plating/snowed/icemoon,
@@ -16953,20 +17251,15 @@
},
/turf/open/openspace,
/area/station/science/ordnance/office)
+"fld" = (
+/turf/open/floor/iron/white/corner,
+/area/station/hallway/secondary/entry)
"fle" = (
/obj/effect/turf_decal/trimline/blue/filled/warning{
dir = 4
},
/turf/open/floor/iron/white,
/area/station/medical/treatment_center)
-"flq" = (
-/obj/structure/table,
-/obj/item/paper_bin{
- pixel_x = 1;
- pixel_y = 9
- },
-/turf/open/floor/iron,
-/area/station/cargo/miningdock)
"flx" = (
/obj/machinery/navbeacon{
codes_txt = "patrol;next_patrol=HOP";
@@ -17021,6 +17314,12 @@
"fmc" = (
/turf/closed/wall,
/area/station/hallway/primary/aft)
+"fmg" = (
+/obj/structure/disposalpipe/junction/yjunction{
+ dir = 1
+ },
+/turf/open/floor/catwalk_floor/iron_smooth,
+/area/station/maintenance/port/lesser)
"fmm" = (
/obj/structure/table,
/obj/item/stack/sheet/glass/fifty{
@@ -17099,19 +17398,16 @@
/obj/effect/turf_decal/delivery,
/turf/open/floor/iron,
/area/station/engineering/atmos)
+"fnC" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"fnF" = (
/obj/structure/chair/sofa/middle/brown,
/turf/open/floor/carpet/blue,
/area/station/security/prison/work)
-"fnL" = (
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
- dir = 8
- },
-/obj/machinery/door/airlock/external{
- name = "Port Docking Bay 2"
- },
-/turf/open/floor/plating,
-/area/station/hallway/secondary/entry)
"fnW" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/trimline/red/warning{
@@ -17181,6 +17477,14 @@
},
/turf/open/floor/grass,
/area/station/maintenance/starboard/fore)
+"fpC" = (
+/obj/structure/rack,
+/obj/item/pickaxe,
+/obj/item/tank/internals/emergency_oxygen,
+/obj/item/clothing/mask/breath,
+/obj/structure/sign/warning/cold_temp/directional/east,
+/turf/open/floor/plating,
+/area/station/commons/dorms/laundry)
"fpD" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/orange/visible,
@@ -17389,14 +17693,17 @@
/obj/effect/turf_decal/tile/neutral/opposingcorners,
/turf/open/floor/iron,
/area/station/commons/vacant_room/commissary)
-"ftg" = (
-/obj/machinery/light/small/directional/west,
-/obj/machinery/mass_driver/trash,
-/obj/effect/turf_decal/stripes/line{
- dir = 1
+"fsZ" = (
+/obj/machinery/door/airlock/maintenance,
+/obj/effect/mapping_helpers/airlock/abandoned,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/mapping_helpers/airlock/unres{
+ dir = 4
},
+/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/plating,
-/area/station/maintenance/disposal)
+/area/station/maintenance/port/fore)
"ftt" = (
/obj/structure/sign/warning/secure_area/directional/south{
desc = "A warning sign which reads 'SERVER ROOM'.";
@@ -17598,6 +17905,15 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/cafeteria,
/area/station/security/prison/mess)
+"fwM" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
"fwO" = (
/obj/machinery/space_heater,
/obj/structure/cable,
@@ -17622,11 +17938,13 @@
dir = 4
},
/area/station/engineering/lobby)
-"fxe" = (
-/obj/effect/spawner/structure/window/reinforced,
-/obj/structure/sign/warning/cold_temp,
-/turf/open/floor/plating,
-/area/station/construction/mining/aux_base)
+"fxd" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/tile/brown/half/contrasted{
+ dir = 4
+ },
+/turf/open/floor/iron/dark,
+/area/station/maintenance/disposal)
"fxl" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 8
@@ -17646,16 +17964,6 @@
/obj/effect/turf_decal/tile/red/anticorner/contrasted,
/turf/open/floor/iron,
/area/station/security/checkpoint/supply)
-"fxJ" = (
-/obj/effect/mapping_helpers/airlock/abandoned,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/door/airlock/grunge{
- name = "Vacant Office A"
- },
-/obj/structure/cable,
-/turf/open/floor/wood,
-/area/station/commons/vacant_room/office)
"fxR" = (
/obj/machinery/telecomms/hub/preset,
/obj/effect/turf_decal/tile/neutral/fourcorners,
@@ -17728,13 +18036,11 @@
/turf/open/floor/iron,
/area/station/hallway/primary/starboard)
"fza" = (
-/obj/structure/disposalpipe/junction/flip{
- dir = 1
- },
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/decal/cleanable/dirt,
/obj/structure/cable,
+/obj/structure/disposalpipe/segment,
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
"fzo" = (
@@ -17747,12 +18053,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/surgery/fore)
-"fzu" = (
-/obj/structure/closet/crate,
-/obj/effect/spawner/random/maintenance/three,
-/obj/structure/sign/poster/random/directional/west,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"fzv" = (
/obj/effect/turf_decal/trimline/blue/filled/corner{
dir = 8
@@ -17779,12 +18079,6 @@
/obj/effect/turf_decal/tile/red,
/turf/open/floor/iron,
/area/station/hallway/primary/central/fore)
-"fzF" = (
-/obj/effect/turf_decal/siding/wood{
- dir = 1
- },
-/turf/open/floor/iron/dark,
-/area/station/service/hydroponics/garden)
"fzG" = (
/obj/structure/closet{
name = "evidence closet 5"
@@ -17827,12 +18121,6 @@
/obj/item/kirbyplants/random,
/turf/open/floor/iron,
/area/station/security/prison/work)
-"fAW" = (
-/obj/structure/cable,
-/obj/structure/railing/corner,
-/obj/effect/turf_decal/tile/blue,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"fBc" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/trimline/yellow/line,
@@ -17896,6 +18184,12 @@
/obj/structure/marker_beacon/burgundy,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors/nospawn)
+"fBQ" = (
+/obj/structure/cable,
+/turf/open/floor/iron/white/corner{
+ dir = 8
+ },
+/area/station/hallway/secondary/entry)
"fBR" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -17994,12 +18288,6 @@
/obj/effect/turf_decal/tile/bar/opposingcorners,
/turf/open/floor/iron,
/area/station/service/bar)
-"fDv" = (
-/obj/machinery/door/firedoor,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"fDI" = (
/obj/structure/table/wood,
/obj/machinery/computer/records/medical/laptop{
@@ -18025,6 +18313,17 @@
},
/turf/open/floor/iron,
/area/station/security/prison/garden)
+"fEd" = (
+/obj/structure/table,
+/obj/effect/spawner/random/maintenance/two,
+/obj/effect/decal/cleanable/dirt,
+/obj/item/stock_parts/capacitor,
+/obj/structure/sign/poster/random/directional/north,
+/obj/effect/turf_decal/tile/yellow{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/maintenance/port/fore)
"fEA" = (
/obj/structure/cable,
/obj/machinery/door/airlock/maintenance{
@@ -18114,6 +18413,13 @@
/obj/effect/turf_decal/stripes/corner,
/turf/open/floor/iron,
/area/station/maintenance/disposal/incinerator)
+"fFD" = (
+/obj/structure/railing,
+/obj/effect/turf_decal/tile/brown/half/contrasted,
+/obj/structure/cable,
+/obj/effect/decal/cleanable/greenglow,
+/turf/open/floor/iron/dark,
+/area/station/maintenance/disposal)
"fFI" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
@@ -18132,18 +18438,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/medbay/aft)
-"fFT" = (
-/obj/structure/table/wood,
-/obj/item/pen/red{
- pixel_x = 6;
- pixel_y = 11
- },
-/obj/item/folder/red{
- pixel_x = -3;
- pixel_y = 2
- },
-/turf/open/floor/carpet/red,
-/area/station/commons/vacant_room/office)
"fGn" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -18166,6 +18460,13 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/station/security/prison/workout)
+"fGJ" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/structure/lattice/catwalk,
+/turf/open/openspace/icemoon/keep_below,
+/area/station/maintenance/port/lesser)
"fGM" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment,
@@ -18307,6 +18608,18 @@
/obj/effect/mapping_helpers/airlock/access/any/engineering/maintenance/departmental,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
+"fJd" = (
+/obj/item/kirbyplants/random,
+/obj/structure/sign/warning/pods/directional/west,
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/obj/machinery/light/directional/south,
+/obj/item/radio/intercom/directional/south,
+/turf/open/floor/iron/cafeteria{
+ dir = 5
+ },
+/area/station/hallway/secondary/entry)
"fJe" = (
/obj/machinery/door/airlock/external{
name = "Atmospherics External Airlock"
@@ -18346,7 +18659,6 @@
"fJG" = (
/obj/structure/rack,
/obj/item/hand_labeler,
-/obj/item/hand_labeler,
/obj/structure/cable,
/obj/effect/turf_decal/tile/red,
/turf/open/floor/iron/textured,
@@ -18389,7 +18701,7 @@
/area/station/engineering/storage_shared)
"fKi" = (
/obj/effect/turf_decal/trimline/blue/filled/line,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/turf/open/floor/iron/white,
/area/station/medical/medbay/central)
@@ -18400,6 +18712,7 @@
/obj/effect/turf_decal/tile/neutral/half/contrasted{
dir = 4
},
+/obj/machinery/firealarm/directional/north,
/turf/open/floor/iron/dark/side{
dir = 4
},
@@ -18541,6 +18854,11 @@
},
/turf/open/floor/iron/white,
/area/station/medical/surgery/fore)
+"fLS" = (
+/obj/structure/disposalpipe/segment,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"fLT" = (
/obj/machinery/door/airlock{
name = "Restroom"
@@ -18604,13 +18922,6 @@
/obj/effect/turf_decal/stripes/line,
/turf/open/floor/plating,
/area/station/maintenance/starboard/upper)
-"fMJ" = (
-/obj/structure/chair{
- dir = 1
- },
-/obj/effect/turf_decal/stripes/line,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"fMP" = (
/obj/effect/turf_decal/tile/neutral/diagonal_edge,
/obj/structure/cable,
@@ -18622,16 +18933,6 @@
/obj/structure/closet/emcloset,
/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
-"fNj" = (
-/obj/machinery/door/airlock/external{
- name = "Common Mining Shuttle Bay"
- },
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
- dir = 8
- },
-/obj/effect/landmark/navigate_destination,
-/turf/open/floor/plating,
-/area/station/hallway/secondary/entry)
"fNp" = (
/obj/structure/girder,
/turf/open/floor/plating/snowed/icemoon,
@@ -18658,6 +18959,25 @@
},
/turf/open/floor/iron,
/area/station/cargo/miningdock)
+"fNy" = (
+/obj/structure/rack,
+/obj/item/clothing/suit/hooded/wintercoat{
+ pixel_x = 3;
+ pixel_y = 3
+ },
+/obj/item/clothing/suit/hooded/wintercoat,
+/obj/item/clothing/shoes/winterboots,
+/obj/item/clothing/shoes/winterboots,
+/obj/structure/sign/warning/gas_mask/directional/west,
+/obj/machinery/light/small/directional/west,
+/obj/machinery/mining_weather_monitor/directional/north,
+/obj/effect/turf_decal/delivery/red,
+/obj/machinery/camera/directional/north{
+ c_tag = "Arrivals External Access";
+ dir = 9
+ },
+/turf/open/floor/iron/textured,
+/area/station/hallway/secondary/entry)
"fNA" = (
/turf/open/openspace,
/area/station/medical/medbay/central)
@@ -18709,14 +19029,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/general/visible,
/turf/open/floor/iron/freezer,
/area/station/science/xenobiology)
-"fPx" = (
-/obj/docking_port/stationary/random/icemoon{
- dir = 8;
- name = "lavaland";
- shuttle_id = "pod_lavaland"
- },
-/turf/open/misc/asteroid/snow/icemoon,
-/area/icemoon/surface/outdoors/unexplored/rivers/no_monsters)
"fPA" = (
/obj/effect/turf_decal/stripes/line{
dir = 8
@@ -18727,10 +19039,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/smooth_large,
/area/station/cargo/warehouse)
-"fPM" = (
-/obj/structure/sign/poster/contraband/random/directional/west,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"fPP" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -18788,6 +19096,16 @@
dir = 1
},
/area/station/security/prison)
+"fRb" = (
+/obj/machinery/door/airlock/maintenance,
+/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
+/obj/effect/mapping_helpers/airlock/unres{
+ dir = 8
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/pink,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"fRv" = (
/obj/machinery/light/small/directional/north,
/turf/open/floor/engine,
@@ -18834,6 +19152,17 @@
/obj/structure/railing/corner,
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/underground/explored)
+"fSi" = (
+/obj/structure/cable/multilayer/multiz,
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/effect/mapping_helpers/burnt_floor,
+/obj/structure/sign/nanotrasen{
+ pixel_y = -32
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"fSj" = (
/obj/effect/decal/cleanable/oil,
/turf/open/floor/plating,
@@ -18844,12 +19173,20 @@
},
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/underground/explored)
+"fSv" = (
+/obj/machinery/status_display/evac/directional/south,
+/turf/open/floor/iron,
+/area/station/hallway/primary/port)
"fSC" = (
/obj/effect/turf_decal/bot,
/obj/effect/landmark/start/hangover,
/obj/structure/sign/warning/electric_shock/directional/east,
/turf/open/floor/iron,
/area/station/hallway/primary/central)
+"fSG" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/closed/wall/r_wall,
+/area/station/science/ordnance/burnchamber)
"fTb" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -18867,6 +19204,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/disposalpipe/segment,
/obj/effect/mapping_helpers/airlock/access/all/command/general,
+/obj/machinery/door/firedoor,
/turf/open/floor/wood,
/area/station/command/meeting_room)
"fTo" = (
@@ -18895,20 +19233,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central)
-"fTz" = (
-/obj/machinery/door/airlock/security/glass{
- id_tag = "permainner";
- name = "Permabrig Transfer"
- },
-/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
- cycle_id = "perma-entrance"
- },
-/obj/machinery/door/firedoor,
-/obj/effect/turf_decal/siding/red/corner{
- dir = 4
- },
-/turf/open/floor/iron/dark/textured,
-/area/station/security/execution/transfer)
"fTB" = (
/obj/machinery/power/turbine/core_rotor{
dir = 8;
@@ -18962,7 +19286,7 @@
/turf/open/floor/plating,
/area/station/maintenance/department/electrical)
"fUj" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/turf/open/floor/iron/white/textured,
/area/station/security/medical)
"fUn" = (
@@ -19094,6 +19418,10 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/wood,
/area/station/maintenance/aft/greater)
+"fWN" = (
+/obj/effect/turf_decal/tile/green/half/contrasted,
+/turf/open/floor/iron,
+/area/station/hallway/primary/port)
"fWO" = (
/obj/effect/spawner/random/trash/mess,
/turf/open/floor/plating,
@@ -19218,6 +19546,12 @@
"fYS" = (
/turf/closed/wall,
/area/station/commons/storage/primary)
+"fYW" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 1
+ },
+/turf/open/floor/iron/large,
+/area/station/hallway/secondary/entry)
"fZb" = (
/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
cycle_id = "miner-passthrough"
@@ -19237,13 +19571,6 @@
},
/turf/open/floor/plating,
/area/station/command/teleporter)
-"fZk" = (
-/obj/structure/table/optable{
- name = "Robotics Operating Table"
- },
-/obj/effect/decal/cleanable/blood/old,
-/turf/open/floor/iron,
-/area/station/maintenance/port/fore)
"fZo" = (
/obj/structure/railing/corner{
dir = 4
@@ -19271,13 +19598,6 @@
},
/turf/open/floor/iron,
/area/station/commons/dorms)
-"gaa" = (
-/obj/machinery/vending/coffee,
-/obj/effect/turf_decal/stripes/line{
- dir = 6
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"gad" = (
/obj/item/radio/intercom/directional/east,
/obj/structure/table/reinforced,
@@ -19294,6 +19614,10 @@
},
/turf/open/floor/iron,
/area/station/command/gateway)
+"gak" = (
+/obj/item/radio/intercom/directional/south,
+/turf/open/floor/iron/freezer,
+/area/station/commons/toilet/locker)
"gam" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/mining/glass{
@@ -19398,10 +19722,6 @@
/obj/machinery/light/small/directional/south,
/turf/open/floor/engine,
/area/station/engineering/supermatter)
-"gbt" = (
-/obj/effect/spawner/structure/window/reinforced,
-/turf/open/floor/plating,
-/area/station/security/checkpoint/customs/auxiliary)
"gbu" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -19471,24 +19791,6 @@
/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/medical/storage)
-"gbS" = (
-/obj/structure/table/glass,
-/obj/item/food/grown/wheat,
-/obj/item/food/grown/watermelon,
-/obj/item/food/grown/watermelon,
-/obj/item/food/grown/watermelon,
-/obj/item/food/grown/citrus/orange,
-/obj/item/food/grown/grapes,
-/obj/item/food/grown/cocoapod,
-/obj/machinery/newscaster/directional/west,
-/obj/effect/turf_decal/siding/wood{
- dir = 1
- },
-/obj/effect/turf_decal/tile/green/half/contrasted{
- dir = 4
- },
-/turf/open/floor/iron/dark,
-/area/station/service/hydroponics/garden)
"gca" = (
/obj/structure/table,
/obj/machinery/cell_charger,
@@ -19512,6 +19814,12 @@
/obj/machinery/light/small/directional/east,
/turf/open/floor/grass,
/area/station/service/hydroponics)
+"gcu" = (
+/obj/effect/mapping_helpers/burnt_floor,
+/obj/structure/cable,
+/obj/machinery/power/apc/auto_name/directional/south,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"gcy" = (
/obj/effect/turf_decal/stripes/line{
dir = 8
@@ -19546,14 +19854,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold/purple/visible,
/turf/open/floor/iron,
/area/station/engineering/atmos)
-"gdx" = (
-/obj/machinery/light/directional/south,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/turf_decal/tile/blue{
- dir = 8
- },
-/turf/open/floor/iron/white/corner,
-/area/station/hallway/secondary/entry)
"gdC" = (
/obj/structure/disposalpipe/segment{
dir = 10
@@ -19586,6 +19886,13 @@
},
/turf/open/floor/iron/smooth,
/area/mine/eva/lower)
+"gdY" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/green/half/contrasted,
+/turf/open/floor/iron,
+/area/station/hallway/primary/port)
"gea" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -19601,10 +19908,27 @@
/obj/item/radio/intercom/directional/north,
/turf/open/floor/iron,
/area/station/science/explab)
+"gel" = (
+/obj/structure/table/wood,
+/obj/machinery/newscaster/directional/south,
+/obj/item/radio/intercom/directional/west,
+/obj/item/flashlight/lamp/green{
+ pixel_y = 5
+ },
+/turf/open/floor/iron/grimy,
+/area/station/hallway/secondary/entry)
"gem" = (
/obj/structure/railing,
/turf/open/floor/plating/snowed/smoothed/icemoon,
/area/icemoon/underground/explored)
+"geq" = (
+/obj/structure/closet/secure_closet/personal{
+ anchored = 1
+ },
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/status_display/ai/directional/south,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"geJ" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -19689,6 +20013,17 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/cafeteria,
/area/station/commons/storage/art)
+"gfY" = (
+/obj/effect/spawner/random/structure/tank_holder,
+/obj/structure/sign/poster/official/wtf_is_co2/directional/east,
+/obj/effect/turf_decal/tile/yellow,
+/turf/open/floor/iron,
+/area/station/maintenance/port/fore)
+"gga" = (
+/obj/machinery/light/small/directional/west,
+/obj/effect/spawner/random/trash/hobo_squat,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"ggn" = (
/obj/machinery/door/airlock/atmos{
name = "Atmospherics Maintenance"
@@ -19794,6 +20129,14 @@
"ghY" = (
/turf/open/floor/iron/dark,
/area/station/ai_monitored/turret_protected/aisat/atmos)
+"gif" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/effect/decal/cleanable/plastic,
+/obj/structure/sign/warning/directional/north,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"giD" = (
/obj/machinery/hydroponics/constructable,
/obj/effect/turf_decal/siding/wideplating/dark{
@@ -19881,6 +20224,17 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/plating,
/area/station/maintenance/starboard/upper)
+"gjN" = (
+/obj/machinery/door/firedoor,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 8
+ },
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 4
+ },
+/turf/open/floor/iron/dark/textured,
+/area/station/hallway/secondary/entry)
"gjP" = (
/obj/structure/table,
/obj/item/clothing/gloves/cargo_gauntlet,
@@ -19900,6 +20254,14 @@
/obj/structure/chair,
/turf/open/floor/iron/cafeteria,
/area/station/hallway/secondary/exit/departure_lounge)
+"gjZ" = (
+/obj/machinery/door/airlock/security{
+ name = "Security Checkpoint"
+ },
+/obj/effect/mapping_helpers/airlock/access/all/security/general,
+/obj/effect/turf_decal/tile/red/fourcorners,
+/turf/open/floor/iron/dark,
+/area/station/security/checkpoint/customs/auxiliary)
"gka" = (
/turf/closed/wall/r_wall,
/area/station/engineering/supermatter/room)
@@ -19951,6 +20313,14 @@
/obj/effect/turf_decal/tile/red/anticorner/contrasted,
/turf/open/floor/iron,
/area/station/engineering/atmos)
+"gkZ" = (
+/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/firealarm/directional/east,
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
"glc" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -20134,6 +20504,11 @@
/obj/effect/mapping_helpers/airlock/access/any/security/general,
/turf/open/floor/iron/dark,
/area/station/engineering/lobby)
+"gnq" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/iron/dark,
+/area/station/science/ordnance)
"gnw" = (
/obj/machinery/atmospherics/pipe/smart/manifold/yellow/visible,
/turf/open/floor/iron,
@@ -20217,6 +20592,12 @@
/obj/effect/turf_decal/tile/green/full,
/turf/open/floor/iron/dark/smooth_large,
/area/station/medical/virology)
+"goI" = (
+/obj/structure/curtain/bounty/start_closed,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/iron/dark,
+/area/station/commons/vacant_room/office)
"goJ" = (
/obj/structure/flora/rock/pile/jungle/style_random,
/mob/living/carbon/human/species/monkey,
@@ -20328,13 +20709,11 @@
},
/turf/open/floor/iron/textured,
/area/station/security/brig)
-"gri" = (
-/obj/structure/chair/stool/directional/west,
-/obj/machinery/camera/emp_proof/directional/south,
-/obj/effect/turf_decal/tile/blue/opposingcorners{
+"grk" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
},
-/turf/open/floor/iron/cafeteria,
+/turf/open/floor/plating,
/area/station/commons/dorms/laundry)
"grr" = (
/obj/structure/table,
@@ -20433,6 +20812,23 @@
/obj/effect/turf_decal/tile/brown/half/contrasted,
/turf/open/floor/iron/dark/side,
/area/mine/eva)
+"gsK" = (
+/obj/machinery/light/small/directional/east,
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 9
+ },
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
+"gsN" = (
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/red/anticorner/contrasted{
+ dir = 1
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/airalarm/directional/west,
+/turf/open/floor/iron/dark,
+/area/station/security/checkpoint/customs/auxiliary)
"gsT" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 4
@@ -20452,6 +20848,13 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/plating,
/area/station/service/kitchen/coldroom)
+"gta" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/structure/table,
+/obj/item/folder,
+/obj/item/pen,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"gtc" = (
/obj/effect/turf_decal/siding/white{
dir = 1
@@ -20486,6 +20889,12 @@
},
/turf/open/floor/iron/white,
/area/station/science/xenobiology)
+"gtG" = (
+/obj/machinery/status_display/evac/directional/north,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/spawner/random/vending/colavend,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"guS" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -20524,6 +20933,15 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/security/prison/workout)
+"gvp" = (
+/obj/item/chair/stool{
+ pixel_y = -3;
+ pixel_x = -1
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/light/small/dim/directional/west,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"gvK" = (
/obj/machinery/newscaster/directional/west,
/turf/open/floor/iron/dark,
@@ -20540,6 +20958,25 @@
dir = 9
},
/area/station/science/research)
+"gwp" = (
+/obj/effect/turf_decal/bot,
+/obj/effect/turf_decal/tile/neutral/full,
+/obj/machinery/holopad,
+/turf/open/floor/iron/large,
+/area/station/commons/locker)
+"gwq" = (
+/obj/machinery/computer/records/security,
+/obj/machinery/requests_console/directional/north{
+ department = "Security";
+ name = "Security Requests Console"
+ },
+/obj/effect/mapping_helpers/requests_console/information,
+/obj/effect/mapping_helpers/requests_console/assistance,
+/obj/effect/turf_decal/tile/red/half/contrasted{
+ dir = 1
+ },
+/turf/open/floor/iron/dark,
+/area/station/security/checkpoint/customs/auxiliary)
"gwy" = (
/obj/structure/window/reinforced/spawner/directional/south,
/obj/structure/flora/bush/sparsegrass/style_random,
@@ -20570,11 +21007,17 @@
"gwK" = (
/turf/closed/wall/r_wall,
/area/station/security/checkpoint/engineering)
-"gxn" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron/dark,
-/area/station/science/ordnance)
+"gwM" = (
+/obj/effect/turf_decal/stripes/line,
+/obj/machinery/light/small/dim/directional/north,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/pink/visible,
+/obj/effect/turf_decal/tile/yellow{
+ dir = 1
+ },
+/turf/open/floor/iron/dark/corner{
+ dir = 4
+ },
+/area/station/maintenance/port/fore)
"gxq" = (
/obj/structure/disposalpipe/segment,
/obj/structure/cable,
@@ -20646,15 +21089,6 @@
/obj/item/storage/medkit/regular,
/turf/open/floor/iron,
/area/station/commons/dorms)
-"gyc" = (
-/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/plating,
-/area/station/maintenance/port/greater)
"gyf" = (
/obj/structure/table/wood,
/obj/machinery/newscaster/directional/south,
@@ -20682,6 +21116,13 @@
},
/turf/open/floor/grass,
/area/station/service/hydroponics)
+"gyH" = (
+/obj/machinery/light/directional/north,
+/obj/machinery/vending/coffee,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/newscaster/directional/north,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"gyR" = (
/turf/closed/wall/r_wall,
/area/station/engineering/main)
@@ -20724,6 +21165,14 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
/area/station/maintenance/starboard/fore)
+"gAd" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/machinery/light/small/dim/directional/north,
+/obj/effect/mapping_helpers/broken_floor,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"gAk" = (
/obj/machinery/airalarm/directional/east,
/obj/structure/closet/l3closet/scientist,
@@ -20752,6 +21201,11 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/dark,
/area/station/service/hydroponics)
+"gAB" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"gAD" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/obj/effect/turf_decal/siding/wood{
@@ -20823,13 +21277,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/starboard)
-"gBs" = (
-/obj/item/kirbyplants/random,
-/obj/effect/turf_decal/siding/wood{
- dir = 4
- },
-/turf/open/floor/wood,
-/area/station/commons/vacant_room/office)
"gBv" = (
/obj/machinery/door/window/left/directional/south{
name = "Engineering Delivery";
@@ -20892,6 +21339,14 @@
},
/turf/open/floor/engine,
/area/station/science/xenobiology)
+"gCq" = (
+/obj/item/kirbyplants/random,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/firealarm/directional/east,
+/obj/machinery/status_display/ai/directional/north,
+/obj/effect/turf_decal/siding/white,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"gCu" = (
/obj/structure/closet/emcloset,
/turf/open/floor/plating,
@@ -20963,11 +21418,6 @@
dir = 1
},
/area/mine/eva)
-"gDO" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"gDS" = (
/obj/structure/table,
/obj/effect/spawner/random/maintenance,
@@ -21099,6 +21549,14 @@
/obj/structure/tank_holder/extinguisher,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
+"gFL" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/turf/open/floor/iron/cafeteria{
+ dir = 5
+ },
+/area/station/hallway/secondary/entry)
"gFR" = (
/obj/structure/table/reinforced,
/obj/item/clothing/suit/utility/radiation,
@@ -21357,10 +21815,12 @@
/obj/effect/landmark/start/assistant,
/turf/open/floor/iron,
/area/station/commons/dorms)
-"gJM" = (
-/obj/structure/grille,
+"gJK" = (
+/obj/effect/spawner/structure/window/hollow/reinforced/middle{
+ dir = 4
+ },
/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
+/area/station/commons/dorms/laundry)
"gJT" = (
/obj/structure/window/reinforced/spawner/directional/west,
/turf/open/floor/iron/white/side{
@@ -21472,6 +21932,16 @@
/obj/structure/window/reinforced/spawner/directional/north,
/turf/open/floor/iron/dark,
/area/station/commons/fitness)
+"gMt" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/structure/cable,
+/obj/effect/turf_decal/siding/wood{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/wood,
+/area/station/commons/vacant_room/office)
"gMw" = (
/obj/structure/sign/warning/gas_mask{
desc = "A sign that warns of dangerous gasses in the air, instructing you to wear internals.";
@@ -21561,6 +22031,11 @@
/obj/machinery/light/small/directional/west,
/turf/open/floor/iron/grimy,
/area/station/service/chapel/office)
+"gNL" = (
+/obj/machinery/status_display/evac/directional/south,
+/obj/machinery/light/directional/south,
+/turf/open/floor/iron/grimy,
+/area/station/hallway/secondary/entry)
"gNP" = (
/obj/machinery/oven/range,
/turf/open/floor/iron/cafeteria,
@@ -21608,6 +22083,11 @@
/obj/structure/cable,
/turf/open/floor/wood,
/area/station/service/lawoffice)
+"gOq" = (
+/obj/effect/spawner/random/trash,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/aft)
"gOx" = (
/obj/effect/turf_decal/loading_area,
/obj/effect/turf_decal/tile/neutral/half/contrasted,
@@ -21685,16 +22165,6 @@
dir = 8
},
/area/station/science/research)
-"gPF" = (
-/obj/structure/cable,
-/obj/structure/disposalpipe/sorting/mail/flip{
- dir = 1
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/mapping_helpers/mail_sorting/supply/disposals,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"gPR" = (
/obj/effect/turf_decal/trimline/green/filled/warning,
/obj/machinery/duct,
@@ -21820,6 +22290,13 @@
/obj/effect/turf_decal/tile/neutral/half/contrasted,
/turf/open/floor/iron,
/area/station/commons/locker)
+"gRs" = (
+/obj/structure/sign/warning/electric_shock/directional/north,
+/obj/effect/turf_decal/stripes/corner{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/hallway/primary/port)
"gRI" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/visible,
@@ -21849,6 +22326,15 @@
"gSy" = (
/turf/open/floor/iron,
/area/station/security/prison/workout)
+"gSE" = (
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 8
+ },
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 8
+ },
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"gSK" = (
/obj/structure/railing/corner{
dir = 1
@@ -21997,6 +22483,18 @@
/obj/item/radio/intercom/directional/east,
/turf/open/floor/iron/dark,
/area/station/science/breakroom)
+"gVm" = (
+/obj/item/coin/silver{
+ pixel_y = -3;
+ pixel_x = -5
+ },
+/obj/item/toy/plush/moth{
+ pixel_y = 5;
+ pixel_x = 5;
+ name = "Marcellus"
+ },
+/turf/open/floor/plating,
+/area/station/commons/dorms/laundry)
"gVn" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -22130,6 +22628,20 @@
/obj/item/pen,
/turf/open/floor/wood,
/area/station/service/library)
+"gXr" = (
+/obj/machinery/atmospherics/pipe/multiz/supply/visible/layer4{
+ dir = 1
+ },
+/obj/structure/cable,
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/machinery/atmospherics/pipe/multiz/scrubbers/visible/layer2{
+ dir = 1
+ },
+/obj/machinery/airalarm/directional/south,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"gXv" = (
/obj/machinery/portable_atmospherics/pump/lil_pump,
/turf/open/floor/iron/dark,
@@ -22150,11 +22662,6 @@
/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/science/lab)
-"gXS" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"gYa" = (
/obj/structure/railing{
dir = 9
@@ -22217,11 +22724,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
-"gYR" = (
-/obj/machinery/vending/clothing,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"gZa" = (
/obj/structure/sign/nanotrasen{
pixel_x = -32
@@ -22234,23 +22736,13 @@
/mob/living/carbon/human/species/monkey,
/turf/open/floor/grass,
/area/station/medical/virology)
-"gZj" = (
-/obj/structure/table/reinforced,
-/obj/item/storage/toolbox/emergency{
- pixel_y = 9
+"gZc" = (
+/obj/structure/sign/warning/electric_shock/directional/north,
+/obj/effect/turf_decal/stripes/corner{
+ dir = 4
},
-/obj/item/assembly/timer,
-/obj/item/assembly/signaler{
- pixel_x = 7;
- pixel_y = -7
- },
-/obj/item/assembly/signaler{
- pixel_x = -8;
- pixel_y = -12
- },
-/obj/machinery/status_display/ai/directional/east,
/turf/open/floor/iron,
-/area/station/command/bridge)
+/area/station/hallway/primary/port)
"gZk" = (
/obj/structure/closet/crate,
/obj/effect/spawner/random/maintenance/four,
@@ -22378,6 +22870,16 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/visible,
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
+"haD" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/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/dust,
+/turf/open/floor/catwalk_floor/iron_smooth,
+/area/station/maintenance/port/lesser)
"haN" = (
/obj/machinery/deepfryer,
/obj/effect/turf_decal/tile/neutral/diagonal_edge,
@@ -22387,23 +22889,26 @@
},
/turf/open/floor/iron/kitchen/diagonal,
/area/station/service/kitchen)
-"haQ" = (
-/obj/machinery/atmospherics/components/unary/outlet_injector/monitored/incinerator_input{
- dir = 8
- },
-/turf/open/floor/engine/vacuum,
-/area/station/maintenance/disposal/incinerator)
-"hbm" = (
-/obj/structure/cable,
-/obj/structure/sign/poster/contraband/random/directional/east,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"hbp" = (
/obj/machinery/photocopier,
/turf/open/floor/wood,
/area/station/command/meeting_room)
+"hbt" = (
+/obj/effect/decal/cleanable/cobweb,
+/obj/effect/spawner/random/clothing/mafia_outfit,
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/spawner/random/bureaucracy/briefcase{
+ pixel_y = 8
+ },
+/obj/item/toy/gun,
+/obj/effect/spawner/random/entertainment/money_small,
+/obj/effect/turf_decal/siding/wood,
+/obj/effect/spawner/random/trash/box,
+/turf/open/floor/iron/grimy,
+/area/station/commons/vacant_room/office)
+"hby" = (
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"hbI" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -22428,6 +22933,13 @@
dir = 1
},
/area/station/service/hydroponics)
+"hbY" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/structure/grille,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"hce" = (
/obj/machinery/door/airlock{
id_tag = "AuxToilet3";
@@ -22451,6 +22963,14 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central)
+"hcw" = (
+/obj/docking_port/stationary/random/icemoon{
+ dir = 8;
+ name = "lavaland";
+ shuttle_id = "pod_2_lavaland"
+ },
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"hcG" = (
/obj/structure/lattice/catwalk,
/obj/structure/railing{
@@ -22541,6 +23061,10 @@
},
/turf/open/floor/iron,
/area/mine/laborcamp)
+"heg" = (
+/obj/effect/spawner/random/engineering/canister,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"hek" = (
/obj/structure/table,
/obj/item/stack/sheet/glass,
@@ -22670,6 +23194,16 @@
"hgh" = (
/turf/closed/wall,
/area/station/medical/medbay/lobby)
+"hgr" = (
+/turf/open/floor/glass/reinforced,
+/area/station/hallway/secondary/entry)
+"hgx" = (
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 5
+ },
+/obj/effect/turf_decal/weather/snow/corner,
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"hgH" = (
/obj/item/radio/intercom/prison/directional/west,
/turf/open/floor/iron/dark/textured,
@@ -22797,6 +23331,12 @@
"hjI" = (
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
+"hjJ" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/firealarm/directional/north,
+/obj/machinery/vending/coffee,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"hjM" = (
/turf/closed/wall/r_wall,
/area/station/maintenance/department/medical/morgue)
@@ -22811,6 +23351,15 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/station/engineering/atmos/project)
+"hjU" = (
+/obj/structure/sign/nanotrasen{
+ pixel_x = 32
+ },
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 9
+ },
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"hjV" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/door/poddoor/shutters/preopen{
@@ -22819,18 +23368,6 @@
},
/turf/open/floor/plating,
/area/station/medical/virology)
-"hkb" = (
-/obj/structure/table/wood,
-/obj/item/newspaper{
- pixel_x = 8;
- pixel_y = 8
- },
-/obj/item/paper_bin/carbon{
- pixel_x = -6;
- pixel_y = 4
- },
-/turf/open/floor/iron/grimy,
-/area/station/commons/vacant_room/office)
"hkd" = (
/obj/structure/cable,
/obj/machinery/light/small/directional/west,
@@ -22926,6 +23463,11 @@
/obj/item/clothing/under/misc/burial,
/turf/open/floor/iron/dark,
/area/station/service/chapel)
+"hlW" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/vending/clothing,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"hmb" = (
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
@@ -22950,6 +23492,18 @@
},
/turf/open/floor/iron/dark,
/area/station/service/hydroponics)
+"hmt" = (
+/obj/machinery/door/firedoor,
+/obj/structure/table/reinforced,
+/obj/machinery/door/window/right/directional/west{
+ dir = 1;
+ name = "Security Checkpoint";
+ req_access = list("security")
+ },
+/obj/effect/turf_decal/delivery,
+/obj/item/paper,
+/turf/open/floor/iron,
+/area/station/security/checkpoint/customs/auxiliary)
"hmX" = (
/obj/machinery/atmospherics/pipe/multiz/supply/visible/layer4{
color = "#0000ff";
@@ -23014,10 +23568,6 @@
dir = 8
},
/area/station/science/research)
-"hnV" = (
-/obj/machinery/newscaster/directional/east,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"hos" = (
/obj/structure/disposalpipe/trunk/multiz/down{
dir = 1
@@ -23036,11 +23586,6 @@
/obj/machinery/newscaster/directional/south,
/turf/open/floor/iron/white,
/area/station/medical/virology)
-"hoO" = (
-/obj/item/paper/crumpled,
-/obj/effect/mapping_helpers/broken_floor,
-/turf/open/floor/iron/icemoon,
-/area/icemoon/surface/outdoors/nospawn)
"hoT" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 8
@@ -23060,6 +23605,15 @@
/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible,
/turf/open/floor/plating,
/area/station/engineering/atmos/pumproom)
+"hoZ" = (
+/obj/effect/spawner/random/entertainment/arcade{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral/opposingcorners{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/commons/dorms/laundry)
"hpd" = (
/turf/open/floor/plating,
/area/station/engineering/engine_smes)
@@ -23163,11 +23717,6 @@
/obj/effect/mapping_helpers/airlock/access/all/supply/general,
/turf/open/floor/iron/smooth,
/area/station/cargo/drone_bay)
-"hpN" = (
-/obj/structure/cable,
-/obj/effect/spawner/random/structure/steam_vent,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"hpR" = (
/obj/effect/spawner/random/entertainment/arcade{
dir = 4
@@ -23209,7 +23758,6 @@
/area/station/commons/storage/art)
"hqx" = (
/obj/effect/landmark/start/assistant,
-/obj/structure/disposalpipe/segment,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/commons/storage/primary)
@@ -23236,6 +23784,12 @@
/obj/structure/sign/warning/radiation/rad_area,
/turf/closed/wall/r_wall,
/area/station/engineering/main)
+"hrh" = (
+/obj/structure/chair/comfy/beige{
+ dir = 1
+ },
+/turf/open/floor/iron/grimy,
+/area/station/hallway/secondary/entry)
"hro" = (
/obj/machinery/computer/records/security{
dir = 1
@@ -23323,9 +23877,6 @@
},
/turf/open/floor/iron/dark,
/area/station/command/heads_quarters/cmo)
-"hsI" = (
-/turf/closed/wall,
-/area/station/construction/mining/aux_base)
"hsN" = (
/obj/structure/table,
/obj/item/storage/box/firingpins,
@@ -23346,6 +23897,10 @@
/obj/item/rcl/pre_loaded,
/turf/open/floor/iron,
/area/station/command/heads_quarters/ce)
+"htd" = (
+/obj/structure/sign/warning/docking/directional/north,
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"hte" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/general/visible,
/turf/open/floor/iron/dark,
@@ -23370,6 +23925,14 @@
},
/turf/open/floor/plating,
/area/station/science/xenobiology)
+"htq" = (
+/obj/structure/rack,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/firealarm/directional/east,
+/obj/machinery/status_display/ai/directional/north,
+/obj/effect/turf_decal/siding/white,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"hty" = (
/obj/item/stack/rods,
/turf/open/misc/asteroid/snow/icemoon,
@@ -23384,11 +23947,6 @@
/obj/effect/landmark/start/depsec/science,
/turf/open/floor/iron/dark,
/area/station/security/checkpoint/science)
-"hub" = (
-/obj/structure/chair/stool/directional/west,
-/obj/effect/landmark/start/assistant,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"hue" = (
/obj/structure/chair/comfy/black,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -23411,6 +23969,12 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply,
/turf/open/floor/plating,
/area/station/maintenance/port/greater)
+"hul" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/status_display/evac/directional/north,
+/obj/machinery/vending/autodrobe/all_access,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"hun" = (
/obj/structure/disposalpipe/trunk{
dir = 1
@@ -23489,6 +24053,12 @@
},
/turf/open/floor/iron/white,
/area/station/science/xenobiology)
+"huS" = (
+/obj/structure/disposalpipe/junction/flip{
+ dir = 8
+ },
+/turf/open/floor/catwalk_floor/iron_smooth,
+/area/station/maintenance/port/lesser)
"huT" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
@@ -23649,6 +24219,12 @@
},
/turf/open/floor/iron/white,
/area/station/medical/break_room)
+"hyj" = (
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 1
+ },
+/turf/open/floor/plating/snowed/icemoon,
+/area/station/maintenance/disposal)
"hyt" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -23747,11 +24323,6 @@
/obj/structure/chair/stool/bar/directional/east,
/turf/open/floor/stone,
/area/station/commons/lounge)
-"hzV" = (
-/obj/structure/lattice/catwalk,
-/obj/machinery/smartfridge/petri/preloaded,
-/turf/open/openspace,
-/area/station/science/xenobiology)
"hzY" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/door/poddoor/shutters/preopen{
@@ -23766,11 +24337,23 @@
dir = 4
},
/area/station/science/research)
+"hAo" = (
+/obj/machinery/photocopier,
+/obj/effect/turf_decal/siding/wood/corner,
+/obj/structure/sign/calendar/directional/west,
+/turf/open/floor/wood,
+/area/station/commons/vacant_room/office)
"hAq" = (
/obj/structure/window/reinforced/spawner/directional/west,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/white/corner,
/area/station/command/heads_quarters/rd)
+"hAG" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 1
+ },
+/turf/open/floor/iron/large,
+/area/station/hallway/secondary/entry)
"hAO" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -23862,6 +24445,13 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/wood,
/area/station/hallway/secondary/service)
+"hCa" = (
+/obj/effect/decal/cleanable/dirt,
+/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/commons/locker)
"hCn" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 8
@@ -23913,6 +24503,28 @@
/obj/item/melee/chainofcommand,
/turf/open/floor/wood,
/area/station/command/heads_quarters/captain)
+"hCY" = (
+/obj/structure/table/wood,
+/obj/item/folder/yellow{
+ pixel_y = 8;
+ pixel_x = 3
+ },
+/obj/item/folder/white{
+ pixel_y = 12;
+ pixel_x = -3
+ },
+/obj/structure/sign/poster/contraband/random/directional/south,
+/obj/item/folder/blue{
+ pixel_y = 3;
+ pixel_x = -3
+ },
+/obj/item/folder/red{
+ pixel_x = 5;
+ pixel_y = 2
+ },
+/obj/item/folder,
+/turf/open/floor/iron/grimy,
+/area/station/commons/vacant_room/office)
"hDb" = (
/obj/effect/turf_decal/tile/purple/half/contrasted,
/turf/open/floor/iron,
@@ -23928,11 +24540,6 @@
},
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/storage/gas)
-"hDj" = (
-/obj/structure/disposalpipe/segment,
-/obj/structure/cable,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"hDp" = (
/turf/open/floor/engine,
/area/station/science/genetics)
@@ -23966,11 +24573,6 @@
"hDK" = (
/turf/open/floor/iron,
/area/mine/laborcamp)
-"hDT" = (
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/blue/half/contrasted,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"hDU" = (
/turf/closed/wall/r_wall,
/area/station/command/gateway)
@@ -23982,11 +24584,6 @@
/obj/structure/closet/emcloset,
/turf/open/floor/iron/dark,
/area/mine/eva)
-"hEy" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/landmark/event_spawn,
-/turf/open/floor/iron,
-/area/station/construction/mining/aux_base)
"hEG" = (
/obj/machinery/door/airlock/security/glass{
name = "Brig Control"
@@ -24215,13 +24812,6 @@
/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
-"hII" = (
-/obj/machinery/door/firedoor,
-/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/hallway/secondary/entry)
"hIN" = (
/obj/machinery/light/small/directional/west,
/turf/open/floor/iron/dark,
@@ -24262,6 +24852,12 @@
},
/turf/open/floor/wood/tile,
/area/station/service/theater)
+"hJp" = (
+/obj/effect/turf_decal/tile/brown/half/contrasted{
+ dir = 1
+ },
+/turf/open/floor/iron/dark,
+/area/station/maintenance/disposal)
"hJx" = (
/obj/effect/spawner/structure/window,
/turf/open/floor/plating,
@@ -24287,16 +24883,29 @@
/obj/machinery/light/directional/west,
/turf/open/floor/iron,
/area/station/hallway/primary/central)
-"hJL" = (
-/obj/effect/spawner/structure/window/reinforced,
-/obj/structure/sign/warning/gas_mask,
-/turf/open/floor/plating,
-/area/station/construction/mining/aux_base)
+"hJG" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/siding/thinplating_new{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/commons/locker)
"hJY" = (
/obj/structure/closet/l3closet/janitor,
/obj/machinery/airalarm/directional/north,
/turf/open/floor/iron,
/area/station/service/janitor)
+"hKj" = (
+/obj/machinery/atmospherics/components/binary/pump/off,
+/obj/machinery/airlock_sensor/incinerator_ordmix{
+ pixel_x = 24
+ },
+/obj/machinery/atmospherics/pipe/layer_manifold/supply/hidden{
+ dir = 4
+ },
+/turf/open/floor/engine,
+/area/station/science/ordnance/burnchamber)
"hKr" = (
/obj/structure/table/glass,
/obj/item/book/manual/wiki/infections{
@@ -24317,6 +24926,11 @@
/obj/effect/turf_decal/tile/blue/full,
/turf/open/floor/iron/dark/smooth_large,
/area/station/command/heads_quarters/cmo)
+"hKu" = (
+/obj/structure/sign/poster/official/cleanliness/directional/east,
+/obj/structure/closet/secure_closet/medical2,
+/turf/open/floor/iron,
+/area/station/maintenance/port/fore)
"hKI" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -24356,20 +24970,6 @@
},
/turf/open/floor/iron,
/area/mine/laborcamp)
-"hLm" = (
-/obj/machinery/airalarm/directional/east,
-/obj/machinery/light/directional/east,
-/obj/machinery/camera/directional/east{
- c_tag = "Auxillary Base Construction"
- },
-/obj/machinery/computer/camera_advanced/base_construction/aux{
- dir = 8
- },
-/obj/effect/turf_decal/tile/yellow/half/contrasted{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/construction/mining/aux_base)
"hLw" = (
/obj/item/radio/intercom/directional/north,
/obj/structure/table/wood,
@@ -24423,13 +25023,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/carpet,
/area/station/service/chapel)
-"hMu" = (
-/obj/structure/table,
-/obj/item/razor{
- pixel_y = 5
- },
-/turf/open/floor/iron,
-/area/station/commons/locker)
"hMw" = (
/obj/structure/bookcase/random/fiction,
/turf/open/floor/plating,
@@ -24511,6 +25104,11 @@
name = "Holodeck Projector Floor"
},
/area/station/holodeck/rec_center)
+"hNz" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
+/obj/machinery/newscaster/directional/north,
+/turf/open/floor/iron/large,
+/area/station/hallway/primary/port)
"hNF" = (
/obj/structure/fence{
dir = 4
@@ -24534,13 +25132,6 @@
},
/turf/open/floor/iron,
/area/station/engineering/storage)
-"hNX" = (
-/obj/structure/closet/toolcloset,
-/obj/effect/turf_decal/tile/yellow/anticorner/contrasted{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/construction/mining/aux_base)
"hOc" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/door/poddoor/preopen{
@@ -24634,12 +25225,6 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/iron,
/area/station/command/heads_quarters/hop)
-"hPD" = (
-/obj/machinery/atmospherics/components/unary/vent_scrubber/layer2{
- dir = 8
- },
-/turf/open/floor/engine/vacuum,
-/area/station/maintenance/disposal/incinerator)
"hPK" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 1
@@ -24658,6 +25243,12 @@
},
/turf/open/floor/iron,
/area/station/command/teleporter)
+"hPX" = (
+/obj/structure/frame/computer,
+/obj/structure/sign/poster/official/help_others/directional/north,
+/obj/machinery/light/small/dim/directional/north,
+/turf/open/floor/iron,
+/area/station/maintenance/port/fore)
"hQc" = (
/obj/structure/cable/multilayer/multiz,
/obj/effect/turf_decal/stripes/line{
@@ -24845,6 +25436,15 @@
/obj/structure/cable,
/turf/open/floor/iron/dark/textured_half,
/area/station/service/bar/atrium)
+"hSt" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"hSy" = (
/obj/structure/table/reinforced,
/obj/machinery/door/window/brigdoor/left/directional/north{
@@ -24856,6 +25456,7 @@
id = "medsecprivacy";
name = "Privacy Shutters"
},
+/obj/machinery/door/firedoor,
/turf/open/floor/plating,
/area/station/security/checkpoint/medical)
"hSF" = (
@@ -24888,17 +25489,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/engine,
/area/station/engineering/supermatter/room)
-"hTt" = (
-/obj/machinery/conveyor_switch/oneway{
- dir = 8;
- id = "garbage";
- name = "disposal conveyor"
- },
-/obj/effect/turf_decal/box/corners{
- dir = 4
- },
-/turf/open/floor/iron/dark,
-/area/station/maintenance/disposal)
"hTw" = (
/obj/structure/cable,
/obj/effect/turf_decal/tile/red/half{
@@ -24918,6 +25508,14 @@
},
/turf/open/floor/iron,
/area/station/maintenance/starboard/fore)
+"hTJ" = (
+/obj/machinery/camera/directional/north{
+ c_tag = "Solar Maintenance - North West Access"
+ },
+/obj/machinery/light/small/dim/directional/north,
+/obj/effect/spawner/random/engineering/tank,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"hUe" = (
/obj/effect/landmark/start/hangover,
/obj/machinery/status_display/evac/directional/south,
@@ -24930,9 +25528,6 @@
/obj/effect/decal/cleanable/blood/drip,
/turf/open/floor/iron,
/area/station/maintenance/starboard/fore)
-"hUj" = (
-/turf/open/floor/carpet,
-/area/station/hallway/secondary/entry)
"hUx" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -25005,6 +25600,13 @@
dir = 6
},
/area/mine/living_quarters)
+"hVu" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/effect/mapping_helpers/broken_floor,
+/turf/open/floor/iron/smooth,
+/area/station/maintenance/port/lesser)
"hVB" = (
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/dark,
@@ -25072,6 +25674,14 @@
/obj/structure/extinguisher_cabinet/directional/west,
/turf/open/floor/plating,
/area/station/medical/virology)
+"hWW" = (
+/obj/structure/sign/warning/directional/south,
+/obj/structure/sign/warning/directional/south,
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 1
+ },
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"hWX" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/window/reinforced/spawner/directional/west,
@@ -25089,20 +25699,25 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/starboard)
-"hXL" = (
-/obj/effect/spawner/random/entertainment/arcade{
- dir = 4
- },
-/obj/effect/turf_decal/tile/blue/opposingcorners{
- dir = 1
- },
-/turf/open/floor/iron/cafeteria,
-/area/station/commons/dorms/laundry)
"hXU" = (
/obj/machinery/newscaster/directional/east,
/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible,
/turf/open/floor/iron/white,
/area/station/medical/cryo)
+"hYb" = (
+/obj/machinery/door/airlock/maintenance{
+ name = "Disposal Access"
+ },
+/obj/effect/mapping_helpers/airlock/access/any/supply/maintenance,
+/obj/effect/mapping_helpers/airlock/unres{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/effect/landmark/navigate_destination/disposals,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"hYs" = (
/obj/machinery/chem_master/condimaster{
desc = "Looks like a knock-off chem-master. Perhaps useful for separating liquids when mixing drinks precisely. Also dispenses condiments.";
@@ -25219,6 +25834,16 @@
/obj/effect/spawner/random/trash/mess,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
+"iaU" = (
+/obj/machinery/door/airlock/command/glass{
+ name = "Emergency EVA Storage"
+ },
+/obj/effect/mapping_helpers/airlock/access/all/command/eva,
+/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/dark/textured,
+/area/station/hallway/secondary/entry)
"iaV" = (
/obj/effect/turf_decal/delivery,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/visible,
@@ -25318,15 +25943,6 @@
},
/turf/open/floor/wood,
/area/station/security/prison/rec)
-"ibB" = (
-/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
- },
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"ibI" = (
/obj/structure/chair/stool/directional/south,
/obj/machinery/camera/directional/north{
@@ -25346,17 +25962,6 @@
},
/turf/open/floor/plating,
/area/station/service/chapel)
-"ibR" = (
-/obj/docking_port/stationary{
- dir = 8;
- dwidth = 2;
- height = 13;
- name = "port bay 2";
- shuttle_id = "ferry_home";
- width = 5
- },
-/turf/open/floor/plating/snowed/icemoon,
-/area/icemoon/surface/outdoors/nospawn)
"ica" = (
/obj/machinery/door/firedoor,
/turf/open/floor/iron/dark,
@@ -25428,6 +26033,16 @@
},
/turf/open/floor/iron/dark/textured,
/area/station/security/range)
+"icU" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/tile/brown/half/contrasted{
+ dir = 8
+ },
+/turf/open/floor/iron/dark,
+/area/station/maintenance/disposal)
"icV" = (
/obj/effect/mapping_helpers/airlock/cyclelink_helper{
dir = 4
@@ -25524,11 +26139,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
/area/station/hallway/primary/port)
-"iep" = (
-/obj/effect/decal/cleanable/oil,
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"ieq" = (
/obj/effect/turf_decal/siding/white{
dir = 4
@@ -25546,11 +26156,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central)
-"ieZ" = (
-/obj/effect/spawner/random/trash,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/plating,
-/area/station/maintenance/starboard/aft)
"ifa" = (
/obj/structure/chair/comfy/brown{
dir = 8
@@ -25624,15 +26229,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/mine/eva/lower)
-"igs" = (
-/obj/structure/closet,
-/obj/item/clothing/under/suit/black,
-/obj/item/clothing/under/suit/black/skirt,
-/obj/effect/turf_decal/tile/blue/opposingcorners{
- dir = 1
- },
-/turf/open/floor/iron/cafeteria,
-/area/station/commons/dorms/laundry)
"igx" = (
/obj/machinery/atmospherics/pipe/smart/simple/purple/visible{
dir = 5
@@ -25671,6 +26267,12 @@
/obj/machinery/firealarm/directional/east,
/turf/open/floor/iron/dark,
/area/station/security/interrogation)
+"ihc" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/spawner/random/trash/mess,
+/turf/open/floor/wood/large,
+/area/station/commons/vacant_room/office)
"ihf" = (
/obj/effect/turf_decal/siding/white{
dir = 10
@@ -25679,6 +26281,12 @@
/obj/effect/turf_decal/tile/red/full,
/turf/open/floor/iron/large,
/area/station/service/kitchen/diner)
+"ihk" = (
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/structure/chair/stool/directional/south,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"ihr" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/door/poddoor/shutters/preopen{
@@ -25713,6 +26321,11 @@
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
},
+/obj/machinery/status_display/door_timer{
+ id = "Isolation_Cell";
+ name = "Isolation Cell";
+ pixel_x = -32
+ },
/turf/open/floor/iron/smooth,
/area/station/security/execution/transfer)
"ihG" = (
@@ -25835,10 +26448,6 @@
},
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/hfr_room)
-"ijA" = (
-/obj/machinery/airalarm/directional/south,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"ijC" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -25918,11 +26527,11 @@
/obj/machinery/airalarm/directional/north,
/turf/open/floor/iron,
/area/station/hallway/primary/starboard)
-"ikp" = (
-/obj/machinery/camera/directional/east{
- c_tag = "Arrivals Hallway"
- },
-/turf/open/floor/iron,
+"iku" = (
+/obj/item/kirbyplants/random,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/siding/white,
+/turf/open/floor/iron/dark,
/area/station/hallway/secondary/entry)
"ikw" = (
/obj/structure/disposalpipe/segment{
@@ -25939,6 +26548,7 @@
},
/obj/effect/mapping_helpers/airlock/access/all/medical/general,
/obj/effect/turf_decal/tile/blue/full,
+/obj/machinery/door/firedoor,
/turf/open/floor/iron/large,
/area/station/maintenance/aft/greater)
"ikz" = (
@@ -26000,9 +26610,19 @@
/obj/structure/table/wood,
/turf/open/floor/wood,
/area/station/security/courtroom)
+"ilv" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"ily" = (
/turf/open/openspace,
/area/station/science/xenobiology)
+"ilD" = (
+/obj/structure/lattice/catwalk,
+/turf/open/openspace/icemoon/keep_below,
+/area/station/maintenance/port/lesser)
"ilJ" = (
/obj/machinery/door/airlock/maintenance_hatch{
name = "MiniSat Maintenance"
@@ -26017,13 +26637,6 @@
},
/turf/open/floor/plating,
/area/station/maintenance/department/medical/morgue)
-"ilQ" = (
-/obj/machinery/conveyor{
- id = "garbage"
- },
-/obj/structure/sign/warning/vacuum/directional/west,
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"ilZ" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -26081,6 +26694,10 @@
/obj/machinery/door/firedoor/border_only,
/turf/open/floor/iron/white,
/area/station/science/ordnance)
+"ini" = (
+/obj/structure/falsewall,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"inw" = (
/obj/machinery/door/airlock/engineering{
name = "Port Bow Solar Access"
@@ -26100,6 +26717,34 @@
/obj/machinery/light/directional/north,
/turf/open/floor/iron,
/area/station/hallway/primary/central)
+"inQ" = (
+/obj/structure/table/wood,
+/obj/item/paper_bin/carbon{
+ pixel_x = -6;
+ pixel_y = 4
+ },
+/obj/item/newspaper{
+ pixel_x = 8;
+ pixel_y = 8
+ },
+/turf/open/floor/iron/grimy,
+/area/station/commons/vacant_room/office)
+"iog" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/structure/table,
+/obj/item/storage/medkit/emergency{
+ pixel_y = 5
+ },
+/obj/item/radio/off,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"ioi" = (
/obj/structure/bed/dogbed/lia,
/obj/structure/cable,
@@ -26120,6 +26765,19 @@
},
/turf/open/floor/iron/dark,
/area/station/ai_monitored/turret_protected/aisat_interior)
+"ior" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/machinery/newscaster/directional/north,
+/obj/machinery/light/directional/north,
+/obj/structure/cable,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"iot" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/public/glass{
@@ -26131,6 +26789,13 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron,
/area/station/hallway/primary/aft)
+"iox" = (
+/obj/effect/turf_decal/siding/wood{
+ dir = 8
+ },
+/obj/structure/closet/crate/bin,
+/turf/open/floor/wood,
+/area/station/commons/vacant_room/office)
"ioz" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -26156,20 +26821,6 @@
},
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/hfr_room)
-"ipa" = (
-/obj/machinery/atmospherics/pipe/multiz/scrubbers/visible/layer2{
- color = "#ff0000";
- dir = 4;
- name = "Scrubbers multi deck pipe adapter"
- },
-/obj/machinery/atmospherics/pipe/multiz/supply/visible/layer4{
- color = "#0000ff";
- dir = 4;
- name = "Supply multi deck pipe adapter"
- },
-/obj/structure/cable,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"ipd" = (
/obj/machinery/light/small/directional/south,
/obj/machinery/camera/directional/south{
@@ -26238,8 +26889,11 @@
/obj/structure/cable,
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
-"ipZ" = (
-/obj/effect/landmark/event_spawn,
+"iqn" = (
+/obj/structure/rack,
+/obj/effect/spawner/random/clothing/costume,
+/obj/machinery/light/small/directional/south,
+/obj/item/toy/foamblade,
/obj/effect/turf_decal/tile/blue/opposingcorners{
dir = 1
},
@@ -26277,14 +26931,6 @@
/obj/effect/turf_decal/tile/red/full,
/turf/open/floor/iron/large,
/area/station/service/kitchen/diner)
-"iqT" = (
-/obj/structure/table,
-/obj/structure/bedsheetbin,
-/obj/effect/turf_decal/tile/blue/opposingcorners{
- dir = 1
- },
-/turf/open/floor/iron/cafeteria,
-/area/station/commons/dorms/laundry)
"irp" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -26373,6 +27019,18 @@
dir = 8
},
/area/station/service/chapel)
+"irX" = (
+/obj/item/kirbyplants/random,
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/structure/sign/warning/pods/directional/west,
+/obj/machinery/light/directional/north,
+/obj/item/radio/intercom/directional/north,
+/turf/open/floor/iron/cafeteria{
+ dir = 8
+ },
+/area/station/hallway/secondary/entry)
"isb" = (
/obj/machinery/atmospherics/components/binary/pump/off{
dir = 1;
@@ -26414,6 +27072,21 @@
/obj/machinery/light/small/directional/north,
/turf/open/floor/carpet/blue,
/area/station/medical/psychology)
+"isu" = (
+/obj/machinery/atmospherics/pipe/smart/simple/dark/visible,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/brown/visible/layer2,
+/obj/machinery/air_sensor/incinerator_tank,
+/turf/open/floor/engine/vacuum,
+/area/station/maintenance/disposal/incinerator)
+"isz" = (
+/obj/machinery/recharger{
+ pixel_y = 4
+ },
+/obj/structure/table,
+/obj/effect/turf_decal/tile/red/half/contrasted,
+/obj/structure/cable,
+/turf/open/floor/iron/dark,
+/area/station/security/checkpoint/customs/auxiliary)
"isP" = (
/obj/effect/landmark/start/medical_doctor,
/turf/open/floor/iron/white,
@@ -26449,15 +27122,6 @@
/obj/effect/turf_decal/stripes/line,
/turf/open/floor/iron,
/area/station/command/heads_quarters/rd)
-"itC" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
- dir = 4
- },
-/obj/effect/turf_decal/tile/yellow/half/contrasted{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/construction/mining/aux_base)
"itE" = (
/obj/effect/turf_decal/weather/snow/corner{
dir = 10
@@ -26525,10 +27189,24 @@
},
/turf/open/floor/iron,
/area/station/service/hydroponics)
+"iuH" = (
+/obj/effect/turf_decal/siding/blue{
+ dir = 8
+ },
+/obj/effect/turf_decal/tile/blue/opposingcorners{
+ dir = 1
+ },
+/turf/open/floor/iron/cafeteria,
+/area/station/commons/dorms/laundry)
"iuS" = (
/obj/machinery/airalarm/directional/north,
/turf/open/floor/glass/reinforced,
/area/station/ai_monitored/security/armory/upper)
+"ivi" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/tile/yellow,
+/turf/open/floor/iron,
+/area/station/maintenance/port/fore)
"ivo" = (
/obj/machinery/airalarm/directional/east,
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
@@ -26554,15 +27232,6 @@
"ivF" = (
/turf/closed/wall,
/area/station/maintenance/disposal)
-"ivG" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/yellow/half/contrasted{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"ivH" = (
/obj/structure/disposalpipe/segment{
dir = 9
@@ -26630,6 +27299,15 @@
/obj/structure/railing,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/underground/explored)
+"ixb" = (
+/obj/machinery/button/door/directional/south{
+ id = "vacantofficemaintshutter";
+ pixel_x = 4;
+ name = "Privacy Shutters";
+ pixel_y = -28
+ },
+/turf/open/floor/iron/grimy,
+/area/station/commons/vacant_room/office)
"ixu" = (
/obj/machinery/camera/directional/north{
c_tag = "Teleporter"
@@ -26753,6 +27431,15 @@
/obj/effect/spawner/structure/window/reinforced/tinted,
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
+"izc" = (
+/obj/machinery/atmospherics/components/binary/pump/on{
+ dir = 1
+ },
+/obj/machinery/atmospherics/pipe/layer_manifold/scrubbers/hidden{
+ dir = 8
+ },
+/turf/open/floor/engine,
+/area/station/science/ordnance/burnchamber)
"izn" = (
/obj/effect/spawner/random/decoration/generic,
/turf/open/floor/plating,
@@ -26822,6 +27509,16 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/engineering/engine_smes)
+"izI" = (
+/obj/machinery/door/airlock/maintenance,
+/obj/structure/disposalpipe/segment,
+/obj/effect/mapping_helpers/airlock/unres,
+/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"izJ" = (
/obj/effect/turf_decal/stripes/line{
dir = 10
@@ -26876,12 +27573,6 @@
/obj/structure/sign/poster/contraband/random/directional/east,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
-"iAy" = (
-/obj/structure/rack,
-/obj/item/poster/random_contraband,
-/obj/effect/spawner/random/maintenance/two,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"iAA" = (
/obj/machinery/hydroponics/constructable,
/obj/structure/window/reinforced/spawner/directional/west,
@@ -27009,6 +27700,17 @@
/obj/item/stack/rods/ten,
/turf/open/floor/plating,
/area/station/maintenance/aft/lesser)
+"iCw" = (
+/obj/effect/turf_decal/tile/blue,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/sign/nanotrasen{
+ pixel_x = 32
+ },
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"iCz" = (
/obj/structure/table/reinforced,
/obj/machinery/door/poddoor/shutters/preopen{
@@ -27116,21 +27818,6 @@
/obj/structure/sign/warning/radiation,
/turf/closed/wall/r_wall,
/area/station/engineering/supermatter)
-"iEh" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/turf_decal/siding/thinplating{
- dir = 1
- },
-/obj/effect/turf_decal/tile/blue/opposingcorners{
- dir = 1
- },
-/turf/open/floor/iron/cafeteria,
-/area/station/commons/dorms/laundry)
-"iEr" = (
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/obj/effect/turf_decal/tile/neutral,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"iEA" = (
/obj/structure/table/glass,
/obj/item/storage/box/gloves{
@@ -27172,11 +27859,14 @@
},
/turf/open/floor/iron,
/area/station/science/xenobiology)
-"iEU" = (
-/obj/machinery/hydroponics/soil,
-/obj/machinery/airalarm/directional/east,
-/turf/open/floor/grass,
-/area/station/service/hydroponics/garden)
+"iES" = (
+/obj/effect/turf_decal/tile/blue,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/light/directional/east,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"iFc" = (
/obj/effect/turf_decal/tile/red/half{
dir = 4
@@ -27338,19 +28028,6 @@
},
/turf/open/floor/iron,
/area/station/maintenance/disposal/incinerator)
-"iIw" = (
-/obj/docking_port/stationary{
- dheight = 4;
- dir = 8;
- dwidth = 4;
- height = 9;
- name = "Aux Base Zone";
- roundstart_template = /datum/map_template/shuttle/aux_base/default;
- shuttle_id = "aux_base_zone";
- width = 9
- },
-/turf/open/floor/plating,
-/area/station/construction/mining/aux_base)
"iIA" = (
/obj/effect/turf_decal/bot,
/turf/open/floor/iron,
@@ -27363,6 +28040,7 @@
/obj/effect/mapping_helpers/airlock/unres,
/obj/effect/mapping_helpers/airlock/access/all/medical/general,
/obj/effect/turf_decal/tile/blue/full,
+/obj/machinery/door/firedoor,
/turf/open/floor/iron/large,
/area/station/medical/medbay/lobby)
"iIF" = (
@@ -27380,8 +28058,14 @@
/turf/open/floor/plating,
/area/station/engineering/storage/tech)
"iJl" = (
-/obj/structure/filingcabinet/chestdrawer,
-/turf/open/floor/iron/grimy,
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/turf_decal/siding/wood{
+ dir = 1
+ },
+/obj/effect/spawner/random/engineering/tracking_beacon,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/wood,
/area/station/commons/vacant_room/office)
"iJr" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
@@ -27391,12 +28075,6 @@
/obj/machinery/light/warm/directional/east,
/turf/open/floor/iron,
/area/station/security/prison/mess)
-"iJt" = (
-/obj/machinery/power/apc/auto_name/directional/west,
-/obj/structure/disposalpipe/segment,
-/obj/structure/cable,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"iJC" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
@@ -27422,6 +28100,10 @@
},
/turf/open/openspace,
/area/station/engineering/atmos/storage)
+"iJL" = (
+/obj/effect/landmark/start/hangover,
+/turf/open/floor/plastic,
+/area/station/commons/dorms/laundry)
"iJM" = (
/obj/structure/stairs/south{
dir = 1
@@ -27470,16 +28152,6 @@
/obj/machinery/status_display/evac/directional/east,
/turf/open/openspace,
/area/station/service/chapel)
-"iKR" = (
-/obj/machinery/door/firedoor,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/door/airlock/public/glass{
- name = "Arrivals"
- },
-/obj/structure/cable,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"iKX" = (
/obj/machinery/door/airlock{
id_tag = "AuxToilet1";
@@ -27500,6 +28172,9 @@
/obj/machinery/atmospherics/pipe/smart/simple/brown/visible,
/turf/open/floor/iron,
/area/station/maintenance/disposal/incinerator)
+"iLh" = (
+/turf/closed/wall,
+/area/station/maintenance/port/lesser)
"iLi" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/dark/smooth_edge{
@@ -27549,6 +28224,11 @@
dir = 8
},
/area/station/security/prison)
+"iLA" = (
+/obj/effect/turf_decal/loading_area,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"iLK" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -27579,17 +28259,6 @@
/obj/machinery/duct,
/turf/open/floor/wood/tile,
/area/station/service/theater)
-"iMh" = (
-/obj/effect/turf_decal/siding/wood,
-/obj/effect/turf_decal/siding/wood{
- dir = 1
- },
-/obj/machinery/door/firedoor,
-/obj/machinery/door/airlock/multi_tile/public/glass{
- name = "The Girly Boar"
- },
-/turf/open/floor/iron/dark/textured_half,
-/area/station/service/bar/atrium)
"iMj" = (
/obj/structure/closet/lasertag/blue,
/obj/effect/landmark/start/hangover/closet,
@@ -27706,19 +28375,9 @@
/turf/open/floor/iron/white,
/area/station/maintenance/port/fore)
"iNH" = (
-/obj/structure/table/wood,
-/obj/item/taperecorder{
- pixel_x = 9;
- pixel_y = 9
+/obj/structure/chair/office{
+ dir = 8
},
-/obj/item/folder/blue{
- pixel_x = -8;
- pixel_y = -2
- },
-/obj/item/pen/blue{
- pixel_y = -2
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/grimy,
/area/station/commons/vacant_room/office)
"iNQ" = (
@@ -27818,16 +28477,6 @@
},
/turf/open/floor/iron/dark,
/area/station/commons/storage/mining)
-"iPD" = (
-/obj/machinery/atmospherics/components/binary/pump/off,
-/obj/machinery/airlock_sensor/incinerator_ordmix{
- pixel_x = 24
- },
-/obj/machinery/atmospherics/pipe/layer_manifold/supply/hidden{
- dir = 4
- },
-/turf/open/floor/engine,
-/area/station/science/ordnance/burnchamber)
"iPR" = (
/obj/structure/closet/emcloset,
/turf/open/floor/plating,
@@ -27858,13 +28507,6 @@
/obj/machinery/computer/records/medical/laptop,
/turf/open/floor/iron/white/textured,
/area/station/security/medical)
-"iQr" = (
-/obj/effect/turf_decal/stripes/corner{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"iQt" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -27922,6 +28564,16 @@
/obj/effect/spawner/structure/window/reinforced/tinted,
/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
+"iQX" = (
+/obj/structure/chair/sofa/bench{
+ dir = 1
+ },
+/obj/effect/turf_decal/stripes/line,
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/turf/open/floor/iron/white/corner,
+/area/station/hallway/secondary/entry)
"iRc" = (
/obj/structure/table,
/obj/item/stack/cable_coil{
@@ -28204,15 +28856,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
/area/station/command/bridge)
-"iUY" = (
-/obj/structure/table,
-/obj/item/toy/foamblade,
-/obj/effect/spawner/random/clothing/kittyears_or_rabbitears,
-/obj/effect/turf_decal/tile/blue/opposingcorners{
- dir = 1
- },
-/turf/open/floor/iron/cafeteria,
-/area/station/commons/dorms/laundry)
"iVb" = (
/obj/structure/railing/corner{
dir = 8
@@ -28222,6 +28865,13 @@
},
/turf/open/floor/iron,
/area/station/commons/storage/primary)
+"iVi" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/obj/machinery/firealarm/directional/south,
+/turf/open/floor/iron/cafeteria,
+/area/station/hallway/secondary/entry)
"iVm" = (
/obj/structure/stairs/north,
/obj/structure/railing{
@@ -28252,6 +28902,12 @@
/obj/structure/stairs/south,
/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
+"iWb" = (
+/obj/structure/sign/nanotrasen{
+ pixel_x = 32
+ },
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"iWq" = (
/obj/structure/chair{
dir = 4
@@ -28393,11 +29049,6 @@
/obj/machinery/door/firedoor,
/turf/open/floor/iron/kitchen/diagonal,
/area/station/service/kitchen)
-"iYq" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/item/trash/raisins,
-/turf/open/floor/plating,
-/area/station/maintenance/aft/greater)
"iYs" = (
/obj/structure/disposalpipe/segment,
/obj/effect/turf_decal/trimline/blue/filled/line{
@@ -28412,6 +29063,10 @@
},
/turf/open/floor/plating,
/area/station/cargo/storage)
+"iYy" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"iYA" = (
/obj/structure/window/reinforced/spawner/directional/north,
/obj/structure/window/reinforced/spawner/directional/west,
@@ -28538,11 +29193,6 @@
/obj/structure/cable/layer3,
/turf/open/floor/iron/dark,
/area/station/ai_monitored/turret_protected/ai)
-"jaj" = (
-/obj/structure/extinguisher_cabinet/directional/east,
-/obj/structure/cable,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"jak" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/obj/structure/disposalpipe/segment{
@@ -28622,10 +29272,6 @@
/obj/machinery/airalarm/directional/north,
/turf/open/floor/iron/dark/textured,
/area/station/security/prison/rec)
-"jbh" = (
-/obj/structure/chair/comfy/beige,
-/turf/open/floor/iron/grimy,
-/area/station/hallway/secondary/entry)
"jbu" = (
/obj/structure/railing/corner,
/turf/open/floor/iron/dark/side{
@@ -28671,6 +29317,15 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/dark,
/area/station/security/courtroom)
+"jbJ" = (
+/obj/effect/turf_decal/siding/thinplating_new/corner{
+ dir = 1
+ },
+/obj/effect/turf_decal/siding/thinplating_new{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
"jbT" = (
/obj/machinery/door/firedoor,
/obj/structure/cable,
@@ -28693,13 +29348,6 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/engineering/atmos/pumproom)
-"jcw" = (
-/obj/effect/mapping_helpers/airlock/cyclelink_helper,
-/obj/machinery/door/airlock/external{
- name = "Port Docking Bay 3"
- },
-/turf/open/floor/plating,
-/area/station/hallway/secondary/entry)
"jcC" = (
/obj/machinery/requests_console/directional/north{
department = "Ordnance";
@@ -28724,18 +29372,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
/area/station/security/prison/mess)
-"jdj" = (
-/obj/structure/table/wood,
-/obj/item/flashlight/lamp,
-/turf/open/floor/iron/grimy,
-/area/station/commons/vacant_room/office)
-"jdB" = (
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/red/anticorner/contrasted{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/security/checkpoint/customs/auxiliary)
"jdJ" = (
/obj/structure/chair/wood,
/turf/open/floor/carpet,
@@ -28772,6 +29408,12 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply,
/turf/open/floor/plating,
/area/station/maintenance/port/greater)
+"jdY" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
"jeh" = (
/obj/machinery/atmospherics/components/unary/outlet_injector/monitored/oxygen_input{
dir = 1
@@ -28805,6 +29447,11 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/mix)
+"jez" = (
+/obj/machinery/light/small/directional/north,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"jeF" = (
/obj/effect/landmark/start/security_officer,
/turf/open/floor/glass/reinforced,
@@ -28818,19 +29465,16 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/wood,
/area/station/service/lawoffice)
+"jeK" = (
+/obj/structure/disposalpipe/segment{
+ dir = 9
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"jfc" = (
/turf/closed/wall,
/area/station/command/heads_quarters/hop)
-"jft" = (
-/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/mapping_helpers/burnt_floor,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"jfN" = (
/obj/structure/stairs/south,
/obj/structure/railing{
@@ -28878,6 +29522,15 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/glass,
/area/station/security/lockers)
+"jgx" = (
+/obj/machinery/airalarm/directional/west,
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/turf_decal/tile/brown/half/contrasted{
+ dir = 8
+ },
+/obj/structure/cable,
+/turf/open/floor/iron/dark,
+/area/station/maintenance/disposal)
"jgD" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/closet/wardrobe/pjs{
@@ -28946,12 +29599,6 @@
/obj/structure/tank_holder/extinguisher,
/turf/open/floor/iron/white,
/area/station/medical/medbay/aft)
-"jiI" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"jjk" = (
/obj/structure/lattice/catwalk,
/obj/structure/railing{
@@ -28959,12 +29606,6 @@
},
/turf/open/openspace,
/area/station/cargo/storage)
-"jjp" = (
-/obj/structure/disposalpipe/segment{
- dir = 6
- },
-/turf/open/floor/iron,
-/area/station/commons/storage/primary)
"jjq" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/turf_decal/tile/dark_green{
@@ -29182,6 +29823,13 @@
},
/turf/open/floor/iron/grimy,
/area/station/service/chapel/office)
+"jnR" = (
+/obj/effect/spawner/structure/window/hollow/reinforced/middle{
+ dir = 4
+ },
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"jnS" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -29236,13 +29884,6 @@
/obj/machinery/power/apc/auto_name/directional/south,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/morgue)
-"joB" = (
-/obj/item/beacon,
-/obj/effect/turf_decal/stripes/line{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"joG" = (
/obj/effect/landmark/event_spawn,
/obj/effect/turf_decal/siding/wideplating/dark{
@@ -29296,6 +29937,13 @@
/obj/item/pen,
/turf/open/floor/wood,
/area/station/service/lawoffice)
+"jpC" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/effect/spawner/structure/window/reinforced/tinted,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"jpE" = (
/obj/structure/closet/l3closet/security,
/obj/machinery/airalarm/directional/north,
@@ -29317,6 +29965,14 @@
/obj/effect/mapping_helpers/airlock/access/any/engineering/maintenance/departmental,
/turf/open/floor/plating,
/area/station/maintenance/aft/lesser)
+"jqj" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/sign/poster/contraband/random/directional/north,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"jqn" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/light/directional/north,
@@ -29404,16 +30060,14 @@
},
/turf/open/floor/iron,
/area/station/science/robotics/lab)
-"jse" = (
-/obj/effect/turf_decal/weather/snow/corner,
-/obj/effect/turf_decal/weather/snow/corner{
- dir = 1
+"jsh" = (
+/obj/structure/table/wood,
+/obj/item/flashlight/lamp/green{
+ pixel_y = 5
},
-/obj/effect/turf_decal/weather/snow/corner{
- dir = 4
- },
-/turf/open/floor/plating/snowed/icemoon,
-/area/icemoon/surface/outdoors/nospawn)
+/obj/machinery/mining_weather_monitor/directional/east,
+/turf/open/floor/iron/grimy,
+/area/station/hallway/secondary/entry)
"jsp" = (
/obj/structure/cable,
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer4,
@@ -29431,6 +30085,14 @@
},
/turf/open/floor/iron/dark,
/area/station/ai_monitored/turret_protected/aisat_interior)
+"jss" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/sign/poster/contraband/random/directional/north,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"jsB" = (
/obj/effect/landmark/start/hangover,
/turf/open/floor/iron,
@@ -29621,17 +30283,31 @@
"jug" = (
/turf/open/floor/glass/reinforced,
/area/station/engineering/atmos/pumproom)
+"jul" = (
+/obj/machinery/conveyor{
+ id = "garbage"
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"jum" = (
/obj/effect/turf_decal/tile/brown,
/turf/open/floor/iron/dark/corner,
/area/mine/eva)
-"jun" = (
-/obj/structure/disposalpipe/segment{
- dir = 6
+"juq" = (
+/obj/structure/closet/secure_closet/personal{
+ anchored = 1
},
-/obj/structure/cable,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/siding/thinplating_new{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/commons/locker)
"jur" = (
/obj/structure/disposalpipe/segment,
/obj/effect/mapping_helpers/broken_floor,
@@ -29641,6 +30317,9 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/maintenance/fore/lesser)
+"juu" = (
+/turf/open/floor/iron/grimy,
+/area/station/hallway/secondary/entry)
"juw" = (
/obj/effect/turf_decal/trimline/blue/filled/corner{
dir = 1
@@ -29746,10 +30425,22 @@
},
/turf/open/floor/iron,
/area/station/security/brig/upper)
+"jwB" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/turf_decal/tile/brown{
+ dir = 1
+ },
+/obj/effect/decal/cleanable/oil,
+/turf/open/floor/iron/dark,
+/area/station/maintenance/disposal)
"jwF" = (
/obj/effect/spawner/random/trash/mess,
/turf/open/floor/iron,
/area/station/maintenance/starboard/fore)
+"jwH" = (
+/obj/effect/spawner/structure/window,
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"jwN" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/obj/structure/cable,
@@ -29787,11 +30478,10 @@
/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/medical/storage)
-"jxK" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/pink/hidden,
-/obj/machinery/space_heater,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
+"jyg" = (
+/obj/machinery/firealarm/directional/north,
+/turf/open/floor/iron,
+/area/station/hallway/primary/starboard)
"jyh" = (
/obj/structure/table/wood,
/obj/effect/turf_decal/siding/wood{
@@ -29801,6 +30491,20 @@
/obj/machinery/digital_clock/directional/south,
/turf/open/floor/iron,
/area/station/service/bar)
+"jyl" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/machinery/holopad,
+/turf/open/floor/iron/dark/textured,
+/area/station/security/execution/transfer)
+"jyo" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 5
+ },
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"jyp" = (
/obj/effect/turf_decal/tile/blue,
/obj/machinery/light/directional/south,
@@ -29963,6 +30667,16 @@
/obj/structure/kitchenspike,
/turf/open/floor/plating/snowed/coldroom,
/area/station/service/kitchen/coldroom)
+"jBK" = (
+/obj/structure/closet/emcloset,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/siding/white{
+ dir = 1
+ },
+/obj/effect/landmark/start/hangover/closet,
+/obj/machinery/mining_weather_monitor/directional/south,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"jBR" = (
/obj/machinery/atmospherics/components/unary/thermomachine/heater{
dir = 8
@@ -30017,6 +30731,11 @@
},
/turf/open/floor/carpet,
/area/station/security/detectives_office)
+"jCE" = (
+/obj/structure/lattice/catwalk,
+/obj/machinery/smartfridge/petri/preloaded,
+/turf/open/openspace,
+/area/station/science/xenobiology)
"jCF" = (
/obj/effect/turf_decal/siding/wood,
/obj/structure/chair/wood{
@@ -30089,6 +30808,29 @@
},
/turf/open/floor/iron,
/area/station/engineering/main)
+"jDS" = (
+/obj/structure/chair/sofa/bench/left,
+/obj/effect/turf_decal/stripes/line{
+ dir = 5
+ },
+/obj/effect/turf_decal/tile/blue,
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
+"jDT" = (
+/obj/structure/table/reinforced,
+/obj/item/computer_disk/engineering,
+/obj/item/computer_disk/engineering,
+/obj/item/computer_disk/engineering,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/command/heads_quarters/ce)
"jDW" = (
/obj/effect/turf_decal/bot_white/left,
/obj/structure/closet/crate/silvercrate,
@@ -30101,17 +30843,12 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/ai_monitored/command/nuke_storage)
-"jDY" = (
-/obj/structure/closet/emcloset,
-/obj/effect/turf_decal/stripes/line,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"jEf" = (
/obj/effect/turf_decal/trimline/green/filled/line{
dir = 5
},
-/obj/structure/bed{
- dir = 4
+/obj/structure/bed/medical/anchored{
+ dir = 8
},
/obj/item/bedsheet/medical{
dir = 4
@@ -30137,6 +30874,14 @@
},
/turf/open/floor/iron,
/area/mine/laborcamp)
+"jEB" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/newscaster/directional/north,
+/obj/machinery/light/small/dim/directional/north{
+ pixel_y = 1
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"jFf" = (
/obj/effect/turf_decal/siding/thinplating/dark{
dir = 1
@@ -30149,16 +30894,6 @@
/obj/structure/rack,
/turf/open/floor/iron,
/area/station/command/gateway)
-"jFi" = (
-/obj/item/paper_bin{
- pixel_x = 1;
- pixel_y = 9
- },
-/obj/item/pen,
-/obj/structure/table,
-/obj/effect/turf_decal/tile/red/half/contrasted,
-/turf/open/floor/iron,
-/area/station/security/checkpoint/customs/auxiliary)
"jFA" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -30200,11 +30935,10 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/dark,
/area/station/tcommsat/computer)
-"jGr" = (
-/obj/machinery/door/airlock/maintenance,
-/obj/effect/mapping_helpers/airlock/access/all/engineering/external,
+"jGo" = (
+/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
-/area/station/commons/dorms/laundry)
+/area/station/maintenance/port/lesser)
"jGB" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
@@ -30241,12 +30975,6 @@
/obj/item/clothing/suit/hazardvest,
/turf/open/floor/plating,
/area/station/maintenance/aft/greater)
-"jHp" = (
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/obj/machinery/light/directional/east,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"jHE" = (
/obj/effect/turf_decal/siding/white/corner,
/obj/machinery/firealarm/directional/south,
@@ -30284,6 +31012,25 @@
},
/turf/open/floor/iron,
/area/station/engineering/atmos)
+"jHV" = (
+/obj/machinery/mineral/stacking_machine{
+ stack_amt = 10;
+ output_dir = 2
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 9
+ },
+/turf/open/floor/iron/dark,
+/area/station/maintenance/disposal)
+"jHX" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/effect/landmark/navigate_destination/dockescpod1,
+/turf/open/floor/iron/cafeteria{
+ dir = 8
+ },
+/area/station/hallway/secondary/entry)
"jIg" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -30309,6 +31056,27 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/dark/smooth_half,
/area/station/security/office)
+"jIn" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/turf/open/floor/iron/dark,
+/area/station/security/checkpoint/customs/auxiliary)
+"jIp" = (
+/obj/item/beacon,
+/obj/machinery/holopad,
+/obj/effect/turf_decal/bot,
+/turf/open/floor/iron/large,
+/area/station/hallway/secondary/entry)
+"jIr" = (
+/obj/effect/turf_decal/tile/blue/opposingcorners{
+ dir = 1
+ },
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/landmark/event_spawn,
+/turf/open/floor/iron/cafeteria,
+/area/station/commons/dorms/laundry)
"jIv" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -30355,9 +31123,12 @@
/obj/structure/cable/multilayer/connected,
/turf/open/floor/circuit,
/area/station/ai_monitored/turret_protected/ai)
-"jJa" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 9
+"jJd" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
},
/turf/open/floor/iron,
/area/station/hallway/secondary/entry)
@@ -30382,10 +31153,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/secondary/service)
-"jJm" = (
-/obj/effect/spawner/random/engineering/tracking_beacon,
-/turf/open/floor/iron/dark,
-/area/station/maintenance/disposal)
"jJF" = (
/obj/structure/window/reinforced/spawner/directional/east,
/obj/effect/turf_decal/stripes/line{
@@ -30489,6 +31256,13 @@
},
/turf/open/floor/iron,
/area/station/commons/dorms)
+"jKP" = (
+/obj/structure/disposalpipe/segment{
+ dir = 6
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"jKV" = (
/obj/item/training_toolbox{
pixel_y = 5
@@ -30502,6 +31276,9 @@
},
/turf/open/floor/iron,
/area/station/commons/fitness)
+"jKY" = (
+/turf/closed/mineral/random/snow/high_chance,
+/area/icemoon/underground/unexplored/rivers/deep/shoreline)
"jLa" = (
/obj/structure/sign/poster/contraband/random/directional/north,
/turf/open/openspace,
@@ -30510,6 +31287,11 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/mine/production)
+"jLf" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/disposalpipe/segment,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"jLl" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden,
/obj/effect/turf_decal/siding/yellow{
@@ -30545,23 +31327,15 @@
/obj/effect/turf_decal/tile/red,
/turf/open/floor/iron,
/area/station/hallway/primary/central/fore)
-"jLD" = (
-/obj/structure/cable,
+"jLM" = (
+/obj/effect/turf_decal/tile/blue,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/turf_decal/siding/thinplating/corner{
- dir = 4
- },
-/obj/structure/disposalpipe/trunk{
+/obj/structure/cable,
+/turf/open/floor/iron/white/corner{
dir = 8
},
-/obj/machinery/disposal/bin,
-/obj/machinery/power/apc/auto_name/directional/north,
-/obj/effect/turf_decal/tile/blue/opposingcorners{
- dir = 1
- },
-/turf/open/floor/iron/cafeteria,
-/area/station/commons/dorms/laundry)
+/area/station/hallway/secondary/entry)
"jLO" = (
/obj/machinery/light/small/directional/west,
/turf/open/floor/plating/snowed/smoothed/icemoon,
@@ -30591,6 +31365,12 @@
/obj/effect/mapping_helpers/mail_sorting/science/ordnance,
/turf/open/floor/iron,
/area/station/science/ordnance/testlab)
+"jLX" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/light/small/dim/directional/north,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"jLZ" = (
/obj/structure/table/reinforced,
/obj/machinery/door/poddoor/shutters/preopen{
@@ -30655,15 +31435,12 @@
"jNp" = (
/turf/closed/wall/r_wall,
/area/station/security/holding_cell)
-"jNA" = (
-/obj/structure/cable,
-/obj/structure/disposalpipe/junction{
+"jNB" = (
+/obj/structure/chair/comfy/beige{
dir = 4
},
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
+/turf/open/floor/carpet/blue,
+/area/station/hallway/secondary/entry)
"jNZ" = (
/obj/effect/turf_decal/weather/snow/corner{
dir = 9
@@ -30816,21 +31593,10 @@
},
/turf/open/floor/iron/dark/smooth_large,
/area/station/science/breakroom)
-"jPA" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron/dark,
-/area/station/science/ordnance)
-"jPE" = (
-/obj/machinery/atmospherics/components/binary/pump/on/supply/hidden/layer4{
- dir = 1
- },
+"jPV" = (
+/obj/structure/sign/poster/random/directional/south,
/turf/open/floor/plating,
-/area/station/maintenance/starboard/aft)
-"jPK" = (
-/obj/effect/turf_decal/stripes/line,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
+/area/station/maintenance/port/fore)
"jPY" = (
/obj/structure/reagent_dispensers/fueltank,
/turf/open/floor/plating,
@@ -30978,6 +31744,17 @@
/obj/structure/cable,
/turf/open/floor/carpet,
/area/station/command/heads_quarters/hop)
+"jRI" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/disposalpipe/segment{
+ dir = 5
+ },
+/obj/structure/disposalpipe/segment{
+ dir = 5
+ },
+/turf/open/floor/iron,
+/area/station/service/hydroponics/garden)
"jRM" = (
/obj/effect/turf_decal/trimline/yellow/filled/line{
dir = 6
@@ -31214,17 +31991,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/cargo/drone_bay)
-"jVD" = (
-/obj/docking_port/stationary{
- dir = 2;
- dwidth = 11;
- height = 24;
- name = "SS13: Auxiliary Dock, Station-Port";
- shuttle_id = "whiteship_home";
- width = 35
- },
-/turf/open/floor/plating/snowed/icemoon,
-/area/icemoon/surface/outdoors/nospawn)
"jVE" = (
/obj/effect/turf_decal/box/white,
/turf/open/floor/engine,
@@ -31284,30 +32050,44 @@
},
/turf/open/floor/carpet,
/area/station/command/heads_quarters/hop)
-"jWX" = (
-/obj/effect/spawner/structure/window/hollow/middle,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"jXc" = (
/obj/structure/sign/poster/official/help_others,
/turf/closed/wall/ice,
/area/icemoon/underground/explored)
+"jXe" = (
+/obj/structure/disposalpipe/segment,
+/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/dust,
+/turf/open/floor/catwalk_floor/iron_smooth,
+/area/station/maintenance/port/lesser)
"jXl" = (
/obj/structure/reagent_dispensers/fueltank,
/turf/open/floor/plating,
/area/station/maintenance/aft/lesser)
+"jXm" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
"jXr" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/stripes/corner,
/obj/machinery/atmospherics/components/unary/vent_scrubber/on,
/turf/open/floor/iron,
/area/station/maintenance/disposal/incinerator)
-"jXB" = (
-/obj/effect/landmark/blobstart,
-/obj/effect/mapping_helpers/burnt_floor,
-/obj/effect/landmark/generic_maintenance_landmark,
+"jXC" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/rack,
+/obj/item/storage/box,
+/obj/effect/spawner/random/bureaucracy/birthday_wrap,
+/obj/structure/sign/poster/contraband/random/directional/north,
+/obj/effect/spawner/random/bureaucracy/birthday_wrap,
+/obj/machinery/light/small/directional/west,
/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
+/area/station/maintenance/port/greater)
"jXD" = (
/obj/machinery/light/directional/north,
/turf/open/floor/iron,
@@ -31431,6 +32211,12 @@
/obj/effect/turf_decal/tile/yellow,
/turf/open/floor/iron,
/area/station/hallway/primary/aft)
+"jZD" = (
+/obj/structure/chair/office{
+ dir = 1
+ },
+/turf/open/floor/carpet/red,
+/area/station/commons/vacant_room/office)
"jZI" = (
/obj/effect/turf_decal/trimline/red/filled/line{
dir = 10
@@ -31488,6 +32274,12 @@
},
/turf/open/floor/iron,
/area/mine/laborcamp)
+"kbd" = (
+/obj/structure/closet,
+/obj/effect/spawner/random/maintenance,
+/obj/item/clothing/shoes/workboots,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"kbn" = (
/obj/effect/decal/cleanable/food/pie_smudge,
/turf/open/floor/iron,
@@ -31497,6 +32289,16 @@
/obj/structure/fluff/fokoff_sign,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors/nospawn)
+"kbq" = (
+/obj/machinery/conveyor{
+ id = "garbage";
+ dir = 1
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 5
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"kbs" = (
/obj/effect/turf_decal/loading_area{
dir = 1
@@ -31616,6 +32418,10 @@
},
/turf/open/floor/plating,
/area/station/security/prison/visit)
+"kcW" = (
+/obj/structure/sign/warning/directional/south,
+/turf/open/genturf/blue,
+/area/icemoon/underground/unexplored/rivers/deep/shoreline)
"kdc" = (
/obj/machinery/atmospherics/pipe/smart/manifold/scrubbers/visible{
dir = 8
@@ -31651,17 +32457,15 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/iron/white/textured,
/area/station/security/medical)
-"kdW" = (
-/obj/machinery/camera/directional/south{
- c_tag = "Customs Security Checkpoint"
- },
-/obj/machinery/airalarm/directional/west,
-/obj/machinery/light_switch/directional/south,
-/obj/effect/turf_decal/tile/red/anticorner/contrasted{
+"kdU" = (
+/obj/effect/turf_decal/siding/thinplating_new{
dir = 8
},
+/obj/effect/turf_decal/siding/thinplating_new{
+ dir = 4
+ },
/turf/open/floor/iron,
-/area/station/security/checkpoint/customs/auxiliary)
+/area/station/hallway/secondary/entry)
"kdY" = (
/obj/machinery/camera/directional/north{
c_tag = "Atmospherics Waste Tank"
@@ -31728,6 +32532,21 @@
dir = 1
},
/area/station/hallway/primary/central)
+"keT" = (
+/obj/machinery/atmospherics/components/trinary/filter{
+ dir = 4
+ },
+/obj/effect/turf_decal/stripes/corner{
+ dir = 8
+ },
+/obj/effect/turf_decal/stripes/corner,
+/obj/effect/turf_decal/tile/yellow{
+ dir = 1
+ },
+/turf/open/floor/iron/dark/corner{
+ dir = 4
+ },
+/area/station/maintenance/port/fore)
"keV" = (
/turf/open/floor/engine/vacuum,
/area/station/science/ordnance/burnchamber)
@@ -31898,6 +32717,13 @@
/obj/machinery/airalarm/directional/north,
/turf/open/floor/iron,
/area/station/hallway/secondary/service)
+"kgy" = (
+/obj/structure/cable,
+/obj/effect/spawner/random/structure/steam_vent,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/pink,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"kgz" = (
/obj/structure/cable,
/obj/effect/spawner/structure/window/hollow/reinforced/middle,
@@ -31931,6 +32757,13 @@
},
/turf/open/floor/iron,
/area/station/cargo/sorting)
+"kgY" = (
+/obj/effect/turf_decal/tile/blue/opposingcorners{
+ dir = 1
+ },
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
+/turf/open/floor/iron/cafeteria,
+/area/station/commons/dorms/laundry)
"khb" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 1
@@ -32016,6 +32849,10 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/wood,
/area/station/maintenance/port/fore)
+"kii" = (
+/obj/effect/spawner/random/trash/food_packaging,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"kin" = (
/obj/machinery/pdapainter/supply,
/turf/open/floor/carpet,
@@ -32088,10 +32925,30 @@
/obj/machinery/light/small/directional/north,
/turf/open/floor/iron/dark,
/area/station/engineering/engine_smes)
+"kjo" = (
+/obj/effect/mapping_helpers/airlock/access/any/supply/maintenance,
+/obj/machinery/door/airlock/engineering{
+ name = "Utilities Room"
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/effect/mapping_helpers/airlock/unres{
+ dir = 8
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"kjr" = (
/obj/structure/sign/warning/test_chamber/directional/south,
/turf/open/floor/engine,
/area/station/science/genetics)
+"kjt" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"kjw" = (
/obj/machinery/power/apc/auto_name/directional/west,
/obj/machinery/camera/directional/south{
@@ -32167,6 +33024,11 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/maintenance/solars/port/aft)
+"kkA" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/newscaster/directional/west,
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"kkB" = (
/obj/machinery/light/small/directional/south,
/obj/structure/closet/secure_closet/brig{
@@ -32223,11 +33085,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/break_room)
-"kln" = (
-/obj/machinery/light/small/directional/south,
-/obj/machinery/airalarm/directional/south,
-/turf/open/floor/iron/dark,
-/area/station/maintenance/disposal)
"klo" = (
/obj/effect/turf_decal/stripes/line,
/obj/structure/table/reinforced,
@@ -32294,7 +33151,9 @@
/turf/open/floor/iron/dark/side,
/area/station/service/chapel)
"kmA" = (
-/obj/structure/bed,
+/obj/structure/bed/medical/anchored{
+ dir = 4
+ },
/obj/item/bedsheet/medical,
/obj/machinery/camera/directional/east{
c_tag = "Labor Camp Infirmary";
@@ -32372,6 +33231,10 @@
/obj/effect/turf_decal/tile/brown/fourcorners,
/turf/open/floor/iron/dark,
/area/station/engineering/lobby)
+"knd" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/plating,
+/area/station/commons/dorms/laundry)
"knf" = (
/obj/effect/spawner/random/trash/mess,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -32406,6 +33269,17 @@
/obj/effect/turf_decal/tile/yellow/opposingcorners,
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/project)
+"kod" = (
+/obj/item/kirbyplants/random,
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/machinery/light/directional/north,
+/obj/item/radio/intercom/directional/north,
+/turf/open/floor/iron/cafeteria{
+ dir = 8
+ },
+/area/station/hallway/secondary/entry)
"koA" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -32422,6 +33296,12 @@
},
/turf/open/floor/plating/elevatorshaft,
/area/mine/storage)
+"koH" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 4
+ },
+/turf/open/floor/iron/large,
+/area/station/commons/locker)
"koO" = (
/obj/machinery/meter,
/obj/machinery/atmospherics/pipe/smart/simple/purple/visible{
@@ -32429,6 +33309,17 @@
},
/turf/closed/wall/r_wall,
/area/station/engineering/atmos)
+"koQ" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/door/firedoor,
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 4
+ },
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 8
+ },
+/turf/open/floor/iron/dark/textured,
+/area/station/hallway/secondary/entry)
"koX" = (
/obj/structure/sign/warning/secure_area/directional/west,
/obj/structure/cable,
@@ -32451,15 +33342,6 @@
},
/turf/open/floor/iron/smooth,
/area/station/security/holding_cell)
-"kpp" = (
-/obj/structure/table/wood,
-/obj/item/clothing/mask/cigarette/cigar{
- pixel_x = 7;
- pixel_y = 10
- },
-/obj/item/storage/box/matches,
-/turf/open/floor/carpet,
-/area/station/command/heads_quarters/captain)
"kpu" = (
/obj/effect/spawner/random/trash/mess,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
@@ -32500,7 +33382,9 @@
/turf/open/floor/iron/white,
/area/station/medical/treatment_center)
"kpX" = (
-/obj/structure/bed,
+/obj/structure/bed/medical{
+ dir = 4
+ },
/obj/item/clothing/suit/jacket/straight_jacket,
/obj/machinery/power/apc/auto_name/directional/north,
/obj/structure/cable,
@@ -32679,10 +33563,6 @@
},
/turf/open/floor/plating,
/area/mine/laborcamp/security)
-"krH" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/pink/hidden,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"krN" = (
/obj/structure/sign/poster/official/random/directional/south,
/obj/structure/window/reinforced/spawner/directional/west,
@@ -32709,19 +33589,14 @@
/obj/structure/window/reinforced/spawner/directional/west,
/turf/open/floor/iron/dark/textured,
/area/station/security/prison)
+"krW" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/item/kirbyplants/random,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"krY" = (
/turf/closed/wall/r_wall,
/area/station/science/breakroom)
-"ksa" = (
-/obj/structure/table,
-/obj/item/stack/sheet/iron/fifty,
-/obj/item/stack/sheet/iron/fifty,
-/obj/item/stack/sheet/glass/fifty,
-/obj/effect/turf_decal/tile/yellow/half/contrasted{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/construction/mining/aux_base)
"kse" = (
/obj/structure/chair/sofa/bench/left{
dir = 8
@@ -32819,6 +33694,16 @@
/obj/effect/spawner/random/engineering/tracking_beacon,
/turf/open/floor/iron,
/area/station/command/bridge)
+"ktp" = (
+/obj/machinery/washing_machine,
+/obj/effect/turf_decal/siding/blue{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral/opposingcorners{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/commons/dorms/laundry)
"ktt" = (
/obj/structure/sign/warning/electric_shock,
/turf/closed/wall/r_wall,
@@ -32870,6 +33755,15 @@
"ktU" = (
/turf/open/floor/carpet,
/area/station/command/meeting_room)
+"ktW" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/item/radio/intercom/directional/south,
+/obj/structure/disposalpipe/trunk{
+ dir = 1
+ },
+/obj/machinery/disposal/bin,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"kub" = (
/obj/machinery/newscaster/directional/east,
/turf/open/floor/iron/dark,
@@ -33090,6 +33984,30 @@
/obj/effect/turf_decal/stripes/corner,
/turf/open/floor/iron,
/area/station/engineering/storage_shared)
+"kyc" = (
+/obj/effect/turf_decal/tile/blue,
+/obj/item/kirbyplants/random,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/sign/warning/electric_shock/directional/east,
+/obj/structure/cable,
+/obj/machinery/status_display/evac/directional/south,
+/obj/structure/disposalpipe/segment{
+ dir = 9
+ },
+/turf/open/floor/iron/white/corner{
+ dir = 8
+ },
+/area/station/hallway/secondary/entry)
+"kyg" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/obj/effect/landmark/navigate_destination/dockescpod2,
+/turf/open/floor/iron/cafeteria{
+ dir = 5
+ },
+/area/station/hallway/secondary/entry)
"kyi" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/turf_decal/stripes/line,
@@ -33113,10 +34031,15 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central)
-"kyO" = (
-/obj/effect/turf_decal/stripes/corner,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
+"kyU" = (
+/obj/machinery/modular_computer/preset/id,
+/obj/machinery/light/directional/north,
+/obj/effect/turf_decal/tile/red/half/contrasted{
+ dir = 1
+ },
+/obj/machinery/status_display/ai/directional/north,
+/turf/open/floor/iron/dark,
+/area/station/security/checkpoint/customs/auxiliary)
"kyW" = (
/obj/machinery/computer/records/medical,
/obj/structure/cable,
@@ -33134,14 +34057,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/station/hallway/secondary/service)
-"kzr" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/turf_decal/siding/wideplating/dark{
- dir = 4
- },
-/obj/machinery/holopad,
-/turf/open/floor/iron/dark/textured,
-/area/station/security/prison/rec)
"kzv" = (
/obj/structure/bed,
/obj/item/bedsheet/random,
@@ -33198,15 +34113,6 @@
dir = 10
},
/area/station/science/research)
-"kzI" = (
-/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/stripes/corner{
- dir = 1
- },
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"kzO" = (
/obj/structure/table,
/obj/machinery/cell_charger{
@@ -33234,12 +34140,6 @@
},
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
-"kAl" = (
-/obj/effect/turf_decal/tile/yellow/anticorner/contrasted{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/construction/mining/aux_base)
"kAm" = (
/obj/machinery/light/small/directional/north,
/turf/open/floor/plating,
@@ -33275,23 +34175,6 @@
},
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors/nospawn)
-"kAO" = (
-/obj/machinery/washing_machine,
-/obj/structure/sign/poster/official/random/directional/north,
-/obj/effect/turf_decal/tile/blue/opposingcorners{
- dir = 1
- },
-/turf/open/floor/iron/cafeteria,
-/area/station/commons/dorms/laundry)
-"kAQ" = (
-/obj/machinery/camera/directional/north{
- c_tag = "Arrivals Lounge"
- },
-/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/hallway/secondary/entry)
"kAW" = (
/obj/effect/turf_decal/tile/red/half/contrasted{
dir = 1
@@ -33338,6 +34221,13 @@
/obj/structure/sink/directional/south,
/turf/open/floor/iron/white,
/area/station/medical/medbay/central)
+"kBU" = (
+/obj/structure/table/wood,
+/obj/item/flashlight/lamp/green{
+ pixel_y = 5
+ },
+/turf/open/floor/carpet/blue,
+/area/station/hallway/secondary/entry)
"kBV" = (
/obj/structure/table,
/obj/item/circuitboard/machine/chem_dispenser/drinks,
@@ -33399,6 +34289,11 @@
/obj/effect/landmark/start/hangover,
/turf/open/floor/iron,
/area/station/commons/dorms)
+"kCv" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/spawner/random/trash/cigbutt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"kCx" = (
/obj/structure/table/wood,
/obj/item/book/granter/action/spell/smoke/lesser{
@@ -33439,6 +34334,23 @@
"kCV" = (
/turf/open/floor/iron/dark,
/area/station/ai_monitored/turret_protected/aisat/service)
+"kCY" = (
+/obj/structure/rack,
+/obj/item/clothing/shoes/winterboots/ice_boots/eva{
+ pixel_y = 2
+ },
+/obj/item/clothing/suit/hooded/wintercoat/eva{
+ pixel_y = 5;
+ pixel_x = 1
+ },
+/obj/machinery/light/small/directional/east,
+/obj/machinery/mining_weather_monitor/directional/north,
+/obj/effect/turf_decal/delivery/red,
+/obj/machinery/camera/directional/north{
+ c_tag = "Arrivals Emergency EVA"
+ },
+/turf/open/floor/iron/dark/textured,
+/area/station/hallway/secondary/entry)
"kDb" = (
/obj/machinery/atmospherics/components/trinary/filter/flipped{
dir = 4;
@@ -33453,10 +34365,24 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/mix)
+"kDc" = (
+/obj/machinery/atmospherics/components/unary/outlet_injector/monitored/incinerator_input{
+ dir = 8
+ },
+/turf/open/floor/engine/vacuum,
+/area/station/maintenance/disposal/incinerator)
"kDj" = (
/obj/effect/landmark/event_spawn,
/turf/open/floor/iron,
/area/station/cargo/sorting)
+"kDm" = (
+/obj/structure/closet/crate/trashcart/laundry,
+/obj/machinery/light/small/directional/north,
+/obj/effect/turf_decal/tile/blue/opposingcorners{
+ dir = 1
+ },
+/turf/open/floor/iron/cafeteria,
+/area/station/commons/dorms/laundry)
"kDs" = (
/turf/closed/mineral/snowmountain/cavern/icemoon,
/area/icemoon/surface/outdoors/nospawn)
@@ -33465,6 +34391,10 @@
/obj/structure/table,
/turf/open/floor/iron/cafeteria,
/area/station/security/prison/mess)
+"kDv" = (
+/obj/effect/spawner/random/trash/bin,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"kDz" = (
/obj/structure/toilet{
pixel_y = 8
@@ -33548,6 +34478,12 @@
},
/turf/open/floor/iron/white,
/area/station/medical/virology)
+"kEY" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"kFu" = (
/obj/structure/table,
/obj/item/stack/sheet/iron/fifty,
@@ -33587,13 +34523,6 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/iron,
/area/mine/eva)
-"kFU" = (
-/obj/machinery/door/airlock/maintenance,
-/obj/structure/cable,
-/obj/effect/mapping_helpers/airlock/unres,
-/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"kGc" = (
/obj/structure/table/wood,
/obj/structure/cable,
@@ -33666,21 +34595,37 @@
},
/turf/open/floor/carpet,
/area/station/service/theater)
+"kHl" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"kHn" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/firealarm/directional/south,
/turf/open/floor/iron/showroomfloor,
/area/station/security/prison/toilet)
+"kHq" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/machinery/status_display/shuttle{
+ pixel_x = -32;
+ shuttle_id = "arrival"
+ },
+/obj/machinery/light/directional/west,
+/obj/effect/turf_decal/stripes/corner{
+ dir = 8
+ },
+/turf/open/floor/iron/white/corner{
+ dir = 8
+ },
+/area/station/hallway/secondary/entry)
"kHr" = (
/turf/closed/wall/r_wall,
/area/station/engineering/atmos/project)
-"kHu" = (
-/obj/machinery/firealarm/directional/south,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/hallway/primary/port)
"kHI" = (
/obj/item/radio/intercom/directional/south,
/obj/effect/turf_decal/tile/blue,
@@ -33697,6 +34642,20 @@
/obj/machinery/firealarm/directional/north,
/turf/open/openspace,
/area/station/science/xenobiology)
+"kHP" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 4
+ },
+/obj/structure/railing{
+ dir = 1
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/turf/open/floor/iron/white/corner{
+ dir = 1
+ },
+/area/station/hallway/secondary/entry)
"kHU" = (
/obj/structure/table,
/obj/item/stack/sheet/iron/fifty,
@@ -33715,6 +34674,18 @@
/obj/structure/flora/bush/jungle/a/style_random,
/turf/open/floor/grass,
/area/station/service/hydroponics)
+"kIh" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/landmark/start/hangover,
+/obj/structure/cable,
+/turf/open/floor/iron/white/corner{
+ dir = 1
+ },
+/area/station/hallway/secondary/entry)
"kIi" = (
/obj/machinery/door/airlock{
name = "Perma Overlook Entrance"
@@ -33812,6 +34783,13 @@
},
/turf/open/floor/iron,
/area/station/maintenance/disposal/incinerator)
+"kJO" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/effect/spawner/structure/window/reinforced/tinted,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"kJP" = (
/obj/effect/turf_decal/tile/blue{
dir = 4
@@ -33847,6 +34825,7 @@
/obj/item/mod/module/plasma_stabilizer,
/obj/item/mod/module/thermal_regulator,
/obj/effect/turf_decal/tile/blue/full,
+/obj/item/mod/module/signlang_radio,
/turf/open/floor/iron/dark/smooth_large,
/area/station/medical/storage)
"kKa" = (
@@ -33856,14 +34835,6 @@
},
/turf/open/floor/iron/dark,
/area/station/medical/morgue)
-"kKe" = (
-/obj/structure/disposalpipe/segment,
-/obj/structure/cable,
-/obj/effect/spawner/random/structure/steam_vent,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"kKl" = (
/obj/structure/table/glass,
/obj/item/plant_analyzer,
@@ -33891,16 +34862,15 @@
/obj/effect/turf_decal/tile/yellow/half/contrasted,
/turf/open/floor/iron,
/area/station/hallway/primary/aft)
-"kKI" = (
-/obj/effect/turf_decal/tile/red/half/contrasted{
- dir = 1
- },
-/obj/structure/closet/crate/mod,
-/turf/open/floor/iron/white,
-/area/station/science/robotics/lab)
"kKL" = (
/turf/closed/wall,
/area/station/maintenance/starboard/fore)
+"kKU" = (
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 8
+ },
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"kKX" = (
/obj/effect/landmark/start/hangover,
/obj/effect/turf_decal/tile/blue{
@@ -33969,15 +34939,6 @@
},
/turf/open/floor/iron,
/area/station/cargo/storage)
-"kMu" = (
-/obj/effect/turf_decal/siding/wood/corner{
- dir = 1
- },
-/obj/effect/turf_decal/tile/neutral/half/contrasted{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/service/hydroponics/garden)
"kMv" = (
/obj/effect/turf_decal/trimline/yellow/filled/shrink_cw{
dir = 4
@@ -33992,19 +34953,21 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/freezer,
/area/station/commons/toilet)
-"kMF" = (
-/obj/effect/turf_decal/box,
-/obj/structure/closet/crate,
-/obj/effect/spawner/random/maintenance/two,
-/turf/open/floor/iron/dark,
-/area/station/maintenance/port/greater)
-"kMM" = (
-/turf/open/floor/iron/grimy,
-/area/station/hallway/secondary/entry)
"kMN" = (
/obj/machinery/space_heater,
/turf/open/floor/plating,
/area/station/maintenance/department/chapel)
+"kMP" = (
+/obj/structure/disposalpipe/segment,
+/obj/structure/rack,
+/obj/item/storage/backpack/satchel/leather/withwallet,
+/obj/item/toy/figure/assistant,
+/obj/structure/sign/calendar/directional/west,
+/obj/effect/turf_decal/tile/neutral/opposingcorners{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/commons/dorms/laundry)
"kMY" = (
/obj/effect/turf_decal/siding/yellow{
dir = 6
@@ -34167,6 +35130,11 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/iron,
/area/station/hallway/primary/aft)
+"kPq" = (
+/obj/effect/spawner/random/structure/steam_vent,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"kPv" = (
/obj/machinery/vending/cigarette,
/turf/open/floor/wood,
@@ -34175,6 +35143,15 @@
/obj/structure/flora/bush/flowers_yw/style_random,
/turf/open/floor/grass,
/area/station/maintenance/starboard/aft)
+"kPy" = (
+/obj/effect/turf_decal/tile/neutral/half/contrasted{
+ dir = 4
+ },
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/service/hydroponics/garden)
"kPL" = (
/obj/machinery/power/apc/auto_name/directional/south,
/obj/structure/cable,
@@ -34269,12 +35246,13 @@
/obj/item/pipe_dispenser,
/turf/open/floor/iron/dark,
/area/station/engineering/supermatter/room)
-"kQS" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/disposalpipe/segment,
-/turf/open/floor/iron,
-/area/station/hallway/primary/port)
+"kQV" = (
+/obj/structure/closet/crate,
+/obj/effect/spawner/random/maintenance/three,
+/obj/structure/sign/departments/maint/directional/west,
+/obj/machinery/light/small/directional/west,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"kQW" = (
/obj/structure/closet/crate/hydroponics,
/obj/item/shovel/spade,
@@ -34311,6 +35289,13 @@
},
/turf/open/floor/engine,
/area/station/engineering/atmos/hfr_room)
+"kRc" = (
+/obj/machinery/light/directional/west,
+/obj/structure/closet/wardrobe/grey,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/status_display/ai/directional/west,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"kRd" = (
/obj/structure/bookcase,
/turf/open/floor/iron,
@@ -34392,16 +35377,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/station/cargo/office)
-"kSh" = (
-/obj/machinery/conveyor/inverted{
- dir = 5;
- id = "garbage"
- },
-/obj/structure/disposalpipe/segment{
- dir = 5
- },
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"kSn" = (
/obj/structure/cable/multilayer/multiz,
/obj/effect/turf_decal/stripes/line,
@@ -34456,6 +35431,12 @@
"kTz" = (
/turf/open/floor/iron/smooth_half,
/area/station/security/brig/upper)
+"kTC" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 1
+ },
+/turf/open/floor/iron/large,
+/area/station/hallway/primary/port)
"kTD" = (
/obj/effect/turf_decal/stripes/corner{
dir = 4
@@ -34491,6 +35472,12 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
/area/station/engineering/lobby)
+"kTX" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 1
+ },
+/turf/open/floor/plastic,
+/area/station/commons/dorms/laundry)
"kUb" = (
/obj/effect/turf_decal/stripes/red/line{
dir = 8
@@ -34498,6 +35485,17 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/smooth,
/area/station/maintenance/fore/lesser)
+"kUn" = (
+/obj/machinery/door/airlock/maintenance,
+/obj/effect/mapping_helpers/airlock/abandoned,
+/obj/effect/mapping_helpers/airlock/unres{
+ dir = 1
+ },
+/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/pink,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"kUu" = (
/obj/machinery/atmospherics/pipe/smart/simple/orange/visible{
dir = 4
@@ -34536,6 +35534,14 @@
/obj/structure/railing/corner,
/turf/open/lava/plasma/ice_moon,
/area/icemoon/underground/explored)
+"kUU" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/effect/spawner/random/structure/steam_vent,
+/obj/effect/mapping_helpers/broken_floor,
+/turf/open/floor/iron/smooth,
+/area/station/maintenance/port/lesser)
"kVl" = (
/obj/effect/landmark/event_spawn,
/obj/machinery/light/floor,
@@ -34720,6 +35726,21 @@
"kXA" = (
/turf/open/floor/iron,
/area/station/cargo/office)
+"kXB" = (
+/obj/structure/table,
+/obj/item/pai_card,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron,
+/area/station/commons/locker)
+"kXD" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 1
+ },
+/obj/effect/turf_decal/siding/thinplating_new/corner{
+ dir = 8
+ },
+/turf/open/floor/iron/large,
+/area/station/hallway/secondary/entry)
"kXE" = (
/obj/machinery/door/firedoor,
/obj/structure/disposalpipe/segment,
@@ -34730,6 +35751,9 @@
/turf/open/floor/iron,
/area/station/hallway/primary/central)
"kXI" = (
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 1
+ },
/turf/open/floor/plating/icemoon,
/area/icemoon/surface/outdoors/nospawn)
"kXM" = (
@@ -34796,15 +35820,6 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/iron/large,
/area/station/engineering/engine_smes)
-"kYQ" = (
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
- dir = 4
- },
-/obj/effect/turf_decal/tile/blue{
- dir = 8
- },
-/turf/open/floor/iron/white/corner,
-/area/station/hallway/secondary/entry)
"kZa" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -34873,13 +35888,6 @@
/obj/machinery/light/small/directional/east,
/turf/open/floor/vault,
/area/station/security/prison/rec)
-"kZQ" = (
-/obj/structure/rack,
-/obj/item/pickaxe,
-/obj/item/tank/internals/emergency_oxygen,
-/obj/item/clothing/mask/breath,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"laa" = (
/obj/machinery/atmospherics/components/tank,
/obj/effect/turf_decal/stripes/line{
@@ -34924,6 +35932,10 @@
/obj/effect/mapping_helpers/airlock/access/all/security/general,
/turf/open/floor/iron/smooth,
/area/station/security/processing)
+"laB" = (
+/obj/effect/spawner/random/engineering/atmospherics_portable,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"laD" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 8
@@ -35046,6 +36058,13 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/station/maintenance/disposal/incinerator)
+"ldw" = (
+/obj/machinery/door/airlock/maintenance,
+/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
+/obj/effect/mapping_helpers/airlock/unres,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"ldz" = (
/obj/structure/rack,
/obj/item/reagent_containers/dropper,
@@ -35101,7 +36120,7 @@
/area/station/science/xenobiology)
"lei" = (
/obj/effect/turf_decal/trimline/blue/filled/line,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/turf/open/floor/iron/white,
/area/station/medical/medbay/aft)
"lek" = (
@@ -35133,12 +36152,6 @@
/obj/machinery/power/apc/auto_name/directional/west,
/turf/open/floor/plating,
/area/station/maintenance/aft/greater)
-"leI" = (
-/obj/machinery/power/apc/auto_name/directional/east,
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"leM" = (
/obj/structure/railing{
dir = 8
@@ -35215,12 +36228,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/treatment_center)
-"lgr" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"lgz" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 8
@@ -35315,17 +36322,11 @@
},
/turf/open/floor/iron/white,
/area/station/medical/virology)
-"lim" = (
-/obj/machinery/conveyor{
- dir = 4;
- id = "garbage"
- },
-/obj/machinery/light/small/directional/north,
-/obj/structure/disposalpipe/segment{
- dir = 6
- },
+"lil" = (
+/obj/structure/cable,
+/obj/structure/sign/poster/random/directional/west,
/turf/open/floor/plating,
-/area/station/maintenance/disposal)
+/area/station/maintenance/port/fore)
"lis" = (
/obj/structure/closet/secure_closet/miner,
/turf/open/floor/iron,
@@ -35370,13 +36371,6 @@
dir = 1
},
/area/station/hallway/secondary/exit/departure_lounge)
-"liQ" = (
-/obj/structure/table/wood,
-/obj/item/flashlight/lamp,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron/grimy,
-/area/station/commons/vacant_room/office)
"liS" = (
/obj/structure/closet/crate/coffin,
/obj/effect/decal/cleanable/dirt,
@@ -35432,12 +36426,30 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/central)
+"ljE" = (
+/obj/machinery/door/firedoor,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/cable,
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 1
+ },
+/obj/effect/turf_decal/stripes/white/line,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron/dark/textured,
+/area/station/commons/locker)
"ljF" = (
/obj/effect/turf_decal/siding/purple{
dir = 8
},
/turf/open/floor/iron/white,
/area/station/science/lab)
+"ljK" = (
+/obj/structure/disposalpipe/trunk/multiz/down{
+ dir = 4
+ },
+/turf/open/floor/catwalk_floor/iron_smooth,
+/area/station/maintenance/port/greater)
"ljL" = (
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/hfr_room)
@@ -35453,6 +36465,7 @@
},
/obj/effect/landmark/navigate_destination,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/textured,
/area/station/commons/storage/primary)
"lka" = (
@@ -35624,6 +36637,13 @@
},
/turf/open/floor/iron/dark,
/area/station/cargo/office)
+"lmy" = (
+/obj/machinery/atmospherics/pipe/smart/simple/dark/visible{
+ dir = 5
+ },
+/obj/machinery/igniter/incinerator_atmos,
+/turf/open/floor/engine/vacuum,
+/area/station/maintenance/disposal/incinerator)
"lmA" = (
/obj/effect/turf_decal/trimline/dark_green/corner,
/obj/effect/decal/cleanable/dirt,
@@ -35668,6 +36688,10 @@
},
/turf/open/floor/carpet,
/area/station/command/meeting_room)
+"lnp" = (
+/obj/machinery/firealarm/directional/west,
+/turf/open/floor/iron/grimy,
+/area/station/hallway/secondary/entry)
"lnq" = (
/obj/effect/turf_decal/siding/white{
dir = 8
@@ -35710,8 +36734,19 @@
/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,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 4
+ },
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 8
+ },
+/turf/open/floor/iron/dark/textured,
/area/station/hallway/primary/central)
+"lnL" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
+/turf/open/floor/iron/large,
+/area/station/hallway/secondary/entry)
"lnY" = (
/obj/structure/table/glass,
/obj/structure/bedsheetbin,
@@ -35779,12 +36814,6 @@
},
/turf/open/floor/iron,
/area/station/engineering/atmos)
-"loW" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"lpj" = (
/obj/effect/turf_decal/stripes/line{
dir = 8
@@ -35804,6 +36833,19 @@
},
/turf/open/floor/iron,
/area/station/commons/vacant_room/commissary)
+"lpH" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 6
+ },
+/obj/effect/turf_decal/tile/blue{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/obj/item/kirbyplants/random,
+/turf/open/floor/iron/white/corner,
+/area/station/hallway/secondary/entry)
"lpL" = (
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
@@ -35851,13 +36893,6 @@
},
/turf/open/floor/plating,
/area/station/maintenance/starboard/lesser)
-"lqv" = (
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
- dir = 1
- },
-/obj/effect/turf_decal/tile/neutral/half/contrasted,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"lqz" = (
/obj/structure/cable,
/turf/closed/wall,
@@ -35898,20 +36933,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/medbay/aft)
-"lqH" = (
-/obj/machinery/computer/records/security,
-/obj/machinery/requests_console/directional/north{
- department = "Security";
- name = "Security Requests Console"
- },
-/obj/effect/mapping_helpers/requests_console/information,
-/obj/effect/mapping_helpers/requests_console/assistance,
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/red/half/contrasted{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/security/checkpoint/customs/auxiliary)
"lqP" = (
/obj/effect/decal/cleanable/insectguts,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
@@ -35948,6 +36969,11 @@
},
/turf/open/floor/iron/dark,
/area/station/service/chapel)
+"lrz" = (
+/obj/effect/spawner/random/structure/crate,
+/obj/effect/spawner/random/trash/janitor_supplies,
+/turf/open/floor/iron/smooth,
+/area/station/maintenance/port/lesser)
"lrD" = (
/obj/machinery/shower/directional/north,
/obj/item/soap/deluxe,
@@ -35970,6 +36996,15 @@
/obj/effect/spawner/structure/window,
/turf/open/floor/plating,
/area/station/science/robotics/lab)
+"lsi" = (
+/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/iron,
+/area/station/hallway/primary/port)
"lso" = (
/turf/open/floor/iron,
/area/station/hallway/primary/starboard)
@@ -36010,15 +37045,6 @@
/obj/effect/turf_decal/tile/blue,
/turf/open/floor/iron,
/area/station/hallway/primary/starboard)
-"lty" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/hallway/primary/port)
"ltE" = (
/obj/structure/closet/crate/freezer,
/obj/item/reagent_containers/blood/random,
@@ -36031,31 +37057,19 @@
/obj/effect/spawner/structure/window,
/turf/open/floor/plating,
/area/station/commons/fitness)
+"ltW" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/tile/blue/opposingcorners{
+ dir = 1
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/iron/cafeteria,
+/area/station/commons/dorms/laundry)
"lub" = (
/obj/effect/turf_decal/tile/yellow/opposingcorners,
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/project)
-"lui" = (
-/obj/effect/turf_decal/bot{
- dir = 1
- },
-/obj/structure/cable,
-/obj/structure/table,
-/obj/item/stack/sheet/iron/fifty,
-/obj/item/stack/sheet/glass/fifty,
-/obj/item/grenade/chem_grenade/smart_metal_foam,
-/obj/item/grenade/chem_grenade/smart_metal_foam,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/obj/item/clothing/shoes/magboots{
- pixel_x = -11;
- pixel_y = 1
- },
-/obj/item/clothing/shoes/magboots{
- pixel_x = -9;
- pixel_y = -4
- },
-/turf/open/floor/iron/dark,
-/area/station/engineering/engine_smes)
"lup" = (
/obj/effect/turf_decal/trimline/blue/filled/warning{
dir = 8
@@ -36134,14 +37148,6 @@
dir = 1
},
/area/station/hallway/secondary/service)
-"lvv" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/turf_decal/siding/wood{
- dir = 4
- },
-/turf/open/floor/wood,
-/area/station/commons/vacant_room/office)
"lvB" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -36189,6 +37195,19 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/mine/eva)
+"lvW" = (
+/obj/structure/table,
+/obj/effect/spawner/random/trash/food_packaging,
+/obj/effect/spawner/random/trash/food_packaging,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/item/radio/intercom/directional/north,
+/obj/item/radio/intercom/directional/north,
+/obj/item/newspaper,
+/obj/machinery/camera/directional/north{
+ c_tag = "Arrivals Lobby North"
+ },
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"lvY" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
@@ -36437,6 +37456,15 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/white,
/area/station/medical/treatment_center)
+"lzO" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/disposalpipe/junction/flip{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/hallway/primary/port)
"lzX" = (
/obj/machinery/light/floor,
/turf/open/floor/iron/white,
@@ -36450,13 +37478,6 @@
/obj/structure/cable,
/turf/open/floor/iron/dark/textured,
/area/station/medical/chemistry)
-"lAr" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/structure/cable,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"lAu" = (
/obj/effect/turf_decal/stripes/corner{
dir = 1
@@ -36836,6 +37857,10 @@
/obj/structure/bookcase/random/adult,
/turf/open/floor/iron/dark/textured,
/area/station/security/prison/safe)
+"lFg" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
+/turf/open/floor/iron/large,
+/area/station/hallway/secondary/entry)
"lFp" = (
/obj/structure/railing{
dir = 10
@@ -36849,16 +37874,16 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
-"lFr" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/disposalpipe/segment{
- dir = 4
+"lFA" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 8
},
-/obj/structure/sign/poster/contraband/random/directional/north,
+/obj/machinery/light/directional/south,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/tile/brown/half/contrasted,
/obj/structure/cable,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
+/turf/open/floor/iron/dark,
+/area/station/maintenance/disposal)
"lFL" = (
/obj/effect/turf_decal/trimline/red/warning,
/obj/effect/turf_decal/stripes/red/line,
@@ -36870,6 +37895,13 @@
dir = 8
},
/area/station/command/heads_quarters/rd)
+"lGd" = (
+/obj/structure/disposalpipe/segment{
+ dir = 10
+ },
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"lGh" = (
/obj/effect/turf_decal/trimline/yellow/filled/line{
dir = 1
@@ -36881,6 +37913,11 @@
/obj/machinery/light/directional/east,
/turf/open/floor/iron/white,
/area/station/medical/treatment_center)
+"lGo" = (
+/obj/machinery/hydroponics/soil,
+/obj/structure/sign/poster/contraband/kudzu/directional/east,
+/turf/open/floor/grass,
+/area/station/service/hydroponics/garden)
"lGp" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -36917,6 +37954,19 @@
},
/turf/open/floor/iron/dark/textured,
/area/station/security/interrogation)
+"lGL" = (
+/obj/machinery/camera/directional/west{
+ c_tag = "Arrivals Hallway South"
+ },
+/obj/machinery/newscaster/directional/west,
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/turf/open/floor/iron/white/corner{
+ dir = 1
+ },
+/area/station/hallway/secondary/entry)
"lGY" = (
/obj/structure/chair/stool/directional/south,
/obj/effect/landmark/start/hangover,
@@ -37028,13 +38078,32 @@
/obj/effect/turf_decal/tile/brown/half/contrasted,
/turf/open/floor/iron/dark/side,
/area/mine/eva/lower)
+"lIT" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/machinery/firealarm/directional/north,
+/obj/structure/cable,
+/turf/open/floor/iron/cafeteria{
+ dir = 8
+ },
+/area/station/hallway/secondary/entry)
+"lIU" = (
+/obj/machinery/light/small/directional/west,
+/obj/structure/table,
+/obj/structure/bedsheetbin,
+/obj/structure/sign/clock/directional/west,
+/obj/effect/turf_decal/siding/blue{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral/opposingcorners{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/commons/dorms/laundry)
"lIW" = (
/turf/open/floor/plating,
/area/station/ai_monitored/turret_protected/aisat_interior)
-"lJj" = (
-/obj/effect/spawner/structure/window/reinforced,
-/turf/open/floor/plating/icemoon,
-/area/station/hallway/secondary/entry)
"lJO" = (
/turf/closed/wall,
/area/station/maintenance/port/fore)
@@ -37045,6 +38114,15 @@
},
/turf/open/floor/iron/dark/textured,
/area/station/security/prison)
+"lKc" = (
+/obj/effect/turf_decal/stripes/corner{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/blue,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"lKk" = (
/obj/machinery/disposal/bin,
/obj/structure/disposalpipe/trunk{
@@ -37068,13 +38146,6 @@
/obj/structure/closet/radiation,
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/hfr_room)
-"lKF" = (
-/obj/machinery/bluespace_vendor/directional/north,
-/obj/effect/turf_decal/tile/neutral/half/contrasted{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"lKZ" = (
/obj/structure/railing/corner{
dir = 8
@@ -37114,6 +38185,14 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/recharge_floor,
/area/mine/mechbay)
+"lMg" = (
+/obj/structure/disposalpipe/segment,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/cable,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"lMh" = (
/obj/machinery/light/small/directional/south,
/turf/open/floor/engine/o2,
@@ -37164,6 +38243,12 @@
/obj/effect/spawner/random/trash/moisture_trap,
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
+"lNj" = (
+/obj/machinery/door/airlock/maintenance,
+/obj/effect/mapping_helpers/airlock/locked,
+/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"lNk" = (
/obj/structure/sign/painting/library{
pixel_y = -32
@@ -37192,6 +38277,12 @@
/obj/structure/cable/layer3,
/turf/open/floor/iron/dark,
/area/station/ai_monitored/turret_protected/ai)
+"lNE" = (
+/obj/machinery/atmospherics/pipe/layer_manifold/supply/hidden{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/aft/greater)
"lNG" = (
/obj/machinery/door/airlock/security/glass{
name = "Security Office"
@@ -37229,13 +38320,6 @@
},
/turf/open/floor/iron/dark,
/area/station/commons/storage/primary)
-"lOg" = (
-/obj/machinery/conveyor{
- dir = 4;
- id = "garbage"
- },
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"lOq" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -37449,6 +38533,12 @@
/obj/machinery/teleport/station,
/turf/open/floor/plating,
/area/station/command/teleporter)
+"lRg" = (
+/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/dark,
+/area/station/hallway/secondary/entry)
"lRs" = (
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
@@ -37565,6 +38655,19 @@
/obj/item/radio/intercom/directional/north,
/turf/open/floor/iron,
/area/station/engineering/atmos/storage/gas)
+"lSF" = (
+/obj/machinery/door/firedoor,
+/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,
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 8
+ },
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 4
+ },
+/turf/open/floor/iron/dark/textured,
+/area/station/hallway/secondary/entry)
"lSP" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -37724,6 +38827,17 @@
},
/turf/open/floor/wood,
/area/station/service/library)
+"lVY" = (
+/obj/effect/turf_decal/siding/thinplating_new/corner{
+ dir = 4
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/turf/open/floor/iron/white/side{
+ dir = 8
+ },
+/area/station/hallway/secondary/entry)
"lVZ" = (
/obj/structure/table/wood,
/obj/item/radio/intercom/command,
@@ -37779,29 +38893,12 @@
},
/turf/open/lava/plasma/ice_moon,
/area/icemoon/underground/explored)
-"lWU" = (
-/obj/machinery/light/directional/north,
-/obj/effect/turf_decal/tile/blue{
- dir = 4
- },
-/turf/open/floor/iron/white/corner{
- dir = 1
- },
-/area/station/hallway/secondary/entry)
"lXi" = (
/obj/structure/disposalpipe/segment{
dir = 4
},
/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
-"lXj" = (
-/obj/structure/table,
-/obj/item/rcl/pre_loaded,
-/obj/effect/turf_decal/tile/blue/opposingcorners{
- dir = 1
- },
-/turf/open/floor/iron/cafeteria,
-/area/station/commons/dorms/laundry)
"lXm" = (
/obj/item/trash/pistachios,
/turf/open/floor/plating,
@@ -37845,15 +38942,6 @@
dir = 8
},
/area/station/security/brig/entrance)
-"lYJ" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/neutral{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"lYR" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 8
@@ -37870,6 +38958,13 @@
/obj/structure/closet/chefcloset,
/turf/open/floor/plating,
/area/station/service/kitchen/coldroom)
+"lZe" = (
+/obj/effect/turf_decal/tile/blue/opposingcorners{
+ dir = 1
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/iron/cafeteria,
+/area/station/commons/dorms/laundry)
"lZi" = (
/obj/structure/railing,
/turf/open/floor/iron,
@@ -38018,7 +39113,7 @@
/obj/effect/turf_decal/trimline/blue/filled/warning{
dir = 1
},
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/white,
/area/station/medical/medbay/aft)
@@ -38099,14 +39194,13 @@
"mcW" = (
/turf/open/floor/iron/white,
/area/station/medical/medbay/central)
-"mcX" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/maintenance/port/fore)
-"mde" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/pink/hidden,
-/turf/closed/wall,
-/area/station/maintenance/port/fore)
+"mdl" = (
+/obj/effect/turf_decal/tile/red/half/contrasted{
+ dir = 1
+ },
+/obj/structure/closet/crate/mod,
+/turf/open/floor/iron/white,
+/area/station/science/robotics/lab)
"mdo" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -38165,6 +39259,10 @@
},
/turf/open/floor/iron,
/area/station/security/checkpoint/supply)
+"mdV" = (
+/obj/structure/sign/warning/electric_shock/directional/west,
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/underground/explored)
"mdZ" = (
/turf/closed/wall,
/area/station/hallway/secondary/service)
@@ -38219,10 +39317,6 @@
},
/turf/open/floor/iron/dark,
/area/station/medical/morgue)
-"meR" = (
-/obj/item/trash/cheesie,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"meT" = (
/obj/machinery/atmospherics/components/binary/pump{
dir = 8;
@@ -38285,6 +39379,18 @@
},
/turf/open/floor/engine,
/area/station/science/xenobiology)
+"mgc" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/structure/chair/sofa/bench/right,
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"mgj" = (
/obj/effect/turf_decal/tile/blue,
/turf/open/floor/iron,
@@ -38365,20 +39471,12 @@
/obj/effect/spawner/random/maintenance,
/turf/open/floor/iron,
/area/station/maintenance/starboard/upper)
-"mhr" = (
-/obj/effect/spawner/random/structure/grille,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"mhx" = (
/obj/effect/turf_decal/bot,
/obj/effect/landmark/secequipment,
/obj/effect/turf_decal/tile/red/half/contrasted,
/turf/open/floor/iron/dark/textured_half,
/area/station/security/office)
-"mhK" = (
-/obj/structure/sign/warning/docking,
-/turf/closed/wall,
-/area/station/maintenance/port/greater)
"mhQ" = (
/turf/closed/wall/r_wall,
/area/station/command/teleporter)
@@ -38427,13 +39525,6 @@
/obj/machinery/light/small/directional/east,
/turf/open/floor/engine/n2o,
/area/station/engineering/atmos)
-"mjj" = (
-/obj/structure/cable,
-/obj/machinery/camera/directional/east{
- c_tag = "Locker Room East"
- },
-/turf/open/floor/iron,
-/area/station/commons/locker)
"mjs" = (
/obj/machinery/disposal/bin,
/obj/structure/disposalpipe/trunk{
@@ -38572,6 +39663,16 @@
},
/turf/open/floor/iron/white,
/area/station/medical/storage)
+"mlS" = (
+/obj/effect/turf_decal/weather/snow/corner,
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 1
+ },
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 4
+ },
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"mmh" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
@@ -38598,14 +39699,12 @@
/obj/structure/sign/poster/official/random/directional/south,
/turf/open/floor/iron/smooth_large,
/area/station/cargo/warehouse)
-"mmo" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/turf_decal/stripes/corner,
-/obj/effect/turf_decal/stripes/corner{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
+"mmn" = (
+/obj/effect/turf_decal/stripes/line,
+/obj/machinery/atmospherics/components/binary/pump,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"mmA" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 1
@@ -38660,6 +39759,13 @@
},
/turf/open/floor/iron/textured_half,
/area/station/hallway/secondary/service)
+"mnu" = (
+/obj/effect/mapping_helpers/airlock/cyclelink_helper{
+ dir = 4
+ },
+/obj/machinery/door/airlock/external/glass,
+/turf/open/floor/plating,
+/area/station/hallway/secondary/entry)
"mny" = (
/obj/effect/turf_decal/tile/blue{
dir = 1
@@ -38688,13 +39794,6 @@
/obj/effect/landmark/start/hangover,
/turf/open/floor/iron/white,
/area/station/medical/medbay/lobby)
-"mnL" = (
-/obj/effect/landmark/start/hangover,
-/obj/effect/turf_decal/tile/neutral/anticorner/contrasted{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/commons/locker)
"moc" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -39098,6 +40197,15 @@
/obj/structure/window/reinforced/spawner/directional/east,
/turf/open/floor/iron,
/area/station/hallway/primary/starboard)
+"mua" = (
+/obj/structure/railing{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/brown/half/contrasted{
+ dir = 4
+ },
+/turf/open/floor/iron/dark,
+/area/station/maintenance/disposal)
"mue" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -39117,6 +40225,17 @@
},
/turf/open/floor/wood/parquet,
/area/station/commons/lounge)
+"mut" = (
+/obj/machinery/hydroponics/soil,
+/obj/machinery/light/directional/east,
+/obj/machinery/newscaster/directional/east,
+/turf/open/floor/grass,
+/area/station/service/hydroponics/garden)
+"muv" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/chair/stool/directional/west,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"muy" = (
/turf/open/openspace,
/area/station/commons/locker)
@@ -39197,6 +40316,13 @@
},
/turf/open/floor/plating/snowed/icemoon,
/area/station/ai_monitored/turret_protected/aisat_interior)
+"mwp" = (
+/obj/structure/disposalpipe/trunk/multiz{
+ dir = 4
+ },
+/obj/structure/sign/poster/contraband/random/directional/west,
+/turf/open/floor/catwalk_floor/iron_smooth,
+/area/station/maintenance/port/lesser)
"mwu" = (
/obj/structure/closet/firecloset,
/obj/effect/mapping_helpers/burnt_floor,
@@ -39221,6 +40347,10 @@
},
/turf/open/floor/iron,
/area/station/engineering/atmos)
+"mxu" = (
+/obj/machinery/digital_clock/directional/north,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"mxD" = (
/obj/machinery/holopad,
/obj/structure/cable,
@@ -39246,6 +40376,10 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central)
+"mxQ" = (
+/obj/machinery/computer/security/telescreen/entertainment/directional/east,
+/turf/open/floor/iron/grimy,
+/area/station/hallway/secondary/entry)
"mye" = (
/obj/machinery/door/airlock/maintenance,
/obj/structure/disposalpipe/segment,
@@ -39270,13 +40404,11 @@
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/door/firedoor,
/obj/structure/cable,
/obj/effect/mapping_helpers/airlock/access/all/security/general,
/turf/open/floor/iron/dark,
/area/station/security/checkpoint/engineering)
"myE" = (
-/obj/structure/disposalpipe/segment,
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
@@ -39436,6 +40568,11 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
/area/station/commons/fitness)
+"mAM" = (
+/obj/structure/ladder,
+/obj/machinery/light/small/red/directional/west,
+/turf/open/floor/iron/smooth,
+/area/station/maintenance/port/lesser)
"mAN" = (
/obj/machinery/requests_console/directional/west{
department = "Cargo Bay";
@@ -39459,6 +40596,18 @@
/obj/structure/extinguisher_cabinet/directional/south,
/turf/open/floor/iron/smooth,
/area/station/security/execution/transfer)
+"mBh" = (
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 4
+ },
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 8
+ },
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 1
+ },
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"mBB" = (
/obj/machinery/door/poddoor/preopen{
id = "ceprivacy";
@@ -39545,14 +40694,6 @@
/obj/structure/sign/warning/electric_shock,
/turf/closed/wall/r_wall,
/area/station/maintenance/aft/lesser)
-"mDn" = (
-/obj/effect/turf_decal/stripes/corner{
- dir = 1
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"mDo" = (
/obj/structure/bed/double,
/obj/item/bedsheet/black/double,
@@ -39611,6 +40752,16 @@
},
/turf/open/floor/iron/white,
/area/station/medical/pharmacy)
+"mEv" = (
+/obj/structure/rack,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/firealarm/directional/east,
+/obj/machinery/status_display/ai/directional/south,
+/obj/effect/turf_decal/siding/white{
+ dir = 1
+ },
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"mEw" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -39709,21 +40860,26 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/hallway/primary/aft)
+"mFY" = (
+/obj/machinery/light/small/directional/south,
+/obj/effect/landmark/start/assistant,
+/obj/structure/chair/stool/directional/north,
+/obj/effect/turf_decal/siding/blue{
+ dir = 8
+ },
+/obj/effect/turf_decal/tile/blue/opposingcorners{
+ dir = 1
+ },
+/obj/machinery/status_display/ai/directional/south,
+/obj/machinery/camera/directional/south{
+ c_tag = "Laundry Room"
+ },
+/turf/open/floor/iron/cafeteria,
+/area/station/commons/dorms/laundry)
"mGf" = (
/obj/effect/spawner/random/structure/crate,
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
-"mGl" = (
-/obj/machinery/door/airlock/maintenance,
-/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/mapping_helpers/airlock/access/all/engineering/maintenance,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"mGm" = (
/obj/structure/rack,
/obj/effect/spawner/random/techstorage/rnd_secure_all,
@@ -39905,6 +41061,13 @@
/obj/structure/sign/nanotrasen,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/underground/explored)
+"mKa" = (
+/obj/effect/turf_decal/tile/blue,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/iron/cafeteria{
+ dir = 8
+ },
+/area/station/hallway/secondary/entry)
"mKh" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -39928,6 +41091,13 @@
/obj/item/kirbyplants/random,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
+"mLm" = (
+/obj/structure/disposalpipe/segment,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/catwalk_floor/iron_smooth,
+/area/station/maintenance/port/lesser)
"mLo" = (
/obj/structure/rack,
/obj/item/crowbar,
@@ -39952,15 +41122,6 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/station/maintenance/starboard/upper)
-"mLK" = (
-/obj/machinery/atmospherics/components/binary/pump/on{
- dir = 1
- },
-/obj/machinery/atmospherics/pipe/layer_manifold/scrubbers/hidden{
- dir = 8
- },
-/turf/open/floor/engine,
-/area/station/science/ordnance/burnchamber)
"mLO" = (
/obj/machinery/camera/directional/west{
c_tag = "Xenobiology Pens - Port Aft";
@@ -40050,12 +41211,12 @@
},
/turf/open/floor/iron/showroomfloor,
/area/station/security/warden)
-"mNE" = (
-/obj/structure/disposalpipe/segment{
- dir = 10
+"mNy" = (
+/obj/effect/turf_decal/tile/green{
+ dir = 8
},
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
+/turf/open/floor/iron,
+/area/station/hallway/primary/port)
"mNF" = (
/obj/machinery/atmospherics/pipe/smart/simple/cyan/visible{
dir = 4
@@ -40323,6 +41484,10 @@
/obj/structure/sign/warning/secure_area,
/turf/closed/wall/ice,
/area/icemoon/surface/outdoors/nospawn)
+"mTc" = (
+/obj/effect/spawner/random/engineering/atmospherics_portable,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"mTh" = (
/obj/structure/reagent_dispensers/fueltank,
/obj/effect/turf_decal/tile/yellow/anticorner/contrasted,
@@ -40389,6 +41554,15 @@
/obj/effect/mapping_helpers/airlock/access/any/science/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
+"mUz" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/effect/decal/cleanable/insectguts,
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/structure/sign/warning/cold_temp/directional/east,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"mUM" = (
/obj/item/radio/intercom/directional/north,
/obj/effect/turf_decal/tile/red/anticorner{
@@ -40444,6 +41618,11 @@
/obj/effect/mapping_helpers/airlock/access/any/science/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
+"mVE" = (
+/obj/effect/spawner/structure/window/reinforced,
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/station/hallway/secondary/entry)
"mVI" = (
/obj/structure/table,
/obj/structure/bedsheetbin,
@@ -40535,6 +41714,13 @@
},
/turf/open/floor/iron,
/area/station/cargo/storage)
+"mWK" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 8
+ },
+/obj/structure/cable,
+/turf/open/floor/iron/dark/smooth_large,
+/area/station/security/checkpoint/customs/auxiliary)
"mWM" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -40544,6 +41730,12 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
/area/station/security/brig/upper)
+"mWN" = (
+/obj/structure/disposalpipe/trunk/multiz{
+ dir = 4
+ },
+/turf/open/floor/catwalk_floor/iron_smooth,
+/area/station/maintenance/port/lesser)
"mWU" = (
/obj/machinery/light/directional/west,
/obj/machinery/status_display/evac/directional/west,
@@ -40555,6 +41747,11 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central)
+"mWY" = (
+/obj/structure/chair/office,
+/obj/effect/turf_decal/tile/red/half/contrasted,
+/turf/open/floor/iron/dark,
+/area/station/security/checkpoint/customs/auxiliary)
"mXa" = (
/obj/structure/disposalpipe/segment,
/turf/open/floor/plating,
@@ -40596,15 +41793,6 @@
},
/turf/open/floor/iron,
/area/mine/laborcamp)
-"mXm" = (
-/obj/effect/turf_decal/stripes/corner{
- dir = 4
- },
-/obj/effect/turf_decal/stripes/corner{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"mXq" = (
/obj/structure/table,
/obj/machinery/recharger,
@@ -40621,12 +41809,26 @@
/obj/effect/turf_decal/tile/bar/opposingcorners,
/turf/open/floor/iron,
/area/station/service/bar)
+"mXA" = (
+/obj/effect/landmark/blobstart,
+/obj/effect/mapping_helpers/burnt_floor,
+/obj/effect/landmark/generic_maintenance_landmark,
+/obj/effect/spawner/random/trash/mess,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"mXD" = (
/obj/structure/rack,
/obj/item/mecha_parts/mecha_equipment/drill,
/obj/structure/sign/poster/official/random/directional/east,
/turf/open/floor/iron/smooth,
/area/mine/mechbay)
+"mXH" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
+/obj/effect/turf_decal/stripes/line{
+ dir = 4
+ },
+/turf/open/floor/iron/large,
+/area/station/hallway/secondary/entry)
"mXK" = (
/obj/structure/table,
/obj/structure/reagent_dispensers/servingdish,
@@ -40638,6 +41840,13 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
+"mXT" = (
+/obj/item/radio/intercom/directional/west,
+/obj/structure/chair{
+ pixel_y = -2
+ },
+/turf/open/floor/plating,
+/area/station/hallway/secondary/entry)
"mYd" = (
/obj/machinery/air_sensor/ordnance_burn_chamber,
/turf/open/floor/engine/vacuum,
@@ -40722,6 +41931,15 @@
},
/turf/open/floor/iron,
/area/mine/laborcamp)
+"mZm" = (
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 1
+ },
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 1
+ },
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"mZn" = (
/obj/structure/sign/poster/official/soft_cap_pop_art/directional/east,
/obj/effect/decal/cleanable/dirt,
@@ -40998,14 +42216,11 @@
},
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/project)
-"ncp" = (
-/obj/machinery/camera/directional/south{
- c_tag = "Arrivals Bay 3 & 4"
- },
-/obj/effect/turf_decal/stripes/line,
-/obj/effect/spawner/random/vending/snackvend,
+"nct" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/item/kirbyplants/random,
/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
+/area/station/commons/locker)
"ncB" = (
/obj/machinery/door/airlock/security/glass{
name = "Brig Walkway"
@@ -41046,16 +42261,13 @@
},
/turf/open/floor/iron,
/area/station/science/ordnance)
-"ndv" = (
-/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
+"ndl" = (
+/obj/effect/turf_decal/tile/brown/half/contrasted{
+ dir = 1
},
-/obj/effect/spawner/random/structure/steam_vent,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
+/obj/structure/cable,
+/turf/open/floor/iron/dark,
+/area/station/maintenance/disposal)
"ndz" = (
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
@@ -41155,6 +42367,12 @@
/obj/structure/sign/warning/cold_temp/directional/south,
/turf/open/floor/plating/snowed/coldroom,
/area/station/service/kitchen/coldroom)
+"neq" = (
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/blue/half/contrasted,
+/obj/effect/turf_decal/siding/thinplating,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"ner" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -41174,6 +42392,27 @@
},
/turf/open/floor/wood,
/area/station/security/courtroom)
+"neF" = (
+/obj/effect/turf_decal/bot{
+ dir = 1
+ },
+/obj/structure/cable,
+/obj/structure/table,
+/obj/item/stack/sheet/iron/fifty,
+/obj/item/stack/sheet/glass/fifty,
+/obj/item/grenade/chem_grenade/smart_metal_foam,
+/obj/item/grenade/chem_grenade/smart_metal_foam,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/item/clothing/shoes/magboots{
+ pixel_x = -11;
+ pixel_y = 1
+ },
+/obj/item/clothing/shoes/magboots{
+ pixel_x = -9;
+ pixel_y = -4
+ },
+/turf/open/floor/iron/dark,
+/area/station/engineering/engine_smes)
"neM" = (
/obj/machinery/hydroponics/soil,
/turf/open/misc/asteroid/snow/icemoon,
@@ -41202,6 +42441,12 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/hallway/primary/central)
+"nfn" = (
+/obj/structure/railing{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"nfr" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -41328,6 +42573,12 @@
/mob/living/carbon/human/species/monkey,
/turf/open/floor/engine,
/area/station/science/genetics)
+"nhS" = (
+/obj/structure/cable,
+/obj/machinery/power/apc/auto_name/directional/south,
+/obj/item/radio/intercom/directional/west,
+/turf/open/floor/iron,
+/area/station/service/hydroponics/garden)
"nhT" = (
/obj/machinery/door/airlock/external{
glass = 1;
@@ -41361,6 +42612,17 @@
/obj/item/radio/intercom/directional/east,
/turf/open/floor/iron/white,
/area/station/medical/virology)
+"nit" = (
+/obj/machinery/conveyor{
+ dir = 8;
+ id = "garbage"
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"niu" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -41400,6 +42662,10 @@
/obj/effect/spawner/structure/window/hollow/reinforced/middle,
/turf/open/floor/plating,
/area/mine/eva/lower)
+"niY" = (
+/obj/effect/spawner/random/trash/bin,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"niZ" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 4
@@ -41568,6 +42834,13 @@
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/plating,
/area/station/medical/chemistry)
+"nlO" = (
+/obj/effect/turf_decal/tile/blue/opposingcorners{
+ dir = 1
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/iron/cafeteria,
+/area/station/commons/dorms/laundry)
"nlP" = (
/obj/machinery/power/apc/auto_name/directional/east,
/obj/structure/cable,
@@ -41650,6 +42923,13 @@
/obj/machinery/light/small/directional/east,
/turf/open/floor/iron/smooth_large,
/area/station/cargo/warehouse)
+"nmx" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/cable,
+/obj/structure/disposalpipe/segment,
+/turf/open/floor/iron,
+/area/station/hallway/primary/port)
"nmz" = (
/obj/structure/lattice/catwalk,
/obj/structure/railing{
@@ -41657,6 +42937,23 @@
},
/turf/open/openspace,
/area/station/science/ordnance/office)
+"nmA" = (
+/obj/machinery/door/firedoor,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 8
+ },
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 4
+ },
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 4
+ },
+/obj/structure/cable,
+/turf/open/floor/iron/dark/textured,
+/area/station/hallway/secondary/entry)
"nmC" = (
/obj/machinery/iv_drip,
/obj/effect/turf_decal/tile/blue/half/contrasted{
@@ -41721,15 +43018,6 @@
/obj/machinery/vending/assist,
/turf/open/floor/plating,
/area/station/engineering/storage/tech)
-"nnK" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
- dir = 8
- },
-/obj/effect/turf_decal/tile/neutral/half/contrasted{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"nnR" = (
/obj/machinery/holopad,
/turf/open/floor/carpet,
@@ -41853,6 +43141,20 @@
},
/turf/open/floor/iron/white,
/area/station/medical/psychology)
+"npq" = (
+/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{
+ dir = 6
+ },
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
+"npr" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/light/small/dim/directional/north,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"npu" = (
/obj/structure/rack,
/obj/effect/turf_decal/delivery/red,
@@ -41871,6 +43173,14 @@
/obj/item/clothing/mask/breath,
/turf/open/floor/iron/dark/textured,
/area/station/ai_monitored/command/storage/eva)
+"npy" = (
+/obj/structure/chair/comfy/beige{
+ dir = 8
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/carpet/blue,
+/area/station/hallway/secondary/entry)
"npB" = (
/obj/machinery/atmospherics/components/unary/portables_connector/visible{
dir = 4
@@ -41937,11 +43247,6 @@
/obj/effect/turf_decal/stripes/box,
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
-"nqo" = (
-/obj/effect/spawner/random/vending/colavend,
-/obj/machinery/light/directional/north,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"nqv" = (
/obj/structure/fence{
dir = 4
@@ -41962,6 +43267,14 @@
/obj/machinery/door/firedoor/border_only,
/turf/open/floor/iron/white,
/area/station/science/ordnance)
+"nqD" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/tile/blue,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"nqL" = (
/obj/machinery/food_cart,
/obj/effect/turf_decal/tile/brown/diagonal_edge,
@@ -41994,12 +43307,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/mix)
-"nrf" = (
-/obj/machinery/atmospherics/pipe/layer_manifold/supply/hidden{
- dir = 4
- },
-/turf/open/floor/plating,
-/area/station/maintenance/aft/greater)
"nrm" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -42105,12 +43412,6 @@
/obj/structure/sign/poster/official/random/directional/north,
/turf/open/floor/wood,
/area/station/hallway/secondary/service)
-"nsi" = (
-/obj/machinery/door/airlock/external{
- name = "Construction Zone"
- },
-/turf/open/floor/plating,
-/area/station/construction/mining/aux_base)
"nsp" = (
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
@@ -42128,13 +43429,8 @@
/area/station/cargo/sorting)
"nsr" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/turf_decal/siding/wood{
- dir = 4
- },
-/obj/effect/turf_decal/siding/wood{
- dir = 8
- },
-/turf/open/floor/wood,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/iron/grimy,
/area/station/commons/vacant_room/office)
"nst" = (
/obj/item/trash/sosjerky,
@@ -42211,6 +43507,16 @@
},
/turf/open/floor/iron,
/area/station/security/processing)
+"ntx" = (
+/obj/structure/sign/nanotrasen{
+ pixel_x = 32
+ },
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 10
+ },
+/obj/structure/marker_beacon/burgundy,
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"ntK" = (
/obj/structure/flora/rock/icy/style_random,
/turf/open/misc/asteroid/snow/icemoon,
@@ -42224,6 +43530,11 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/iron/cafeteria,
/area/station/security/prison/mess)
+"nud" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/pink,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"nuj" = (
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
@@ -42244,6 +43555,23 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/security/prison/visit)
+"nuM" = (
+/obj/machinery/door/firedoor,
+/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,
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 8
+ },
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 4
+ },
+/obj/machinery/door/airlock/multi_tile/public/glass{
+ name = "Arrivals Dock";
+ dir = 4
+ },
+/turf/open/floor/iron/dark/textured,
+/area/station/hallway/secondary/entry)
"nuN" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -42290,6 +43618,21 @@
},
/turf/open/floor/iron/cafeteria,
/area/station/security/prison/work)
+"nvI" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/iron/white/corner,
+/area/station/hallway/secondary/entry)
+"nvU" = (
+/obj/effect/mapping_helpers/airlock/access/all/command/eva,
+/obj/machinery/door/airlock/external{
+ name = "Port Docking Bay 1"
+ },
+/turf/open/floor/iron/textured,
+/area/station/hallway/secondary/entry)
"nvW" = (
/obj/machinery/duct,
/turf/open/floor/iron,
@@ -42313,6 +43656,15 @@
},
/turf/open/floor/iron/white,
/area/station/science/genetics)
+"nwr" = (
+/obj/effect/turf_decal/tile/red/half/contrasted{
+ dir = 8
+ },
+/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/dark,
+/area/station/security/checkpoint/customs/auxiliary)
"nwF" = (
/obj/structure/chair/sofa/bench{
dir = 4
@@ -42335,6 +43687,11 @@
dir = 9
},
/area/station/science/research)
+"nxe" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/pink,
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"nxm" = (
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
@@ -42362,15 +43719,6 @@
/obj/structure/reagent_dispensers/fueltank,
/turf/open/floor/iron/white,
/area/station/science/robotics/lab)
-"nxV" = (
-/obj/effect/spawner/random/engineering/tracking_beacon,
-/obj/effect/turf_decal/siding/green{
- dir = 1
- },
-/obj/effect/landmark/event_spawn,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron,
-/area/station/service/hydroponics/garden)
"nxW" = (
/obj/effect/turf_decal/plaque{
icon_state = "L2"
@@ -42482,6 +43830,11 @@
/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/medical/chemistry)
+"nza" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/iron,
+/area/station/service/hydroponics/garden)
"nzj" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -42575,6 +43928,13 @@
/obj/item/wrench,
/turf/open/floor/iron/white,
/area/station/science/xenobiology)
+"nAg" = (
+/obj/structure/disposalpipe/segment{
+ dir = 6
+ },
+/obj/structure/lattice/catwalk,
+/turf/open/openspace/icemoon/keep_below,
+/area/station/maintenance/port/lesser)
"nAr" = (
/obj/structure/disposalpipe/segment,
/turf/open/floor/plating,
@@ -42591,6 +43951,9 @@
},
/turf/open/floor/iron,
/area/station/security/prison/workout)
+"nAH" = (
+/turf/open/openspace/icemoon/keep_below,
+/area/station/hallway/secondary/entry)
"nAM" = (
/obj/structure/railing/corner{
dir = 8
@@ -42613,6 +43976,18 @@
},
/turf/open/floor/iron/white,
/area/station/medical/break_room)
+"nAX" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/obj/machinery/camera/directional/south{
+ c_tag = "Arrivals Dock South"
+ },
+/obj/item/radio/intercom/directional/south,
+/turf/open/floor/iron/white/corner,
+/area/station/hallway/secondary/entry)
"nBe" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 4
@@ -42661,6 +44036,9 @@
/area/station/maintenance/solars/starboard/aft)
"nBE" = (
/obj/machinery/light/small/directional/east,
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 10
+ },
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
"nBG" = (
@@ -42675,6 +44053,13 @@
/obj/effect/turf_decal/delivery,
/turf/open/floor/iron/dark,
/area/station/maintenance/starboard/aft)
+"nBQ" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/components/tank/air{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/aft/greater)
"nBV" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on,
/turf/open/floor/engine/vacuum,
@@ -42789,12 +44174,6 @@
/obj/structure/closet/radiation,
/turf/open/floor/iron/dark,
/area/station/maintenance/disposal/incinerator)
-"nDk" = (
-/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/goonplaque,
-/area/station/hallway/secondary/entry)
"nDl" = (
/obj/structure/railing/corner,
/obj/machinery/door/firedoor/border_only,
@@ -42813,13 +44192,6 @@
"nDq" = (
/turf/open/floor/iron,
/area/station/maintenance/disposal/incinerator)
-"nDv" = (
-/obj/structure/table,
-/obj/item/folder,
-/obj/item/pen,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"nDw" = (
/obj/structure/railing/corner{
dir = 8
@@ -42866,6 +44238,17 @@
"nDE" = (
/turf/closed/wall/r_wall,
/area/station/security/prison/garden)
+"nDJ" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/structure/cable,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"nDV" = (
/obj/machinery/shower/directional/south,
/obj/effect/spawner/random/contraband/permabrig_weapon,
@@ -42902,11 +44285,24 @@
/obj/effect/mapping_helpers/mail_sorting/supply/cargo_bay,
/turf/open/floor/iron,
/area/station/cargo/office)
+"nEq" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/spawner/random/trash/garbage,
+/obj/effect/spawner/random/trash/caution_sign,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"nEs" = (
/obj/item/kirbyplants/random,
/obj/machinery/light/small/directional/west,
/turf/open/floor/iron/dark/textured,
/area/station/security/processing)
+"nEA" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"nEV" = (
/obj/machinery/vending/wardrobe/sec_wardrobe,
/obj/structure/cable,
@@ -42977,6 +44373,11 @@
},
/turf/open/floor/iron/dark,
/area/station/commons/storage/primary)
+"nFL" = (
+/obj/machinery/door/airlock/external/glass,
+/obj/effect/mapping_helpers/airlock/access/all/engineering/external,
+/turf/open/floor/plating,
+/area/station/hallway/secondary/entry)
"nFN" = (
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/plating,
@@ -43233,14 +44634,6 @@
"nKa" = (
/turf/closed/wall,
/area/station/security/checkpoint/medical)
-"nKe" = (
-/obj/structure/table,
-/obj/item/hand_tele{
- pixel_x = 3;
- pixel_y = 13
- },
-/turf/open/floor/iron,
-/area/station/command/teleporter)
"nKj" = (
/obj/structure/window/reinforced/spawner/directional/south,
/obj/machinery/rnd/production/circuit_imprinter,
@@ -43252,6 +44645,12 @@
/obj/effect/mapping_helpers/requests_console/assistance,
/turf/open/floor/iron/dark,
/area/station/engineering/lobby)
+"nKk" = (
+/obj/effect/turf_decal/siding/thinplating_new{
+ dir = 8
+ },
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
"nKl" = (
/obj/structure/railing{
dir = 6
@@ -43377,6 +44776,10 @@
},
/turf/closed/wall/r_wall,
/area/station/medical/virology)
+"nMj" = (
+/obj/structure/sign/warning/docking/directional/north,
+/turf/open/floor/plating/snowed/smoothed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"nMu" = (
/obj/effect/turf_decal/trimline/blue/filled/warning{
dir = 1
@@ -43484,10 +44887,6 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/catwalk_floor/iron_smooth,
/area/station/maintenance/starboard/fore)
-"nNw" = (
-/obj/effect/turf_decal/tile/neutral/half/contrasted,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"nNy" = (
/obj/structure/sign/warning/xeno_mining{
pixel_x = 29
@@ -43512,12 +44911,6 @@
/obj/effect/turf_decal/tile/bar/opposingcorners,
/turf/open/floor/iron,
/area/station/service/bar/backroom)
-"nNY" = (
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/cable,
-/turf/open/floor/iron,
-/area/station/construction/mining/aux_base)
"nOb" = (
/obj/machinery/door/airlock/external{
name = "Labor Camp Shuttle Airlock"
@@ -43546,6 +44939,10 @@
/obj/item/pillow/random,
/turf/open/floor/carpet,
/area/station/commons/dorms)
+"nOx" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/iron,
+/area/station/maintenance/port/fore)
"nOG" = (
/obj/effect/turf_decal/stripes/line{
dir = 8
@@ -43622,12 +45019,6 @@
},
/turf/open/floor/iron/white/corner,
/area/station/commons/storage/art)
-"nQI" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
- dir = 1
- },
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"nQO" = (
/obj/machinery/navbeacon{
codes_txt = "patrol;next_patrol=AIW";
@@ -43699,6 +45090,24 @@
},
/turf/open/floor/iron,
/area/station/cargo/office)
+"nRv" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/catwalk_floor/iron_smooth,
+/area/station/maintenance/port/lesser)
+"nRx" = (
+/obj/machinery/washing_machine,
+/obj/effect/turf_decal/siding/blue{
+ dir = 8
+ },
+/obj/effect/turf_decal/tile/neutral/opposingcorners{
+ dir = 1
+ },
+/obj/structure/sign/poster/official/nanotrasen_logo/directional/east,
+/turf/open/floor/iron,
+/area/station/commons/dorms/laundry)
"nRO" = (
/obj/structure/cable/multilayer/multiz,
/obj/structure/sign/poster/contraband/random/directional/north,
@@ -43731,6 +45140,12 @@
/obj/structure/flora/bush/snow/style_random,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors/nospawn)
+"nSr" = (
+/obj/effect/spawner/random/entertainment/arcade{
+ dir = 1
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"nSw" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/pipe/layer_manifold/brown/visible,
@@ -43778,13 +45193,6 @@
/obj/machinery/atmospherics/pipe/smart/simple/orange/visible,
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
-"nSX" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 1
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"nTp" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -43856,6 +45264,10 @@
},
/turf/open/floor/iron/dark/side,
/area/station/security/processing)
+"nUh" = (
+/obj/effect/mapping_helpers/burnt_floor,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"nUi" = (
/obj/effect/spawner/structure/window/hollow/reinforced/middle,
/turf/open/floor/plating,
@@ -43870,12 +45282,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/dark/smooth_half,
/area/station/ai_monitored/command/storage/eva)
-"nUw" = (
-/obj/machinery/conveyor{
- id = "garbage"
- },
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"nUJ" = (
/obj/machinery/flasher/directional/east{
id = "brigentry"
@@ -43966,6 +45372,15 @@
/obj/item/plate,
/turf/open/floor/iron/checker,
/area/station/maintenance/port/fore)
+"nWn" = (
+/obj/structure/tank_holder/extinguisher,
+/obj/effect/mapping_helpers/burnt_floor,
+/obj/effect/spawner/random/trash/graffiti{
+ pixel_y = -32;
+ spawn_loot_chance = 50
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"nWw" = (
/obj/structure/chair/wood{
dir = 4
@@ -43981,14 +45396,6 @@
/obj/machinery/holopad,
/turf/open/floor/iron/white,
/area/station/science/xenobiology)
-"nWP" = (
-/obj/effect/turf_decal/stripes/corner{
- dir = 8
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"nXb" = (
/turf/closed/wall,
/area/icemoon/surface/outdoors/nospawn)
@@ -44035,12 +45442,6 @@
/obj/structure/disposalpipe/trunk,
/turf/open/floor/plating,
/area/station/commons/vacant_room/commissary)
-"nXR" = (
-/obj/effect/turf_decal/stripes/corner{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"nXV" = (
/obj/machinery/door/airlock/security{
name = "Permabrig Visitation"
@@ -44177,13 +45578,6 @@
/obj/effect/spawner/random/structure/steam_vent,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/central)
-"obd" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 1
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"obj" = (
/obj/structure/disposalpipe/segment,
/obj/structure/cable,
@@ -44366,15 +45760,15 @@
/obj/effect/mapping_helpers/airlock/access/all/security/general,
/turf/open/floor/plating,
/area/station/hallway/secondary/exit/departure_lounge)
-"oel" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/hallway/primary/port)
"oex" = (
/turf/open/openspace/icemoon/keep_below,
/area/station/maintenance/department/medical/morgue)
+"oeB" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 1
+ },
+/turf/open/floor/plastic,
+/area/station/commons/dorms/laundry)
"oeM" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/dark,
@@ -44454,16 +45848,6 @@
},
/turf/open/floor/plating,
/area/station/maintenance/department/medical/morgue)
-"ofS" = (
-/obj/machinery/atmospherics/pipe/multiz/scrubbers/visible/layer2{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/multiz/supply/visible/layer4{
- dir = 4
- },
-/obj/structure/cable,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"ofT" = (
/obj/structure/closet/secure_closet/hydroponics,
/obj/effect/turf_decal/siding/thinplating/dark,
@@ -44512,14 +45896,6 @@
dir = 9
},
/area/station/security/prison)
-"ogM" = (
-/obj/effect/turf_decal/stripes/corner{
- dir = 1
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"oha" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/cable,
@@ -44532,15 +45908,6 @@
"ohp" = (
/turf/open/floor/glass,
/area/station/maintenance/department/medical/central)
-"ohs" = (
-/obj/effect/turf_decal/stripes/corner{
- dir = 8
- },
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"oht" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -44552,14 +45919,11 @@
/obj/effect/turf_decal/caution{
dir = 8
},
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 8
+ },
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
-"ohG" = (
-/obj/effect/landmark/start/prisoner,
-/obj/effect/landmark/event_spawn,
-/obj/machinery/holopad,
-/turf/open/floor/carpet/red,
-/area/station/security/prison/work)
"ohS" = (
/obj/structure/railing{
dir = 8
@@ -44573,10 +45937,6 @@
},
/turf/open/openspace,
/area/station/security/prison)
-"ohV" = (
-/obj/structure/chair/office,
-/turf/open/floor/iron/grimy,
-/area/station/commons/vacant_room/office)
"oic" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -44621,7 +45981,7 @@
"oiv" = (
/obj/effect/turf_decal/tile/neutral/fourcorners,
/obj/structure/table/reinforced,
-/obj/item/storage/backpack/duffelbag/coroner/surgery,
+/obj/item/surgery_tray/full/morgue,
/turf/open/floor/iron/dark,
/area/station/medical/morgue)
"oiy" = (
@@ -44641,6 +46001,21 @@
/obj/effect/mapping_helpers/airlock/access/all/medical/chemistry,
/turf/open/floor/iron/smooth,
/area/station/maintenance/department/medical/central)
+"oiD" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/structure/cable,
+/obj/machinery/camera/directional/north{
+ c_tag = "Arrivals Dock North"
+ },
+/obj/item/radio/intercom/directional/north,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"oiH" = (
/obj/structure/cable,
/turf/open/floor/plating,
@@ -44917,6 +46292,13 @@
},
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
+"omH" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/siding/thinplating_new{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/commons/locker)
"omJ" = (
/obj/machinery/door/airlock{
name = "Perma Overlook Closet"
@@ -44956,15 +46338,6 @@
dir = 9
},
/area/station/science/research)
-"onj" = (
-/obj/structure/cable,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"ons" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -44985,6 +46358,15 @@
},
/turf/open/floor/plating,
/area/station/security/courtroom)
+"onQ" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/turf_decal/siding/wood,
+/turf/open/floor/wood,
+/area/station/commons/vacant_room/office)
+"ooa" = (
+/obj/effect/turf_decal/siding/wood,
+/turf/open/floor/wood,
+/area/station/commons/vacant_room/office)
"ooe" = (
/obj/structure/table,
/obj/item/paper_bin{
@@ -45015,6 +46397,21 @@
/obj/effect/mapping_helpers/airlock/access/all/engineering/external,
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
+"oor" = (
+/obj/machinery/door/firedoor,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 8
+ },
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 4
+ },
+/obj/machinery/door/airlock/multi_tile/public/glass{
+ name = "Arrivals Dock";
+ dir = 4
+ },
+/turf/open/floor/iron/dark/textured,
+/area/station/hallway/secondary/entry)
"oot" = (
/obj/effect/turf_decal/weather/snow/corner{
dir = 4
@@ -45030,14 +46427,6 @@
},
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
-"ooO" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/structure/cable,
-/obj/effect/landmark/blobstart,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"ooR" = (
/obj/structure/table,
/obj/machinery/cell_charger,
@@ -45136,6 +46525,14 @@
},
/turf/open/floor/iron,
/area/station/science/ordnance/testlab)
+"opS" = (
+/obj/machinery/vending/wardrobe/sec_wardrobe,
+/obj/effect/turf_decal/tile/red/half/contrasted{
+ dir = 1
+ },
+/obj/item/radio/intercom/directional/north,
+/turf/open/floor/iron/dark,
+/area/station/security/checkpoint/customs/auxiliary)
"oqb" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/obj/machinery/power/apc/auto_name/directional/west,
@@ -45172,6 +46569,15 @@
},
/turf/open/floor/wood,
/area/station/commons/dorms)
+"oqj" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/siding/thinplating/corner{
+ dir = 1
+ },
+/obj/machinery/airalarm/directional/north,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plastic,
+/area/station/commons/dorms/laundry)
"oqy" = (
/obj/machinery/airalarm/directional/south,
/obj/effect/turf_decal/delivery,
@@ -45194,6 +46600,11 @@
/obj/effect/landmark/start/station_engineer,
/turf/open/floor/iron,
/area/station/engineering/main)
+"oqJ" = (
+/obj/structure/sign/warning/docking/directional/north,
+/obj/structure/flora/grass/green/style_random,
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"oqL" = (
/obj/structure/cable,
/obj/effect/spawner/structure/window/hollow/reinforced/middle,
@@ -45307,15 +46718,6 @@
dir = 4
},
/area/mine/living_quarters)
-"orT" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 8
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/light/directional/west,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"orU" = (
/obj/machinery/vending/coffee,
/obj/structure/sign/poster/random/directional/east,
@@ -45377,11 +46779,6 @@
/obj/machinery/duct,
/turf/open/floor/iron/white,
/area/station/medical/virology)
-"osD" = (
-/obj/structure/chair/stool/directional/south,
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/dark,
-/area/station/maintenance/disposal)
"osI" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/pipe/smart/manifold4w/purple/visible,
@@ -45432,6 +46829,13 @@
/obj/structure/railing,
/turf/open/genturf,
/area/icemoon/surface/outdoors/unexplored/rivers/no_monsters)
+"otG" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/turf/open/floor/iron/white/corner,
+/area/station/hallway/secondary/entry)
"otK" = (
/obj/machinery/light_switch/directional/west,
/obj/structure/disposalpipe/segment,
@@ -45506,6 +46910,16 @@
},
/turf/open/floor/iron/white,
/area/station/science/genetics)
+"ovm" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"ovt" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -45539,6 +46953,12 @@
/obj/machinery/newscaster/directional/east,
/turf/open/floor/iron,
/area/station/security/prison/workout)
+"owk" = (
+/obj/effect/turf_decal/tile/red/anticorner/contrasted{
+ dir = 8
+ },
+/turf/open/floor/iron/dark,
+/area/station/security/checkpoint/customs/auxiliary)
"owr" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 8
@@ -45583,18 +47003,6 @@
},
/turf/open/misc/asteroid/snow/icemoon,
/area/station/ai_monitored/turret_protected/aisat/maint)
-"oxu" = (
-/obj/effect/turf_decal/weather/snow/corner{
- dir = 4
- },
-/obj/effect/turf_decal/weather/snow/corner{
- dir = 8
- },
-/obj/effect/turf_decal/weather/snow/corner{
- dir = 1
- },
-/turf/open/floor/plating/snowed/icemoon,
-/area/icemoon/surface/outdoors/nospawn)
"oxB" = (
/obj/machinery/door/airlock/maintenance,
/obj/effect/mapping_helpers/airlock/abandoned,
@@ -45791,7 +47199,7 @@
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 6
},
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/turf/open/floor/iron/white,
/area/station/medical/medbay/aft)
"ozV" = (
@@ -45825,12 +47233,6 @@
"oAh" = (
/turf/open/floor/glass/reinforced,
/area/station/security/brig/entrance)
-"oAk" = (
-/obj/effect/turf_decal/stripes/corner{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"oAl" = (
/obj/machinery/door/airlock/atmos/glass{
name = "Atmospherics"
@@ -45930,6 +47332,9 @@
pixel_y = 9
},
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
+/obj/item/radio/intercom/directional/east{
+ pixel_y = -6
+ },
/turf/open/floor/iron/smooth,
/area/station/security/execution/transfer)
"oBp" = (
@@ -45979,14 +47384,6 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/maintenance/solars/starboard/fore)
-"oCj" = (
-/obj/structure/table/wood,
-/obj/item/camera_film{
- pixel_x = -4;
- pixel_y = 4
- },
-/turf/open/floor/iron/grimy,
-/area/station/commons/vacant_room/office)
"oCs" = (
/obj/structure/table,
/obj/item/toy/figure/virologist{
@@ -46043,13 +47440,6 @@
"oCO" = (
/turf/closed/wall,
/area/station/service/hydroponics/garden)
-"oCR" = (
-/obj/effect/turf_decal/siding/wood{
- dir = 8
- },
-/obj/machinery/airalarm/directional/north,
-/turf/open/floor/wood,
-/area/station/commons/vacant_room/office)
"oCT" = (
/obj/item/instrument/harmonica,
/obj/structure/flora/bush/fullgrass/style_random,
@@ -46155,6 +47545,16 @@
/obj/structure/cable,
/turf/open/floor/iron/dark,
/area/station/medical/chemistry)
+"oDV" = (
+/obj/structure/closet,
+/obj/item/radio/intercom/directional/east,
+/obj/effect/landmark/start/hangover/closet,
+/obj/effect/landmark/start/hangover/closet,
+/obj/effect/turf_decal/tile/blue/opposingcorners{
+ dir = 1
+ },
+/turf/open/floor/iron/cafeteria,
+/area/station/commons/dorms/laundry)
"oEh" = (
/obj/effect/turf_decal/tile/neutral/diagonal_edge,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
@@ -46348,20 +47748,6 @@
},
/turf/open/floor/carpet,
/area/station/command/heads_quarters/captain)
-"oGR" = (
-/obj/item/radio/intercom/directional/north,
-/obj/structure/reagent_dispensers/plumbed,
-/obj/effect/turf_decal/stripes/line{
- dir = 4
- },
-/turf/open/floor/plating,
-/area/station/hallway/secondary/service)
-"oGX" = (
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/commons/locker)
"oHh" = (
/obj/machinery/shower/directional/north,
/obj/structure/window/reinforced/spawner/directional/west,
@@ -46371,6 +47757,12 @@
/obj/item/soap/nanotrasen,
/turf/open/floor/iron/freezer,
/area/station/maintenance/starboard/fore)
+"oHo" = (
+/obj/machinery/atmospherics/components/binary/pump/on/supply/hidden/layer4{
+ dir = 1
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/aft)
"oHp" = (
/obj/machinery/camera/directional/west{
c_tag = "Engineering Escape Pod"
@@ -46384,19 +47776,28 @@
"oHK" = (
/turf/closed/wall/r_wall,
/area/station/science/lab)
-"oHU" = (
-/obj/structure/closet/toolcloset,
-/obj/effect/turf_decal/tile/yellow/half/contrasted{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/construction/mining/aux_base)
"oHV" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/holopad,
/turf/open/floor/iron/dark,
/area/station/service/chapel)
+"oHY" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/obj/machinery/status_display/shuttle{
+ pixel_x = -32;
+ shuttle_id = "arrival"
+ },
+/obj/machinery/light/directional/west,
+/obj/effect/turf_decal/stripes/corner{
+ dir = 1
+ },
+/turf/open/floor/iron/white/corner{
+ dir = 1
+ },
+/area/station/hallway/secondary/entry)
"oIB" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -46443,6 +47844,13 @@
/obj/structure/flora/bush/snow/style_random,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors/nospawn)
+"oJH" = (
+/obj/structure/marker_beacon/burgundy,
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 5
+ },
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"oJP" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/turf_decal/tile/dark_green,
@@ -46467,6 +47875,14 @@
},
/turf/open/floor/plating,
/area/station/service/kitchen)
+"oKu" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/sign/warning/docking/directional/south,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"oKv" = (
/obj/item/trash/popcorn,
/turf/open/floor/plating,
@@ -46486,6 +47902,15 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central/fore)
+"oKL" = (
+/obj/machinery/door/airlock/public/glass/incinerator/atmos_exterior,
+/obj/effect/mapping_helpers/airlock/cyclelink_helper{
+ dir = 1
+ },
+/obj/effect/mapping_helpers/airlock/locked,
+/obj/effect/mapping_helpers/airlock/access/all/engineering/atmos,
+/turf/open/floor/engine/vacuum,
+/area/station/maintenance/disposal/incinerator)
"oKY" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/turf/open/floor/plating,
@@ -46517,6 +47942,14 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/plating,
/area/station/maintenance/aft/greater)
+"oLo" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/turf_decal/siding/wood{
+ dir = 1
+ },
+/obj/effect/spawner/random/structure/closet_private,
+/turf/open/floor/iron/grimy,
+/area/station/commons/vacant_room/office)
"oLs" = (
/obj/effect/turf_decal/stripes/asteroid/line{
dir = 5
@@ -46543,16 +47976,21 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/hallway/secondary/exit/departure_lounge)
+"oLC" = (
+/obj/structure/disposalpipe/segment{
+ dir = 9
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"oLG" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/cable,
/turf/open/floor/iron/dark,
/area/station/service/chapel)
-"oLI" = (
-/obj/structure/table/wood,
-/turf/open/floor/iron/grimy,
-/area/station/hallway/secondary/entry)
"oLJ" = (
/obj/machinery/door/airlock/hatch{
name = "MiniSat Foyer"
@@ -46587,6 +48025,13 @@
dir = 8
},
/area/station/security/brig/entrance)
+"oMa" = (
+/obj/structure/marker_beacon/burgundy,
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 10
+ },
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"oMd" = (
/obj/effect/mapping_helpers/airlock/cyclelink_helper{
dir = 4
@@ -46603,6 +48048,14 @@
},
/turf/open/floor/iron,
/area/station/cargo/storage)
+"oMq" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/turf/open/floor/iron/white/corner{
+ dir = 1
+ },
+/area/station/hallway/secondary/entry)
"oMs" = (
/obj/effect/spawner/random/trash/mess,
/turf/open/floor/iron/grimy,
@@ -46688,13 +48141,6 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/wood,
/area/station/maintenance/aft/lesser)
-"oNU" = (
-/obj/machinery/camera/directional/north{
- c_tag = "Solar Maintenance - North West Access"
- },
-/obj/machinery/light/small/dim/directional/north,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"oNX" = (
/obj/machinery/airalarm/directional/west,
/turf/open/floor/iron/dark,
@@ -46712,10 +48158,6 @@
/obj/machinery/status_display/evac/directional/west,
/turf/open/floor/iron/white,
/area/station/science/research)
-"oOq" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/plating,
-/area/station/maintenance/starboard/aft)
"oOx" = (
/obj/machinery/door/airlock/public/glass/incinerator/atmos_interior,
/obj/effect/mapping_helpers/airlock/cyclelink_helper,
@@ -46737,6 +48179,15 @@
/obj/structure/sign/warning/secure_area/directional/south,
/turf/open/floor/plating,
/area/station/ai_monitored/turret_protected/aisat_interior)
+"oOP" = (
+/obj/effect/turf_decal/siding/thinplating_new/corner,
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/turf/open/floor/iron/white/side{
+ dir = 8
+ },
+/area/station/hallway/secondary/entry)
"oOQ" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
@@ -46773,14 +48224,6 @@
dir = 9
},
/area/station/science/lab)
-"oPt" = (
-/obj/structure/table,
-/obj/item/papercutter{
- pixel_x = 8;
- pixel_y = 6
- },
-/turf/open/floor/iron,
-/area/station/command/heads_quarters/hop)
"oPv" = (
/obj/machinery/turretid{
control_area = "/area/station/ai_monitored/turret_protected/aisat/service";
@@ -46834,10 +48277,11 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron,
/area/station/hallway/primary/aft)
-"oQv" = (
-/obj/effect/spawner/structure/window/reinforced,
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
+"oQt" = (
+/obj/structure/disposalpipe/segment,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating/icemoon,
+/area/station/maintenance/port/lesser)
"oQx" = (
/turf/open/floor/iron/smooth_half,
/area/station/command/heads_quarters/rd)
@@ -46910,6 +48354,17 @@
},
/turf/open/floor/iron,
/area/station/cargo/office)
+"oRE" = (
+/obj/machinery/conveyor{
+ dir = 10;
+ id = "garbage"
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/stripes/corner{
+ dir = 1
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"oRM" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -47009,6 +48464,16 @@
/obj/structure/flora/grass/green/style_random,
/turf/open/misc/asteroid/snow/standard_air,
/area/station/hallway/secondary/exit/departure_lounge)
+"oTc" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/item/radio/intercom/directional/east,
+/obj/machinery/light/directional/east,
+/turf/open/floor/iron/white/corner,
+/area/station/hallway/secondary/entry)
"oTd" = (
/obj/machinery/camera/directional/south{
c_tag = "Research Division Testing Lab - Chamber";
@@ -47083,15 +48548,6 @@
},
/turf/open/floor/iron/dark,
/area/station/ai_monitored/turret_protected/aisat_interior)
-"oUr" = (
-/obj/structure/extinguisher_cabinet/directional/east,
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/turf_decal/tile/blue{
- dir = 4
- },
-/turf/open/floor/iron/white/corner,
-/area/station/hallway/secondary/entry)
"oUG" = (
/obj/machinery/door/airlock{
id_tag = "Toilet2";
@@ -47166,11 +48622,31 @@
},
/turf/open/floor/circuit,
/area/station/ai_monitored/turret_protected/ai)
+"oVG" = (
+/obj/machinery/door/airlock/public/glass{
+ name = "Art Storage"
+ },
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/door/firedoor,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/iron/textured,
+/area/station/commons/storage/art)
"oVR" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/command/bridge)
+"oVX" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/obj/machinery/newscaster/directional/south,
+/obj/machinery/light/directional/south,
+/turf/open/floor/iron/white/corner,
+/area/station/hallway/secondary/entry)
"oVY" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -47194,6 +48670,18 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible,
/turf/closed/wall/r_wall,
/area/station/engineering/atmos/storage/gas)
+"oWu" = (
+/obj/structure/closet/wardrobe/grey,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/structure/sign/calendar/directional/west,
+/turf/open/floor/iron,
+/area/station/commons/locker)
+"oWN" = (
+/obj/machinery/requests_console/auto_name/directional/east,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/structure/chair/stool/directional/west,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"oWQ" = (
/obj/structure/table,
/obj/item/stack/sheet/iron/fifty,
@@ -47283,6 +48771,15 @@
/obj/item/radio/intercom/directional/north,
/turf/open/floor/iron/white,
/area/station/medical/virology)
+"oXB" = (
+/obj/structure/table,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/item/storage/medkit/regular,
+/obj/item/razor{
+ pixel_y = 5
+ },
+/turf/open/floor/iron,
+/area/station/commons/locker)
"oXJ" = (
/obj/machinery/newscaster/directional/north,
/obj/item/kirbyplants/random,
@@ -47318,6 +48815,17 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
+"oYa" = (
+/obj/structure/closet/secure_closet/personal{
+ anchored = 1
+ },
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/siding/thinplating_new/corner{
+ dir = 4
+ },
+/obj/machinery/status_display/evac/directional/south,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"oYc" = (
/obj/structure/chair/wood/wings{
dir = 8
@@ -47348,10 +48856,6 @@
},
/turf/open/floor/iron/dark,
/area/station/ai_monitored/turret_protected/ai_upload)
-"oYv" = (
-/obj/machinery/bluespace_vendor/directional/south,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"oYx" = (
/obj/machinery/door/airlock/maintenance,
/obj/effect/mapping_helpers/airlock/abandoned,
@@ -47462,11 +48966,6 @@
},
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
-"paV" = (
-/obj/structure/reagent_dispensers/watertank,
-/obj/machinery/airalarm/directional/north,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"paZ" = (
/obj/structure/closet/wardrobe/black,
/obj/item/clothing/shoes/jackboots,
@@ -47552,6 +49051,18 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/white,
/area/station/medical/medbay/central)
+"pcc" = (
+/obj/item/stack/spacecash/c10{
+ pixel_y = 4;
+ pixel_x = 4
+ },
+/obj/item/toy/plush/beeplushie{
+ pixel_y = -6;
+ name = "Coolidge"
+ },
+/obj/effect/decal/cleanable/dirt/dust,
+/turf/open/floor/plating,
+/area/station/commons/dorms/laundry)
"pcg" = (
/obj/machinery/computer/apc_control{
dir = 4
@@ -47616,6 +49127,13 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/mine/laborcamp/security)
+"pdd" = (
+/obj/structure/disposalpipe/segment,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"pdf" = (
/turf/open/floor/plating,
/area/station/maintenance/port/greater)
@@ -47718,6 +49236,18 @@
dir = 1
},
/area/station/security/prison)
+"peG" = (
+/obj/effect/spawner/random/structure/girder,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
+"peM" = (
+/obj/effect/turf_decal/tile/blue,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/item/radio/intercom/directional/east,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"peV" = (
/obj/machinery/portable_atmospherics/canister/air,
/turf/open/floor/plating,
@@ -47730,19 +49260,6 @@
/obj/structure/grille/broken,
/turf/open/openspace/icemoon/keep_below,
/area/icemoon/underground/explored)
-"pfj" = (
-/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/blue/opposingcorners{
- dir = 1
- },
-/turf/open/floor/iron/cafeteria,
-/area/station/commons/dorms/laundry)
"pfn" = (
/obj/structure/sign/poster/official/work_for_a_future/directional/north,
/obj/machinery/airalarm/directional/east,
@@ -47808,6 +49325,12 @@
/obj/effect/mapping_helpers/requests_console/assistance,
/turf/open/floor/wood,
/area/station/command/meeting_room)
+"pgE" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/spawner/random/structure/steam_vent,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"pgG" = (
/obj/structure/table,
/obj/item/clothing/gloves/color/orange,
@@ -47827,6 +49350,14 @@
/obj/effect/decal/cleanable/blood/splatter,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/underground/explored)
+"phf" = (
+/obj/item/assembly/timer{
+ pixel_x = -3;
+ pixel_y = 15
+ },
+/obj/structure/table,
+/turf/open/floor/wood,
+/area/station/command/meeting_room)
"phj" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -47836,6 +49367,20 @@
},
/turf/open/floor/iron/white,
/area/station/medical/break_room)
+"phu" = (
+/obj/structure/chair/sofa/bench/left{
+ dir = 1
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 10
+ },
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/turf/open/floor/iron/cafeteria{
+ dir = 5
+ },
+/area/station/hallway/secondary/entry)
"phB" = (
/obj/machinery/vending/coffee,
/obj/structure/sign/poster/official/science/directional/south,
@@ -47887,6 +49432,13 @@
/obj/structure/closet/radiation,
/turf/open/floor/iron/dark,
/area/station/engineering/main)
+"pig" = (
+/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/commons/locker)
"pii" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 8
@@ -47908,16 +49460,6 @@
/obj/machinery/duct,
/turf/open/floor/iron,
/area/station/service/hydroponics)
-"piy" = (
-/obj/machinery/door/airlock/external{
- name = "Common Mining Shuttle Bay";
- space_dir = 8
- },
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
- dir = 4
- },
-/turf/open/floor/plating,
-/area/station/hallway/secondary/entry)
"piB" = (
/obj/structure/sign/warning/electric_shock/directional/north,
/obj/effect/turf_decal/stripes/corner{
@@ -47991,6 +49533,11 @@
},
/turf/open/floor/iron/white,
/area/station/science/ordnance/office)
+"piP" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/iron/grimy,
+/area/station/hallway/secondary/entry)
"piV" = (
/obj/machinery/button/door/directional/south{
id = "Cargo_Store_In";
@@ -48035,6 +49582,15 @@
},
/turf/open/floor/wood/tile,
/area/station/service/theater)
+"pji" = (
+/obj/structure/cable,
+/obj/machinery/camera/directional/east{
+ c_tag = "Locker Room East"
+ },
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/newscaster/directional/east,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"pjj" = (
/obj/structure/chair,
/turf/open/floor/plating/snowed/icemoon,
@@ -48171,15 +49727,6 @@
/obj/machinery/door/firedoor/heavy,
/turf/open/floor/iron/dark,
/area/station/science/ordnance)
-"pmb" = (
-/obj/machinery/door/airlock/public/glass/incinerator/atmos_exterior,
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
- dir = 1
- },
-/obj/effect/mapping_helpers/airlock/locked,
-/obj/effect/mapping_helpers/airlock/access/all/engineering/atmos,
-/turf/open/floor/engine/vacuum,
-/area/station/maintenance/disposal/incinerator)
"pmg" = (
/obj/effect/turf_decal/siding/white{
dir = 1
@@ -48275,6 +49822,34 @@
/obj/structure/sign/poster/contraband/random/directional/north,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
+"poe" = (
+/obj/machinery/door/airlock/security/glass{
+ id_tag = "permainner";
+ name = "Permabrig Transfer"
+ },
+/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
+ cycle_id = "perma-entrance"
+ },
+/obj/machinery/door/firedoor,
+/obj/effect/mapping_helpers/airlock/access/all/security/brig,
+/turf/open/floor/iron/dark/textured,
+/area/station/security/execution/transfer)
+"pog" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/light/small/directional/north,
+/obj/machinery/light_switch/directional/north{
+ pixel_x = 6
+ },
+/obj/effect/turf_decal/siding/blue{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral/opposingcorners{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/commons/dorms/laundry)
"pou" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible,
@@ -48289,6 +49864,15 @@
"poy" = (
/turf/open/floor/carpet/green,
/area/station/service/library)
+"poK" = (
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/siding/thinplating_new{
+ dir = 8
+ },
+/obj/machinery/airalarm/directional/east,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"poY" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 8
@@ -48352,15 +49936,6 @@
/obj/structure/cable,
/turf/open/floor/iron/dark,
/area/station/tcommsat/computer)
-"ppE" = (
-/obj/structure/cable,
-/obj/structure/disposalpipe/segment{
- dir = 9
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"ppK" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/obj/effect/turf_decal/tile/yellow{
@@ -48368,10 +49943,6 @@
},
/turf/open/floor/iron,
/area/station/command/bridge)
-"ppN" = (
-/obj/structure/sign/warning/pods,
-/turf/closed/wall,
-/area/station/hallway/secondary/entry)
"ppQ" = (
/obj/structure/table,
/obj/item/clothing/gloves/latex,
@@ -48391,10 +49962,6 @@
/obj/effect/turf_decal/tile/red,
/turf/open/floor/iron,
/area/station/hallway/primary/central/fore)
-"pqa" = (
-/obj/structure/table/wood,
-/turf/open/floor/carpet,
-/area/station/hallway/secondary/entry)
"pqc" = (
/obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible{
dir = 6
@@ -48437,11 +50004,6 @@
/obj/effect/spawner/random/engineering/tracking_beacon,
/turf/open/floor/iron/dark,
/area/station/service/hydroponics)
-"pqD" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"pqK" = (
/obj/structure/sign/warning/secure_area/directional/east,
/turf/open/floor/plating,
@@ -48449,11 +50011,6 @@
"pra" = (
/turf/open/floor/iron/dark,
/area/station/science/robotics/lab)
-"prb" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"prf" = (
/obj/structure/closet/crate,
/obj/effect/spawner/random/maintenance/two,
@@ -48462,6 +50019,18 @@
"prg" = (
/turf/open/floor/wood,
/area/station/service/library)
+"prs" = (
+/obj/docking_port/stationary{
+ dir = 8;
+ dwidth = 3;
+ height = 15;
+ name = "arrivals";
+ roundstart_template = /datum/map_template/shuttle/arrival/box;
+ shuttle_id = "arrival_stationary";
+ width = 7
+ },
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"prE" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -48495,17 +50064,10 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central/fore)
-"psr" = (
-/obj/item/storage/bag/plants/portaseeder,
-/obj/structure/table/glass,
-/obj/item/plant_analyzer,
-/obj/item/radio/intercom/directional/east,
-/obj/machinery/light_switch/directional/south,
-/obj/effect/turf_decal/tile/green/half/contrasted{
- dir = 8
- },
-/turf/open/floor/iron/dark,
-/area/station/service/hydroponics/garden)
+"psp" = (
+/obj/effect/landmark/event_spawn,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"pst" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/orange/visible,
@@ -48794,6 +50356,10 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
/area/station/command/teleporter)
+"pwg" = (
+/obj/effect/spawner/random/structure/closet_maintenance,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"pwn" = (
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
@@ -48921,17 +50487,6 @@
/obj/structure/displaycase/forsale/kitchen,
/turf/open/floor/iron/kitchen/diagonal,
/area/station/service/kitchen)
-"pxH" = (
-/obj/machinery/camera/directional/east{
- c_tag = "Garden"
- },
-/obj/machinery/disposal/bin,
-/obj/structure/disposalpipe/trunk{
- dir = 8
- },
-/obj/machinery/light/directional/east,
-/turf/open/floor/iron/dark,
-/area/station/service/hydroponics/garden)
"pxL" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -49111,16 +50666,6 @@
},
/turf/open/floor/iron/cafeteria,
/area/mine/laborcamp)
-"pzQ" = (
-/obj/machinery/conveyor{
- dir = 8;
- id = "garbage"
- },
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"pzV" = (
/obj/structure/table,
/obj/item/paper_bin{
@@ -49139,6 +50684,15 @@
},
/turf/open/floor/iron,
/area/station/cargo/storage)
+"pAc" = (
+/obj/machinery/door/airlock/maintenance_hatch{
+ name = "Ordnance Lab Maintenance"
+ },
+/obj/machinery/door/firedoor/heavy,
+/obj/effect/mapping_helpers/airlock/access/all/science/ordnance,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/science/ordnance)
"pAp" = (
/obj/machinery/deepfryer,
/obj/effect/turf_decal/tile/neutral/diagonal_edge,
@@ -49173,6 +50727,7 @@
/area/station/security/prison/mess)
"pBk" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/disposalpipe/segment,
/turf/open/floor/iron,
/area/station/hallway/primary/port)
"pBr" = (
@@ -49319,6 +50874,19 @@
"pDW" = (
/turf/open/floor/plating,
/area/mine/laborcamp/security)
+"pEg" = (
+/obj/machinery/light/small/directional/east,
+/obj/structure/table,
+/obj/structure/bedsheetbin/empty,
+/obj/effect/turf_decal/siding/blue{
+ dir = 8
+ },
+/obj/effect/turf_decal/tile/neutral/opposingcorners{
+ dir = 1
+ },
+/obj/item/radio/intercom/directional/east,
+/turf/open/floor/iron,
+/area/station/commons/dorms/laundry)
"pEq" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/medical{
@@ -49414,12 +50982,9 @@
/turf/open/floor/iron/smooth,
/area/station/maintenance/fore/lesser)
"pFW" = (
-/obj/effect/turf_decal/siding/wood,
-/obj/effect/turf_decal/siding/wood/corner{
- dir = 1
- },
-/obj/effect/spawner/random/engineering/tracking_beacon,
-/turf/open/floor/wood,
+/obj/structure/filingcabinet/chestdrawer,
+/obj/machinery/computer/security/telescreen/entertainment/directional/north,
+/turf/open/floor/iron/grimy,
/area/station/commons/vacant_room/office)
"pFZ" = (
/obj/item/target/syndicate,
@@ -49428,6 +50993,13 @@
/obj/effect/turf_decal/bot_red,
/turf/open/floor/iron/dark/textured,
/area/station/security/range)
+"pGd" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 1
+ },
+/obj/effect/turf_decal/siding/wood,
+/turf/open/floor/wood,
+/area/station/commons/vacant_room/office)
"pGf" = (
/obj/machinery/atmospherics/pipe/smart/simple/purple/visible{
dir = 10
@@ -49462,6 +51034,12 @@
},
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/underground/explored)
+"pGy" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/iron/dark,
+/area/station/service/hydroponics/garden)
"pGJ" = (
/obj/structure/sign/poster/contraband/random/directional/north,
/obj/effect/mapping_helpers/burnt_floor,
@@ -49606,12 +51184,16 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/command/heads_quarters/ce)
-"pIX" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/wood,
-/area/station/commons/vacant_room/office)
+"pJb" = (
+/obj/structure/sign/nanotrasen{
+ pixel_x = -32
+ },
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 6
+ },
+/obj/structure/marker_beacon/burgundy,
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"pJc" = (
/obj/machinery/component_printer,
/obj/machinery/camera/directional/west{
@@ -49653,6 +51235,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/structure/disposalpipe/segment,
/obj/effect/mapping_helpers/airlock/access/all/command/hop,
+/obj/machinery/door/firedoor,
/turf/open/floor/iron,
/area/station/command/heads_quarters/hop)
"pJQ" = (
@@ -49663,6 +51246,15 @@
},
/turf/open/floor/plating,
/area/station/engineering/atmos/storage/gas)
+"pJU" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/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/iron_smooth,
+/area/station/maintenance/port/lesser)
"pJV" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -49753,6 +51345,18 @@
/obj/structure/sign/warning/xeno_mining,
/turf/closed/wall/ice,
/area/icemoon/surface/outdoors/nospawn)
+"pLn" = (
+/obj/effect/turf_decal/tile/blue,
+/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{
+ dir = 4
+ },
+/turf/open/floor/iron/white/corner{
+ dir = 8
+ },
+/area/station/hallway/secondary/entry)
"pLr" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
@@ -49791,14 +51395,15 @@
},
/turf/open/floor/iron/freezer,
/area/station/commons/toilet/locker)
-"pLO" = (
-/obj/machinery/status_display/evac/directional/east,
+"pLZ" = (
/obj/structure/cable,
-/obj/effect/turf_decal/tile/blue{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/spawner/random/food_or_drink/seed,
+/obj/structure/closet,
+/obj/effect/spawner/random/food_or_drink/seed,
+/obj/effect/spawner/random/trash/botanical_waste,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"pMg" = (
/obj/machinery/door/airlock/external{
name = "Labor Camp Shuttle Airlock";
@@ -49904,14 +51509,6 @@
},
/turf/open/floor/iron/dark/airless,
/area/station/science/ordnance/freezerchamber)
-"pNG" = (
-/obj/structure/table,
-/obj/item/storage/crayons,
-/obj/effect/turf_decal/tile/blue/opposingcorners{
- dir = 1
- },
-/turf/open/floor/iron/cafeteria,
-/area/station/commons/dorms/laundry)
"pNK" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 4
@@ -49970,6 +51567,12 @@
/obj/effect/landmark/start/hangover/closet,
/turf/open/floor/carpet,
/area/station/commons/dorms)
+"pOq" = (
+/obj/machinery/airalarm/directional/north,
+/obj/structure/closet/firecloset,
+/obj/machinery/light/small/dim/directional/north,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"pOy" = (
/obj/structure/cable,
/turf/open/floor/iron,
@@ -50040,13 +51643,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/virology)
-"pPG" = (
-/obj/effect/turf_decal/tile/blue{
- dir = 8
- },
-/obj/machinery/light/directional/south,
-/turf/open/floor/iron/white/corner,
-/area/station/hallway/secondary/entry)
"pPK" = (
/obj/structure/stairs/east,
/turf/open/floor/iron/dark/textured,
@@ -50083,6 +51679,15 @@
},
/turf/open/floor/iron,
/area/station/service/hydroponics/garden)
+"pPY" = (
+/obj/machinery/light/small/dim/directional/west,
+/obj/effect/mapping_helpers/broken_floor,
+/obj/effect/spawner/random/trash/grime,
+/obj/effect/decal/cleanable/generic,
+/obj/structure/sign/departments/maint/directional/west,
+/obj/structure/sign/departments/maint/directional/west,
+/turf/open/floor/iron/smooth,
+/area/station/maintenance/port/lesser)
"pQa" = (
/obj/structure/disposalpipe/segment{
dir = 6
@@ -50112,14 +51717,6 @@
/obj/structure/cable,
/turf/open/floor/iron/textured,
/area/station/medical/chem_storage)
-"pQs" = (
-/obj/machinery/space_heater,
-/obj/effect/spawner/random/trash/graffiti{
- pixel_y = -32;
- spawn_loot_chance = 50
- },
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"pQv" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
@@ -50141,17 +51738,6 @@
/obj/effect/turf_decal/stripes/box,
/turf/open/floor/plating,
/area/station/maintenance/aft/lesser)
-"pQI" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/turf_decal/siding/thinplating/corner{
- dir = 1
- },
-/obj/machinery/washing_machine,
-/obj/effect/turf_decal/tile/blue/opposingcorners{
- dir = 1
- },
-/turf/open/floor/iron/cafeteria,
-/area/station/commons/dorms/laundry)
"pQK" = (
/obj/structure/closet/secure_closet/evidence,
/turf/open/floor/iron/dark/textured_edge{
@@ -50170,13 +51756,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/white,
/area/station/medical/treatment_center)
-"pQQ" = (
-/obj/structure/cable,
-/obj/effect/mapping_helpers/burnt_floor,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"pRa" = (
/turf/closed/wall,
/area/station/science/ordnance/bomb)
@@ -50213,6 +51792,10 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/iron/freezer,
/area/mine/laborcamp)
+"pSd" = (
+/obj/machinery/digital_clock/directional/east,
+/turf/open/floor/iron/grimy,
+/area/station/hallway/secondary/entry)
"pSk" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -50394,6 +51977,12 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/maintenance/solars/port/fore)
+"pVQ" = (
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 6
+ },
+/turf/open/floor/plating/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"pVV" = (
/obj/effect/turf_decal/stripes/line{
dir = 10
@@ -50468,6 +52057,12 @@
/obj/effect/decal/cleanable/blood,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/underground/explored)
+"pXh" = (
+/obj/effect/turf_decal/tile/green{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/hallway/primary/port)
"pXj" = (
/obj/machinery/power/shieldwallgen/xenobiologyaccess,
/obj/structure/cable,
@@ -50518,6 +52113,13 @@
/obj/machinery/portable_atmospherics/canister/air,
/turf/open/floor/plating,
/area/station/maintenance/port/greater)
+"pXU" = (
+/obj/machinery/camera/directional/east{
+ c_tag = "Arrivals Lounge"
+ },
+/obj/machinery/status_display/ai/directional/east,
+/turf/open/floor/iron/grimy,
+/area/station/hallway/secondary/entry)
"pXY" = (
/obj/machinery/atmospherics/pipe/heat_exchanging/simple,
/turf/open/floor/plating/snowed/smoothed/icemoon,
@@ -50749,6 +52351,10 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/hallway/primary/aft)
+"qbU" = (
+/obj/structure/sign/warning/electric_shock/directional/south,
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/underground/explored)
"qbW" = (
/obj/structure/rack,
/obj/effect/spawner/random/maintenance/three,
@@ -50785,10 +52391,6 @@
/obj/machinery/plumbing/sender,
/turf/open/floor/plating,
/area/station/medical/chemistry)
-"qcZ" = (
-/obj/machinery/vending/modularpc,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"qde" = (
/obj/structure/table,
/obj/machinery/cell_charger,
@@ -50871,6 +52473,20 @@
/obj/machinery/microwave,
/turf/open/floor/stone,
/area/mine/eva/lower)
+"qeF" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/machinery/camera/directional/north{
+ c_tag = "Arrivals Aux Dock"
+ },
+/obj/item/radio/intercom/directional/north,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"qeJ" = (
/obj/structure/chair/plastic{
dir = 1
@@ -50975,12 +52591,6 @@
/obj/effect/landmark/start/medical_doctor,
/turf/open/floor/iron/white,
/area/station/medical/surgery/fore)
-"qgM" = (
-/obj/effect/spawner/structure/window/hollow/directional{
- dir = 10
- },
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"qgO" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -51108,14 +52718,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/freezer,
/area/station/maintenance/starboard/fore)
-"qjj" = (
-/obj/effect/turf_decal/tile/blue{
- dir = 4
- },
-/turf/open/floor/iron/white/corner{
- dir = 1
- },
-/area/station/hallway/secondary/entry)
"qjm" = (
/obj/machinery/camera/directional/south{
c_tag = "Bridge West Access"
@@ -51124,15 +52726,30 @@
/obj/effect/turf_decal/tile/blue/half/contrasted,
/turf/open/floor/iron,
/area/station/hallway/primary/central)
+"qjp" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/siding/thinplating_new,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"qjq" = (
/obj/machinery/telecomms/processor/preset_four,
/turf/open/floor/circuit/telecomms/mainframe,
/area/station/tcommsat/server)
+"qjr" = (
+/obj/structure/girder,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"qjx" = (
/obj/structure/cable,
/obj/machinery/holopad/secure,
/turf/open/floor/wood,
/area/station/command/heads_quarters/captain)
+"qjC" = (
+/obj/structure/sign/nanotrasen{
+ pixel_x = -32
+ },
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"qjF" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 9
@@ -51171,9 +52788,12 @@
/turf/open/floor/iron/dark,
/area/station/medical/medbay/aft)
"qku" = (
-/obj/item/kirbyplants/random,
-/turf/open/floor/iron/grimy,
-/area/station/commons/vacant_room/office)
+/obj/structure/chair/comfy/beige{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/carpet/blue,
+/area/station/hallway/secondary/entry)
"qky" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/turf_decal/tile/red/half{
@@ -51202,10 +52822,6 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/station/security/lockers)
-"qkP" = (
-/obj/item/trash/semki,
-/turf/open/floor/iron,
-/area/station/maintenance/port/fore)
"qkT" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -51254,6 +52870,14 @@
/obj/machinery/firealarm/directional/north,
/turf/open/floor/iron,
/area/station/science/explab)
+"qlP" = (
+/obj/machinery/door/airlock/external/glass,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/mapping_helpers/airlock/access/all/engineering/external,
+/obj/structure/cable,
+/turf/open/floor/iron/textured,
+/area/station/hallway/secondary/entry)
"qlU" = (
/obj/structure/closet/crate,
/turf/open/floor/plating/snowed/icemoon,
@@ -51279,6 +52903,14 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/morgue)
+"qmN" = (
+/obj/item/radio/intercom/directional/north,
+/obj/structure/reagent_dispensers/plumbed,
+/obj/effect/turf_decal/stripes/line{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/station/hallway/secondary/service)
"qmT" = (
/obj/structure/bed{
dir = 4
@@ -51379,6 +53011,23 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/starboard)
+"qnV" = (
+/obj/structure/table/reinforced,
+/obj/item/storage/toolbox/emergency{
+ pixel_y = 9
+ },
+/obj/item/assembly/timer,
+/obj/item/assembly/signaler{
+ pixel_x = 7;
+ pixel_y = -7
+ },
+/obj/item/assembly/signaler{
+ pixel_x = -8;
+ pixel_y = -12
+ },
+/obj/machinery/status_display/ai/directional/east,
+/turf/open/floor/iron,
+/area/station/command/bridge)
"qob" = (
/obj/structure/table,
/obj/effect/decal/cleanable/cobweb,
@@ -51452,10 +53101,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/catwalk_floor/iron_smooth,
/area/station/maintenance/starboard/fore)
-"qpe" = (
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"qpp" = (
/obj/machinery/camera/directional/west{
c_tag = "Quartermaster's Office"
@@ -51479,6 +53124,15 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/mix)
+"qpt" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
"qpu" = (
/obj/machinery/button/door/directional/west{
id = "gene_shutters";
@@ -51541,6 +53195,26 @@
/obj/machinery/recharge_station,
/turf/open/floor/wood,
/area/station/command/meeting_room)
+"qpZ" = (
+/obj/structure/table,
+/obj/item/folder/blue{
+ pixel_x = -6;
+ pixel_y = 3
+ },
+/obj/item/pen{
+ pixel_x = -1;
+ pixel_y = 1
+ },
+/obj/item/paper_bin/carbon{
+ pixel_x = 5;
+ pixel_y = 18
+ },
+/obj/item/stamp/head/hop{
+ pixel_x = 8;
+ pixel_y = 5
+ },
+/turf/open/floor/iron,
+/area/station/command/heads_quarters/hop)
"qqh" = (
/obj/machinery/atmospherics/components/unary/portables_connector/visible{
dir = 8;
@@ -51566,16 +53240,6 @@
/obj/item/kirbyplants/organic/applebush,
/turf/open/floor/wood,
/area/station/hallway/secondary/service)
-"qqz" = (
-/obj/machinery/door/airlock/security{
- name = "Security Checkpoint"
- },
-/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/security/general,
-/obj/structure/cable,
-/turf/open/floor/iron,
-/area/station/security/checkpoint/customs/auxiliary)
"qqB" = (
/obj/machinery/button/door/directional/north{
id = "maint3";
@@ -51671,6 +53335,16 @@
/obj/item/radio/intercom/directional/north,
/turf/open/floor/iron/dark,
/area/station/service/chapel)
+"qsh" = (
+/obj/structure/plaque/static_plaque/golden/commission/icebox,
+/obj/effect/landmark/navigate_destination/dockarrival,
+/obj/effect/turf_decal/bot_white,
+/turf/open/floor/iron/large,
+/area/station/hallway/secondary/entry)
+"qsq" = (
+/obj/structure/sign/warning/directional/south,
+/turf/open/openspace/icemoon/keep_below,
+/area/icemoon/underground/explored)
"qsy" = (
/obj/effect/landmark/event_spawn,
/obj/structure/cable,
@@ -51678,18 +53352,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
/area/station/hallway/primary/central)
-"qsE" = (
-/obj/machinery/door/firedoor,
-/obj/structure/table/reinforced,
-/obj/item/paper,
-/obj/machinery/door/window/right/directional/west{
- dir = 1;
- name = "Security Checkpoint";
- req_access = list("security")
- },
-/obj/effect/turf_decal/delivery,
-/turf/open/floor/iron,
-/area/station/security/checkpoint/customs/auxiliary)
"qsG" = (
/obj/effect/turf_decal/trimline/green/filled/line{
dir = 9
@@ -51782,6 +53444,7 @@
/obj/machinery/door/window/left/directional/north{
name = "Armory Desk"
},
+/obj/item/hand_labeler,
/turf/open/floor/iron,
/area/station/ai_monitored/security/armory/upper)
"quB" = (
@@ -51824,13 +53487,6 @@
/obj/machinery/light/small/directional/east,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
-"qvm" = (
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
- dir = 8
- },
-/obj/machinery/light/directional/east,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"qvE" = (
/obj/structure/window/reinforced/spawner/directional/north,
/obj/machinery/light/small/directional/east,
@@ -51917,6 +53573,11 @@
},
/turf/open/floor/iron/dark,
/area/station/ai_monitored/command/storage/eva)
+"qwn" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/vending/cigarette,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"qwB" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/turf/open/floor/wood,
@@ -52009,6 +53670,13 @@
/obj/effect/mapping_helpers/requests_console/supplies,
/turf/open/floor/iron,
/area/station/science/explab)
+"qxm" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
+/turf/open/floor/iron/smooth,
+/area/station/maintenance/port/lesser)
"qxo" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/atmospherics/pipe/smart/simple/yellow/visible{
@@ -52044,17 +53712,13 @@
/obj/machinery/duct,
/turf/open/floor/iron,
/area/station/engineering/lobby)
+"qxI" = (
+/turf/open/floor/plastic,
+/area/station/commons/dorms/laundry)
"qxQ" = (
/obj/effect/turf_decal/delivery,
/turf/open/floor/iron,
/area/station/cargo/lobby)
-"qxW" = (
-/obj/structure/rack,
-/obj/item/storage/briefcase,
-/obj/item/pai_card,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"qxY" = (
/obj/item/chair/plastic,
/obj/effect/decal/cleanable/dirt,
@@ -52074,6 +53738,15 @@
},
/turf/open/floor/plating,
/area/station/engineering/atmos/pumproom)
+"qyL" = (
+/obj/structure/closet/secure_closet/personal{
+ anchored = 1
+ },
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/structure/sign/poster/official/random/directional/south,
+/obj/machinery/light/directional/south,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"qyO" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 8
@@ -52091,12 +53764,6 @@
},
/turf/open/floor/iron/dark,
/area/station/cargo/miningdock)
-"qyU" = (
-/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/hallway/secondary/entry)
"qzq" = (
/obj/structure/sign/departments/cargo,
/turf/closed/wall/r_wall,
@@ -52165,12 +53832,11 @@
/obj/machinery/light/small/directional/west,
/turf/open/floor/iron/dark,
/area/station/engineering/storage)
-"qAz" = (
-/obj/structure/disposalpipe/trunk/multiz{
- dir = 1
- },
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
+"qAB" = (
+/obj/structure/table/wood,
+/obj/item/flashlight/lamp,
+/turf/open/floor/iron/grimy,
+/area/station/commons/vacant_room/office)
"qAI" = (
/obj/effect/decal/cleanable/food/flour,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -52263,15 +53929,6 @@
},
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
-"qCE" = (
-/obj/machinery/door/firedoor,
-/obj/effect/turf_decal/stripes/line{
- dir = 8
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"qCF" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -52436,6 +54093,17 @@
"qEJ" = (
/turf/closed/wall,
/area/station/service/chapel/office)
+"qEK" = (
+/obj/item/paper_bin{
+ pixel_x = -3;
+ pixel_y = 4
+ },
+/obj/item/pen,
+/obj/structure/table,
+/obj/effect/turf_decal/tile/red/half/contrasted,
+/obj/structure/cable,
+/turf/open/floor/iron/dark,
+/area/station/security/checkpoint/customs/auxiliary)
"qEM" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -52489,6 +54157,12 @@
dir = 8
},
/area/station/security/processing)
+"qFs" = (
+/obj/effect/spawner/random/vending/snackvend,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/structure/extinguisher_cabinet/directional/south,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"qFt" = (
/obj/effect/spawner/structure/window,
/turf/open/floor/plating,
@@ -52512,6 +54186,14 @@
},
/turf/open/floor/iron,
/area/station/service/hydroponics)
+"qFJ" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/holopad,
+/obj/effect/landmark/event_spawn,
+/obj/effect/turf_decal/bot,
+/obj/structure/cable,
+/turf/open/floor/iron/dark/smooth_large,
+/area/station/security/checkpoint/customs/auxiliary)
"qFX" = (
/obj/machinery/door/airlock{
name = "Custodial Closet"
@@ -52552,6 +54234,13 @@
},
/turf/open/floor/iron/white,
/area/station/science/xenobiology)
+"qGJ" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/effect/spawner/random/trash/grime,
+/turf/open/floor/catwalk_floor/iron_smooth,
+/area/station/maintenance/port/lesser)
"qGQ" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 4
@@ -52637,6 +54326,15 @@
},
/turf/open/floor/iron,
/area/station/command/bridge)
+"qHO" = (
+/obj/machinery/bluespace_vendor/directional/south,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/structure/chair/sofa/bench/right{
+ dir = 1
+ },
+/obj/effect/landmark/start/hangover,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"qIf" = (
/obj/machinery/power/smes,
/obj/structure/cable,
@@ -52711,16 +54409,6 @@
"qIU" = (
/turf/open/floor/iron,
/area/station/commons/dorms)
-"qIV" = (
-/obj/machinery/door/airlock/public/glass{
- name = "Art Storage"
- },
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/door/firedoor,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron,
-/area/station/commons/storage/art)
"qJh" = (
/obj/structure/disposalpipe/segment{
dir = 9
@@ -52826,6 +54514,13 @@
/obj/effect/spawner/structure/window/hollow/reinforced/end,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/morgue)
+"qKJ" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/turf/open/floor/iron/dark/smooth_large,
+/area/station/hallway/secondary/entry)
"qKQ" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/cable,
@@ -53014,9 +54709,6 @@
dir = 1
},
/area/station/hallway/secondary/service)
-"qNk" = (
-/turf/open/floor/plating,
-/area/station/construction/mining/aux_base)
"qNl" = (
/obj/structure/plasticflaps/opaque,
/obj/effect/turf_decal/delivery,
@@ -53073,10 +54765,6 @@
/obj/machinery/light/floor,
/turf/open/floor/iron,
/area/station/engineering/atmos)
-"qNL" = (
-/obj/effect/spawner/random/vending/colavend,
-/turf/open/floor/iron/dark,
-/area/station/hallway/secondary/entry)
"qNV" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/general/visible,
/obj/effect/decal/cleanable/dirt,
@@ -53154,6 +54842,26 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/smooth,
/area/station/security/holding_cell)
+"qPq" = (
+/obj/machinery/door/airlock/maintenance{
+ name = "Security Maintenance"
+ },
+/obj/structure/cable,
+/obj/effect/mapping_helpers/airlock/access/all/security/general,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/security/checkpoint/customs/auxiliary)
+"qPs" = (
+/obj/effect/landmark/start/hangover,
+/obj/effect/turf_decal/siding/blue{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral/opposingcorners{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/commons/dorms/laundry)
"qPt" = (
/obj/structure/closet/secure_closet/chemical,
/obj/item/radio/headset/headset_med,
@@ -53174,13 +54882,6 @@
},
/turf/open/floor/wood,
/area/station/maintenance/port/aft)
-"qPC" = (
-/obj/structure/disposalpipe/segment,
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"qPE" = (
/obj/structure/closet/secure_closet/freezer/meat,
/turf/open/misc/asteroid/snow/coldroom,
@@ -53294,10 +54995,14 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/science/ordnance)
-"qRT" = (
-/obj/structure/cable,
-/turf/open/floor/iron,
-/area/station/hallway/primary/port)
+"qRR" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/structure/sign/poster/contraband/random/directional/south,
+/obj/effect/spawner/random/structure/steam_vent,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"qSb" = (
/obj/structure/window/reinforced/spawner/directional/north,
/obj/structure/window/reinforced/spawner/directional/west,
@@ -53424,6 +55129,28 @@
},
/turf/open/floor/plating,
/area/station/maintenance/department/medical/central)
+"qTj" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/obj/structure/sign/warning/pods/directional/west,
+/obj/structure/cable,
+/turf/open/floor/iron/white/corner{
+ dir = 1
+ },
+/area/station/hallway/secondary/entry)
+"qTm" = (
+/obj/effect/turf_decal/tile/neutral/half/contrasted{
+ dir = 8
+ },
+/obj/effect/turf_decal/siding/wood/corner{
+ dir = 1
+ },
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/service/hydroponics/garden)
"qTs" = (
/turf/open/floor/iron/showroomfloor,
/area/station/security/prison/mess)
@@ -53500,6 +55227,13 @@
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
+"qVg" = (
+/obj/structure/cable,
+/obj/structure/chair/stool/directional/south,
+/obj/effect/landmark/start/assistant,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"qVk" = (
/obj/effect/turf_decal/trimline/yellow/filled/line,
/obj/item/kirbyplants/random,
@@ -53522,6 +55256,17 @@
/obj/structure/rack,
/turf/open/floor/iron/white,
/area/station/science/xenobiology)
+"qVD" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 1
+ },
+/obj/structure/cable,
+/obj/effect/spawner/random/trash/graffiti{
+ pixel_y = -32;
+ spawn_loot_chance = 50
+ },
+/turf/open/floor/iron/smooth,
+/area/station/maintenance/port/lesser)
"qVJ" = (
/obj/machinery/disposal/bin,
/obj/machinery/light_switch/directional/south,
@@ -53530,6 +55275,12 @@
},
/turf/open/floor/iron/dark/smooth_large,
/area/station/command/heads_quarters/hos)
+"qVN" = (
+/obj/structure/table/glass,
+/obj/item/stock_parts/matter_bin,
+/obj/effect/spawner/random/food_or_drink/booze,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"qWh" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -53568,6 +55319,10 @@
/obj/machinery/duct,
/turf/open/floor/iron/white,
/area/station/medical/virology)
+"qWI" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/closed/wall/r_wall,
+/area/station/maintenance/starboard/aft)
"qWJ" = (
/obj/item/crowbar/large,
/obj/structure/rack,
@@ -53696,6 +55451,14 @@
},
/turf/open/floor/plating,
/area/station/hallway/secondary/entry)
+"qYA" = (
+/obj/machinery/computer/security,
+/obj/structure/reagent_dispensers/wall/peppertank/directional/north,
+/obj/effect/turf_decal/tile/red/half/contrasted{
+ dir = 1
+ },
+/turf/open/floor/iron/dark,
+/area/station/security/checkpoint/customs/auxiliary)
"qYD" = (
/obj/effect/turf_decal/trimline/green/filled/line{
dir = 4
@@ -53725,13 +55488,6 @@
},
/turf/open/floor/engine,
/area/station/engineering/supermatter/room)
-"qYR" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/item/radio/intercom/directional/south,
-/turf/open/floor/iron,
-/area/station/hallway/primary/port)
"qYZ" = (
/obj/effect/turf_decal/trimline/yellow/filled/line,
/obj/machinery/newscaster/directional/south,
@@ -53906,10 +55662,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/mine/laborcamp)
-"rbW" = (
-/obj/machinery/airalarm/directional/east,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"rbY" = (
/obj/structure/table/reinforced,
/obj/item/pipe_dispenser,
@@ -53946,11 +55698,6 @@
},
/turf/open/floor/iron,
/area/station/science/explab)
-"rcq" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/pink/hidden,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"rcx" = (
/obj/machinery/light/directional/west,
/obj/structure/window/reinforced/spawner/directional/north,
@@ -54015,6 +55762,10 @@
},
/turf/open/floor/iron/white,
/area/station/science/xenobiology)
+"rdn" = (
+/obj/item/radio/intercom/directional/north,
+/turf/open/floor/iron,
+/area/station/hallway/primary/port)
"rdw" = (
/obj/structure/bookcase,
/obj/machinery/light/small/directional/north,
@@ -54104,11 +55855,11 @@
codes_txt = "delivery;dir=8";
location = "Tool Storage"
},
-/obj/structure/disposalpipe/segment{
- dir = 5
- },
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/disposalpipe/segment{
+ dir = 6
+ },
/turf/open/floor/iron,
/area/station/commons/storage/primary)
"reM" = (
@@ -54152,14 +55903,11 @@
"rfu" = (
/turf/closed/wall/r_wall,
/area/station/security/prison/rec)
-"rfz" = (
-/obj/machinery/light/small/directional/west,
-/obj/item/kirbyplants/random,
-/obj/effect/turf_decal/tile/blue/opposingcorners{
- dir = 1
- },
-/turf/open/floor/iron/cafeteria,
-/area/station/commons/dorms/laundry)
+"rfF" = (
+/obj/effect/spawner/random/trash/mess,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"rfR" = (
/obj/machinery/telecomms/bus/preset_two,
/turf/open/floor/circuit/telecomms/mainframe,
@@ -54221,6 +55969,12 @@
/obj/item/stack/package_wrap,
/turf/open/floor/wood/large,
/area/mine/eva/lower)
+"rgs" = (
+/obj/structure/cable,
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"rgB" = (
/obj/structure/cable,
/obj/item/radio/intercom/directional/south,
@@ -54270,24 +56024,6 @@
dir = 8
},
/area/station/science/ordnance/office)
-"rho" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/turf_decal/siding/green/corner{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/service/hydroponics/garden)
-"rhE" = (
-/obj/machinery/door/airlock/external{
- name = "Escape Pod Two";
- space_dir = 8
- },
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
- dir = 4
- },
-/turf/open/floor/plating,
-/area/station/hallway/secondary/entry)
"rhF" = (
/obj/machinery/camera/directional/north{
c_tag = "Security - Permabrig Observation North";
@@ -54327,6 +56063,20 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/catwalk_floor/iron_smooth,
/area/station/maintenance/department/medical/central)
+"rin" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 10
+ },
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/obj/structure/chair{
+ dir = 1
+ },
+/turf/open/floor/iron/cafeteria{
+ dir = 5
+ },
+/area/station/hallway/secondary/entry)
"riv" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -54710,6 +56460,11 @@
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
+"roX" = (
+/obj/effect/spawner/structure/window/reinforced,
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/station/security/checkpoint/customs/auxiliary)
"rpa" = (
/obj/structure/closet/athletic_mixed,
/turf/open/floor/plating,
@@ -54787,6 +56542,21 @@
dir = 1
},
/area/station/science/explab)
+"rqi" = (
+/obj/item/crowbar{
+ pixel_y = 3
+ },
+/obj/item/assembly/flash/handheld{
+ pixel_y = 3;
+ pixel_x = -19
+ },
+/obj/structure/table,
+/obj/effect/turf_decal/tile/red/anticorner/contrasted,
+/obj/item/radio/off{
+ pixel_y = 6
+ },
+/turf/open/floor/iron/dark,
+/area/station/security/checkpoint/customs/auxiliary)
"rqq" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -54848,6 +56618,11 @@
/obj/structure/table/wood,
/turf/open/floor/iron/dark,
/area/station/service/chapel/office)
+"rrn" = (
+/obj/structure/closet/emcloset,
+/obj/structure/sign/poster/contraband/random/directional/north,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"rrp" = (
/obj/structure/railing{
dir = 4
@@ -54880,11 +56655,17 @@
/obj/machinery/duct,
/turf/open/floor/iron,
/area/station/service/theater)
-"rrY" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/pink/hidden,
-/obj/effect/landmark/generic_maintenance_landmark,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
+"rsw" = (
+/obj/effect/turf_decal/stripes/corner{
+ dir = 8
+ },
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/turf/open/floor/iron/white/corner{
+ dir = 1
+ },
+/area/station/hallway/secondary/entry)
"rsL" = (
/obj/structure/cable,
/turf/open/floor/circuit,
@@ -55045,10 +56826,19 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/mine/laborcamp)
-"rvE" = (
-/obj/structure/sign/warning/docking,
-/turf/closed/wall/r_wall,
-/area/station/hallway/secondary/entry)
+"rvS" = (
+/obj/structure/rack,
+/obj/item/poster/random_contraband,
+/obj/effect/spawner/random/maintenance/two,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
+"rvW" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/catwalk_floor/iron_smooth,
+/area/station/maintenance/port/greater)
"rvZ" = (
/obj/effect/landmark/start/hangover,
/turf/open/floor/iron,
@@ -55206,6 +56996,19 @@
/obj/structure/cable,
/turf/open/floor/iron/smooth,
/area/station/security/holding_cell)
+"ryM" = (
+/obj/structure/rack,
+/obj/item/pickaxe,
+/obj/item/pickaxe,
+/obj/item/shovel,
+/obj/item/flashlight,
+/obj/item/flashlight,
+/obj/item/radio/off,
+/obj/item/radio/intercom/directional/east,
+/obj/structure/cable,
+/obj/effect/turf_decal/delivery/red,
+/turf/open/floor/iron/textured,
+/area/station/hallway/secondary/entry)
"ryO" = (
/obj/item/kirbyplants/random,
/turf/open/floor/wood,
@@ -55245,8 +57048,9 @@
"rzr" = (
/obj/structure/table,
/obj/item/mod/module/plasma_stabilizer,
-/obj/item/mod/module/thermal_regulator,
/obj/item/assembly/flash/handheld,
+/obj/item/mod/module/signlang_radio,
+/obj/item/mod/module/thermal_regulator,
/turf/open/floor/iron/dark/textured_half{
dir = 1
},
@@ -55372,11 +57176,6 @@
/obj/effect/turf_decal/stripes/line,
/turf/open/floor/iron/dark/smooth_large,
/area/station/ai_monitored/command/storage/eva)
-"rBj" = (
-/obj/effect/turf_decal/stripes/line,
-/obj/machinery/atmospherics/components/binary/pump,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"rBn" = (
/obj/structure/cable,
/turf/open/floor/iron,
@@ -55411,6 +57210,14 @@
/obj/machinery/light/directional/west,
/turf/open/openspace,
/area/station/commons/storage/mining)
+"rBM" = (
+/obj/machinery/door/airlock/external,
+/obj/effect/mapping_helpers/airlock/cyclelink_helper{
+ dir = 8
+ },
+/obj/effect/mapping_helpers/airlock/access/all/engineering/external,
+/turf/open/floor/plating,
+/area/station/commons/dorms/laundry)
"rBQ" = (
/obj/machinery/atmospherics/pipe/smart/manifold/yellow/visible{
dir = 1
@@ -55420,12 +57227,6 @@
"rBV" = (
/turf/closed/wall,
/area/station/tcommsat/computer)
-"rCb" = (
-/obj/docking_port/stationary/public_mining_dock{
- dir = 8
- },
-/turf/open/floor/plating,
-/area/station/construction/mining/aux_base)
"rCe" = (
/obj/structure/toilet{
dir = 4
@@ -55446,6 +57247,12 @@
},
/turf/open/floor/iron/textured_half,
/area/station/service/hydroponics)
+"rCj" = (
+/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/commons/locker)
"rCu" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/obj/effect/landmark/start/hangover,
@@ -55511,6 +57318,15 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/general/visible,
/turf/open/floor/plating,
/area/station/maintenance/starboard/upper)
+"rCU" = (
+/obj/structure/closet/emcloset,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/siding/white{
+ dir = 1
+ },
+/obj/machinery/mining_weather_monitor/directional/south,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"rCW" = (
/obj/machinery/door/airlock/external{
name = "Atmospherics Internal Airlock"
@@ -55542,7 +57358,7 @@
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 8
},
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/white,
/area/station/medical/medbay/aft)
@@ -55622,14 +57438,6 @@
},
/turf/open/floor/iron/dark,
/area/station/engineering/storage)
-"rDR" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 8
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"rDZ" = (
/turf/open/floor/engine,
/area/station/science/explab)
@@ -55683,11 +57491,6 @@
/obj/effect/turf_decal/bot_white,
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/project)
-"rEB" = (
-/obj/structure/closet,
-/obj/effect/spawner/random/maintenance,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"rEG" = (
/obj/effect/turf_decal/trimline/blue/filled/line,
/obj/effect/turf_decal/trimline/blue/filled/corner{
@@ -55695,11 +57498,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/treatment_center)
-"rEN" = (
-/obj/structure/cable,
-/obj/machinery/power/apc/auto_name/directional/south,
-/turf/open/floor/iron,
-/area/station/service/hydroponics/garden)
"rEP" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/obj/effect/turf_decal/tile/red/half/contrasted{
@@ -55707,6 +57505,16 @@
},
/turf/open/floor/iron/dark/side,
/area/station/security/processing)
+"rEU" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/aft)
+"rFb" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 1
+ },
+/turf/open/floor/iron/grimy,
+/area/station/hallway/secondary/entry)
"rFf" = (
/obj/effect/turf_decal/trimline/neutral/filled/line{
dir = 6
@@ -55903,6 +57711,13 @@
/obj/effect/turf_decal/delivery,
/turf/open/floor/iron,
/area/station/science/xenobiology)
+"rJr" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/siding/white,
+/obj/structure/closet/firecloset,
+/obj/machinery/mining_weather_monitor/directional/north,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"rJv" = (
/obj/machinery/bluespace_beacon,
/obj/structure/cable,
@@ -55989,11 +57804,6 @@
/obj/machinery/portable_atmospherics/canister,
/turf/open/floor/iron,
/area/station/science/xenobiology)
-"rLb" = (
-/obj/structure/chair/comfy/beige,
-/obj/effect/landmark/start/assistant,
-/turf/open/floor/iron/grimy,
-/area/station/hallway/secondary/entry)
"rLo" = (
/turf/open/floor/plating,
/area/station/cargo/miningdock)
@@ -56009,6 +57819,14 @@
/obj/effect/turf_decal/bot,
/turf/open/floor/iron,
/area/station/cargo/office)
+"rLw" = (
+/obj/machinery/mass_driver/trash{
+ dir = 1
+ },
+/obj/structure/sign/warning/cold_temp/directional/east,
+/obj/effect/turf_decal/stripes/line,
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"rLV" = (
/obj/structure/window/reinforced/spawner/directional/east,
/obj/effect/turf_decal/siding/thinplating/dark{
@@ -56042,6 +57860,11 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/cargo/lobby)
+"rMu" = (
+/obj/effect/turf_decal/bot,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"rME" = (
/obj/structure/railing{
dir = 4
@@ -56112,6 +57935,17 @@
dir = 4
},
/area/mine/living_quarters)
+"rNE" = (
+/obj/docking_port/stationary{
+ dir = 2;
+ dwidth = 2;
+ height = 13;
+ name = "port bay 2";
+ shuttle_id = "ferry_home";
+ width = 5
+ },
+/turf/open/floor/plating/snowed/smoothed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"rNQ" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -56122,28 +57956,19 @@
/obj/effect/landmark/start/hangover,
/turf/open/floor/iron,
/area/station/hallway/primary/starboard)
-"rNR" = (
-/obj/structure/table/wood,
-/obj/item/flashlight/lamp/green{
- pixel_x = 1;
- pixel_y = 5
+"rOb" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/cable,
+/obj/structure/disposalpipe/segment{
+ dir = 4
},
-/turf/open/floor/iron/grimy,
-/area/station/hallway/secondary/entry)
+/turf/open/floor/iron,
+/area/station/hallway/primary/port)
"rOe" = (
/obj/structure/closet/toolcloset,
/turf/open/floor/iron/dark,
/area/station/engineering/supermatter/room)
-"rOj" = (
-/obj/effect/turf_decal/stripes/corner{
- dir = 1
- },
-/obj/effect/turf_decal/stripes/corner{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"rOA" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -56192,15 +58017,6 @@
/obj/effect/landmark/start/hangover,
/turf/open/floor/iron/dark,
/area/station/engineering/lobby)
-"rOV" = (
-/obj/item/storage/backpack{
- pixel_x = 4;
- pixel_y = 4
- },
-/obj/item/storage/backpack,
-/obj/structure/table,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"rOX" = (
/obj/structure/chair,
/turf/open/floor/plating,
@@ -56327,16 +58143,6 @@
/obj/effect/spawner/structure/window,
/turf/open/floor/plating,
/area/station/maintenance/department/chapel)
-"rRd" = (
-/obj/machinery/conveyor{
- dir = 6;
- id = "garbage"
- },
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"rRk" = (
/obj/structure/table,
/obj/item/storage/belt/utility,
@@ -56385,12 +58191,6 @@
},
/turf/open/floor/catwalk_floor/iron_smooth,
/area/station/maintenance/starboard/fore)
-"rSn" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/obj/effect/turf_decal/tile/neutral,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"rSq" = (
/obj/structure/closet,
/obj/effect/spawner/random/maintenance,
@@ -56453,14 +58253,10 @@
},
/turf/open/floor/iron,
/area/station/maintenance/disposal/incinerator)
-"rSY" = (
-/obj/docking_port/stationary/random/icemoon{
- dir = 8;
- name = "lavaland";
- shuttle_id = "pod_2_lavaland"
- },
-/turf/open/misc/asteroid/snow/icemoon,
-/area/icemoon/surface/outdoors/unexplored/rivers/no_monsters)
+"rTs" = (
+/obj/machinery/atmospherics/pipe/layer_manifold/supply/hidden,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/aft)
"rTt" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -56469,15 +58265,6 @@
},
/turf/open/floor/iron,
/area/station/cargo/office)
-"rTD" = (
-/obj/machinery/door/airlock/external{
- name = "Escape Pod One"
- },
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
- dir = 8
- },
-/turf/open/floor/plating,
-/area/station/hallway/secondary/entry)
"rTO" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/turf_decal/tile/neutral/opposingcorners,
@@ -56501,6 +58288,16 @@
/obj/machinery/door/firedoor,
/turf/open/floor/iron,
/area/station/security/processing)
+"rUa" = (
+/obj/structure/cable/multilayer/multiz,
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/structure/sign/nanotrasen{
+ pixel_y = -32
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"rUb" = (
/obj/structure/railing,
/obj/machinery/flasher/portable,
@@ -56518,6 +58315,15 @@
},
/turf/open/floor/iron,
/area/station/command/bridge)
+"rUv" = (
+/obj/effect/turf_decal/tile/blue,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/firealarm/directional/east,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"rUz" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/decal/cleanable/dirt,
@@ -56581,6 +58387,16 @@
},
/turf/open/floor/iron/white,
/area/station/medical/treatment_center)
+"rVt" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/spawner/random/structure/table_or_rack,
+/obj/effect/spawner/random/engineering/toolbox,
+/obj/effect/spawner/random/engineering/toolbox,
+/obj/effect/turf_decal/siding/wood,
+/obj/effect/spawner/random/trash/janitor_supplies,
+/turf/open/floor/iron/grimy,
+/area/station/commons/vacant_room/office)
"rVA" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -56597,6 +58413,15 @@
},
/turf/open/floor/plating,
/area/station/maintenance/fore/lesser)
+"rVC" = (
+/obj/structure/table,
+/obj/item/storage/backpack{
+ pixel_x = 4;
+ pixel_y = 4
+ },
+/obj/item/storage/backpack,
+/turf/open/floor/plastic,
+/area/station/commons/dorms/laundry)
"rVO" = (
/obj/structure/reagent_dispensers/beerkeg,
/obj/item/stack/package_wrap{
@@ -56662,7 +58487,14 @@
/area/station/medical/storage)
"rWZ" = (
/obj/machinery/door/firedoor,
-/turf/open/floor/iron,
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 4
+ },
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 8
+ },
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron/dark/textured,
/area/station/hallway/primary/port)
"rXe" = (
/obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible{
@@ -56824,10 +58656,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/storage)
-"rZs" = (
-/obj/machinery/holopad,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"rZE" = (
/obj/machinery/atmospherics/components/binary/pump{
dir = 8
@@ -56882,16 +58710,10 @@
dir = 4
},
/area/station/service/chapel)
-"sbc" = (
-/obj/machinery/conveyor{
- id = "garbage"
- },
-/obj/machinery/door/poddoor/preopen{
- id = "Disposal Exit";
- name = "Disposal Exit Vent"
- },
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
+"sbd" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/iron/dark,
+/area/station/science/ordnance)
"sbf" = (
/obj/structure/sign/plaques/kiddie/devils_tooth{
pixel_y = 32
@@ -56903,6 +58725,15 @@
/obj/machinery/photocopier,
/turf/open/floor/iron,
/area/station/command/heads_quarters/hop)
+"sbv" = (
+/obj/structure/closet/secure_closet/personal{
+ anchored = 1
+ },
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/light/directional/south,
+/obj/structure/sign/clock/directional/south,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"sby" = (
/obj/effect/turf_decal/trimline/red/filled/line{
dir = 1
@@ -57030,26 +58861,6 @@
/obj/structure/sign/departments/cargo,
/turf/closed/wall/r_wall,
/area/mine/eva)
-"sde" = (
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
- dir = 1
- },
-/obj/machinery/door/airlock/external{
- name = "Port Docking Bay 1"
- },
-/obj/effect/landmark/navigate_destination{
- location = "Arrival Shuttle"
- },
-/turf/open/floor/plating,
-/area/station/hallway/secondary/entry)
-"sdi" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/structure/cable,
-/obj/structure/sign/poster/contraband/random/directional/south,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"sdk" = (
/obj/structure/extinguisher_cabinet/directional/west,
/obj/effect/turf_decal/tile/neutral/half/contrasted,
@@ -57146,6 +58957,11 @@
/obj/structure/cable,
/turf/open/floor/plating/snowed/smoothed/icemoon,
/area/icemoon/underground/explored)
+"sfr" = (
+/obj/machinery/holopad,
+/obj/effect/turf_decal/bot,
+/turf/open/floor/iron/large,
+/area/station/hallway/secondary/entry)
"sfv" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/general/visible,
@@ -57222,6 +59038,17 @@
},
/turf/open/floor/iron,
/area/station/hallway/secondary/exit/departure_lounge)
+"sgT" = (
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/obj/structure/railing/corner/end,
+/obj/effect/turf_decal/siding/thinplating/corner{
+ dir = 8
+ },
+/turf/open/floor/iron,
+/area/station/commons/locker)
"sgV" = (
/obj/effect/turf_decal/siding/brown/corner,
/obj/effect/turf_decal/trimline/brown/filled/line{
@@ -57297,8 +59124,18 @@
/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/command/hop,
+/obj/machinery/door/firedoor,
/turf/open/floor/wood,
/area/station/command/heads_quarters/hop)
+"shT" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/item/kirbyplants/random,
+/turf/open/floor/iron/cafeteria{
+ dir = 8
+ },
+/area/station/hallway/secondary/entry)
"sib" = (
/obj/effect/turf_decal/stripes/line{
dir = 8
@@ -57369,18 +59206,9 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/dark,
/area/mine/eva)
-"siX" = (
-/obj/structure/cable,
-/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/locker)
"sjb" = (
/turf/closed/wall/r_wall,
/area/station/cargo/drone_bay)
-"sjc" = (
-/turf/open/floor/iron,
-/area/station/construction/mining/aux_base)
"sjk" = (
/obj/machinery/atmospherics/pipe/smart/simple/green/visible{
dir = 6
@@ -57412,6 +59240,10 @@
/obj/effect/landmark/start/hangover,
/turf/open/floor/iron/freezer,
/area/station/commons/toilet)
+"sjU" = (
+/obj/structure/sign/warning/docking/directional/east,
+/turf/open/floor/plating/snowed/smoothed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"sjX" = (
/obj/effect/turf_decal/stripes/line{
dir = 8
@@ -57549,23 +59381,24 @@
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 10
},
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/white,
/area/station/medical/medbay/aft)
-"sle" = (
-/obj/structure/table,
-/obj/item/stack/sheet/plasteel{
- amount = 10
+"sll" = (
+/obj/machinery/door/firedoor,
+/obj/machinery/door/airlock/public/glass{
+ name = "Arrivals"
},
-/obj/item/stack/rods/fifty,
-/obj/machinery/power/apc/auto_name/directional/east,
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/yellow/half/contrasted{
+/obj/effect/turf_decal/stripes/white/line{
dir = 4
},
-/turf/open/floor/iron,
-/area/station/construction/mining/aux_base)
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 8
+ },
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron/dark/textured,
+/area/station/hallway/secondary/entry)
"slp" = (
/obj/structure/cable,
/obj/machinery/door/poddoor/preopen{
@@ -57575,14 +59408,6 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/station/science/xenobiology)
-"slv" = (
-/obj/structure/cable,
-/obj/effect/turf_decal/siding/green/corner{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron,
-/area/station/service/hydroponics/garden)
"slx" = (
/obj/structure/sign/warning/fire/directional/west,
/obj/machinery/atmospherics/components/unary/passive_vent/layer2{
@@ -57596,14 +59421,6 @@
/obj/effect/turf_decal/tile/yellow/opposingcorners,
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/project)
-"slI" = (
-/obj/structure/sign/warning/electric_shock/directional/north,
-/obj/effect/turf_decal/stripes/corner{
- dir = 1
- },
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
-/turf/open/floor/iron,
-/area/station/hallway/primary/port)
"slK" = (
/obj/machinery/atmospherics/components/unary/cryo_cell,
/obj/effect/turf_decal/stripes/line{
@@ -57612,6 +59429,12 @@
/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,
+/obj/machinery/door/poddoor/massdriver_trash,
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"smg" = (
/obj/structure/disposalpipe/segment{
dir = 10
@@ -57625,6 +59448,15 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/maintenance/solars/port/aft)
+"smn" = (
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/siding/thinplating_new/corner{
+ dir = 1
+ },
+/obj/item/kirbyplants/random,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"smw" = (
/obj/structure/closet/emcloset,
/obj/machinery/light/small/dim/directional/south,
@@ -57662,6 +59494,13 @@
},
/turf/open/floor/iron,
/area/station/command/bridge)
+"snd" = (
+/obj/effect/spawner/structure/window/hollow/reinforced/middle{
+ dir = 1
+ },
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"sng" = (
/obj/structure/table,
/obj/item/wrench,
@@ -57790,11 +59629,6 @@
/obj/machinery/light/small/directional/north,
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/hfr_room)
-"spf" = (
-/obj/machinery/vending/cigarette,
-/obj/machinery/status_display/evac/directional/north,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"spg" = (
/obj/structure/table,
/obj/item/storage/box/monkeycubes{
@@ -57849,6 +59683,22 @@
/obj/effect/spawner/random/structure/table_fancy,
/turf/open/floor/wood,
/area/station/service/library)
+"sqb" = (
+/obj/item/coin/iron{
+ pixel_y = -5
+ },
+/obj/item/coin/plasma{
+ pixel_y = -2;
+ pixel_x = 3
+ },
+/obj/item/toy/plush/lizard_plushie{
+ pixel_x = 11;
+ pixel_y = -4;
+ name = "Cassius"
+ },
+/obj/effect/decal/cleanable/dirt/dust,
+/turf/open/floor/plating,
+/area/station/commons/dorms/laundry)
"sqn" = (
/obj/machinery/computer/records/security{
dir = 1
@@ -57919,6 +59769,13 @@
/obj/structure/sign/warning/bodysposal/directional/north,
/turf/open/floor/iron/white,
/area/station/medical/surgery/fore)
+"sre" = (
+/obj/structure/cable,
+/obj/effect/turf_decal/siding/thinplating_new{
+ dir = 8
+ },
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
"srk" = (
/obj/machinery/door/window/right/directional/north{
dir = 8;
@@ -58004,14 +59861,11 @@
/obj/structure/sign/warning/secure_area,
/turf/closed/wall/r_wall,
/area/station/engineering/storage/tech)
-"ssB" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/yellow{
- dir = 1
- },
+"ssv" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/siding/thinplating_new/corner,
/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
+/area/station/commons/locker)
"ssF" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -58038,13 +59892,6 @@
/obj/item/radio/intercom/directional/north,
/turf/open/floor/iron/white,
/area/station/science/ordnance)
-"std" = (
-/obj/item/radio/intercom/directional/north,
-/obj/effect/turf_decal/stripes/line{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"sth" = (
/obj/item/radio/intercom/directional/east,
/obj/structure/disposalpipe/trunk{
@@ -58126,6 +59973,18 @@
/obj/structure/flora/grass/brown/style_random,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors/nospawn)
+"stL" = (
+/obj/structure/reagent_dispensers/watertank,
+/obj/structure/cable,
+/obj/machinery/power/apc/auto_name/directional/north,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
+"stP" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/spawner/random/structure/crate_abandoned,
+/obj/effect/turf_decal/siding/wood,
+/turf/open/floor/iron/grimy,
+/area/station/commons/vacant_room/office)
"stQ" = (
/obj/machinery/camera/directional/west{
c_tag = "Security Post - Science";
@@ -58309,13 +60168,6 @@
},
/turf/open/floor/iron,
/area/station/maintenance/disposal/incinerator)
-"swz" = (
-/obj/machinery/camera/directional/south{
- c_tag = "Locker Room West"
- },
-/obj/structure/cable,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"swF" = (
/turf/closed/wall,
/area/station/ai_monitored/turret_protected/aisat_interior)
@@ -58326,6 +60178,14 @@
},
/turf/open/floor/iron/white,
/area/station/medical/medbay/lobby)
+"swK" = (
+/obj/effect/turf_decal/tile/blue,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"swS" = (
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
@@ -58374,6 +60234,10 @@
},
/turf/open/floor/iron,
/area/station/maintenance/starboard/fore)
+"sxQ" = (
+/obj/structure/sign/warning/electric_shock/directional/east,
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"sxT" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/structure/cable,
@@ -58429,15 +60293,6 @@
},
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/underground/explored)
-"syy" = (
-/obj/machinery/portable_atmospherics/canister/air,
-/obj/machinery/atmospherics/components/unary/portables_connector/visible{
- dir = 4
- },
-/obj/effect/turf_decal/stripes/line,
-/obj/machinery/light/small/dim/directional/north,
-/turf/open/floor/iron,
-/area/station/maintenance/port/fore)
"syB" = (
/obj/effect/turf_decal/siding/red{
dir = 4
@@ -58451,6 +60306,15 @@
/obj/effect/turf_decal/trimline/blue/corner,
/turf/open/floor/iron/dark,
/area/station/service/hydroponics)
+"syL" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/structure/cable,
+/turf/open/floor/iron/white/corner{
+ dir = 8
+ },
+/area/station/hallway/secondary/entry)
"syT" = (
/obj/machinery/light/small/dim/directional/south,
/turf/open/floor/plating,
@@ -58509,6 +60373,10 @@
dir = 4
},
/area/station/engineering/lobby)
+"szX" = (
+/obj/effect/mapping_helpers/broken_floor,
+/turf/open/floor/plating,
+/area/station/commons/dorms/laundry)
"sAa" = (
/obj/structure/stairs/north,
/obj/structure/railing{
@@ -58564,15 +60432,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/pharmacy)
-"sAV" = (
-/obj/machinery/firealarm/directional/west,
-/obj/effect/turf_decal/stripes/line{
- dir = 8
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"sBi" = (
/obj/structure/cable,
/obj/effect/decal/cleanable/dirt,
@@ -58738,6 +60597,13 @@
/obj/machinery/airalarm/directional/north,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/central)
+"sEg" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 4
+ },
+/obj/structure/sign/poster/random/directional/west,
+/turf/open/floor/iron/large,
+/area/station/hallway/secondary/entry)
"sEi" = (
/turf/open/floor/carpet,
/area/station/service/library)
@@ -58761,10 +60627,6 @@
},
/turf/open/floor/plating,
/area/mine/living_quarters)
-"sEx" = (
-/obj/structure/closet/secure_closet/medical2,
-/turf/open/floor/iron,
-/area/station/maintenance/port/fore)
"sEz" = (
/obj/structure/disposalpipe/segment{
dir = 5
@@ -58831,18 +60693,6 @@
/obj/effect/turf_decal/tile/blue/full,
/turf/open/floor/iron/large,
/area/station/medical/treatment_center)
-"sEM" = (
-/obj/structure/table/wood,
-/obj/item/phone{
- pixel_x = -5;
- pixel_y = 6
- },
-/obj/item/reagent_containers/cup/glass/mug/britcup{
- pixel_x = 8;
- pixel_y = 8
- },
-/turf/open/floor/carpet/red,
-/area/station/commons/vacant_room/office)
"sEO" = (
/obj/machinery/light/floor,
/turf/open/floor/iron/smooth,
@@ -58860,6 +60710,20 @@
},
/turf/open/floor/iron/white/corner,
/area/station/engineering/atmos)
+"sFd" = (
+/obj/machinery/light/small/directional/north,
+/obj/effect/turf_decal/siding/blue{
+ dir = 8
+ },
+/obj/effect/turf_decal/tile/blue/opposingcorners{
+ dir = 1
+ },
+/obj/structure/closet/crate/trashcart/laundry,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/extinguisher_cabinet/directional/north,
+/turf/open/floor/iron/cafeteria,
+/area/station/commons/dorms/laundry)
"sFj" = (
/obj/structure/chair/office/light{
dir = 4
@@ -58938,6 +60802,17 @@
},
/turf/open/floor/iron,
/area/station/security/brig/upper)
+"sGq" = (
+/obj/effect/turf_decal/siding/wood{
+ dir = 1
+ },
+/obj/machinery/disposal/bin,
+/obj/structure/disposalpipe/trunk{
+ dir = 4
+ },
+/obj/machinery/status_display/evac/directional/west,
+/turf/open/floor/iron/dark,
+/area/station/service/hydroponics/garden)
"sGv" = (
/obj/structure/ladder,
/obj/machinery/light/small/directional/east,
@@ -58980,6 +60855,14 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/dark,
/area/station/engineering/supermatter/room)
+"sGM" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/light/small/directional/east,
+/obj/structure/sign/warning/directional/east,
+/turf/open/floor/catwalk_floor/iron_smooth,
+/area/station/maintenance/port/lesser)
"sGZ" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/spawner/random/structure/crate,
@@ -59027,6 +60910,15 @@
/obj/effect/spawner/random/structure/steam_vent,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/morgue)
+"sHK" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/spawner/random/structure/steam_vent,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"sHM" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -59036,6 +60928,20 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/plating,
/area/station/maintenance/starboard/upper)
+"sHO" = (
+/obj/machinery/atmospherics/components/unary/portables_connector/visible{
+ dir = 1
+ },
+/obj/effect/turf_decal/stripes/end,
+/obj/effect/turf_decal/tile/yellow/opposingcorners,
+/turf/open/floor/iron,
+/area/station/maintenance/port/fore)
+"sHV" = (
+/obj/machinery/atmospherics/components/tank/air{
+ initialize_directions = 2
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/aft)
"sHX" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -59282,6 +61188,17 @@
dir = 1
},
/area/station/medical/chemistry)
+"sLR" = (
+/obj/machinery/conveyor{
+ id = "garbage";
+ dir = 1
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/stripes/line{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"sMb" = (
/obj/structure/table,
/obj/effect/turf_decal/tile/neutral/diagonal_edge,
@@ -59344,6 +61261,7 @@
id = "hopflash";
pixel_y = -23
},
+/obj/machinery/door/firedoor,
/turf/open/floor/iron,
/area/station/command/heads_quarters/hop)
"sMY" = (
@@ -59356,6 +61274,21 @@
dir = 1
},
/area/station/security/office)
+"sNr" = (
+/obj/machinery/door/airlock/security/glass{
+ id_tag = "permainner";
+ name = "Permabrig Transfer"
+ },
+/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
+ cycle_id = "perma-entrance"
+ },
+/obj/machinery/door/firedoor,
+/obj/effect/turf_decal/siding/red/corner{
+ dir = 4
+ },
+/obj/effect/mapping_helpers/airlock/access/all/security/brig,
+/turf/open/floor/iron/dark/textured,
+/area/station/security/execution/transfer)
"sNs" = (
/obj/structure/closet/crate/hydroponics,
/obj/effect/turf_decal/trimline/green/filled,
@@ -59386,6 +61319,13 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
/area/station/engineering/atmos)
+"sNA" = (
+/obj/structure/sign/nanotrasen{
+ pixel_x = 32
+ },
+/obj/structure/marker_beacon/burgundy,
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"sNI" = (
/obj/effect/landmark/event_spawn,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -59421,13 +61361,6 @@
"sOn" = (
/turf/closed/wall,
/area/station/cargo/lobby)
-"sOo" = (
-/obj/effect/mapping_helpers/broken_floor,
-/obj/machinery/atmospherics/components/binary/pump/on/supply/hidden/layer4{
- dir = 8
- },
-/turf/open/floor/plating,
-/area/station/maintenance/aft/greater)
"sOz" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -59536,19 +61469,6 @@
/obj/effect/turf_decal/tile/purple/fourcorners,
/turf/open/floor/iron,
/area/mine/living_quarters)
-"sQm" = (
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
- dir = 1
- },
-/obj/machinery/door/airlock/external{
- name = "Port Docking Bay 3"
- },
-/turf/open/floor/plating,
-/area/station/hallway/secondary/entry)
-"sQx" = (
-/obj/effect/mapping_helpers/broken_floor,
-/turf/open/floor/iron/icemoon,
-/area/icemoon/surface/outdoors/nospawn)
"sQB" = (
/turf/closed/wall,
/area/station/security/brig/upper)
@@ -59662,6 +61582,11 @@
/obj/machinery/atmospherics/pipe/bridge_pipe/purple/visible,
/turf/open/floor/plating,
/area/station/engineering/atmos/pumproom)
+"sTh" = (
+/obj/structure/table,
+/obj/item/storage/toolbox/emergency,
+/turf/open/floor/plastic,
+/area/station/commons/dorms/laundry)
"sTi" = (
/obj/effect/turf_decal/box/white{
color = "#52B4E9"
@@ -60092,6 +62017,13 @@
/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plating,
/area/station/security/prison/safe)
+"tba" = (
+/obj/structure/cable,
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/pink,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"tbb" = (
/obj/machinery/meter,
/obj/machinery/atmospherics/pipe/smart/manifold/cyan/visible{
@@ -60113,14 +62045,34 @@
/obj/structure/flora/bush/sunny/style_random,
/turf/open/floor/grass,
/area/station/service/hydroponics)
-"tbx" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/machinery/atmospherics/components/unary/portables_connector/visible,
-/turf/open/floor/iron,
-/area/station/maintenance/port/fore)
+"tbN" = (
+/obj/effect/mapping_helpers/airlock/access/any/supply/maintenance,
+/obj/machinery/door/airlock/engineering{
+ name = "Utilities Room"
+ },
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/mapping_helpers/airlock/unres{
+ dir = 8
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"tbQ" = (
/turf/open/floor/iron/grimy,
/area/station/maintenance/aft/greater)
+"tbR" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 9
+ },
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/item/kirbyplants/random,
+/turf/open/floor/iron/cafeteria{
+ dir = 8
+ },
+/area/station/hallway/secondary/entry)
"tbX" = (
/obj/effect/spawner/structure/window/hollow/reinforced/middle{
dir = 4
@@ -60155,6 +62107,14 @@
},
/turf/open/floor/iron/dark/textured,
/area/station/security/prison/rec)
+"tcR" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/landmark/generic_maintenance_landmark,
+/obj/effect/turf_decal/tile/yellow{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/maintenance/port/fore)
"tda" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/tile/brown/half/contrasted{
@@ -60170,17 +62130,12 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron,
/area/station/hallway/primary/aft)
-"tdi" = (
-/obj/machinery/door/airlock/maintenance,
-/obj/structure/cable,
-/obj/effect/mapping_helpers/airlock/unres{
- dir = 4
- },
-/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
+"tdp" = (
+/obj/machinery/vending/cigarette,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/structure/sign/poster/official/random/directional/north,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"tdE" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/door/poddoor/shutters/preopen{
@@ -60204,10 +62159,6 @@
/obj/structure/cable,
/turf/open/floor/iron/dark,
/area/station/service/chapel)
-"tdY" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/closed/wall/r_wall,
-/area/station/science/ordnance/burnchamber)
"ted" = (
/obj/machinery/holopad,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -60229,6 +62180,15 @@
/obj/structure/fence,
/turf/open/floor/plating/snowed/smoothed/icemoon,
/area/icemoon/underground/explored)
+"teE" = (
+/obj/effect/spawner/structure/window,
+/obj/machinery/door/poddoor/shutters{
+ id = "vacantofficemaintshutter";
+ name = "Privacy Shutters";
+ dir = 8
+ },
+/turf/open/floor/plating,
+/area/station/commons/vacant_room/office)
"teN" = (
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
@@ -60300,6 +62260,9 @@
name = "Garden"
},
/obj/machinery/door/firedoor,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
/turf/open/floor/iron/dark,
/area/station/commons/storage/primary)
"tge" = (
@@ -60322,13 +62285,6 @@
/obj/structure/reagent_dispensers/watertank,
/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
-"tgu" = (
-/obj/effect/spawner/random/maintenance,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"tgw" = (
/obj/machinery/door/airlock/maintenance{
name = "Research Delivery Access"
@@ -60380,6 +62336,11 @@
/obj/machinery/airalarm/directional/north,
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
+"thE" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"thI" = (
/obj/machinery/camera/directional/south{
c_tag = "Fore Primary Hallway - Courtroom Hallway"
@@ -60411,6 +62372,21 @@
/obj/effect/spawner/random/trash/mess,
/turf/open/floor/wood,
/area/station/maintenance/port/aft)
+"thX" = (
+/obj/effect/turf_decal/tile/blue,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
+"thY" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"tia" = (
/obj/structure/table,
/obj/item/stack/sheet/glass/fifty{
@@ -60532,14 +62508,11 @@
/turf/open/floor/iron/dark/corner,
/area/station/engineering/atmos/storage/gas)
"tkc" = (
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
-/obj/effect/turf_decal/siding/wood{
- dir = 4
- },
-/obj/effect/turf_decal/siding/wood/corner{
- dir = 8
- },
-/turf/open/floor/wood,
+/obj/machinery/airalarm/directional/north,
+/obj/item/kirbyplants/random,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/iron/grimy,
/area/station/commons/vacant_room/office)
"tkf" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
@@ -60551,6 +62524,21 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/station/hallway/secondary/service)
+"tku" = (
+/obj/machinery/door/firedoor,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 8
+ },
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 4
+ },
+/obj/machinery/door/airlock/multi_tile/public/glass{
+ name = "Auxiliary Dock";
+ dir = 4
+ },
+/turf/open/floor/iron/dark/textured,
+/area/station/hallway/secondary/entry)
"tkP" = (
/obj/effect/turf_decal/stripes/line{
dir = 5
@@ -60580,6 +62568,12 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/engineering/storage_shared)
+"tlm" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/disposalpipe/segment,
+/obj/effect/spawner/random/structure/steam_vent,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"tln" = (
/obj/machinery/portable_atmospherics/canister/oxygen,
/turf/open/floor/engine/o2,
@@ -60617,6 +62611,14 @@
"tlH" = (
/turf/open/openspace/icemoon,
/area/icemoon/surface/outdoors/nospawn)
+"tlO" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/machinery/power/apc/auto_name/directional/east,
+/obj/structure/disposalpipe/segment,
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
"tlP" = (
/obj/effect/turf_decal/stripes/corner{
dir = 4
@@ -60640,15 +62642,15 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/dark/textured,
/area/station/security/prison/safe)
-"tmb" = (
-/obj/machinery/door/airlock/maintenance_hatch{
- name = "Ordnance Lab Maintenance"
+"tma" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/door/firedoor,
+/obj/effect/turf_decal/stripes/white/line,
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 1
},
-/obj/machinery/door/firedoor/heavy,
-/obj/effect/mapping_helpers/airlock/access/all/science/ordnance,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/plating,
-/area/station/science/ordnance)
+/turf/open/floor/iron/dark/textured,
+/area/station/hallway/secondary/entry)
"tml" = (
/obj/structure/grille,
/turf/open/floor/plating,
@@ -60681,6 +62683,19 @@
/obj/structure/extinguisher_cabinet/directional/south,
/turf/open/floor/iron/dark,
/area/mine/eva/lower)
+"tmL" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 4
+ },
+/obj/item/kirbyplants/random,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/machinery/status_display/evac/directional/north,
+/turf/open/floor/iron/white/corner{
+ dir = 1
+ },
+/area/station/hallway/secondary/entry)
"tmQ" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/door/poddoor/preopen{
@@ -60820,6 +62835,16 @@
/obj/machinery/light/directional/south,
/turf/open/floor/engine,
/area/station/engineering/supermatter/room)
+"tpG" = (
+/obj/machinery/door/firedoor,
+/obj/effect/landmark/navigate_destination,
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 1
+ },
+/obj/effect/turf_decal/stripes/white/line,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron/dark/textured,
+/area/station/commons/locker)
"tpH" = (
/turf/closed/wall,
/area/station/security/execution/education)
@@ -60910,6 +62935,14 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/dark,
/area/station/science/explab)
+"trc" = (
+/obj/machinery/conveyor{
+ dir = 4;
+ id = "garbage"
+ },
+/obj/effect/turf_decal/stripes/line,
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"trl" = (
/obj/effect/landmark/start/hangover,
/turf/open/floor/iron/white/smooth_large,
@@ -61134,6 +63167,18 @@
},
/turf/open/floor/iron/dark/corner,
/area/station/engineering/atmos)
+"tvm" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/machinery/newscaster/directional/north,
+/obj/machinery/light/directional/north,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"tvv" = (
/obj/machinery/door/airlock/command/glass{
name = "Research Director"
@@ -61207,6 +63252,12 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/engineering/engine_smes)
+"tww" = (
+/obj/effect/landmark/start/prisoner,
+/obj/effect/landmark/event_spawn,
+/obj/machinery/holopad,
+/turf/open/floor/carpet/red,
+/area/station/security/prison/work)
"twK" = (
/obj/machinery/porta_turret/ai{
dir = 8
@@ -61276,6 +63327,15 @@
/obj/effect/mapping_helpers/airlock/access/all/engineering/construction,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
+"txd" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/sign/warning/cold_temp/directional/west,
+/obj/machinery/light/small/directional/west,
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
"txe" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/decal/cleanable/dirt,
@@ -61284,15 +63344,6 @@
/obj/effect/turf_decal/tile/yellow/opposingcorners,
/turf/open/floor/iron/white,
/area/station/maintenance/port/fore)
-"txh" = (
-/obj/structure/cable,
-/obj/machinery/door/airlock/maintenance{
- name = "Locker Room Maintenance"
- },
-/obj/effect/mapping_helpers/airlock/unres,
-/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"txj" = (
/obj/effect/turf_decal/trimline/yellow/filled/line{
dir = 8
@@ -61304,10 +63355,6 @@
/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/medical/chemistry)
-"txk" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/closed/wall/r_wall,
-/area/station/maintenance/starboard/aft)
"txo" = (
/obj/effect/turf_decal/siding/yellow/end{
dir = 4
@@ -61422,6 +63469,15 @@
},
/turf/open/floor/iron,
/area/station/engineering/main)
+"tzM" = (
+/obj/structure/filingcabinet,
+/obj/effect/turf_decal/siding/wood{
+ dir = 4
+ },
+/obj/machinery/newscaster/directional/west,
+/obj/machinery/light/small/directional/west,
+/turf/open/floor/wood,
+/area/station/commons/vacant_room/office)
"tAe" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -61470,15 +63526,11 @@
},
/turf/open/floor/iron/white,
/area/mine/laborcamp)
-"tAR" = (
-/obj/machinery/camera/directional/south{
- c_tag = "Port Hallway West"
- },
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/hallway/primary/port)
+"tAO" = (
+/obj/machinery/space_heater,
+/obj/effect/mapping_helpers/burnt_floor,
+/turf/open/floor/iron/smooth,
+/area/station/maintenance/port/lesser)
"tAS" = (
/obj/machinery/door/airlock/mining/glass{
name = "Mining Dock"
@@ -61545,15 +63597,6 @@
/obj/structure/sign/warning,
/turf/closed/wall/r_wall,
/area/icemoon/surface/outdoors/nospawn)
-"tCn" = (
-/obj/structure/closet/secure_closet/security,
-/obj/machinery/power/apc/auto_name/directional/north,
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/red/anticorner/contrasted{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/security/checkpoint/customs/auxiliary)
"tCr" = (
/obj/structure/grille,
/turf/open/misc/asteroid/snow/icemoon,
@@ -61694,12 +63737,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
-"tDG" = (
-/obj/effect/turf_decal/tile/blue/opposingcorners{
- dir = 1
- },
-/turf/open/floor/iron/cafeteria,
-/area/station/commons/dorms/laundry)
"tDL" = (
/obj/structure/cable,
/obj/effect/turf_decal/tile/red/anticorner/contrasted{
@@ -61725,6 +63762,13 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/security/prison/visit)
+"tEc" = (
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
"tEd" = (
/obj/machinery/power/apc/auto_name/directional/south,
/obj/structure/cable,
@@ -61741,6 +63785,10 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/carpet,
/area/station/service/theater)
+"tEi" = (
+/obj/structure/sink/directional/south,
+/turf/open/floor/iron,
+/area/station/maintenance/port/fore)
"tEj" = (
/obj/machinery/conveyor{
dir = 9;
@@ -61768,10 +63816,6 @@
/obj/structure/ore_box,
/turf/open/floor/plating/snowed/smoothed/icemoon,
/area/icemoon/underground/explored)
-"tEG" = (
-/obj/effect/turf_decal/stripes/line,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"tEK" = (
/obj/structure/table,
/obj/item/tank/internals/emergency_oxygen{
@@ -61949,6 +63993,16 @@
/obj/effect/turf_decal/trimline/blue/filled/warning,
/turf/open/floor/iron/white,
/area/station/medical/treatment_center)
+"tHB" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/structure/sign/warning/pods/directional/west,
+/obj/structure/cable,
+/turf/open/floor/iron/white/corner{
+ dir = 8
+ },
+/area/station/hallway/secondary/entry)
"tHK" = (
/obj/structure/window/reinforced/spawner/directional/west,
/obj/structure/railing{
@@ -61984,6 +64038,22 @@
},
/turf/open/floor/iron/dark,
/area/station/science/ordnance/office)
+"tHX" = (
+/obj/structure/railing{
+ dir = 6
+ },
+/obj/effect/decal/cleanable/generic,
+/obj/effect/turf_decal/tile/brown/anticorner/contrasted,
+/obj/structure/cable,
+/turf/open/floor/iron/dark,
+/area/station/maintenance/disposal)
+"tIc" = (
+/obj/structure/sign/warning/electric_shock/directional/south,
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 1
+ },
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"tIf" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -62057,6 +64127,10 @@
},
/turf/open/floor/iron/dark,
/area/station/service/chapel)
+"tJu" = (
+/obj/machinery/status_display/ai/directional/south,
+/turf/open/floor/iron,
+/area/station/hallway/primary/port)
"tJv" = (
/obj/machinery/portable_atmospherics/scrubber,
/obj/effect/turf_decal/stripes/line{
@@ -62139,6 +64213,15 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/engineering/lobby)
+"tKq" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/turf/open/floor/catwalk_floor/iron_smooth,
+/area/station/maintenance/port/lesser)
"tKz" = (
/obj/structure/closet/wardrobe/mixed,
/turf/open/floor/plating,
@@ -62196,6 +64279,10 @@
/obj/structure/flora/bush/sparsegrass/style_random,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors/nospawn)
+"tLj" = (
+/obj/structure/flora/rock/pile/style_random,
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/underground/explored)
"tLp" = (
/obj/machinery/computer/records/medical{
dir = 4
@@ -62203,6 +64290,13 @@
/obj/effect/turf_decal/tile/blue/full,
/turf/open/floor/iron/dark/smooth_large,
/area/station/command/heads_quarters/cmo)
+"tLB" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/pink/visible,
+/obj/effect/turf_decal/tile/yellow{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/maintenance/port/fore)
"tLF" = (
/turf/closed/wall,
/area/station/hallway/primary/starboard)
@@ -62234,6 +64328,12 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/engine,
/area/station/engineering/supermatter)
+"tMa" = (
+/obj/structure/sign/nanotrasen{
+ pixel_y = 32
+ },
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"tMe" = (
/obj/machinery/computer/mechpad{
dir = 1
@@ -62276,6 +64376,18 @@
/obj/effect/spawner/random/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
+"tNd" = (
+/obj/effect/spawner/random/engineering/tracking_beacon,
+/obj/effect/turf_decal/siding/green{
+ dir = 1
+ },
+/obj/effect/landmark/event_spawn,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/service/hydroponics/garden)
"tNi" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 4
@@ -62400,12 +64512,6 @@
/obj/item/trash/energybar,
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
-"tPg" = (
-/obj/structure/table/wood,
-/obj/item/food/chips,
-/obj/item/reagent_containers/cup/soda_cans/cola,
-/turf/open/floor/carpet,
-/area/station/hallway/secondary/entry)
"tPz" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/white/side{
@@ -62472,6 +64578,14 @@
/obj/machinery/power/apc/auto_name/directional/east,
/turf/open/floor/plating,
/area/station/ai_monitored/turret_protected/aisat/maint)
+"tQS" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/landmark/start/assistant,
+/obj/structure/chair/stool/directional/west,
+/obj/machinery/status_display/ai/directional/east,
+/obj/machinery/light/directional/east,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"tQW" = (
/obj/item/kirbyplants/organic/plant5,
/turf/open/floor/iron/dark,
@@ -62536,6 +64650,16 @@
},
/turf/open/floor/iron/dark,
/area/station/service/chapel)
+"tTc" = (
+/obj/item/storage/bag/plants/portaseeder,
+/obj/structure/table/glass,
+/obj/item/plant_analyzer,
+/obj/effect/turf_decal/tile/green/half/contrasted{
+ dir = 8
+ },
+/obj/machinery/light/directional/east,
+/turf/open/floor/iron/dark,
+/area/station/service/hydroponics/garden)
"tTw" = (
/obj/structure/stairs/east,
/obj/structure/railing,
@@ -62660,13 +64784,6 @@
/obj/machinery/power/apc/auto_name/directional/north,
/turf/open/floor/iron/dark,
/area/station/science/server)
-"tVz" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/red/half/contrasted,
-/turf/open/floor/iron,
-/area/station/security/checkpoint/customs/auxiliary)
"tVA" = (
/obj/effect/turf_decal/bot,
/obj/structure/closet/radiation,
@@ -62786,26 +64903,11 @@
},
/turf/open/floor/iron/white,
/area/station/science/robotics/lab)
-"tXn" = (
-/obj/machinery/light/directional/north,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/turf_decal/tile/blue{
- dir = 4
- },
-/turf/open/floor/iron/white/corner{
- dir = 1
- },
-/area/station/hallway/secondary/entry)
-"tXw" = (
-/obj/machinery/conveyor{
- dir = 10;
- id = "garbage"
- },
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
+"tXs" = (
+/obj/structure/ladder,
+/obj/machinery/light/small/red/directional/west,
+/turf/open/floor/iron/smooth,
+/area/station/maintenance/port/greater)
"tXB" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -62824,12 +64926,6 @@
},
/turf/open/floor/iron/dark,
/area/station/service/chapel)
-"tXW" = (
-/obj/structure/cable,
-/obj/item/radio/intercom/directional/east,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"tXY" = (
/obj/structure/rack,
/obj/item/storage/toolbox/electrical{
@@ -62960,6 +65056,15 @@
},
/turf/open/floor/stone,
/area/station/commons/lounge)
+"uah" = (
+/obj/machinery/light_switch/directional/west,
+/obj/structure/cable,
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/turf_decal/tile/brown/half/contrasted{
+ dir = 8
+ },
+/turf/open/floor/iron/dark,
+/area/station/maintenance/disposal)
"uan" = (
/obj/structure/disposalpipe/trunk/multiz,
/obj/effect/turf_decal/stripes/line,
@@ -62989,7 +65094,6 @@
/area/station/engineering/storage)
"uaI" = (
/obj/structure/closet/secure_closet/brig,
-/obj/machinery/airalarm/directional/north,
/turf/open/floor/iron/smooth,
/area/station/security/execution/transfer)
"uaT" = (
@@ -63039,6 +65143,16 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/iron/white,
/area/station/medical/storage)
+"ubx" = (
+/obj/effect/turf_decal/tile/blue,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/light/directional/east,
+/obj/item/radio/intercom/directional/east,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"ubE" = (
/obj/machinery/atmospherics/pipe/multiz/scrubbers/visible/layer2{
dir = 1
@@ -63052,13 +65166,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/purple/visible,
/turf/open/floor/iron,
/area/station/engineering/atmos)
-"ubG" = (
-/obj/structure/reagent_dispensers/fueltank,
-/obj/effect/turf_decal/tile/yellow/anticorner/contrasted{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/construction/mining/aux_base)
"ubH" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -63101,6 +65208,12 @@
},
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors/nospawn)
+"ucs" = (
+/obj/effect/spawner/random/structure/grille,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"ucD" = (
/obj/machinery/plate_press,
/obj/structure/window/reinforced/spawner/directional/west,
@@ -63113,24 +65226,6 @@
/obj/structure/sign/warning/electric_shock,
/turf/closed/wall/r_wall,
/area/station/engineering/supermatter)
-"udc" = (
-/obj/structure/cable/multilayer/multiz,
-/obj/machinery/light/small/dim/directional/west,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
-"udd" = (
-/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/structure/closet/crate/trashcart/laundry,
-/obj/effect/turf_decal/tile/blue/opposingcorners{
- dir = 1
- },
-/turf/open/floor/iron/cafeteria,
-/area/station/commons/dorms/laundry)
"udj" = (
/obj/effect/turf_decal/stripes/asteroid/line,
/obj/structure/cable,
@@ -63252,12 +65347,6 @@
/obj/effect/landmark/start/hangover,
/turf/open/floor/iron,
/area/station/hallway/primary/central)
-"ufy" = (
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/cable,
-/turf/open/floor/iron/large,
-/area/station/security/checkpoint/customs/auxiliary)
"ufF" = (
/obj/structure/table,
/obj/item/storage/box/prisoner{
@@ -63343,6 +65432,14 @@
/obj/structure/cable,
/turf/open/floor/iron/showroomfloor,
/area/station/engineering/atmos)
+"uhb" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/turf_decal/tile/brown{
+ dir = 4
+ },
+/obj/structure/cable,
+/turf/open/floor/iron/dark,
+/area/station/maintenance/disposal)
"uhk" = (
/obj/structure/beebox,
/turf/open/floor/grass,
@@ -63387,6 +65484,13 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/station/hallway/secondary/entry)
+"uhA" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 1
+ },
+/obj/effect/landmark/navigate_destination/dockaux,
+/turf/open/floor/iron/large,
+/area/station/hallway/secondary/entry)
"uhE" = (
/obj/effect/turf_decal/stripes/asteroid/line{
dir = 9
@@ -63500,18 +65604,18 @@
},
/turf/open/floor/iron/dark,
/area/station/security/checkpoint/science)
+"ukd" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/spawner/random/trash/cigbutt,
+/obj/effect/spawner/random/trash/cigbutt,
+/obj/effect/spawner/random/trash/cigbutt,
+/obj/effect/decal/cleanable/plastic,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"ukf" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/general/visible,
/turf/open/floor/iron/dark,
/area/station/science/explab)
-"ukn" = (
-/obj/structure/sign/warning/electric_shock/directional/north,
-/obj/effect/turf_decal/stripes/corner{
- dir = 4
- },
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
-/turf/open/floor/iron,
-/area/station/hallway/primary/port)
"uko" = (
/obj/structure/chair/pew/left{
dir = 1
@@ -63559,16 +65663,11 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/cafeteria,
/area/station/maintenance/port/aft)
-"ukJ" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/turf_decal/stripes/corner{
+"ukD" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
},
-/obj/effect/turf_decal/stripes/corner{
- dir = 8
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
+/turf/open/floor/iron/grimy,
/area/station/hallway/secondary/entry)
"ukN" = (
/obj/structure/table,
@@ -63581,14 +65680,6 @@
/obj/machinery/door/window/left/directional/south,
/turf/open/floor/iron,
/area/station/security/prison/visit)
-"ukR" = (
-/obj/machinery/recharger{
- pixel_y = 4
- },
-/obj/structure/table,
-/obj/effect/turf_decal/tile/red/half/contrasted,
-/turf/open/floor/iron,
-/area/station/security/checkpoint/customs/auxiliary)
"ukV" = (
/obj/structure/closet/crate/freezer,
/obj/item/reagent_containers/blood/random,
@@ -63648,6 +65739,10 @@
/obj/item/storage/crayons,
/turf/open/floor/sepia,
/area/station/security/prison/rec)
+"umb" = (
+/obj/structure/sign/warning/docking/directional/south,
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"umv" = (
/obj/effect/turf_decal/siding/white{
dir = 9
@@ -63805,6 +65900,13 @@
},
/turf/open/floor/iron/textured,
/area/station/engineering/atmos)
+"uoz" = (
+/obj/machinery/door/airlock/multi_tile/public/glass{
+ name = "Hydroponics"
+ },
+/obj/effect/mapping_helpers/airlock/access/all/service/hydroponics,
+/turf/open/floor/iron/textured_half,
+/area/station/service/hydroponics)
"uoB" = (
/obj/structure/disposalpipe/junction/yjunction{
dir = 1
@@ -64027,12 +66129,6 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/white,
/area/station/science/research)
-"usm" = (
-/obj/structure/table,
-/obj/item/storage/medkit/regular,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"uso" = (
/obj/structure/closet/crate/trashcart,
/obj/effect/spawner/random/contraband/prison,
@@ -64100,6 +66196,10 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible,
/turf/open/floor/engine,
/area/station/engineering/supermatter/room)
+"utN" = (
+/obj/machinery/firealarm/directional/east,
+/turf/open/floor/wood,
+/area/station/command/meeting_room)
"utR" = (
/obj/effect/turf_decal/tile/blue{
dir = 8
@@ -64299,12 +66399,6 @@
},
/turf/open/floor/iron/white,
/area/station/science/research)
-"uxF" = (
-/obj/machinery/atmospherics/pipe/smart/simple/dark/visible,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/brown/visible/layer2,
-/obj/machinery/air_sensor/incinerator_tank,
-/turf/open/floor/engine/vacuum,
-/area/station/maintenance/disposal/incinerator)
"uxK" = (
/obj/machinery/light/small/directional/east,
/turf/open/floor/engine/vacuum,
@@ -64323,6 +66417,12 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/smooth,
/area/mine/eva/lower)
+"uyx" = (
+/obj/effect/spawner/random/structure/chair_maintenance,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/spawner/random/engineering/flashlight,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"uyH" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/mapping_helpers/broken_floor,
@@ -64351,6 +66451,16 @@
},
/turf/open/floor/plating/icemoon,
/area/station/science/ordnance/bomb)
+"uyW" = (
+/obj/machinery/washing_machine,
+/obj/effect/turf_decal/siding/blue{
+ dir = 8
+ },
+/obj/effect/turf_decal/tile/neutral/opposingcorners{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/commons/dorms/laundry)
"uzc" = (
/obj/effect/decal/cleanable/food/flour,
/obj/effect/turf_decal/tile/bar/opposingcorners,
@@ -64487,10 +66597,36 @@
"uBA" = (
/turf/closed/wall,
/area/station/engineering/atmos/project)
+"uBL" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/sign/poster/official/random/directional/east,
+/obj/structure/cable,
+/turf/open/floor/iron/cafeteria{
+ dir = 5
+ },
+/area/station/hallway/secondary/entry)
"uBP" = (
/obj/effect/decal/cleanable/glass,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/morgue)
+"uBX" = (
+/obj/machinery/atmospherics/components/unary/portables_connector/visible{
+ dir = 8
+ },
+/obj/effect/turf_decal/stripes/line,
+/obj/effect/turf_decal/tile/yellow{
+ dir = 1
+ },
+/obj/structure/closet/cardboard,
+/obj/effect/turf_decal/tile/yellow,
+/turf/open/floor/iron/dark/corner{
+ dir = 4
+ },
+/area/station/maintenance/port/fore)
"uCe" = (
/obj/effect/turf_decal/trimline/green/filled/corner{
dir = 1
@@ -64575,6 +66711,12 @@
/obj/machinery/door/window/left/directional/south,
/turf/open/floor/plating/icemoon,
/area/station/security/execution/education)
+"uDc" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/pink,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"uDi" = (
/obj/structure/closet/emcloset/anchored,
/obj/machinery/light/small/directional/west,
@@ -64659,11 +66801,6 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on,
/turf/open/floor/iron/white,
/area/station/medical/virology)
-"uDR" = (
-/obj/effect/turf_decal/stripes/corner,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"uDV" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -64822,10 +66959,6 @@
},
/turf/open/floor/iron,
/area/station/engineering/atmos)
-"uGG" = (
-/obj/effect/spawner/structure/window,
-/turf/open/floor/plating,
-/area/station/hallway/secondary/entry)
"uGT" = (
/obj/machinery/light/directional/east,
/obj/item/radio/intercom/directional/east,
@@ -64847,16 +66980,6 @@
},
/turf/open/floor/iron/white,
/area/station/science/xenobiology)
-"uHi" = (
-/obj/machinery/door/airlock/external{
- name = "Escape Pod One";
- space_dir = 8
- },
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
- dir = 4
- },
-/turf/open/floor/plating,
-/area/station/hallway/secondary/entry)
"uHv" = (
/obj/structure/chair/stool/directional/north,
/obj/structure/cable,
@@ -64973,10 +67096,6 @@
/obj/machinery/holopad,
/turf/open/floor/iron/dark,
/area/station/service/chapel)
-"uJs" = (
-/obj/structure/closet/bombcloset,
-/turf/open/floor/plating,
-/area/station/maintenance/starboard/aft)
"uJt" = (
/turf/open/floor/carpet,
/area/station/service/chapel)
@@ -65000,11 +67119,6 @@
/obj/effect/turf_decal/tile/red/half,
/turf/open/floor/iron/smooth_half,
/area/station/security/brig/upper)
-"uJZ" = (
-/obj/machinery/door/firedoor,
-/obj/effect/turf_decal/tile/neutral,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"uKj" = (
/obj/machinery/portable_atmospherics/canister/anesthetic_mix,
/obj/machinery/atmospherics/components/unary/portables_connector/visible{
@@ -65050,6 +67164,9 @@
/obj/effect/turf_decal/tile/neutral/full,
/turf/open/floor/iron/dark/smooth_large,
/area/station/command/heads_quarters/ce)
+"uKO" = (
+/turf/open/floor/glass,
+/area/station/commons/locker)
"uKP" = (
/obj/structure/table/wood,
/obj/item/radio{
@@ -65132,6 +67249,11 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/dark/textured,
/area/station/commons/storage/emergency/port)
+"uMm" = (
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"uMq" = (
/obj/structure/sign/warning/cold_temp{
pixel_x = -29
@@ -65146,6 +67268,15 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/station/hallway/primary/starboard)
+"uMD" = (
+/obj/machinery/conveyor{
+ dir = 4;
+ id = "garbage"
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/stripes/line,
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"uME" = (
/turf/closed/wall/r_wall,
/area/station/security/execution/transfer)
@@ -65182,10 +67313,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/white,
/area/station/medical/treatment_center)
-"uNt" = (
-/obj/structure/sign/poster/contraband/random/directional/north,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"uNu" = (
/obj/effect/turf_decal/siding/yellow/corner{
dir = 8
@@ -65197,9 +67324,7 @@
/area/station/engineering/storage)
"uNw" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/components/tank/air{
- dir = 4
- },
+/obj/item/trash/raisins,
/turf/open/floor/plating,
/area/station/maintenance/aft/greater)
"uNA" = (
@@ -65217,6 +67342,14 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/circuit,
/area/station/ai_monitored/turret_protected/aisat/hallway)
+"uNV" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/turf_decal/siding/wideplating/dark{
+ dir = 4
+ },
+/obj/machinery/holopad,
+/turf/open/floor/iron/dark/textured,
+/area/station/security/prison/rec)
"uNX" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -65366,6 +67499,15 @@
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/iron/smooth,
/area/station/maintenance/fore/lesser)
+"uPB" = (
+/obj/structure/table/wood,
+/obj/machinery/recharger,
+/obj/item/coin/plasma{
+ pixel_x = -6;
+ pixel_y = 13
+ },
+/turf/open/floor/wood,
+/area/station/command/heads_quarters/captain)
"uPE" = (
/obj/effect/turf_decal/trimline/neutral/warning{
dir = 8
@@ -65389,20 +67531,15 @@
/obj/structure/noticeboard/directional/east,
/turf/open/floor/wood,
/area/station/command/meeting_room)
-"uPZ" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/turf_decal/tile/blue{
- dir = 4
- },
-/turf/open/floor/iron/white/corner{
- dir = 1
- },
-/area/station/hallway/secondary/entry)
"uQl" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/mine/production)
+"uQu" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"uQx" = (
/obj/effect/spawner/structure/window,
/turf/open/floor/plating,
@@ -65416,20 +67553,6 @@
/obj/effect/turf_decal/tile/red,
/turf/open/floor/iron/textured,
/area/station/security/brig)
-"uQL" = (
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/blue{
- dir = 4
- },
-/turf/open/floor/iron/white/corner,
-/area/station/hallway/secondary/entry)
-"uQS" = (
-/obj/effect/mapping_helpers/airlock/cyclelink_helper,
-/obj/machinery/door/airlock/external{
- name = "Port Docking Bay 4"
- },
-/turf/open/floor/plating,
-/area/station/hallway/secondary/entry)
"uQV" = (
/obj/machinery/power/apc/auto_name/directional/north,
/obj/structure/cable,
@@ -65473,6 +67596,16 @@
},
/turf/open/floor/iron/dark/textured,
/area/station/security/prison)
+"uRx" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/structure/sign/poster/official/wtf_is_co2/directional/north,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"uRz" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -65573,6 +67706,17 @@
/obj/effect/spawner/random/structure/steam_vent,
/turf/open/floor/plating,
/area/station/maintenance/department/cargo)
+"uTI" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/turf/open/floor/iron/white/corner{
+ dir = 1
+ },
+/area/station/hallway/secondary/entry)
"uTL" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -65596,6 +67740,17 @@
/obj/effect/decal/cleanable/blood/old,
/turf/open/floor/engine,
/area/station/science/xenobiology)
+"uUu" = (
+/obj/structure/sign/nanotrasen{
+ pixel_x = -32
+ },
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/turf/open/floor/iron/white/corner{
+ dir = 1
+ },
+/area/station/hallway/secondary/entry)
"uUH" = (
/obj/machinery/atmospherics/pipe/smart/simple/dark/visible/layer1{
dir = 10
@@ -65611,13 +67766,6 @@
},
/turf/open/floor/wood/parquet,
/area/station/service/bar/atrium)
-"uVf" = (
-/obj/effect/turf_decal/stripes/corner,
-/obj/effect/turf_decal/stripes/corner{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"uVj" = (
/obj/effect/turf_decal/arrows/white,
/obj/effect/turf_decal/stripes/line{
@@ -65687,27 +67835,6 @@
},
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/underground/explored)
-"uWD" = (
-/obj/machinery/disposal/delivery_chute{
- dir = 4
- },
-/obj/structure/window/reinforced/spawner/directional/south,
-/obj/structure/window/reinforced/spawner/directional/west,
-/obj/structure/window/reinforced/spawner/directional/north,
-/obj/machinery/door/window{
- base_state = "right";
- dir = 4;
- icon_state = "right";
- layer = 3
- },
-/obj/effect/turf_decal/stripes/line{
- dir = 4
- },
-/obj/structure/disposalpipe/trunk{
- dir = 1
- },
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"uWE" = (
/obj/machinery/light/small/directional/south,
/turf/open/floor/plating/snowed/smoothed/icemoon,
@@ -65785,16 +67912,6 @@
/obj/machinery/light/directional/west,
/turf/open/floor/iron/dark/textured,
/area/station/security/office)
-"uXY" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/blue{
- dir = 4
- },
-/turf/open/floor/iron/white/corner{
- dir = 1
- },
-/area/station/hallway/secondary/entry)
"uYj" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -65869,6 +67986,21 @@
/obj/effect/spawner/random/maintenance/two,
/turf/open/floor/iron/smooth,
/area/station/maintenance/starboard/fore)
+"uZT" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 4
+ },
+/obj/structure/railing/corner/end{
+ dir = 8
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/landmark/event_spawn,
+/obj/structure/cable,
+/turf/open/floor/iron/white/corner{
+ dir = 1
+ },
+/area/station/hallway/secondary/entry)
"vaa" = (
/obj/effect/turf_decal/stripes/line,
/obj/effect/turf_decal/stripes/line{
@@ -65878,6 +68010,19 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/white,
/area/station/science/ordnance/office)
+"vad" = (
+/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 = 10
+ },
+/obj/effect/turf_decal/tile/neutral/opposingcorners{
+ dir = 1
+ },
+/obj/structure/sign/poster/contraband/random/directional/north,
+/turf/open/floor/iron,
+/area/station/commons/dorms/laundry)
"vah" = (
/obj/machinery/door/airlock/maintenance,
/obj/structure/barricade/wooden,
@@ -65984,12 +68129,6 @@
},
/turf/open/floor/iron/smooth,
/area/mine/laborcamp/security)
-"vbj" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 5
- },
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"vbn" = (
/obj/machinery/power/smes{
charge = 5e+006
@@ -66048,6 +68187,14 @@
/obj/effect/spawner/random/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
+"vcc" = (
+/obj/structure/table/optable{
+ name = "Robotics Operating Table"
+ },
+/obj/effect/decal/cleanable/blood/old,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/iron,
+/area/station/maintenance/port/fore)
"vcj" = (
/turf/closed/wall/r_wall,
/area/mine/storage)
@@ -66061,15 +68208,6 @@
/obj/structure/window/reinforced/spawner/directional/north,
/turf/open/floor/iron/dark,
/area/station/commons/fitness)
-"vcx" = (
-/obj/machinery/door/airlock/maintenance,
-/obj/effect/mapping_helpers/airlock/abandoned,
-/obj/effect/mapping_helpers/airlock/unres{
- dir = 4
- },
-/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"vcH" = (
/obj/machinery/atmospherics/pipe/smart/simple/dark/visible{
dir = 9
@@ -66311,6 +68449,14 @@
/obj/structure/grille,
/turf/open/floor/plating,
/area/station/science/xenobiology)
+"vgj" = (
+/obj/structure/filingcabinet,
+/obj/effect/turf_decal/siding/wood{
+ dir = 4
+ },
+/obj/structure/sign/poster/contraband/random/directional/west,
+/turf/open/floor/wood,
+/area/station/commons/vacant_room/office)
"vgu" = (
/obj/structure/table,
/obj/item/toy/plush/beeplushie{
@@ -66402,28 +68548,6 @@
},
/turf/open/floor/iron,
/area/station/maintenance/disposal/incinerator)
-"vhX" = (
-/obj/structure/rack,
-/obj/item/electronics/airlock,
-/obj/item/electronics/airlock,
-/obj/item/electronics/airlock,
-/obj/item/electronics/airlock,
-/obj/item/stack/cable_coil,
-/obj/item/stack/cable_coil,
-/obj/item/wallframe/camera,
-/obj/item/wallframe/camera,
-/obj/item/wallframe/camera,
-/obj/item/wallframe/camera,
-/obj/item/assault_pod/mining,
-/obj/machinery/computer/security/telescreen/auxbase{
- dir = 8;
- pixel_x = 30
- },
-/obj/effect/turf_decal/tile/yellow/half/contrasted{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/construction/mining/aux_base)
"via" = (
/turf/open/floor/iron/white/side{
dir = 6
@@ -66436,11 +68560,6 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/engineering/supermatter/room)
-"viP" = (
-/obj/machinery/door/firedoor,
-/obj/machinery/status_display/evac/directional/east,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"viQ" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -66466,13 +68585,6 @@
"vjh" = (
/turf/closed/wall/r_wall,
/area/mine/laborcamp)
-"vji" = (
-/obj/effect/turf_decal/tile/blue/opposingcorners{
- dir = 1
- },
-/obj/machinery/light/directional/east,
-/turf/open/floor/iron/cafeteria,
-/area/station/commons/dorms/laundry)
"vjj" = (
/obj/effect/spawner/structure/window,
/obj/machinery/door/poddoor/shutters/preopen{
@@ -66517,22 +68629,6 @@
/obj/effect/turf_decal/trimline/blue/filled/warning,
/turf/open/floor/iron/dark,
/area/station/service/hydroponics)
-"vky" = (
-/obj/machinery/computer/pod/old/mass_driver_controller/trash{
- pixel_x = -24;
- pixel_y = -6
- },
-/obj/machinery/button/door/directional/west{
- id = "Disposal Exit";
- name = "Disposal Vent Control";
- pixel_y = 4;
- req_access = list("maint_tunnels")
- },
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
- dir = 1
- },
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"vkz" = (
/obj/machinery/suit_storage_unit/ce,
/obj/effect/turf_decal/stripes/line{
@@ -66607,12 +68703,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central)
-"vlh" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/disposalpipe/segment,
-/turf/open/floor/iron,
-/area/station/service/hydroponics/garden)
"vlq" = (
/obj/effect/turf_decal/siding/white{
dir = 8
@@ -66714,6 +68804,17 @@
},
/turf/open/floor/engine,
/area/station/engineering/atmos/hfr_room)
+"vmx" = (
+/obj/machinery/door/airlock/maintenance,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/mapping_helpers/airlock/unres{
+ dir = 1
+ },
+/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"vmA" = (
/obj/structure/fluff/tram_rail{
pixel_y = 17
@@ -66721,6 +68822,16 @@
/obj/structure/fluff/tram_rail,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/underground/explored)
+"vmC" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 4
+ },
+/obj/machinery/camera/directional/west{
+ c_tag = "Arrivals Hallway North"
+ },
+/obj/structure/cable,
+/turf/open/floor/iron/large,
+/area/station/hallway/secondary/entry)
"vmP" = (
/obj/effect/spawner/structure/window/hollow/reinforced/end,
/turf/open/floor/plating,
@@ -66896,12 +69007,6 @@
/obj/structure/sign/warning/gas_mask/directional/west,
/turf/open/floor/iron,
/area/station/cargo/drone_bay)
-"vpx" = (
-/obj/effect/turf_decal/tile/yellow/half/contrasted{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/construction/mining/aux_base)
"vpR" = (
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/dark,
@@ -66928,12 +69033,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/command/heads_quarters/ce)
-"vqg" = (
-/obj/effect/turf_decal/tile/neutral/anticorner/contrasted{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/commons/locker)
"vqi" = (
/obj/structure/disposalpipe/trunk/multiz{
dir = 1
@@ -67072,6 +69171,15 @@
dir = 1
},
/area/station/hallway/secondary/exit/departure_lounge)
+"vsT" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/turf/open/floor/catwalk_floor/iron_smooth,
+/area/station/maintenance/port/greater)
"vsZ" = (
/obj/structure/table,
/turf/open/floor/plating,
@@ -67112,10 +69220,6 @@
dir = 10
},
/area/station/science/research)
-"vtD" = (
-/obj/effect/spawner/random/trash/mess,
-/turf/open/floor/iron,
-/area/station/maintenance/port/fore)
"vuh" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -67391,6 +69495,14 @@
},
/turf/open/floor/iron,
/area/station/hallway/secondary/service)
+"vxO" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/turf_decal/siding/wood,
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 1
+ },
+/turf/open/floor/wood,
+/area/station/commons/vacant_room/office)
"vxV" = (
/obj/structure/cable,
/obj/machinery/duct,
@@ -67466,6 +69578,12 @@
/obj/structure/sign/poster/contraband/random/directional/north,
/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
+"vzn" = (
+/obj/machinery/door/airlock/maintenance,
+/obj/effect/mapping_helpers/airlock/access/all/engineering/external,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/plating,
+/area/station/commons/dorms/laundry)
"vzo" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -67491,12 +69609,6 @@
"vzD" = (
/turf/closed/wall,
/area/station/maintenance/starboard/aft)
-"vzE" = (
-/obj/effect/turf_decal/tile/neutral/half/contrasted{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"vzI" = (
/obj/structure/sign/directions/engineering{
desc = "A sign that shows there are doors here. There are doors everywhere!";
@@ -67530,10 +69642,6 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron,
/area/station/engineering/lobby)
-"vzW" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/construction/mining/aux_base)
"vzX" = (
/obj/machinery/newscaster/directional/west,
/turf/open/floor/iron/recharge_floor,
@@ -67732,6 +69840,14 @@
},
/turf/open/floor/iron,
/area/station/security/prison/mess)
+"vCy" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/turf/open/floor/catwalk_floor/iron_smooth,
+/area/station/maintenance/port/lesser)
"vCz" = (
/obj/effect/landmark/start/medical_doctor,
/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible,
@@ -67816,13 +69932,6 @@
},
/turf/open/floor/iron,
/area/station/commons/fitness)
-"vEu" = (
-/obj/machinery/vending/cigarette,
-/obj/effect/turf_decal/stripes/line{
- dir = 6
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"vEw" = (
/obj/machinery/camera/directional/west{
c_tag = "Atmospherics Access"
@@ -67857,7 +69966,7 @@
dir = 10
},
/obj/structure/sign/warning/chem_diamond/directional/west,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/machinery/light/small/directional/west,
/turf/open/floor/iron/white,
@@ -67877,12 +69986,15 @@
/obj/effect/mapping_helpers/airlock/access/all/supply/general,
/turf/open/floor/iron/smooth,
/area/station/cargo/drone_bay)
-"vFe" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
+"vFb" = (
+/obj/structure/table/wood,
+/obj/item/clothing/mask/cigarette/cigar{
+ pixel_x = 7;
+ pixel_y = 10
+ },
+/obj/item/storage/box/matches,
+/turf/open/floor/carpet,
+/area/station/command/heads_quarters/captain)
"vFg" = (
/obj/structure/falsewall,
/turf/open/floor/plating,
@@ -67955,14 +70067,6 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
/area/station/maintenance/department/chapel)
-"vGM" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"vGY" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -67999,10 +70103,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
-"vHE" = (
-/obj/effect/mapping_helpers/broken_floor,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"vHI" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/public/glass{
@@ -68036,11 +70136,6 @@
},
/turf/open/floor/iron/white/smooth_large,
/area/station/medical/chemistry)
-"vHT" = (
-/obj/effect/spawner/random/trash/mess,
-/obj/item/storage/box,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"vHU" = (
/obj/item/radio/intercom/prison/directional/south,
/obj/effect/turf_decal/tile/red/half/contrasted,
@@ -68076,13 +70171,6 @@
},
/turf/open/floor/iron/dark,
/area/station/science/ordnance/office)
-"vIm" = (
-/obj/structure/closet/emcloset,
-/obj/effect/turf_decal/stripes/line{
- dir = 9
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"vIH" = (
/obj/structure/closet{
name = "evidence closet 1"
@@ -68169,6 +70257,12 @@
/obj/machinery/light/small/dim/directional/east,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/morgue)
+"vKq" = (
+/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/commons/locker)
"vKC" = (
/obj/effect/turf_decal/siding/wood{
dir = 8
@@ -68213,10 +70307,6 @@
/obj/structure/sign/warning/gas_mask,
/turf/closed/wall,
/area/station/maintenance/starboard/fore)
-"vLl" = (
-/obj/effect/spawner/structure/window/reinforced,
-/turf/open/floor/plating,
-/area/station/construction/mining/aux_base)
"vLn" = (
/obj/machinery/camera/directional/south{
c_tag = "Service Hallway - Upper East"
@@ -68262,10 +70352,10 @@
/obj/effect/turf_decal/siding/thinplating/dark/corner{
dir = 8
},
-/obj/item/roller{
+/obj/item/emergency_bed{
pixel_x = -1
},
-/obj/item/roller{
+/obj/item/emergency_bed{
pixel_x = 4
},
/obj/item/storage/medkit/regular{
@@ -68321,6 +70411,17 @@
/obj/item/seeds/glowshroom,
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
+"vNe" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/door/firedoor,
+/obj/effect/turf_decal/stripes/white/line,
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 1
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/iron/dark/textured,
+/area/station/hallway/secondary/entry)
"vNs" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -68387,22 +70488,6 @@
/obj/machinery/duct,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/morgue)
-"vOY" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 5
- },
-/obj/structure/industrial_lift{
- radial_travel = 0
- },
-/obj/structure/railing{
- dir = 5
- },
-/obj/machinery/elevator_control_panel/directional/north{
- linked_elevator_id = "publicElevator";
- preset_destination_names = list("3"="Icemoon Level","4"="Station Level")
- },
-/turf/open/floor/plating/elevatorshaft,
-/area/mine/storage)
"vPh" = (
/obj/machinery/light/directional/north,
/obj/machinery/digital_clock/directional/north,
@@ -68472,13 +70557,6 @@
},
/turf/open/floor/iron/dark,
/area/station/commons/storage/mining)
-"vQL" = (
-/obj/machinery/conveyor{
- dir = 8;
- id = "garbage"
- },
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"vQN" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
@@ -68684,16 +70762,6 @@
/obj/item/radio/intercom/directional/south,
/turf/open/floor/iron,
/area/station/hallway/primary/fore)
-"vTi" = (
-/obj/structure/table/reinforced,
-/obj/item/computer_disk/engineering,
-/obj/item/computer_disk/engineering,
-/obj/item/computer_disk/engineering,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/command/heads_quarters/ce)
"vTl" = (
/obj/machinery/door/airlock/engineering{
name = "Starboard Quarter Solar Access"
@@ -68742,6 +70810,12 @@
/obj/effect/mapping_helpers/airlock/access/all/security/general,
/turf/open/floor/iron/white,
/area/station/security/checkpoint/science)
+"vTP" = (
+/obj/effect/turf_decal/tile/green{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/hallway/primary/port)
"vUi" = (
/obj/structure/sign/picture_frame/portrait/bar{
pixel_y = -32
@@ -69077,6 +71151,12 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/iron,
/area/station/maintenance/starboard/fore)
+"vZg" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/structure/table,
+/obj/effect/spawner/random/entertainment/dice,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"vZp" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/sink/kitchen/directional/east{
@@ -69141,11 +71221,6 @@
/obj/machinery/light/directional/south,
/turf/open/floor/wood/parquet,
/area/station/commons/lounge)
-"waa" = (
-/obj/machinery/door/poddoor/massdriver_trash,
-/obj/structure/fans/tiny,
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"wab" = (
/obj/structure/cable,
/obj/machinery/holopad,
@@ -69198,6 +71273,10 @@
/obj/item/reagent_containers/blood/random,
/turf/open/floor/iron,
/area/station/maintenance/port/fore)
+"waT" = (
+/obj/structure/sign/warning/docking/directional/south,
+/turf/open/floor/plating/snowed/smoothed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"waZ" = (
/obj/structure/table,
/obj/item/assembly/igniter{
@@ -69287,12 +71366,6 @@
/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
-"wch" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/machinery/firealarm/directional/north,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"wck" = (
/obj/structure/chair{
dir = 8
@@ -69336,19 +71409,38 @@
},
/turf/open/floor/plating,
/area/mine/eva)
-"wda" = (
-/obj/effect/turf_decal/stripes/corner{
- dir = 1
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"wdg" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/plating,
/area/station/maintenance/central/lesser)
+"wdo" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 4
+ },
+/obj/structure/railing/corner/end/flip{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/turf/open/floor/iron/white/corner{
+ dir = 1
+ },
+/area/station/hallway/secondary/entry)
+"wds" = (
+/obj/structure/chair/stool/directional/west,
+/obj/machinery/light/small/directional/south,
+/obj/effect/turf_decal/siding/blue{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral/opposingcorners{
+ dir = 1
+ },
+/obj/machinery/status_display/evac/directional/south,
+/turf/open/floor/iron,
+/area/station/commons/dorms/laundry)
"wdI" = (
/obj/effect/turf_decal/trimline/neutral/warning{
dir = 6
@@ -69376,22 +71468,29 @@
},
/turf/open/floor/iron/smooth,
/area/mine/mechbay)
-"wet" = (
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
- dir = 4
- },
-/obj/machinery/door/airlock/external{
- name = "Port Docking Bay 2"
- },
-/turf/open/floor/plating,
-/area/station/hallway/secondary/entry)
"weF" = (
/obj/structure/reagent_dispensers/fueltank,
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
+"weL" = (
+/obj/structure/chair/stool/directional/north,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/tile/yellow{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/maintenance/port/fore)
"weR" = (
/turf/open/floor/wood,
/area/station/maintenance/space_hut/cabin)
+"weW" = (
+/obj/docking_port/stationary/random/icemoon{
+ dir = 8;
+ name = "lavaland";
+ shuttle_id = "pod_lavaland"
+ },
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"weY" = (
/obj/structure/window/reinforced/spawner/directional/west,
/obj/structure/table/glass,
@@ -69434,14 +71533,19 @@
},
/turf/open/floor/iron,
/area/station/security/brig/upper)
-"wfs" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"wfu" = (
/obj/structure/sign/poster/official/wtf_is_co2,
/turf/closed/wall/r_wall,
/area/station/maintenance/aft/greater)
+"wfF" = (
+/obj/effect/turf_decal/tile/blue,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/light/directional/east,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"wfK" = (
/obj/item/folder/blue,
/obj/structure/table/wood,
@@ -69690,13 +71794,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/engineering/engine_smes)
-"wjj" = (
-/obj/machinery/camera/directional/west{
- c_tag = "Vacant Office"
- },
-/obj/machinery/photocopier,
-/turf/open/floor/iron/grimy,
-/area/station/commons/vacant_room/office)
"wjv" = (
/obj/machinery/computer/cargo{
dir = 4
@@ -69746,12 +71843,6 @@
},
/turf/open/floor/iron,
/area/station/cargo/miningdock)
-"wkj" = (
-/obj/effect/spawner/structure/window/hollow/reinforced/middle{
- dir = 4
- },
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"wkl" = (
/obj/machinery/camera/directional/west{
c_tag = "Telecomms Server Room";
@@ -69771,12 +71862,25 @@
/obj/machinery/power/emitter,
/turf/open/floor/plating,
/area/station/engineering/engine_smes)
+"wkB" = (
+/obj/structure/sign/nanotrasen{
+ pixel_y = 32
+ },
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/underground/explored)
"wkC" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/public/glass{
name = "Central Access"
},
-/turf/open/floor/iron,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 4
+ },
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 8
+ },
+/turf/open/floor/iron/dark/textured,
/area/station/hallway/primary/central)
"wkH" = (
/obj/structure/window/reinforced/spawner/directional/east,
@@ -69818,14 +71922,6 @@
},
/turf/open/floor/iron,
/area/station/maintenance/disposal/incinerator)
-"wlc" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"wlr" = (
/obj/structure/table,
/obj/item/stack/spacecash/c10,
@@ -69850,12 +71946,6 @@
},
/turf/open/floor/iron/freezer,
/area/station/commons/toilet/locker)
-"wlx" = (
-/obj/machinery/camera/directional/east{
- c_tag = "Arrivals Bay 2"
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"wlz" = (
/obj/structure/filingcabinet,
/turf/open/floor/iron/dark,
@@ -69895,6 +71985,13 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/mine/eva)
+"wml" = (
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/blue,
+/obj/structure/railing/corner/end/flip,
+/obj/effect/turf_decal/siding/thinplating/corner,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"wmG" = (
/obj/structure/disposalpipe/segment,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -70140,17 +72237,21 @@
dir = 8
},
/area/mine/eva)
-"wpy" = (
-/obj/effect/turf_decal/tile/neutral/half/contrasted{
- dir = 8
- },
+"wpC" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
+/area/station/commons/locker)
"wpO" = (
/obj/machinery/power/apc/auto_name/directional/north,
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/hallway/primary/port)
+"wpQ" = (
+/obj/machinery/bluespace_vendor/directional/south,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"wpV" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -70240,6 +72341,20 @@
},
/turf/open/floor/iron/dark,
/area/mine/storage)
+"wqU" = (
+/obj/machinery/atmospherics/pipe/multiz/supply/visible/layer4{
+ dir = 1
+ },
+/obj/structure/cable,
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/machinery/atmospherics/pipe/multiz/scrubbers/visible/layer2{
+ dir = 1
+ },
+/obj/machinery/airalarm/directional/south,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"wrc" = (
/obj/structure/cable,
/obj/machinery/power/apc/auto_name/directional/north,
@@ -70251,6 +72366,14 @@
},
/turf/open/floor/iron,
/area/station/engineering/storage)
+"wrl" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/tile/brown/half/contrasted{
+ dir = 4
+ },
+/turf/open/floor/iron/dark,
+/area/station/maintenance/disposal)
"wrA" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/public/glass{
@@ -70258,6 +72381,7 @@
},
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/textured,
/area/station/commons/storage/primary)
"wrE" = (
@@ -70303,11 +72427,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/white,
/area/station/medical/chemistry)
-"wsx" = (
-/obj/structure/closet,
-/obj/machinery/light_switch/directional/east,
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"wsD" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -70335,15 +72454,12 @@
/obj/effect/landmark/blobstart,
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
-"wsS" = (
-/obj/machinery/modular_computer/preset/id,
-/obj/machinery/light/directional/north,
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/red/half/contrasted{
- dir = 1
- },
+"wsV" = (
+/obj/effect/landmark/start/hangover,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/siding/thinplating_new,
/turf/open/floor/iron,
-/area/station/security/checkpoint/customs/auxiliary)
+/area/station/commons/locker)
"wta" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -70369,11 +72485,33 @@
/obj/structure/flora/grass/brown/style_2,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors/nospawn)
+"wtr" = (
+/obj/structure/table/glass,
+/obj/item/food/grown/wheat,
+/obj/item/food/grown/watermelon,
+/obj/item/food/grown/watermelon,
+/obj/item/food/grown/watermelon,
+/obj/item/food/grown/citrus/orange,
+/obj/item/food/grown/grapes,
+/obj/item/food/grown/cocoapod,
+/obj/effect/turf_decal/tile/green/half/contrasted{
+ dir = 8
+ },
+/turf/open/floor/iron/dark,
+/area/station/service/hydroponics/garden)
"wtC" = (
/obj/structure/chair/stool/directional/south,
/obj/machinery/light/small/dim/directional/north,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
+"wtP" = (
+/obj/machinery/power/apc/auto_name/directional/north,
+/obj/structure/cable,
+/obj/effect/turf_decal/siding/wood{
+ dir = 4
+ },
+/turf/open/floor/wood,
+/area/station/commons/vacant_room/office)
"wtT" = (
/obj/machinery/light/directional/west,
/turf/open/floor/iron/white/side{
@@ -70408,6 +72546,12 @@
/obj/effect/turf_decal/tile/blue/half/contrasted,
/turf/open/floor/iron/white,
/area/station/medical/surgery/fore)
+"wuA" = (
+/obj/structure/disposalpipe/segment{
+ dir = 6
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"wuC" = (
/obj/structure/grille,
/turf/open/floor/plating,
@@ -70422,10 +72566,6 @@
},
/turf/open/floor/iron/dark/textured,
/area/station/security/prison)
-"wuO" = (
-/obj/machinery/light/directional/south,
-/turf/open/floor/iron/grimy,
-/area/station/commons/vacant_room/office)
"wuV" = (
/obj/effect/turf_decal/siding/yellow/corner,
/obj/machinery/status_display/evac/directional/south,
@@ -70613,6 +72753,11 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/plating,
/area/station/maintenance/department/chapel)
+"wxy" = (
+/obj/structure/disposalpipe/segment,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"wxH" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 4
@@ -70646,6 +72791,14 @@
/obj/effect/mapping_helpers/airlock/access/all/security/general,
/turf/open/floor/iron,
/area/station/hallway/secondary/exit/departure_lounge)
+"wyr" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"wyB" = (
/obj/machinery/conveyor{
dir = 1;
@@ -70677,6 +72830,17 @@
},
/turf/open/floor/iron/cafeteria,
/area/station/security/prison/mess)
+"wyQ" = (
+/obj/effect/turf_decal/siding/wood,
+/obj/effect/turf_decal/siding/wood{
+ dir = 1
+ },
+/obj/machinery/door/firedoor,
+/obj/machinery/door/airlock/multi_tile/public/glass{
+ name = "The Girly Boar"
+ },
+/turf/open/floor/iron/dark/textured_half,
+/area/station/service/bar/atrium)
"wzc" = (
/obj/machinery/power/apc/auto_name/directional/north,
/obj/structure/cable,
@@ -70762,18 +72926,6 @@
/obj/effect/turf_decal/tile/red/half/contrasted,
/turf/open/floor/iron,
/area/station/security/brig/upper)
-"wAU" = (
-/obj/machinery/light/directional/north,
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
- dir = 4
- },
-/obj/effect/turf_decal/tile/blue{
- dir = 4
- },
-/turf/open/floor/iron/white/corner{
- dir = 1
- },
-/area/station/hallway/secondary/entry)
"wAW" = (
/obj/structure/table,
/obj/item/knife/kitchen,
@@ -70849,24 +73001,17 @@
},
/turf/open/floor/wood,
/area/station/hallway/secondary/service)
+"wBT" = (
+/obj/machinery/camera/directional/south{
+ c_tag = "Port Hallway Center"
+ },
+/obj/machinery/light/directional/south,
+/turf/open/floor/iron,
+/area/station/hallway/primary/port)
"wBV" = (
/obj/structure/closet/crate,
/turf/open/floor/iron,
/area/station/cargo/miningdock)
-"wBZ" = (
-/obj/machinery/conveyor{
- dir = 4;
- id = "garbage"
- },
-/obj/machinery/recycler,
-/obj/structure/sign/warning/secure_area/directional/north{
- name = "\improper STAY CLEAR HEAVY MACHINERY"
- },
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"wCo" = (
/obj/effect/spawner/structure/window/hollow/reinforced/middle{
dir = 1
@@ -70880,6 +73025,24 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/mix)
+"wCL" = (
+/obj/item/reagent_containers/spray/plantbgone,
+/obj/item/reagent_containers/spray/pestspray{
+ pixel_x = 3;
+ pixel_y = 4
+ },
+/obj/item/reagent_containers/cup/bottle/nutrient/ez,
+/obj/item/reagent_containers/cup/bottle/nutrient/rh{
+ pixel_x = 2;
+ pixel_y = 1
+ },
+/obj/structure/table/glass,
+/obj/effect/turf_decal/tile/green/anticorner/contrasted{
+ dir = 1
+ },
+/obj/machinery/airalarm/directional/east,
+/turf/open/floor/iron/dark,
+/area/station/service/hydroponics/garden)
"wCV" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -71039,6 +73202,14 @@
/obj/machinery/power/apc/auto_name/directional/west,
/turf/open/floor/plating,
/area/station/maintenance/aft/lesser)
+"wEM" = (
+/obj/effect/landmark/start/hangover,
+/obj/effect/turf_decal/tile/blue/opposingcorners{
+ dir = 1
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/iron/cafeteria,
+/area/station/commons/dorms/laundry)
"wET" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -71110,15 +73281,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
/area/station/service/chapel)
-"wGD" = (
-/obj/machinery/vending/assist,
-/obj/effect/turf_decal/bot,
-/obj/machinery/status_display/evac/directional/west,
-/obj/effect/turf_decal/tile/neutral/anticorner/contrasted{
- dir = 8
- },
-/turf/open/floor/iron/dark,
-/area/station/commons/storage/primary)
"wGE" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 1
@@ -71261,17 +73423,10 @@
/obj/structure/table,
/turf/open/floor/plating,
/area/station/maintenance/aft/greater)
-"wJd" = (
-/obj/effect/turf_decal/siding/wood{
- dir = 1
- },
-/obj/effect/turf_decal/siding/wood,
-/obj/machinery/door/firedoor,
-/obj/machinery/door/airlock/multi_tile/public/glass{
- name = "The Girly Boar"
- },
-/turf/open/floor/iron/dark/textured_half,
-/area/station/service/bar/atrium)
+"wIZ" = (
+/obj/effect/decal/remains/plasma,
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/underground/explored)
"wJe" = (
/obj/effect/turf_decal/siding/thinplating/dark{
dir = 4
@@ -71370,15 +73525,6 @@
},
/turf/open/floor/carpet,
/area/station/command/heads_quarters/captain)
-"wKA" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral/half/contrasted{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/service/hydroponics/garden)
"wKC" = (
/turf/open/floor/iron/cafeteria,
/area/station/security/prison/mess)
@@ -71409,15 +73555,6 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/iron,
/area/station/command/bridge)
-"wLJ" = (
-/obj/item/circuitboard/machine/stasis,
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
- dir = 8
- },
-/obj/item/wrench/medical,
-/obj/effect/mapping_helpers/broken_floor,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"wLK" = (
/obj/machinery/light/small/directional/north,
/turf/open/floor/iron/dark,
@@ -71508,6 +73645,17 @@
"wMt" = (
/turf/closed/wall,
/area/station/hallway/primary/central/fore)
+"wMw" = (
+/obj/structure/disposalpipe/trunk{
+ dir = 1
+ },
+/obj/machinery/disposal/bin,
+/obj/effect/turf_decal/tile/neutral/opposingcorners{
+ dir = 1
+ },
+/obj/item/radio/intercom/directional/west,
+/turf/open/floor/iron,
+/area/station/commons/dorms/laundry)
"wMz" = (
/obj/machinery/atmospherics/pipe/multiz/supply/visible/layer4{
color = "#0000ff";
@@ -71576,6 +73724,12 @@
/obj/effect/turf_decal/tile/bar/opposingcorners,
/turf/open/floor/iron,
/area/station/service/bar)
+"wNR" = (
+/obj/structure/disposalpipe/segment{
+ dir = 9
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"wNT" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -71793,6 +73947,7 @@
/obj/effect/turf_decal/tile/neutral/half/contrasted{
dir = 8
},
+/obj/machinery/firealarm/directional/north,
/turf/open/floor/iron/dark/side{
dir = 8
},
@@ -71889,13 +74044,6 @@
/obj/effect/spawner/structure/window/hollow/reinforced/middle,
/turf/open/floor/plating,
/area/station/medical/chemistry)
-"wRU" = (
-/obj/machinery/door/firedoor,
-/obj/effect/turf_decal/stripes/line{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/hallway/primary/port)
"wSd" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -71903,6 +74051,23 @@
/obj/structure/sign/warning/secure_area/directional/north,
/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
+"wSf" = (
+/obj/machinery/vending/assist,
+/obj/effect/turf_decal/bot,
+/obj/effect/turf_decal/tile/neutral/anticorner/contrasted{
+ dir = 8
+ },
+/obj/machinery/status_display/ai/directional/west,
+/turf/open/floor/iron/dark,
+/area/station/commons/storage/primary)
+"wSk" = (
+/obj/structure/disposalpipe/segment,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/cable,
+/obj/effect/spawner/random/structure/steam_vent,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"wSo" = (
/obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -71958,12 +74123,6 @@
"wTg" = (
/turf/closed/wall,
/area/station/engineering/main)
-"wTh" = (
-/obj/structure/disposalpipe/segment{
- dir = 9
- },
-/turf/open/floor/iron,
-/area/station/hallway/primary/port)
"wTw" = (
/obj/effect/turf_decal/trimline/neutral/warning{
dir = 10
@@ -72031,14 +74190,14 @@
},
/turf/open/floor/iron/white,
/area/station/science/research)
-"wUw" = (
-/obj/machinery/door/poddoor/shutters{
- id = "aux_base_shutters";
- name = "Auxillary Base Shutters"
+"wUu" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
},
-/obj/effect/turf_decal/delivery,
-/turf/open/floor/iron,
-/area/station/construction/mining/aux_base)
+/obj/structure/disposalpipe/segment,
+/obj/structure/lattice/catwalk,
+/turf/open/openspace/icemoon/keep_below,
+/area/station/maintenance/port/lesser)
"wUz" = (
/obj/structure/window/reinforced/spawner/directional/south,
/obj/machinery/camera/directional/east{
@@ -72144,6 +74303,15 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/carpet,
/area/station/service/library)
+"wVq" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/effect/spawner/random/trash/caution_sign,
+/obj/effect/decal/cleanable/glass,
+/obj/structure/sign/warning/directional/east,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"wVu" = (
/obj/effect/turf_decal/stripes/line{
dir = 10
@@ -72192,6 +74360,12 @@
/obj/machinery/light/directional/west,
/turf/open/floor/engine,
/area/station/engineering/supermatter/room)
+"wWc" = (
+/obj/effect/decal/cleanable/oil,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/spawner/random/structure/tank_holder,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"wWm" = (
/obj/item/trash/raisins,
/turf/open/floor/plating,
@@ -72212,6 +74386,13 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/engineering/storage_shared)
+"wWS" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/turf_decal/stripes/line{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
"wWU" = (
/obj/structure/cable,
/turf/open/floor/iron/showroomfloor,
@@ -72283,12 +74464,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central/fore)
-"wYm" = (
-/obj/machinery/atmospherics/components/binary/valve{
- dir = 4
- },
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"wYp" = (
/obj/structure/sign/nanotrasen,
/turf/closed/wall/ice,
@@ -72318,6 +74493,14 @@
/obj/item/kirbyplants/random,
/turf/open/floor/iron/white,
/area/mine/living_quarters)
+"wYz" = (
+/obj/effect/turf_decal/tile/blue/opposingcorners{
+ dir = 1
+ },
+/obj/structure/chair/stool/directional/south,
+/obj/machinery/requests_console/auto_name/directional/north,
+/turf/open/floor/iron/cafeteria,
+/area/station/commons/dorms/laundry)
"wYJ" = (
/turf/closed/wall,
/area/station/engineering/storage_shared)
@@ -72414,13 +74597,6 @@
/obj/effect/landmark/start/hangover,
/turf/open/floor/stone,
/area/station/commons/lounge)
-"wZL" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/turf_decal/tile/yellow{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"wZV" = (
/obj/structure/window/reinforced/spawner/directional/east,
/obj/machinery/portable_atmospherics/canister/oxygen,
@@ -72481,6 +74657,13 @@
/obj/effect/turf_decal/tile/purple/fourcorners,
/turf/open/floor/iron,
/area/mine/living_quarters)
+"xau" = (
+/obj/effect/mapping_helpers/airlock/cyclelink_helper{
+ dir = 8
+ },
+/obj/machinery/door/airlock/external/glass,
+/turf/open/floor/plating,
+/area/station/hallway/secondary/entry)
"xaA" = (
/obj/structure/closet/secure_closet/hop,
/obj/effect/turf_decal/tile/blue/anticorner/contrasted{
@@ -72511,6 +74694,11 @@
"xaI" = (
/turf/open/floor/iron/dark/telecomms,
/area/station/tcommsat/server)
+"xaO" = (
+/obj/effect/spawner/random/trash/moisture_trap,
+/obj/machinery/light/small/directional/west,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"xaV" = (
/obj/effect/turf_decal/stripes/asteroid/line{
dir = 4
@@ -72598,6 +74786,12 @@
/obj/structure/ladder,
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
+"xce" = (
+/obj/structure/rack,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/siding/white,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"xcp" = (
/obj/item/trash/pistachios,
/turf/open/floor/plating,
@@ -72628,6 +74822,13 @@
},
/turf/open/lava/plasma/ice_moon,
/area/icemoon/underground/explored)
+"xcJ" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/obj/machinery/firealarm/directional/south,
+/turf/open/floor/iron,
+/area/station/hallway/primary/starboard)
"xcW" = (
/obj/machinery/atmospherics/pipe/multiz/scrubbers/visible/layer2{
dir = 1
@@ -72672,10 +74873,26 @@
/obj/structure/chair/stool/bar/directional/east,
/turf/open/floor/iron/white/smooth_large,
/area/station/service/kitchen/diner)
+"xdH" = (
+/obj/effect/turf_decal/stripes/line,
+/obj/structure/chair{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/turf/open/floor/iron/white/corner,
+/area/station/hallway/secondary/entry)
"xdM" = (
/obj/structure/sign/warning/cold_temp,
/turf/closed/wall,
/area/station/hallway/secondary/exit/departure_lounge)
+"xdU" = (
+/obj/machinery/atmospherics/components/binary/pump{
+ dir = 1
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"xdW" = (
/obj/machinery/camera/directional/east{
c_tag = "Central Hallway South-East"
@@ -72683,12 +74900,20 @@
/obj/item/radio/intercom/directional/east,
/turf/open/floor/iron,
/area/station/hallway/primary/central)
+"xdY" = (
+/obj/structure/sign/warning/directional/west,
+/turf/open/genturf/blue,
+/area/icemoon/underground/unexplored/rivers/deep/shoreline)
"xdZ" = (
/obj/effect/turf_decal/siding/wideplating/dark{
dir = 6
},
/turf/open/floor/iron/dark/textured,
/area/station/security/prison/rec)
+"xeg" = (
+/obj/effect/turf_decal/weather/snow/corner,
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"xei" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/structure/disposalpipe/segment{
@@ -72790,6 +75015,10 @@
},
/turf/open/floor/engine,
/area/station/engineering/supermatter/room)
+"xft" = (
+/obj/structure/cable,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"xfB" = (
/obj/machinery/atmospherics/pipe/smart/simple/green/visible,
/turf/open/floor/iron,
@@ -72935,6 +75164,15 @@
},
/turf/open/floor/iron/dark/textured_edge,
/area/station/security/prison)
+"xgM" = (
+/obj/structure/disposalpipe/segment{
+ dir = 6
+ },
+/obj/effect/mapping_helpers/burnt_floor,
+/obj/machinery/airalarm/directional/north,
+/obj/effect/decal/cleanable/dirt/dust,
+/turf/open/floor/plating,
+/area/station/maintenance/port/lesser)
"xgO" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/trimline/yellow/corner{
@@ -72951,6 +75189,30 @@
},
/turf/open/floor/iron/smooth_large,
/area/station/cargo/drone_bay)
+"xgX" = (
+/obj/structure/table/wood,
+/obj/effect/spawner/random/entertainment/deck{
+ pixel_y = 15;
+ pixel_x = -2
+ },
+/obj/effect/spawner/random/food_or_drink/snack{
+ pixel_x = 5;
+ pixel_y = 6
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/carpet/blue,
+/area/station/hallway/secondary/entry)
+"xhg" = (
+/obj/effect/turf_decal/siding/wood{
+ dir = 1
+ },
+/obj/machinery/camera/directional/east{
+ c_tag = "Garden"
+ },
+/obj/item/kirbyplants/random,
+/obj/machinery/status_display/ai/directional/east,
+/turf/open/floor/iron/dark,
+/area/station/service/hydroponics/garden)
"xhk" = (
/turf/open/floor/iron/dark,
/area/station/commons/storage/primary)
@@ -72988,6 +75250,10 @@
dir = 1
},
/area/station/hallway/primary/central)
+"xhx" = (
+/obj/structure/extinguisher_cabinet/directional/south,
+/turf/open/floor/iron,
+/area/station/hallway/primary/port)
"xhz" = (
/obj/structure/ladder{
name = "Kitchen Access"
@@ -73018,19 +75284,6 @@
},
/turf/open/floor/iron/dark,
/area/station/engineering/transit_tube)
-"xio" = (
-/obj/machinery/door/airlock/maintenance{
- name = "Disposal Access"
- },
-/obj/structure/cable,
-/obj/effect/mapping_helpers/airlock/access/any/supply/maintenance,
-/obj/effect/mapping_helpers/airlock/unres{
- dir = 8
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"xit" = (
/obj/item/book/manual/wiki/security_space_law,
/obj/structure/table/wood,
@@ -73070,10 +75323,6 @@
/obj/structure/sign/departments/medbay/alt,
/turf/closed/wall,
/area/station/medical/medbay/lobby)
-"xji" = (
-/obj/machinery/vending/cigarette,
-/turf/open/floor/iron/dark,
-/area/station/hallway/secondary/entry)
"xjj" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -73128,15 +75377,6 @@
},
/turf/open/floor/plating,
/area/station/cargo/sorting)
-"xjY" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
- dir = 1
- },
-/obj/effect/turf_decal/tile/blue/opposingcorners{
- dir = 1
- },
-/turf/open/floor/iron/cafeteria,
-/area/station/commons/dorms/laundry)
"xjZ" = (
/obj/structure/tank_dispenser/oxygen,
/turf/open/floor/iron/dark,
@@ -73164,13 +75404,23 @@
/obj/effect/turf_decal/tile/yellow/opposingcorners,
/turf/open/floor/iron/white,
/area/station/maintenance/port/fore)
+"xkH" = (
+/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/siding/thinplating/corner{
+ dir = 4
+ },
+/obj/machinery/power/apc/auto_name/directional/north,
+/obj/item/kirbyplants/random,
+/turf/open/floor/plastic,
+/area/station/commons/dorms/laundry)
"xkZ" = (
/obj/machinery/teleport/station,
/obj/machinery/light/small/directional/east,
/turf/open/floor/plating,
/area/station/ai_monitored/turret_protected/aisat_interior)
"xlf" = (
-/obj/machinery/lapvend,
/obj/effect/turf_decal/tile/purple/half/contrasted{
dir = 8
},
@@ -73268,12 +75518,12 @@
dir = 9
},
/area/station/science/research)
-"xmu" = (
-/obj/effect/turf_decal/siding/wood{
- dir = 1
- },
-/turf/open/floor/wood,
-/area/station/commons/vacant_room/office)
+"xmo" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"xmx" = (
/obj/structure/sink/kitchen/directional/south,
/obj/effect/decal/cleanable/dirt,
@@ -73369,6 +75619,14 @@
/obj/machinery/light/small/directional/south,
/turf/open/floor/stone,
/area/mine/eva/lower)
+"xnV" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 8
+ },
+/obj/structure/cable,
+/turf/open/floor/iron/dark/smooth_large,
+/area/station/security/checkpoint/customs/auxiliary)
"xnX" = (
/obj/structure/lattice/catwalk,
/obj/structure/railing{
@@ -73459,6 +75717,12 @@
/obj/effect/spawner/random/trash/mess,
/turf/open/floor/plating,
/area/station/maintenance/aft/greater)
+"xqj" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/turf/open/floor/catwalk_floor/iron_smooth,
+/area/station/maintenance/port/greater)
"xqu" = (
/obj/machinery/door/window/left/directional/north{
dir = 4;
@@ -73497,6 +75761,13 @@
/obj/effect/mapping_helpers/airlock/access/all/service/general,
/turf/open/floor/iron/dark/textured,
/area/station/hallway/secondary/service)
+"xqX" = (
+/obj/structure/sign/poster/contraband/random/directional/north,
+/obj/structure/cable,
+/obj/effect/mapping_helpers/broken_floor,
+/obj/structure/closet/firecloset,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"xqY" = (
/obj/machinery/firealarm/directional/east,
/turf/open/floor/iron/dark,
@@ -73527,6 +75798,13 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/wood,
/area/station/commons/dorms)
+"xrs" = (
+/obj/structure/disposalpipe/segment{
+ dir = 9
+ },
+/obj/structure/lattice/catwalk,
+/turf/open/openspace/icemoon/keep_below,
+/area/station/maintenance/port/lesser)
"xry" = (
/obj/machinery/newscaster/directional/west,
/turf/open/floor/wood,
@@ -73543,6 +75821,17 @@
},
/turf/open/floor/iron/dark,
/area/mine/storage)
+"xrL" = (
+/obj/machinery/washing_machine,
+/obj/structure/sign/poster/official/no_erp/directional/west,
+/obj/effect/turf_decal/siding/blue{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral/opposingcorners{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/commons/dorms/laundry)
"xrS" = (
/obj/structure/ladder,
/obj/effect/turf_decal/stripes/box,
@@ -73560,16 +75849,6 @@
dir = 5
},
/area/station/maintenance/port/aft)
-"xsq" = (
-/obj/machinery/atmospherics/components/trinary/filter{
- dir = 4
- },
-/obj/effect/turf_decal/stripes/corner{
- dir = 8
- },
-/obj/effect/turf_decal/stripes/corner,
-/turf/open/floor/iron,
-/area/station/maintenance/port/fore)
"xss" = (
/obj/machinery/light/directional/south,
/obj/effect/turf_decal/tile/yellow/half/contrasted,
@@ -73595,15 +75874,6 @@
/obj/item/food/grown/carrot,
/turf/open/misc/asteroid/snow/standard_air,
/area/station/science/research)
-"xsE" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 1
- },
-/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/dark,
-/area/station/maintenance/disposal)
"xtc" = (
/obj/effect/turf_decal/trimline/blue/filled/warning{
dir = 1
@@ -73726,6 +75996,15 @@
},
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors/nospawn)
+"xuW" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/obj/item/kirbyplants/random,
+/turf/open/floor/iron/cafeteria{
+ dir = 5
+ },
+/area/station/hallway/secondary/entry)
"xvj" = (
/obj/machinery/atmospherics/pipe/smart/simple/dark/visible{
dir = 5
@@ -73739,6 +76018,21 @@
},
/turf/open/floor/iron,
/area/station/engineering/atmos)
+"xvk" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/effect/landmark/blobstart,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
+"xvl" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
+/obj/effect/turf_decal/siding/thinplating_new/corner{
+ dir = 4
+ },
+/turf/open/floor/iron/large,
+/area/station/hallway/secondary/entry)
"xvn" = (
/obj/effect/turf_decal/stripes/line{
dir = 8
@@ -73901,9 +76195,10 @@
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/hfr_room)
"xxI" = (
-/obj/structure/filingcabinet,
+/obj/machinery/airalarm/directional/north,
+/obj/item/kirbyplants/random,
/turf/open/floor/iron/grimy,
-/area/station/commons/vacant_room/office)
+/area/station/hallway/secondary/entry)
"xxQ" = (
/obj/structure/table,
/obj/item/screwdriver{
@@ -73913,6 +76208,10 @@
/obj/machinery/airalarm/directional/north,
/turf/open/floor/plating,
/area/station/engineering/storage/tech)
+"xxV" = (
+/obj/structure/flora/grass/brown/style_random,
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/underground/explored)
"xyc" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 4
@@ -74032,10 +76331,6 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/iron/showroomfloor,
/area/station/security/prison/mess)
-"xyY" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/security/checkpoint/customs/auxiliary)
"xzd" = (
/obj/machinery/camera/directional/east{
c_tag = "Library South"
@@ -74050,6 +76345,11 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central)
+"xzo" = (
+/obj/effect/turf_decal/delivery,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"xzp" = (
/obj/item/kirbyplants/random,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -74076,6 +76376,13 @@
/obj/structure/sign/poster/contraband/random/directional/east,
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
+"xAk" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/turf/open/floor/iron/large,
+/area/station/hallway/secondary/entry)
"xAm" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/computer/atmos_control/nocontrol/incinerator{
@@ -74150,13 +76457,6 @@
},
/turf/open/floor/iron/dark,
/area/station/service/chapel)
-"xBu" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/cable,
-/obj/machinery/holopad,
-/turf/open/floor/iron/dark/textured,
-/area/station/security/execution/transfer)
"xBv" = (
/obj/machinery/light/directional/north,
/obj/effect/decal/cleanable/dirt,
@@ -74216,6 +76516,15 @@
"xCl" = (
/turf/open/floor/iron,
/area/station/science/robotics/lab)
+"xCr" = (
+/obj/effect/turf_decal/siding/blue{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral/opposingcorners{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/commons/dorms/laundry)
"xCv" = (
/obj/machinery/computer/security,
/obj/effect/turf_decal/tile/red/half/contrasted,
@@ -74257,12 +76566,25 @@
"xDb" = (
/turf/closed/wall/r_wall,
/area/station/medical/virology)
+"xDh" = (
+/obj/machinery/camera/directional/south{
+ c_tag = "Locker Room West"
+ },
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron,
+/area/station/commons/locker)
"xDr" = (
/obj/effect/turf_decal/siding/white,
/obj/effect/spawner/random/vending/snackvend,
/obj/effect/turf_decal/tile/bar/opposingcorners,
/turf/open/floor/iron,
/area/station/hallway/secondary/service)
+"xDw" = (
+/obj/structure/grille/broken,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"xDG" = (
/obj/machinery/meter,
/obj/machinery/atmospherics/pipe/smart/simple/green/visible{
@@ -74320,9 +76642,7 @@
/turf/open/floor/iron/dark/smooth_large,
/area/station/medical/virology)
"xEt" = (
-/obj/machinery/atmospherics/components/tank/air{
- initialize_directions = 2
- },
+/obj/structure/closet/bombcloset,
/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
"xEx" = (
@@ -74335,6 +76655,10 @@
/obj/effect/turf_decal/tile/bar/opposingcorners,
/turf/open/floor/iron,
/area/station/service/bar/backroom)
+"xEE" = (
+/obj/machinery/firealarm/directional/south,
+/turf/open/floor/iron,
+/area/station/hallway/primary/port)
"xEF" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
@@ -74373,12 +76697,6 @@
/obj/structure/disposalpipe/trunk,
/turf/open/floor/iron/dark,
/area/station/maintenance/disposal/incinerator)
-"xEP" = (
-/obj/machinery/door/firedoor,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"xEQ" = (
/obj/machinery/atmospherics/pipe/smart/simple/yellow/visible,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -74413,6 +76731,12 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron,
/area/station/security/brig/upper)
+"xFs" = (
+/obj/effect/turf_decal/siding/thinplating_new{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
"xFv" = (
/obj/effect/turf_decal/siding/white{
dir = 6
@@ -74516,6 +76840,7 @@
id = "medsecprivacy";
name = "Privacy Shutters"
},
+/obj/machinery/door/firedoor,
/turf/open/floor/plating,
/area/station/security/checkpoint/medical)
"xGI" = (
@@ -74652,12 +76977,6 @@
"xJj" = (
/turf/open/floor/iron,
/area/station/science/xenobiology)
-"xJv" = (
-/obj/structure/sign/map/right{
- pixel_y = 32
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"xJw" = (
/obj/machinery/camera/directional/south{
c_tag = "Atmospherics Project Room"
@@ -74738,12 +77057,6 @@
/obj/effect/mapping_helpers/airlock/access/all/engineering/external,
/turf/open/floor/plating,
/area/station/maintenance/starboard/upper)
-"xKG" = (
-/obj/structure/closet,
-/obj/effect/spawner/random/maintenance/two,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/pink/hidden,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"xKJ" = (
/turf/closed/wall,
/area/station/command/meeting_room)
@@ -74814,15 +77127,6 @@
},
/turf/open/floor/iron/cafeteria,
/area/station/security/prison/work)
-"xMg" = (
-/obj/machinery/computer/security,
-/obj/structure/reagent_dispensers/wall/peppertank/directional/north,
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/red/half/contrasted{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/security/checkpoint/customs/auxiliary)
"xMh" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/atmospherics/pipe/bridge_pipe/cyan/visible,
@@ -74935,10 +77239,6 @@
/obj/machinery/atmospherics/components/unary/portables_connector/visible,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
-"xOm" = (
-/obj/machinery/airalarm/directional/east,
-/turf/closed/wall,
-/area/station/maintenance/port/greater)
"xOM" = (
/obj/structure/table,
/obj/machinery/mineral/processing_unit_console,
@@ -75024,6 +77324,14 @@
/obj/structure/closet/secure_closet/freezer/fridge/all_access,
/turf/open/floor/iron/showroomfloor,
/area/station/security/prison/mess)
+"xQs" = (
+/obj/effect/turf_decal/tile/red/half/contrasted{
+ dir = 4
+ },
+/obj/structure/cable,
+/obj/machinery/newscaster/directional/east,
+/turf/open/floor/iron/dark,
+/area/station/security/checkpoint/customs/auxiliary)
"xQu" = (
/obj/machinery/light/directional/north,
/turf/open/floor/plating/snowed/smoothed/icemoon,
@@ -75071,6 +77379,12 @@
/obj/machinery/light/dim/directional/south,
/turf/open/floor/iron/dark,
/area/station/medical/morgue)
+"xRI" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/light/small/directional/east,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"xRP" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -75100,13 +77414,13 @@
/turf/open/floor/carpet,
/area/station/service/theater)
"xSl" = (
-/obj/item/radio/intercom/directional/south,
/obj/effect/turf_decal/siding/wood{
- dir = 4
- },
-/obj/effect/turf_decal/siding/wood{
- dir = 8
+ dir = 1
},
+/obj/item/radio/intercom/directional/east,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/light/small/directional/east,
/turf/open/floor/wood,
/area/station/commons/vacant_room/office)
"xSn" = (
@@ -75144,17 +77458,12 @@
"xSA" = (
/turf/open/floor/wood,
/area/station/service/lawoffice)
-"xSM" = (
-/obj/structure/table,
-/obj/item/flashlight{
- pixel_x = 1;
- pixel_y = 5
+"xSL" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 1
},
-/obj/item/wirecutters,
-/obj/machinery/status_display/ai/directional/east,
-/obj/effect/turf_decal/tile/neutral/anticorner/contrasted,
-/turf/open/floor/iron/dark,
-/area/station/commons/storage/primary)
+/turf/open/floor/iron/large,
+/area/station/hallway/primary/port)
"xTp" = (
/obj/machinery/camera/directional/south{
c_tag = "Solar Maintenance - North East"
@@ -75169,6 +77478,7 @@
c_tag = "Atmospherics Incinerator"
},
/obj/machinery/atmospherics/components/tank/plasma,
+/obj/machinery/firealarm/directional/west,
/turf/open/floor/iron,
/area/station/maintenance/disposal/incinerator)
"xTw" = (
@@ -75184,15 +77494,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/maintenance/starboard/upper)
-"xTP" = (
-/obj/machinery/computer/shuttle/mining{
- dir = 8
- },
-/obj/effect/turf_decal/tile/yellow/half/contrasted{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/construction/mining/aux_base)
"xTQ" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -75268,6 +77569,15 @@
/obj/structure/sign/departments/maint/directional/west,
/turf/open/floor/plating/snowed/smoothed/icemoon,
/area/icemoon/underground/explored)
+"xUF" = (
+/obj/machinery/power/apc/auto_name/directional/west,
+/obj/structure/cable,
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/turf_decal/tile/brown/half/contrasted{
+ dir = 8
+ },
+/turf/open/floor/iron/dark,
+/area/station/maintenance/disposal)
"xUG" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -75325,13 +77635,13 @@
"xVK" = (
/turf/closed/wall,
/area/station/service/janitor)
-"xVL" = (
-/obj/structure/closet/secure_closet/personal{
- anchored = 1
+"xVN" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
},
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/commons/locker)
+/obj/machinery/airalarm/directional/south,
+/turf/open/floor/iron/white/corner,
+/area/station/hallway/secondary/entry)
"xVO" = (
/obj/structure/table/wood,
/obj/item/reagent_containers/cup/glass/mug/coco{
@@ -75414,6 +77724,16 @@
},
/turf/open/floor/iron,
/area/station/commons/storage/primary)
+"xXd" = (
+/obj/effect/turf_decal/tile/blue/opposingcorners{
+ dir = 1
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/door/airlock/multi_tile/public/glass{
+ name = "Laundry Room"
+ },
+/turf/open/floor/iron/cafeteria,
+/area/station/commons/dorms/laundry)
"xXf" = (
/obj/machinery/portable_atmospherics/pump,
/obj/machinery/atmospherics/components/unary/portables_connector/visible{
@@ -75500,11 +77820,19 @@
dir = 10
},
/area/station/science/research)
-"xYv" = (
-/obj/structure/rack,
-/obj/effect/spawner/random/maintenance,
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
+"xYr" = (
+/obj/machinery/mineral/stacking_unit_console{
+ pixel_x = -32
+ },
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/turf_decal/tile/brown/half/contrasted{
+ dir = 8
+ },
+/obj/machinery/camera/directional/west{
+ c_tag = "Disposals"
+ },
+/turf/open/floor/iron/dark,
+/area/station/maintenance/disposal)
"xYw" = (
/obj/structure/flora/bush/leavy/style_random,
/turf/open/floor/grass,
@@ -75514,20 +77842,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/maintenance/department/electrical)
-"xYB" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/structure/railing{
- dir = 8
- },
-/obj/effect/turf_decal/tile/blue/half/contrasted{
- dir = 8
- },
-/obj/effect/turf_decal/tile/neutral/half/contrasted{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral,
-/turf/open/floor/iron,
-/area/station/commons/locker)
"xYI" = (
/obj/machinery/telecomms/server/presets/science,
/turf/open/floor/iron/dark/telecomms,
@@ -75646,12 +77960,6 @@
"yaL" = (
/turf/closed/wall/r_wall,
/area/station/engineering/engine_smes)
-"yaR" = (
-/obj/structure/disposalpipe/trunk/multiz/down{
- dir = 4
- },
-/turf/open/floor/plating,
-/area/station/maintenance/port/greater)
"yaT" = (
/obj/machinery/atmospherics/components/unary/vent_pump/siphon/monitored/oxygen_output{
dir = 1
@@ -75801,6 +78109,13 @@
},
/turf/open/floor/wood/tile,
/area/station/service/theater)
+"ycA" = (
+/obj/effect/turf_decal/stripes/corner,
+/obj/effect/turf_decal/tile/blue{
+ dir = 4
+ },
+/turf/open/floor/iron/white/corner,
+/area/station/hallway/secondary/entry)
"ycB" = (
/obj/effect/spawner/structure/window,
/turf/open/floor/plating,
@@ -75871,6 +78186,12 @@
/obj/machinery/light/small/directional/south,
/turf/open/floor/iron/smooth,
/area/station/maintenance/starboard/fore)
+"ydH" = (
+/obj/structure/disposalpipe/segment,
+/obj/effect/decal/cleanable/glass,
+/obj/structure/sign/warning/no_smoking/circle/directional/west,
+/turf/open/floor/plating/icemoon,
+/area/station/maintenance/port/lesser)
"ydI" = (
/turf/closed/wall/r_wall,
/area/station/hallway/secondary/entry)
@@ -75906,6 +78227,12 @@
},
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
+"yel" = (
+/obj/structure/disposalpipe/segment,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"yep" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -75945,13 +78272,6 @@
/obj/machinery/light/small/directional/west,
/turf/open/floor/wood,
/area/station/service/library)
-"yfb" = (
-/obj/structure/closet/emcloset,
-/obj/effect/turf_decal/stripes/line{
- dir = 5
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"yfp" = (
/obj/machinery/firealarm/directional/north,
/turf/open/floor/wood/parquet,
@@ -76024,24 +78344,11 @@
},
/turf/open/floor/iron/smooth_half,
/area/station/security/brig/upper)
-"ygX" = (
-/obj/effect/turf_decal/stripes/corner{
- dir = 8
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"yhe" = (
/obj/structure/cable,
/obj/machinery/light/directional/south,
/turf/open/floor/iron,
/area/station/cargo/sorting)
-"yhp" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/closed/wall,
-/area/station/maintenance/port/greater)
"yhw" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -76098,6 +78405,12 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/dark/textured,
/area/station/security/prison)
+"yjn" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 8
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"yju" = (
/obj/structure/table,
/obj/effect/spawner/random/maintenance/two,
@@ -76130,6 +78443,15 @@
/obj/structure/chair/stool/directional/south,
/turf/open/floor/iron,
/area/station/hallway/primary/starboard)
+"ykb" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"ykn" = (
/obj/structure/cable,
/obj/machinery/power/apc/auto_name/directional/west,
@@ -76182,6 +78504,12 @@
/obj/structure/sign/warning/cold_temp/directional/south,
/turf/open/floor/plating,
/area/station/maintenance/department/crew_quarters/bar)
+"ylt" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/pink/visible,
+/obj/structure/sign/poster/official/safety_internals/directional/east,
+/obj/structure/sign/poster/official/safety_internals/directional/east,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"ylz" = (
/obj/machinery/airalarm/directional/north,
/obj/effect/turf_decal/trimline/neutral/warning,
@@ -76229,6 +78557,13 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central)
+"ylV" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/components/binary/valve{
+ dir = 8
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"ymb" = (
/obj/structure/railing/corner{
dir = 4
@@ -88696,10 +91031,10 @@ oSU
oSU
oSU
oSU
-oSU
-oSU
-oSU
-oSU
+thA
+thA
+thA
+thA
oSU
oSU
oSU
@@ -88952,12 +91287,12 @@ oSU
oSU
oSU
oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
+thA
+thA
+thA
+thA
+thA
+thA
oSU
oSU
oSU
@@ -89208,15 +91543,15 @@ oSU
oSU
oSU
oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
+thA
+thA
+thA
+jAv
+iDt
+thA
+thA
+thA
+thA
oSU
oSU
oSU
@@ -89465,15 +91800,15 @@ oSU
oSU
oSU
oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
+thA
+thA
+iDt
+ghx
+ghx
+iDt
+thA
+thA
+thA
oSU
oSU
oSU
@@ -89721,17 +92056,17 @@ oSU
oSU
oSU
oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
+thA
+thA
+thA
+ghx
+ghx
+ghx
+ghx
+ghx
+thA
+thA
+thA
oSU
oSU
oSU
@@ -89978,18 +92313,18 @@ oSU
oSU
oSU
oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
+thA
+thA
+iDt
+ghx
+ghx
+ghx
+ghx
+ghx
+iDt
+thA
+thA
+thA
oSU
oSU
oSU
@@ -90235,18 +92570,18 @@ oSU
oSU
oSU
oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
+thA
+jAv
+ghx
+ghx
+ghx
+wIZ
+ghx
+ghx
+xxV
+thA
+thA
+thA
oSU
oSU
oSU
@@ -90491,19 +92826,19 @@ oSU
oSU
oSU
oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
+thA
+thA
+cCb
+ghx
+ghx
+euI
+ijY
+ghx
+ghx
+ghx
+iDt
+thA
+thA
oSU
oSU
oSU
@@ -90748,19 +93083,19 @@ oSU
oSU
oSU
oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
+thA
+thA
+iDt
+ghx
+ghx
+ghx
+ghx
+ghx
+ghx
+ghx
+iDt
+thA
+thA
oSU
oSU
oSU
@@ -91005,19 +93340,19 @@ oSU
oSU
oSU
oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
+thA
+iDt
+ghx
+ghx
+ghx
+ghx
+ghx
+ghx
+ghx
+iDt
+iDt
+thA
+thA
oSU
oSU
oSU
@@ -91261,20 +93596,20 @@ oSU
oSU
oSU
oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
+thA
+thA
+xxV
+ghx
+ghx
+ghx
+ghx
+ghx
+pfw
+iDt
+thA
+thA
+thA
+thA
oSU
oSU
oSU
@@ -91518,19 +93853,19 @@ oSU
oSU
oSU
oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
+thA
+thA
+ghx
+ghx
+ghx
+ghx
+iDt
+iDt
+iDt
+thA
+thA
+thA
+thA
oSU
oSU
oSU
@@ -91774,19 +94109,19 @@ oSU
oSU
oSU
oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
+thA
+thA
+thA
+ghx
+ghx
+ghx
+ghx
+thA
+thA
+thA
+thA
+thA
+thA
oSU
oSU
oSU
@@ -92031,17 +94366,17 @@ oSU
oSU
oSU
oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
+thA
+thA
+iDt
+ghx
+ghx
+ghx
+thA
+thA
+thA
+thA
+thA
oSU
oSU
oSU
@@ -92288,16 +94623,16 @@ thA
thA
oSU
oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
+thA
+thA
+iDt
+ghx
+ghx
+thA
+thA
+thA
+thA
+thA
oSU
oSU
oSU
@@ -92544,15 +94879,15 @@ thA
thA
thA
thA
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
+thA
+thA
+thA
+ghx
+ghx
+ghx
+thA
+thA
+thA
oSU
oSU
oSU
@@ -92802,21 +95137,21 @@ thA
thA
thA
thA
-ipf
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
+thA
+thA
+ghx
+ghx
+ghx
+thA
+thA
+thA
oSU
oSU
oSU
oSU
+thA
+thA
+thA
oSU
oSU
oSU
@@ -93060,22 +95395,22 @@ thA
thA
thA
thA
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
+thA
+ghx
+ghx
+ghx
+thA
+thA
+thA
+thA
+thA
+thA
+thA
+thA
+pfw
+thA
+thA
+thA
oSU
oSU
oSU
@@ -93318,21 +95653,21 @@ thA
thA
thA
thA
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
+ghx
+ghx
+ghx
+thA
+thA
+thA
+thA
+thA
+thA
+jAv
+iDt
+iDt
+thA
+iDt
+thA
oSU
oSU
oSU
@@ -93575,21 +95910,21 @@ thA
thA
thA
thA
+ghx
+ghx
+ghx
+thA
+iDt
+iDt
+thA
+thA
+ghx
+ghx
+ghx
+ghx
+ghx
+iDt
thA
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
oSU
oSU
oSU
@@ -93832,21 +96167,21 @@ thA
thA
thA
thA
+ghx
+ghx
+ghx
+ijY
+iDt
+ghx
+ghx
+ghx
+ghx
+ghx
+ghx
+ghx
+tLj
+iDt
thA
-thA
-thA
-thA
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
oSU
oSU
oSU
@@ -94089,21 +96424,21 @@ thA
thA
thA
thA
+iDt
+ghx
+ghx
+ghx
+ghx
+ghx
+thA
+thA
+xxV
+thA
+thA
thA
thA
thA
thA
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
-oSU
oSU
thA
thA
@@ -94346,16 +96681,16 @@ ghx
thA
thA
thA
+iDt
+ghx
+ghx
+ghx
+ghx
thA
thA
thA
thA
thA
-thA
-oSU
-oSU
-oSU
-oSU
oSU
oSU
oSU
@@ -94603,10 +96938,10 @@ ghx
thA
thA
thA
-thA
-thA
-thA
-thA
+iDt
+ghx
+ghx
+iDt
thA
thA
thA
@@ -94859,11 +97194,11 @@ ghx
thA
thA
thA
-thA
-thA
-thA
-thA
-thA
+iDt
+iDt
+ghx
+ghx
+iDt
thA
thA
thA
@@ -95115,12 +97450,12 @@ ghx
ghx
ghx
ghx
-thA
-thA
+iDt
+iDt
ghx
ghx
ghx
-thA
+iDt
thA
thA
thA
@@ -95377,7 +97712,7 @@ ghx
ghx
ghx
ghx
-thA
+iDt
thA
thA
thA
@@ -95634,7 +97969,7 @@ ghx
ghx
ghx
ghx
-thA
+iDt
thA
thA
thA
@@ -95890,8 +98225,8 @@ ghx
ghx
ghx
ghx
-thA
-thA
+iDt
+iDt
thA
thA
thA
@@ -96148,8 +98483,8 @@ ghx
ghx
ghx
ghx
-thA
-thA
+iDt
+iDt
thA
thA
thA
@@ -96405,9 +98740,9 @@ ghx
ghx
ghx
ghx
-thA
-thA
-thA
+iDt
+iDt
+iDt
thA
thA
thA
@@ -96665,7 +99000,7 @@ ghx
hpE
xuo
xuo
-thA
+iDt
thA
thA
thA
@@ -101762,7 +104097,7 @@ lBR
lBR
sCa
jRu
-kzr
+uNV
khb
xdZ
nNn
@@ -154233,9 +156568,9 @@ tjo
tjo
tjo
tjo
+iDt
tjo
-tjo
-tjo
+iDt
tjo
tjo
tjo
@@ -154490,9 +156825,9 @@ tjo
tjo
tjo
tjo
-tjo
-tjo
-tjo
+xxV
+jAv
+iDt
tjo
tjo
tjo
@@ -154747,9 +157082,9 @@ tjo
tjo
tjo
tjo
-tjo
-tjo
-tjo
+iDt
+pfw
+ebd
tjo
tjo
tjo
@@ -155003,10 +157338,10 @@ tjo
tjo
tjo
tjo
-tjo
-tjo
-tjo
-tjo
+iDt
+iDt
+iDt
+iDt
tjo
tjo
tjo
@@ -155260,11 +157595,11 @@ tjo
tjo
tjo
tjo
-tjo
-tjo
-tjo
-tjo
-tjo
+iDt
+gjq
+gjq
+gjq
+iDt
tjo
tjo
tjo
@@ -155516,12 +157851,12 @@ tjo
tjo
tjo
tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
+iDt
+gjq
+gjq
+gjq
+gjq
+iDt
tjo
tjo
tjo
@@ -155773,20 +158108,20 @@ tjo
tjo
tjo
tjo
+iDt
+gjq
+gjq
+gjq
+gjq
+jAv
tjo
tjo
tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
+thA
+thA
+thA
+thA
+thA
thA
thA
thA
@@ -156030,15 +158365,15 @@ tjo
tjo
tjo
tjo
+iDt
+xxV
+gjq
+gjq
+gjq
+gjq
tjo
tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
+thA
thA
thA
thA
@@ -156287,21 +158622,21 @@ tjo
tjo
tjo
tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
+iDt
+iDt
+gjq
+gjq
+gjq
+gjq
tjo
thA
thA
-thA
-thA
-thA
-thA
-thA
+iLh
+iLh
+iLh
+iLh
+iLh
+iLh
thA
thA
thA
@@ -156546,19 +158881,19 @@ tjo
tjo
tjo
tjo
-tjo
-tjo
-tjo
-tjo
+gjq
+gjq
+gjq
tjo
tjo
thA
thA
-thA
-thA
-thA
-thA
-thA
+iLh
+mWN
+mAM
+mwp
+fSi
+iLh
thA
thA
thA
@@ -156807,15 +159142,15 @@ tjo
tjo
tjo
tjo
-tjo
-tjo
-thA
-thA
-thA
-thA
thA
thA
thA
+iLh
+eoy
+dHk
+pJU
+wqU
+iLh
thA
thA
thA
@@ -157064,15 +159399,15 @@ tjo
tjo
tjo
tjo
-tjo
thA
thA
-thA
-thA
-tKI
-tKI
-tKI
-tKI
+iLh
+iLh
+jpC
+tbN
+jpC
+iLh
+iLh
thA
thA
szG
@@ -157320,16 +159655,16 @@ tjo
tjo
tjo
tjo
-tjo
-tjo
thA
thA
thA
-thA
-tKI
-ipa
-udc
-tKI
+iLh
+gga
+eoy
+dHk
+eoy
+pPY
+iLh
thA
thA
szG
@@ -157572,21 +159907,21 @@ tjo
tjo
tjo
tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
thA
thA
thA
thA
-tKI
-ibB
-qAz
-tKI
+thA
+thA
+thA
+thA
+iLh
+xgM
+mLm
+dxE
+ccB
+gcu
+iLh
thA
thA
gjq
@@ -157828,22 +160163,22 @@ tjo
tjo
tjo
tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
thA
thA
thA
thA
-tKI
-ndv
-kcE
-tKI
+thA
+thA
+thA
+thA
+thA
+iLh
+qxm
+nRv
+dHk
+vCy
+qVD
+iLh
szG
thA
gjq
@@ -158084,23 +160419,23 @@ tjo
tjo
tjo
tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
thA
thA
thA
-thA
-tKI
-jft
-pQs
-tKI
+iLh
+iLh
+iLh
+iLh
+iLh
+iLh
+iLh
+iLh
+gif
+huS
+jXe
+fmg
+tAO
+iLh
szG
szG
myZ
@@ -158340,24 +160675,24 @@ tjo
tjo
tjo
tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
thA
thA
thA
thA
-tKI
-lFr
-cwK
-tKI
+iLh
+pwg
+peG
+ucs
+crT
+xaO
+jGo
+iLh
+hVu
+eoy
+dHk
+qGJ
+nWn
+iLh
szG
szG
nzG
@@ -158592,29 +160927,29 @@ thA
thA
thA
thA
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
thA
thA
thA
thA
-tKI
-gyc
-afz
-tKI
+thA
+thA
+thA
+thA
+thA
+iLh
+jqj
+aiA
+wVq
+dcW
+kjt
+mUz
+kUU
+hSt
+tKq
+sGM
+haD
+lrz
+iLh
szG
szG
eId
@@ -158850,28 +161185,28 @@ thA
thA
thA
thA
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
thA
thA
thA
thA
-tKI
-mGl
-tKI
-tKI
+thA
+thA
+thA
+thA
+iLh
+gAd
+ukd
+iLh
+aBX
+aBX
+iLh
+iLh
+bPs
+bPs
+iLh
+bjv
+iLh
+iLh
iwS
iwS
sbf
@@ -159108,28 +161443,28 @@ thA
thA
thA
thA
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
thA
thA
thA
thA
-iwS
-pfj
-ehc
-rfz
-hXL
+thA
+thA
+thA
+iLh
+dcW
+niY
+ini
+dwo
+eKN
+oQt
+ydH
+wUu
+xrs
+iLh
+vad
+kMP
+wMw
+hoZ
iwS
iDt
iDt
@@ -159366,27 +161701,27 @@ thA
thA
thA
thA
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
thA
thA
thA
thA
-thA
-iwS
-udd
-gwz
-tDG
-gri
+ivF
+ivF
+iLh
+hYb
+iLh
+iLh
+fGJ
+nAg
+fkt
+oQt
+xrs
+ilD
+iLh
+pog
+qPs
+xCr
+wds
iwS
iDt
iDt
@@ -159624,26 +161959,26 @@ thA
thA
thA
thA
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-thA
-thA
-thA
-thA
-iwS
-iwS
-jLD
-xjY
-tDG
-iUY
+iDt
+kcW
+ivF
+ivF
+xUF
+uah
+icU
+jgx
+iLh
+bPs
+bPs
+iLh
+iLh
+iLh
+iLh
+iLh
+xkH
+oeB
+qxI
+sTh
qMo
iDt
cCb
@@ -159880,27 +162215,27 @@ thA
thA
thA
thA
-thA
-thA
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-thA
-thA
-thA
-thA
+iDt
+iDt
+iDt
+snd
+kkA
+erw
+wrl
+aOa
+uhb
+aSC
+cQi
+boS
+ivF
+sqb
+gVm
iwS
iJM
-iEh
-tDG
-nMH
-lXj
+dNl
+qxI
+qxI
+rVC
qMo
iDt
iDt
@@ -160137,27 +162472,27 @@ gjq
thA
thA
thA
-thA
-thA
-thA
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-tjo
-thA
-thA
-thA
-thA
+iDt
+iDt
+scw
+snd
+ndl
+lFA
+ivF
+ivF
+dER
+fFD
+bYz
+trc
+ivF
+pcc
+fdX
iwS
iJM
-iEh
-tDG
-ipZ
-pNG
+dNl
+qxI
+qxI
+coT
qMo
iDt
iDt
@@ -160394,27 +162729,27 @@ gjq
gjq
thA
thA
-thA
-thA
-thA
-thA
-thA
-thA
-tjo
-tjo
-tjo
-tjo
-tjo
-thA
-thA
-thA
-thA
+iDt
+iDt
+scw
+snd
+hJp
+hby
+czz
+xYr
+jwB
+bIo
+nit
+uMD
+ivF
iwS
iwS
-pQI
-bIq
-gwz
-dKl
+iwS
+iwS
+oqj
+kTX
+iJL
+dwI
qMo
iDt
iDt
@@ -160651,33 +162986,33 @@ gjq
gjq
gjq
gjq
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-iwS
-iqT
-tDG
-tDG
-igs
-iwS
-tKI
-wkj
-tKI
iDt
iDt
+iDt
+snd
+cmT
+fxd
+bEd
+mua
+nfn
+tHX
+nit
+ebC
+ivF
+ktp
+lIU
+xrL
+iwS
+sFd
+iuH
+iuH
+mFY
+iwS
+iwS
+gJK
+iwS
+wkB
+iDt
jZN
gjq
gjq
@@ -160908,31 +163243,31 @@ gjq
gjq
gjq
gjq
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-iwS
-kAO
-nMH
-vji
-tDG
-jGr
-pdf
-pdf
-aFr
+gjq
+nfG
+qbU
+ivF
+jwH
+jwH
+jwH
+jHV
+aLz
+jul
+oRE
+uMD
+ivF
+wYz
+jIr
+lZe
+xXd
+ltW
+nlO
+wEM
+nlO
+vzn
+knd
+grk
+qMo
iDt
iDt
iDt
@@ -161155,7 +163490,7 @@ thA
thA
thA
thA
-thA
+jKY
gjq
gjq
thA
@@ -161166,30 +163501,30 @@ gjq
gjq
gjq
gjq
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
+gjq
+scw
+hyj
+slX
+rLw
+ceY
+kbq
+sLR
+awR
+sLR
+dsR
+ivF
+bUW
+kgY
+bar
+nlO
+nlO
+gwz
+nMH
+ciH
iwS
-iwS
-iwS
-iwS
-iwS
-iwS
-kZQ
-vHE
-aFr
+fpC
+szX
+qMo
iDt
scw
scw
@@ -161424,29 +163759,29 @@ gjq
gjq
gjq
gjq
-gjq
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-tKI
-aqy
-tKI
+qsq
+ivF
+ivF
+ivF
+ivF
+ivF
+jnR
+jnR
+jnR
+ivF
+ivF
+nRx
+pEg
+uyW
+iwS
+kDm
+ePn
+oDV
+iqn
+iwS
+iwS
+aBT
+iwS
iDt
iDt
iDt
@@ -161683,27 +164018,27 @@ gjq
gjq
gjq
gjq
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-thA
-tKI
-pdf
-aFr
+iDt
+iDt
+iDt
+mdV
+scw
+scw
+iDt
+xdY
+iwS
+iwS
+iwS
+iwS
+iwS
+iwS
+iwS
+iwS
+iwS
+iwS
+iwS
+dYq
+qMo
iDt
scw
gjq
@@ -161942,6 +164277,12 @@ gjq
gjq
gjq
gjq
+scw
+iDt
+iDt
+iDt
+iDt
+iDt
thA
thA
thA
@@ -161952,15 +164293,9 @@ thA
thA
thA
thA
-thA
-thA
-thA
-thA
-thA
-thA
-tKI
-czV
-tKI
+iwS
+rBM
+iwS
iDt
scw
gjq
@@ -166007,7 +168342,7 @@ hPs
qdH
dck
scl
-ohG
+tww
scl
ilZ
sws
@@ -169109,7 +171444,7 @@ xHE
xHE
hgM
fvO
-eHK
+mBa
hgM
mKq
xEd
@@ -169366,7 +171701,7 @@ uME
uME
uME
bYB
-mBa
+hBg
hgM
xhK
xhK
@@ -169874,7 +172209,7 @@ hUz
hUz
bjp
bjp
-bBn
+poe
ryu
kZt
ryu
@@ -170133,7 +172468,7 @@ ate
ate
fgJ
cpw
-xBu
+jyl
ihB
ddp
hBg
@@ -170186,7 +172521,7 @@ iDt
vcj
vcj
vcj
-vOY
+bfa
koA
uFw
vcj
@@ -170388,7 +172723,7 @@ syB
syB
syB
syB
-fTz
+sNr
pdz
eic
mLT
@@ -176844,7 +179179,7 @@ mdZ
wUY
iZp
mdZ
-oGR
+qmN
pbD
let
sBy
@@ -190765,9 +193100,9 @@ egf
egf
egf
egf
-tdY
-tdY
-dRF
+fSG
+fSG
+bId
gcy
jJG
jJG
@@ -191022,10 +193357,10 @@ inb
keV
gWZ
wHd
-mLK
+izc
wHd
vcH
-gxn
+gnq
xEF
qSk
oFd
@@ -191279,10 +193614,10 @@ inb
sDA
mYd
mIC
-aWs
+dJk
wPC
qSk
-jPA
+sbd
rEh
qSk
jwj
@@ -191536,10 +193871,10 @@ inb
keV
nBV
iao
-iPD
+hKj
iao
odf
-jPA
+sbd
jaY
rhY
uSq
@@ -191793,10 +194128,10 @@ bgx
bgx
bgx
bgx
-txk
+qWI
bgx
bgx
-tmb
+pAc
bgx
uIf
uIf
@@ -192048,12 +194383,12 @@ vzD
vzD
vzD
jdd
-xEt
-aUv
-oOq
-jPE
-ieZ
-coH
+sHV
+rTs
+rEU
+oHo
+gOq
+bBb
vzD
thA
thA
@@ -192564,7 +194899,7 @@ jCl
bFq
axu
dVq
-uJs
+xEt
jCl
jCl
iVY
@@ -213849,6 +216184,11 @@ wNO
wNO
wNO
wNO
+bln
+bln
+lSu
+bln
+bln
wNO
wNO
wNO
@@ -213860,18 +216200,13 @@ wNO
wNO
wNO
wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
+bln
+bln
+lSu
+lSu
+bln
+bln
+bln
wNO
wNO
wNO
@@ -214105,6 +216440,13 @@ wNO
wNO
wNO
wNO
+bln
+gnZ
+bln
+hcw
+lSu
+gnZ
+bln
wNO
wNO
wNO
@@ -214114,22 +216456,15 @@ wNO
wNO
wNO
wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
+bln
+gnZ
+lSu
+weW
+bln
+gnZ
+bln
+bln
+bln
wNO
wNO
wNO
@@ -214361,33 +216696,33 @@ wNO
wNO
wNO
wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
+bln
+bln
+bln
+sEB
+sEB
+sEB
+lSu
+bln
+bln
+lSu
+bln
+bln
+bln
+bln
+bln
+lSu
+bln
+lSu
+lSu
+sEB
+sEB
+sEB
+lSu
+bln
+bln
+bln
+bln
wNO
wNO
wNO
@@ -214617,35 +216952,35 @@ wNO
wNO
wNO
wNO
-wNO
-wNO
-rSY
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-fPx
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
+bln
+bln
+lSu
+eqn
+sEB
+sEB
+sEB
+sjU
+bln
+lSu
+bln
+bln
+jNZ
+kKU
+rzO
+lSu
+bln
+lSu
+bln
+eqn
+sEB
+sEB
+sEB
+sjU
+bln
+mQb
+bln
+bln
+bln
wNO
wNO
wNO
@@ -214873,37 +217208,37 @@ wNO
wNO
wNO
wNO
+bln
+bln
+bln
+bln
+fUR
sEB
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
+sEB
+sEB
+fUR
+bln
+bln
+bln
+jNZ
+sEB
+sEB
+sEB
+rzO
+bln
+bln
+bln
+fUR
+sEB
+sEB
+sEB
+fUR
+bln
+bln
+bln
+bln
+bln
+bln
wNO
wNO
wNO
@@ -215129,39 +217464,39 @@ wNO
wNO
wNO
wNO
-wNO
+bln
+bln
+bln
+mQb
+bln
+fUR
sEB
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
+tqR
+sEB
+fUR
+lSu
+gnZ
+jNZ
+sEB
+sEB
+sEB
+sEB
+sEB
+rzO
+gnZ
+lSu
+fUR
+sEB
+tqR
+sEB
+fUR
+lSu
+ntK
+bln
+uer
+bln
+bln
+bln
wNO
wNO
wNO
@@ -215385,41 +217720,41 @@ wNO
wNO
wNO
wNO
-wNO
-wNO
+bln
+bln
+mQb
+bln
+ntK
+bln
+fUR
+fUR
+mnu
+fUR
+fUR
+lSu
+bln
+miY
sEB
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
-wNO
+sEB
+sEB
+sEB
+sEB
+qVo
+bln
+bln
+fUR
+fUR
+mnu
+fUR
+fUR
+bln
+bln
+lBD
+bln
+fsm
+stJ
+bln
+bln
wNO
wNO
wNO
@@ -215632,53 +217967,53 @@ wNO
wNO
wNO
wNO
+wNO
+wNO
+wNO
+wNO
+wNO
+wNO
+wNO
bln
bln
bln
bln
bln
+uer
bln
bln
+umb
+fUR
+mXT
+cJt
+eWF
+fUR
+htd
+jNZ
sEB
-bln
-bln
-bln
-bln
sEB
-bln
sEB
-tqR
sEB
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
sEB
-tqR
sEB
+qVo
+lSu
+umb
+fUR
+mXT
+cJt
+iMu
+fUR
+oqJ
+iWb
+lSu
+lSu
bln
bln
bln
bln
bln
-bln
-bln
-vsI
-sEB
-vsI
-bln
-bln
-bln
-bln
-bln
-bln
+gnZ
bln
bln
bln
@@ -215690,7 +218025,7 @@ aBR
aBR
aBR
aBR
-aBR
+gnZ
aBR
aBR
aBR
@@ -215889,59 +218224,59 @@ wNO
wNO
wNO
wNO
+wNO
+wNO
+wNO
bln
bln
bln
bln
bln
bln
+bln
+bln
+stJ
+bln
+bln
+lSu
+bln
+fUR
+fUR
+xau
+fUR
+fUR
+gSE
+sNA
sEB
sEB
sEB
sEB
sEB
-bln
sEB
-ydI
+sEB
+ntx
+lSu
fUR
-rhE
fUR
-ydI
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-ydI
+xau
fUR
-uHi
-fUR
-ydI
-bln
-bln
-bln
-bln
-bln
-bln
-fUR
-piy
fUR
bln
+fUR
+fUR
+fUR
+fUR
+fUR
+htd
bln
bln
bln
+lSu
bln
bln
bln
-bln
-bln
-bln
-bln
-bln
+lSu
+gnZ
aBR
aBR
aBR
@@ -216146,56 +218481,56 @@ wNO
wNO
wNO
wNO
+wNO
bln
bln
bln
-hsI
-hsI
-hsI
-hsI
-hsI
-hsI
-hsI
-hsI
-hsI
-hsI
-hsI
-ack
-cJt
-eWF
-rvE
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-rvE
-ack
-cJt
-iMu
-ydI
-bln
-bln
-bln
-bln
-bln
-bln
-lJj
-cJt
-lJj
-bln
-bln
+mQb
+bln
+bln
+lBD
bln
bln
bln
bln
bln
+gnZ
+lSu
+fBN
+fUR
+irX
+kyg
+rwW
+uhx
+uhx
+uhx
+sEB
+sEB
+sEB
+sEB
+sEB
+sEB
+sEB
+uhx
+uhx
+uhx
+rwW
+jHX
+fJd
+fUR
+lSu
+fUR
+kod
+gFL
+rwW
+uhx
+uhx
+uhx
+tMa
+lSu
bln
bln
+lSu
bln
bln
bln
@@ -216403,24 +218738,7 @@ wNO
wNO
wNO
wNO
-bln
-bln
-bln
-hsI
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-hsI
-ppN
-bRt
-fUR
-ydI
+wNO
bln
bln
bln
@@ -216429,35 +218747,52 @@ bln
bln
bln
bln
+lBD
bln
-ydI
-fUR
-rTD
-ppN
-ydI
+lSu
+hjU
+kKU
+kKU
+rzO
+uhx
+ykb
+hAG
+dDp
+cJt
+cJt
+jMw
+sEB
+sEB
+sEB
+sEB
+sEB
+sEB
+sEB
+skc
+cJt
+cJt
+qYz
+lnL
+otG
+uhx
+lSu
+uhx
+ykb
+hAG
+skc
+cJt
+cJt
+qYz
+lSu
+lSu
+lSu
+bln
+lSu
bln
bln
+lSu
bln
bln
-bln
-ydI
-ydI
-fNj
-fUR
-rvE
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-aBR
aBR
aBR
aBR
@@ -216660,62 +218995,62 @@ wNO
wNO
wNO
wNO
+wNO
bln
bln
-sEB
-hsI
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-hsI
-qjj
-tEG
-rwW
+uer
+bln
+stJ
+bln
+bln
+bln
+bln
+bln
+jNZ
+fUR
+fUR
+nFL
+fUR
+fUR
+ykb
+wOy
+fHb
+uhx
uhx
uhx
sEB
-bln
-bln
-bln
-bln
-bln
+sEB
+sEB
+sEB
+sEB
+sEB
sEB
uhx
uhx
-rwW
-fdO
-crc
-ydI
-bln
-bln
-bln
-bln
-bln
-ydI
-qjj
-tEG
-rwW
+uhx
+fHb
+bzg
+otG
+uhx
+lSu
+uhx
+ykb
+wOy
+fHb
uhx
uhx
-sEB
+uhx
+lSu
+lSu
+lSu
+lSu
+bln
+lSu
bln
bln
bln
bln
bln
-bln
-bln
-bln
-bln
-bln
-aBR
-aBR
aBR
aBR
aBR
@@ -216917,63 +219252,63 @@ wNO
wNO
wNO
wNO
+wNO
bln
bln
+bln
+bln
+bln
+bln
+bln
+bln
+bln
+bln
+miY
+fUR
+fNy
+xAk
+txd
+fUR
+uRx
+jdY
+rsw
+rin
+uhx
+caX
sEB
-hsI
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-hsI
-bAp
-abu
-dDp
-cJt
-jMw
sEB
-bln
-bln
-bln
-bln
-bln
sEB
-skc
-cJt
-qYz
-mXm
-pPG
-ydI
+sEB
+sEB
+sEB
+sEB
+oMa
+uhx
+tbR
+dcG
+jXm
+otG
+uhx
+lSu
+uhx
+ykb
+jdY
+rsw
+phu
+uhx
+dsg
+bln
+lSu
bln
bln
bln
-bln
-bln
-ydI
-lWU
-uVf
-uQS
-cJt
-dBj
-jVD
+lSu
bln
bln
bln
+lSu
bln
bln
-bln
-bln
-bln
-bln
-bln
-bln
-aBR
-aBR
aBR
aBR
aBR
@@ -217174,64 +219509,64 @@ wNO
wNO
wNO
wNO
+wNO
bln
bln
-sEB
-hsI
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-hsI
-qjj
-tEG
-fHb
-uhx
+bln
+bln
+lBD
+bln
+bln
+mQb
+bln
+bln
+miY
+mVE
+ryM
+uee
+dJY
+qlP
+nDJ
+sfr
+fsv
+aZK
uhx
sEB
-bln
-bln
-bln
-bln
-bln
+sEB
+sEB
+sEB
+sEB
+sEB
+sEB
+sEB
sEB
uhx
+iog
+fsv
+lFg
+dvO
uhx
-fHb
-fdO
-wOy
+lSu
uhx
-bln
-bln
-bln
-bln
-bln
+ykb
+sfr
+fsv
+iQX
uhx
-qjj
-tEG
-fHb
-uhx
-uhx
-sEB
+qVo
+bln
+bln
+lSu
+bln
+lSu
+bln
+lSu
bln
bln
bln
bln
bln
bln
-bln
-bln
-bln
-bln
-bln
-aBR
-aBR
-aBR
aBR
aBR
aBR
@@ -217431,65 +219766,65 @@ wNO
wNO
wNO
wNO
+wNO
+bln
+bln
+lBD
bln
bln
bln
-hsI
-qNk
-qNk
-qNk
-qNk
-iIw
-qNk
-qNk
-qNk
-qNk
-hsI
-qjj
-ohs
-bPP
-cSb
+bln
+bln
+fsm
+bln
+tIc
+fUR
+fUR
+mXH
+wWS
+mVE
+nDJ
+fYW
+fsv
+xdH
uhx
-bln
-bln
-bln
-bln
-bln
-bln
-bln
+sEB
+sEB
+sEB
+sEB
+sEB
+sEB
+sEB
+sEB
+qVo
uhx
-dgk
-bPP
-nXR
-wOy
+mgc
+fsv
+sfr
+dvO
uhx
-bln
-bln
-bln
-bln
-bln
+lSu
uhx
-qjj
-oAk
-bPP
-cSb
+ovm
+fYW
+fsv
+asm
uhx
+qVo
+bln
+lSu
+bln
+lSu
+bln
+bln
+lSu
+bln
+lSu
bln
bln
bln
bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-aBR
-aBR
-aBR
-aBR
+gnZ
aBR
aBR
aBR
@@ -217688,49 +220023,57 @@ wNO
wNO
wNO
wNO
+wNO
bln
bln
bln
-hsI
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-hsI
-qjj
-wfs
-fsv
-jDY
+bln
+bln
+bln
+bln
+bln
+uer
+bln
+miY
+sEB
+ydI
+nvU
+ydI
+ydI
+btm
+fld
+ycA
+lpH
uhx
-bln
-bln
-bln
-bln
-bln
-bln
-bln
+oJH
+sEB
+sEB
+sEB
+sEB
+sEB
+sEB
+sEB
+fiv
uhx
-joB
-fsv
-loW
-wOy
+jDS
+lKc
+uMm
+dvO
uhx
-bln
-bln
-bln
-bln
-bln
+lSu
uhx
-qjj
-fsv
-fsv
-jDY
+ovm
+fld
+ycA
+lpH
uhx
+hgx
+bln
+lSu
+bln
+bln
+lSu
+lSu
bln
bln
bln
@@ -217739,14 +220082,6 @@ bln
bln
bln
bln
-bln
-bln
-bln
-bln
-aBR
-aBR
-aBR
-aBR
aBR
aBR
aBR
@@ -217945,65 +220280,65 @@ wNO
wNO
wNO
wNO
-bln
-bln
-bln
-hsI
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-hsI
-dtY
-wfs
-fsv
-tEG
-uhx
+wNO
bln
bln
bln
bln
bln
+stJ
bln
bln
-uhx
-eVn
-fsv
-wfs
+bln
+bln
+hWW
+ydI
+ydI
+qKJ
+kHl
+mVE
+nDJ
wOy
+rwW
+uhx
+uhx
+uhx
+sEB
+sEB
+sEB
+sEB
+sEB
+sEB
+sEB
+uhx
+uhx
+uhx
+fHb
+bzg
+dvO
+uhx
+lSu
+uhx
+ovm
+wOy
+fHb
+uhx
+uhx
uhx
bln
+lSu
+lSu
bln
bln
bln
+lSu
bln
-uhx
-ceh
-fsv
-fsv
-ncp
-uhx
+lSu
bln
bln
+lSu
bln
bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-aBR
-aBR
-aBR
-aBR
aBR
aBR
aBR
@@ -218202,65 +220537,65 @@ wNO
wNO
wNO
wNO
+wNO
bln
bln
+bln
+lBD
+bln
+bln
+bln
+hjU
+kKU
+kKU
sEB
-hsI
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-qNk
-hsI
-qjj
-uDR
-dhJ
-gaa
+mVE
+azN
+xft
+lRg
+iaU
+nDJ
+hAG
+dDp
+cJt
+cJt
+jMw
+sEB
+sEB
+sEB
+sEB
+sEB
+sEB
+sEB
+lAC
+cJt
+cJt
+qYz
+lnL
+dvO
uhx
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-uhx
-yfb
-dhJ
-iQr
-wOy
+lSu
uhx
+ovm
+uhA
+lAC
+cJt
+cJt
+qYz
+rNE
+lSu
+lSu
+bln
+ozo
bln
bln
bln
bln
bln
-uhx
-uPZ
-kyO
-dhJ
-vEu
-uhx
+lSu
+lSu
bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-aBR
-aBR
-aBR
-aBR
+lSu
aBR
aBR
aBR
@@ -218461,63 +220796,63 @@ wNO
wNO
bln
bln
+lBD
bln
-hsI
-qNk
-qNk
-qNk
-qNk
-rCb
-qNk
-qNk
-qNk
-qNk
-hsI
-qjj
-jPK
+bln
+bln
+bln
+bln
+lJO
+hEI
+hEI
+biY
+biY
+kCY
+bLs
+xRI
+ydI
+ior
+wOy
+fHb
+uhx
+uhx
+uhx
+sEB
+sEB
+sEB
+sEB
+sEB
+sEB
+sEB
+uhx
+uhx
+uhx
+rwW
+bzg
+oVX
+fUR
+lSu
+fUR
+tvm
+wOy
rwW
uhx
uhx
-sEB
-bln
-bln
-bln
-bln
-bln
-sEB
-uhx
-uhx
-fHb
-nSX
-wOy
uhx
+tMa
+lSu
+lSu
+lSu
+bln
+lSu
bln
bln
+lSu
+lSu
+lSu
bln
+lSu
bln
-bln
-uhx
-uPZ
-tEG
-fHb
-uhx
-uhx
-sEB
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-aBR
-aBR
-aBR
-aBR
aBR
aBR
aBR
@@ -218719,62 +221054,62 @@ wNO
bln
bln
bln
-hsI
-hsI
-hsI
-vLl
-fxe
-nsi
-hJL
-vLl
-vLl
-vLl
-hsI
-wAU
-mmo
-dDp
-cJt
-jMw
+bln
+bln
+bln
+stJ
+bln
+lJO
+cyV
+muv
+qVN
+biY
+biY
+biY
+biY
+ydI
+oiD
+xVN
+fUR
+fUR
+nMj
+chP
sEB
-bln
-bln
-bln
-bln
-bln
sEB
-lAC
-cJt
-sde
-rOj
-kYQ
-uhx
-bln
sEB
-ibR
+prs
sEB
-bln
-uhx
-uPZ
-uVf
-jcw
-cJt
-sQm
sEB
+sEB
+pJb
+waT
+fUR
+fUR
+bAo
+nAX
+fUR
+fUR
+fUR
+qeF
+xVN
+fUR
+fUR
+oqJ
+bln
+bln
+lSu
+bln
+bln
+lSu
+bln
+bln
+lSu
bln
bln
bln
+lSu
bln
bln
-bln
-bln
-bln
-bln
-bln
-bln
-aBR
-aBR
-aBR
-aBR
aBR
aBR
aBR
@@ -218977,61 +221312,61 @@ bln
bln
bln
bln
+mQb
+bln
+bln
+lJO
+lJO
+jEB
+nOx
+cwe
+dIx
+laB
+laB
+lJO
+iku
+nDJ
+wOy
+jBK
+fUR
+rzO
+lSu
+mZf
+ooL
sEB
-hsI
-hNX
-vpx
-vpx
-itC
-vpx
-vpx
-kAl
-wUw
-wZL
-jPK
-fHb
-uhx
-uhx
sEB
-bln
-bln
-bln
-bln
-bln
sEB
-uhx
-uhx
-rwW
-nSX
-gdx
-ydI
+ooL
+rwt
+lSu
+lSu
+fUR
+rJr
+bzg
+dvO
+clT
+fUR
+xce
+ovm
+wOy
+rCU
+fUR
bln
-uhx
-wet
-uhx
+uer
bln
-ydI
-tXn
-tEG
-rwW
-uhx
-uhx
-sEB
+gnZ
+lSu
+bln
+bln
+bln
+lSu
+gnZ
bln
bln
bln
bln
bln
-ozo
-bln
-bln
-bln
-bln
-bln
-aBR
-aBR
-aBR
-aBR
+gnZ
aBR
aBR
aBR
@@ -219235,43 +221570,46 @@ bln
bln
bln
bln
-vLl
-oHU
-sjc
-sjc
-vzW
-hEy
-nNY
-cjG
-bGn
-ivG
-ygX
-exl
-uhx
bln
-bln
-bln
-bln
-dLv
-bln
-bln
-bln
-bln
-uhx
-jJa
-wda
-bFP
-ydI
+lBD
+lJO
+kQg
+tLB
+bIl
+ivi
+sbD
+hjI
+heg
+lJO
+htq
+nDJ
+wOy
+eyk
+fUR
+fUR
+fUR
+fUR
uhx
uhx
-cJt
uhx
uhx
-ydI
-uPZ
-oAk
-exl
uhx
+fUR
+fUR
+fUR
+fUR
+dWl
+bzg
+dvO
+mEv
+fUR
+gCq
+ovm
+wOy
+eyk
+fUR
+bln
+iWb
bln
bln
bln
@@ -219308,9 +221646,6 @@ aBR
aBR
aBR
aBR
-aBR
-aBR
-aBR
wNO
wNO
wNO
@@ -219489,46 +221824,50 @@ wNO
wNO
bln
bln
+lBD
bln
bln
+uer
bln
-hsI
-ubG
-xTP
-hLm
-vhX
-ksa
-sle
-cRS
-hsI
-ssB
-wfs
-efP
-ydI
-ydI
-ydI
-uhx
-uhx
-uhx
-uhx
-uhx
-ydI
-ydI
-ydI
-std
-wfs
-aDN
+lJO
+kQg
+ylt
+ylV
+gfY
+lJO
+lJO
+lJO
+lJO
fUR
-cSb
-fHb
-fnL
-rwW
-vIm
+nmA
+oor
fUR
-dnD
-fsv
-bGL
-ydI
+fUR
+fUR
+shT
+kHq
+oOP
+ccS
+ccS
+ccS
+lVY
+oHY
+xuW
+fUR
+fUR
+fUR
+gjN
+nuM
+fUR
+fUR
+fUR
+lSF
+tku
+fUR
+fUR
+fUR
+fUR
+stJ
bln
bln
bln
@@ -219540,10 +221879,6 @@ bln
bln
bln
bln
-bln
-bln
-aBR
-aBR
aBR
aBR
aBR
@@ -219749,58 +222084,58 @@ bln
bln
bln
bln
-hsI
-hsI
-hsI
-hsI
+bln
+bln
lJO
lJO
lJO
+fRb
lJO
lJO
-uXY
-gDO
-nWP
-qCE
-rDR
-rDR
-rDR
-rDR
-rDR
-rDR
-rDR
-sAV
-rDR
-orT
-ogM
-gDO
-gDO
-xEP
-nWP
-rDR
-ukJ
-rDR
-mDn
-gXS
-gXS
+fjF
+qhO
+lJO
+lIT
+qpt
+fBQ
+tHB
+vmC
+syL
+dwb
fsv
-fMJ
-rvE
+cuc
+hgr
+qsh
+hgr
+xFs
+fsv
+cmV
+bXx
+aui
+qTj
+btW
+jJd
+eyj
+lGL
+bXx
+oMq
+tEc
+uUu
+sEg
+iVi
+tKI
+tKI
+tKI
+tKI
+htd
+ntK
+bln
+lBD
bln
bln
bln
bln
bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-aBR
-aBR
aBR
aBR
aBR
@@ -220006,51 +222341,51 @@ bln
bln
bln
bln
-sEB
-sEB
-sEB
+bln
+jNZ
mGf
lJO
-sbD
-qhO
-vFe
-aHL
-bFL
-oUr
-uQL
-emL
-uQL
-dEL
-aLK
-uQL
-pLO
-qyU
+rrn
+nud
+hjI
+ndz
+hjI
+xmo
+vmx
+uBL
+nvI
+nvI
+oTc
+cQa
+nvI
+fwM
fsv
+cuc
+hgr
+hgr
+hgr
+xFs
fsv
-rZs
-fsv
-fsv
-wfs
-fsv
-viP
-wlx
-fsv
-qvm
-qyU
-jaj
-uee
-dkN
-fsv
-fMJ
-fUR
-bln
-bln
-bln
-bln
-bln
-bln
-bln
+dpU
+swK
+iCw
+ubx
+swK
+swK
+swK
+wfF
+rUv
+nqD
+thX
+peM
+iES
+mKa
+ldw
+bCQ
+bCQ
+tKI
bln
+uer
bln
bln
bln
@@ -220257,59 +222592,59 @@ wNO
wNO
wNO
wNO
-wNO
+bln
bln
ozo
bln
bln
+ntK
bln
-bln
-sEB
lJO
lJO
lJO
-paV
-aDx
-eUf
+pOq
+cKe
+thY
+hjI
+ilv
+xmo
lJO
-lJO
-lJO
-lJO
-lJO
-lJO
-iRo
-iRo
-iRo
-iRo
-hII
-uJZ
-uGG
-uGG
-uGG
-uGG
-eMF
-cSM
+fUR
+fUR
+mVE
+fUR
+fUR
+fUR
+kIh
+fsv
+cuc
+hgr
+jIp
+hgr
+xFs
+fsv
+jLM
+fUR
+fUR
+fUR
+koQ
+koQ
+fUR
+fUR
+fUR
+krW
+nEA
nwT
nwT
nwT
nwT
-fxJ
-nwT
tKI
-tdi
+pgE
tKI
-ivF
-ivF
-ivF
-ivF
-ivF
-ivF
-ivF
-bln
-bln
-bln
-bln
+iWb
+lBD
bln
+mQb
bln
bln
bln
@@ -220514,58 +222849,58 @@ wNO
wNO
wNO
wNO
-wNO
bln
bln
bln
+stJ
bln
bln
bln
-sEB
cyH
hjI
nbj
-eUf
+hjI
+uDc
xyO
eUf
-eUf
-hpN
-anl
-anl
-anl
-lJO
-tCn
-eaS
-kdW
-iRo
-aUr
-nNw
-rLb
-oLI
-apz
-dHG
-anG
-fsv
+aUm
+kEY
+kEY
+qPq
+gsN
+nwr
+owk
+gjZ
+abv
+wdo
+alD
+ael
+kdU
+kdU
+kdU
+jbJ
+xvl
+jLM
+buF
+fUR
+xxI
+juu
+juu
+lnp
+gel
+fUR
+teE
+bKA
nwT
-bPw
-wjj
-xmu
-pIX
-esj
+hAo
+tzM
+vgj
+tKI
+bCQ
tKI
-lgr
tKI
-dRm
-kSh
-nUw
-ilQ
-sbc
-ftg
-waa
-bln
-bln
-bln
bln
+mQb
bln
bln
bln
@@ -220771,56 +223106,56 @@ wNO
wNO
wNO
wNO
-wNO
-bln
-bln
+bln
+lBD
bln
bln
+uer
bln
bln
lJO
lJO
lJO
lJO
-eUf
+uDc
lJO
lJO
-cya
+fsZ
lJO
lJO
lJO
-anl
-lJO
-dzX
-ufy
-tVz
-qqz
-aUr
-nNw
-jbh
-tPg
-pqa
-ejW
-anG
-fsv
-nwT
-ohV
-jdj
-eye
-lvv
-gBs
+opS
+jIn
+byd
+iRo
+bvq
+kHP
+cuc
+mVE
+mVE
+mVE
+mVE
+mVE
+xFs
+jLM
+dvf
+fUR
+juu
+jNB
+qku
+ukD
+hrh
+fUR
+wtP
+gMt
+cut
+pGd
+bPw
+ixb
tKI
-lgr
-tKI
-lOg
-pzQ
-ivF
-oQv
-ivF
-oQv
-oQv
-bln
-bln
+jLX
+fbY
+teN
bln
bln
bln
@@ -221034,52 +223369,52 @@ bln
bln
bln
bln
-bln
lJO
-cTK
-asO
-bBr
-eUf
lJO
-sEx
-mcX
-awh
-aaI
+fEd
+weL
lJO
-anl
+uDc
lJO
-xMg
-xyY
-jFi
-gbt
-aUr
-nNw
-kMM
-hUj
-hUj
-kMM
-nnK
-ijA
-nwT
-bPw
-oCj
-dAO
-liQ
+tEi
+dxu
+nUh
+qjr
+lJO
+qYA
+xnV
+qEK
+roX
+rMu
+kHP
+cuc
+mVE
+nAH
+nAH
+nAH
+mVE
+xFs
+jLM
+qHO
+fUR
+juu
+kBU
+xgX
+juu
+gNL
+fUR
+qAB
+cTh
iJl
-tKI
-lgr
-tKI
-lim
-aqT
-uWD
-bJZ
-vky
-hTt
-oQv
-bln
-bln
-bln
-bln
+ooa
+dWP
+bam
+erK
+rfF
+brM
+teN
+stJ
+fsm
bln
bln
bln
@@ -221290,61 +223625,61 @@ bln
bln
bln
bln
-sEB
+bln
lJO
+cKB
+tcR
+hjI
lJO
-tbx
-rrY
-lJO
-hpN
+kgy
lJO
rmZ
-wLJ
+egT
xiW
-qkP
+lnY
lJO
-iwD
-lJO
-wsS
-dZG
-cmm
-qsE
-aUr
-nNw
-jbh
-hUj
-hUj
-dHG
-vzE
-fsv
-nwT
-oCR
-wRM
+kyU
+qFJ
+mWY
+hmt
+xzo
+kHP
+cuc
+mVE
+nAH
+nAH
+nAH
+mVE
+xFs
+jLM
+fnC
+vNe
+piP
+npy
+npy
+rFb
+hrh
+fUR
pFW
iNH
-aCW
-tKI
-lgr
-tKI
-wBZ
-pzQ
-vQL
-obd
-jJm
-osD
-oQv
+aVb
+onQ
+inQ
+jZD
+erK
+bCQ
+pdf
+teN
+bln
+bln
+stJ
bln
bln
bln
+ozo
bln
bln
bln
-bln
-bln
-bln
-bln
-bln
-aBR
aBR
aBR
aBR
@@ -221544,52 +223879,54 @@ tCr
tCr
bln
bln
-bln
+uer
bln
bln
bln
lJO
-syy
-hjI
-wYm
-cnz
-iwD
+gwM
+xdU
+nxe
+kUn
+tba
lJO
-atn
-fZk
-jXB
-vtD
+hPX
+vcc
+mXA
+waM
lJO
-anl
-lJO
-lqH
-coB
-ukR
-gbt
-qyU
-lqv
-rNR
-aWX
-aWX
-rNR
-vzE
-egK
-nwT
-aCJ
-aCJ
+gwq
+mWK
+isz
+roX
+iLA
+uZT
+cuc
+mVE
+nAH
+nAH
+nAH
+mVE
+xFs
+jLM
+iYy
+tma
+agG
+mxQ
+pXU
+pSd
+jsh
+fUR
tkc
nsr
xSl
+vxO
+qAB
+hCY
tKI
-lgr
-tKI
-rRd
-tXw
-eZJ
-xsE
-nQI
-kln
-ivF
+npr
+uyx
+teN
bln
bln
bln
@@ -221616,8 +223953,6 @@ aBR
aBR
aBR
aBR
-aBR
-aBR
bln
bln
bln
@@ -221801,57 +224136,57 @@ bln
tCr
bln
bln
-bln
+mQb
bln
bln
bln
lJO
-xsq
-eZw
-cLM
+keT
+sHO
+hjI
lJO
-anl
+eUf
lJO
nKW
-fhL
-uPS
+dak
+byv
sOY
lJO
-anl
-bFe
-jdB
-cAl
-eov
+bpm
+xQs
+rqi
iRo
-kAQ
-nNw
-fUR
-fUR
-fUR
-fUR
-lKF
-fsv
+lvW
+uTI
+cuc
+mVE
+nAH
+nAH
+nAH
+mVE
+xFs
+bwn
+ktW
+tKI
+tKI
+tKI
+tKI
+tKI
+tKI
nwT
-qku
-bPw
-bPw
-bPw
-wuO
+goI
+nwT
+nwT
+aLO
+wRM
+iox
+tKI
+bCQ
tKI
-lgr
tKI
-yhp
-yhp
-elr
-kzI
-dZj
-wsx
-ivF
-bln
-bln
-bln
-bln
bln
+stJ
+fsm
bln
bln
bln
@@ -222060,52 +224395,52 @@ bln
bln
bln
bln
-bln
+mQb
bln
lJO
-cLy
+uBX
+hjI
hjI
-xKG
lJO
-anl
+eUf
lJO
jvj
-exo
-lnY
-waM
+hKu
+aaI
lJO
lJO
-lJO
-iRo
-iRo
-iRo
-iRo
-emO
-nNw
-xji
-bOL
-qNL
-bIB
-vzE
-fsv
-nwT
-hkb
-aaT
-fFT
-sEM
-bPw
+oCO
+oCO
+oCO
+oCO
+gyH
+uTI
+cuc
+mVE
+mVE
+mVE
+mVE
+mVE
+xFs
+pLn
+aDy
tKI
-lgr
-hbm
-onj
-dxV
+ljK
+tXs
+ljK
+rUa
tKI
-xio
+hbt
+cTD
+akK
tKI
-ivF
-ivF
-bln
-bln
+tKI
+cyA
+tKI
+tKI
+kPq
+tKI
+qjC
bln
bln
bln
@@ -222322,7 +224657,7 @@ bln
lJO
lJO
lJO
-mde
+lJO
lJO
erk
lJO
@@ -222330,35 +224665,38 @@ lJO
lJO
lJO
lJO
-lJO
mCT
-bsq
blA
-gbS
-mZu
+mCT
+sGq
oCO
-eLt
-lYJ
-awk
-awk
-wpy
-wpy
-bcn
-adW
-nwT
-xxI
-bam
-cfB
-bam
-bPw
+tdp
+uTI
+kXD
+nKk
+nKk
+sre
+nKk
+nKk
+aWN
+pLn
+qFs
+tKI
+rvW
+xqj
+vsT
+gXr
+tKI
+rVt
+ihc
+bod
tKI
hsQ
+bCQ
+eVp
+eVp
+bCQ
tKI
-jNA
-gPF
-cYX
-jiI
-teN
bln
bln
bln
@@ -222366,9 +224704,6 @@ bln
bln
bln
bln
-sEB
-bln
-bln
bln
bln
bln
@@ -222571,55 +224906,55 @@ uei
bln
bln
bln
+mQb
bln
bln
+uer
bln
-bln
-bln
-sEB
-sEB
+mZm
hEI
-jxK
-iwD
+qhO
+eUf
+rgs
+eUf
anl
+lil
anl
-anl
-anl
-iwD
-anl
+pLZ
lJO
geZ
aPM
aPM
-kMu
-esB
+qTm
oCO
-xJv
-hnV
-fsv
-nDk
-fsv
-fsv
-ddt
-ikp
+oCO
+tmL
+arG
+cIa
+dJY
+npq
+ecU
+gkZ
+tlO
+kyc
+tKI
+tKI
+kJO
+kjo
+kJO
+tKI
+tKI
+stP
+dVX
+oLo
+tKI
+eae
+bCQ
tKI
tKI
tKI
tKI
-tKI
-tKI
-tKI
-tKI
-tKI
-lAr
-jWX
-wlc
-cUy
-teN
-bln
-bln
-bln
-sEB
+htd
bln
bln
bln
@@ -222830,61 +225165,61 @@ bln
bln
bln
bln
+sxQ
bln
bln
-bln
-sEB
-sEB
+miY
hEI
-krH
+flD
+eUf
+hjI
+hjt
+hjI
+hjI
+hjI
anl
-lJO
-lJO
-lJO
-lJO
-lJO
-iwD
icY
esv
lCb
ddZ
-slv
-rEN
+eUA
+nhS
oCO
oCO
oCO
-aPI
-iKR
-aPI
+oCO
+sll
+eyf
+sll
tKI
tKI
tKI
tKI
-kEs
-qgM
-fzu
-ofS
-udc
-tKI
-xYv
-tKI
-ooO
-mhr
-wlc
+jXC
+wBb
+xvk
+wBb
+kQV
tKI
tKI
+tKI
+tKI
+tKI
+jez
+bCQ
+tKI
+lSu
+bln
+bln
+gnZ
bln
bln
bln
-fBN
-bln
-bln
-bln
-vsI
-bln
+gnZ
bln
bln
bln
+gnZ
bln
bln
bln
@@ -223093,53 +225428,53 @@ biY
lJO
lJO
lJO
-eXk
-anl
+dYj
+hjI
+lJO
+lJO
+lJO
lJO
-sQx
-kXI
-sQx
lJO
-anl
lJO
dZJ
eUi
eBB
-nxV
+tNd
nor
qiT
cgw
+mZu
hjv
-gpp
-ons
+pXh
+rOb
gpp
tKI
dat
-gJM
-fPM
-pdf
-eyD
-vHT
-pQQ
-yaR
-meR
-pdf
-elu
-dXT
-kcE
-dAT
-duW
+kDv
tKI
-bln
-bln
-bln
-sEB
+kEs
+wBb
+fgo
+aSI
+nEq
+tKI
+kCv
+gvp
+nSr
+tKI
+xDw
+bCQ
+tKI
+lSu
bln
bln
bln
bln
+lSu
bln
bln
+lSu
+lSu
bln
bln
bln
@@ -223347,54 +225682,54 @@ nhb
sxF
kjw
biY
-oNU
-flD
+hTJ
+gks
qDI
-krH
-cKM
+eUf
+jPV
lJO
-kXI
-bDp
+pVQ
bln
-lJO
-iwD
+efI
+efI
lJO
jaS
hBG
pEs
-rho
-eMu
-vlh
-vlh
+aFH
+jRI
+nza
+nza
+nza
cNS
-kQS
+doW
awz
-eRK
-coa
-qPC
-qPC
-qPC
-qPC
-qPC
-qPC
-qPC
-bmK
-qPC
-bDZ
-kKe
-ppE
-jiI
-jiI
-cAs
-mhK
+nmx
+izI
+pdd
+lMg
+wSk
+pdd
+oLC
+bVn
+cHs
+fLS
+fLS
+yel
+edN
+jLf
+tlm
+jLf
+dpZ
+tKI
+htd
bln
-bln
-bln
-bln
-bln
-bln
-bln
-sEB
+lSu
+lSu
+lSu
+lSu
+lSu
+lSu
bln
bln
bln
@@ -223607,26 +225942,32 @@ inw
iwD
anl
anl
-rcq
-anl
+eUf
+hjI
lJO
-hoO
-sQx
-sQx
-lJO
-anl
+efI
+bln
+mQb
+kXI
lJO
wDf
sAR
sAR
cBD
-wKA
+kPy
dQI
pPT
+pPT
hjv
+vTP
+lsi
gpp
-oRM
-oel
+tKI
+kii
+cEG
+tKI
+afz
+mTc
tKI
tKI
tKI
@@ -223636,24 +225977,18 @@ tKI
tKI
tKI
tKI
-tKI
-tKI
-tKI
-tKI
-tKI
-tKI
-vGM
-tKI
-bln
-bln
-bln
-vsI
-bln
-bln
-bln
-fBN
+dBJ
+teN
+bln
+lSu
+lSu
+lSu
+lSu
+lSu
bln
bln
+lSu
+lSu
bln
bln
bln
@@ -223861,35 +226196,35 @@ pVN
bvd
eAh
aiT
-krH
-krH
-krH
-krH
+hjI
+hjI
+hjI
+eUf
nst
lJO
lJO
-hEI
+lNj
+qDI
lJO
lJO
-anl
-lJO
mCT
-iEU
-mCT
-fzF
-pxH
-aNz
-psr
+mut
+lGo
+xhg
+pGy
+wCL
+tTc
+wtr
oCO
kxs
-oRM
-oel
+lsi
+gpp
+qnj
+qnj
+qnj
+qnj
+qnj
qnj
-omg
-hzL
-aAu
-cNQ
-paZ
tOw
xan
tOw
@@ -223899,20 +226234,20 @@ pLw
tOw
orq
tKI
-vGM
-tKI
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-sEB
-bln
+dBJ
+teN
+bln
+lSu
+lSu
bln
bln
+lSu
+lSu
+lSu
+lSu
+lSu
bln
+gnZ
bln
bln
bln
@@ -224114,21 +226449,21 @@ bln
bln
bln
eGr
+wxN
biY
biY
biY
-biY
-wYm
+hjI
hjI
qDI
+eUf
hjI
-hjI
-hjI
-hjI
+dIx
+kEq
ndz
-hjI
-iep
-anl
+hdh
+wWc
+lJO
lJO
lJO
lJO
@@ -224139,14 +226474,14 @@ fYS
fYS
fYS
wpO
-oRM
-oel
+lsi
+kTC
qnj
-wch
-ykG
-ykG
-ykG
-mnL
+omg
+hzL
+kRc
+oWu
+paZ
tOw
iKX
tOw
@@ -224156,18 +226491,18 @@ hce
tOw
wbY
tKI
-vGM
-tKI
-bln
-bln
-bln
-bln
-bln
-bln
-bln
-bln
+dBJ
+teN
bln
bln
+lSu
+lSu
+lSu
+lSu
+lSu
+lSu
+lSu
+lSu
bln
bln
bln
@@ -224371,39 +226706,39 @@ bln
bln
bln
bln
+miY
+hEI
+dYC
+hjI
+hjI
+hjI
lJO
-kQg
-krH
-krH
-krH
-jnV
-lJO
-hjI
-hjI
-dIx
-kEq
-hdh
-flD
-hjI
-anl
-rEB
+eUf
+eUf
+eUf
+eUf
+eUf
+eUf
+eUf
+eUf
+cKD
gks
lJO
-wGD
-xhk
+wSf
+tak
bPr
dRc
bVS
vQt
-etx
-oRM
-qYR
+gpp
+lsi
+xhx
qnj
-usm
+nct
+gAB
ykG
ykG
-vqg
-oYv
+wpQ
tOw
sVn
wlt
@@ -224411,20 +226746,20 @@ kEM
bLn
kEM
vkW
-kEM
+gak
tKI
-vGM
-mhK
+oKu
+tKI
+nMj
+bln
+lSu
+lSu
bln
bln
bln
-vsI
-bln
-bln
-bln
-fBN
-bln
+lSu
bln
+lSu
bln
bln
bln
@@ -224628,9 +226963,9 @@ bln
bln
bln
bln
-lJO
-kQg
-hjI
+miY
+hEI
+kbd
hjI
lJO
lJO
@@ -224647,20 +226982,20 @@ lFq
dix
lJO
veN
-iMT
+ekn
dTD
eMH
dTD
ljT
pBk
-aJA
-kHu
+lzO
+tJu
qnj
-czs
+hul
ykG
-ykG
-dVj
-siX
+gwp
+hCa
+pig
wpc
xBn
jjO
@@ -224670,16 +227005,16 @@ xQf
vQO
hlv
tKI
-vGM
+dBJ
tKI
bln
bln
bln
-sEB
-bln
+lSu
bln
+lSu
bfP
-sEB
+lSu
bln
bln
bln
@@ -224888,7 +227223,7 @@ hEI
lJO
lJO
lJO
-vcx
+adq
lJO
lZU
fIx
@@ -224910,14 +227245,14 @@ uAl
wQh
vQt
gpp
-aJA
-oel
+bAB
+xEE
qnj
-cQb
+hlW
ykG
-vqg
-ubH
-swz
+ykG
+rCj
+xDh
tOw
tOw
tOw
@@ -224927,10 +227262,10 @@ tKI
tKI
tKI
tKI
-vGM
+jss
tKI
-bln
-bln
+mZf
+ooL
maT
wSM
oMd
@@ -224938,9 +227273,9 @@ maT
oMd
bNo
maT
+sEB
bln
-bln
-bln
+gnZ
bln
bln
bln
@@ -225166,16 +227501,16 @@ fjD
gOx
nbT
fYS
-gpp
-aJA
-tAR
+rdn
+bAB
+aaW
qnj
-gYR
-vqg
-oGX
+mxu
+awx
+koH
ubH
-fAW
-bJa
+wml
+bvg
bJa
btG
ehp
@@ -225184,7 +227519,7 @@ plg
huj
qjO
tKI
-vGM
+sHK
tKI
maT
maT
@@ -225195,8 +227530,8 @@ jIE
bde
ksf
maT
-bln
-bln
+miY
+xeg
bln
bln
bln
@@ -225423,25 +227758,25 @@ nQu
gOx
vYa
fYS
-gpp
-aJA
-bBe
-fDv
-blq
-blq
-blq
-ubH
-hDT
+hNz
+bAB
+gdY
+ljE
+vKq
+vKq
+vKq
+eTC
+neq
muy
muy
gRp
-aQb
+sbv
tKI
plg
jdW
-rBj
+mmn
ggn
-vGM
+dBJ
tKI
cYo
tEL
@@ -225452,10 +227787,10 @@ kXr
hFU
bNo
maT
-bln
-bln
-bln
-bln
+mZf
+kKU
+kKU
+dPX
bln
bln
bln
@@ -225681,24 +228016,24 @@ iVb
xWU
vQt
gpp
-aJA
-lty
-bCl
+bAB
+fWN
+tpG
awx
jsB
-awx
-dfj
-hDT
+uQu
+psp
+neq
muy
muy
gRp
-xVL
+geq
tKI
-kMF
-vbj
+bsO
+jyo
pXR
tKI
-lAr
+dBJ
tKI
grr
kLZ
@@ -225932,30 +228267,30 @@ jnV
lJO
iWO
gHS
-jjp
+iMT
hqx
myE
reJ
wrA
djr
-aJA
-oel
+lzO
+mNy
qnj
-erE
+etY
awx
-arO
-nDv
-fbK
-xYB
+bjQ
+awx
+sgT
+dmk
sua
frd
-xVL
+qyL
tKI
tKI
tKI
tKI
tKI
-lAr
+wyr
tKI
kMh
ajw
@@ -225974,7 +228309,7 @@ bln
bln
bln
bln
-nBE
+gsK
ohx
nBE
bln
@@ -226160,12 +228495,12 @@ bln
vbG
bln
bln
+uer
+bln
+mQb
bln
bln
-bln
-bln
-bln
-bln
+stJ
bln
bln
bln
@@ -226173,7 +228508,7 @@ bln
lJO
cIq
lJO
-hjI
+hjt
lJO
csf
xht
@@ -226188,34 +228523,34 @@ eUf
iPR
lJO
ejo
-xSM
-tak
+cSe
+xhk
skj
kkK
lNP
vQt
gpp
-aJA
-oel
+bAB
+gpp
qnj
-nqo
-awx
-hMu
-cIu
-prb
-dxj
-qxW
+hjJ
ykG
-xVL
+aUi
+kXB
+ihk
+ssv
+omH
+hJG
+oYa
tKI
dzl
-jJX
-jun
-hDj
-cpj
-bzh
-vlN
-pqD
+bCQ
+jKP
+fLS
+jeK
+cse
+ajw
+bff
otd
otd
ajw
@@ -226416,8 +228751,8 @@ bln
bln
vbG
bln
-bln
-bln
+fsm
+lBD
bln
bln
bln
@@ -226452,27 +228787,27 @@ lJO
lJO
lJO
kxs
-aJA
-oel
+bAB
+fSv
qnj
-spf
-awx
-aoK
-erJ
-dvR
-agh
-cVq
+gtG
ykG
-xVL
+dVb
+oXB
+qVg
+wsV
+uKO
+uKO
+juq
tKI
-cWn
-gJM
-lAr
+stL
+thE
+hbY
tKI
tKI
tKI
ghl
-vlN
+ajw
ajw
otd
otd
@@ -226682,7 +229017,7 @@ bln
bln
bln
bln
-bln
+lBD
bln
bln
bln
@@ -226710,26 +229045,26 @@ ygk
jKJ
hMg
cke
-wTh
+kTC
qnj
-qcZ
-qpe
-hub
-awx
-eNA
-iEr
-iEr
-rSn
-xVL
+qwn
+wpC
+vZg
+gta
+ihk
+qjp
+uKO
+uKO
+juq
tKI
-uNt
-pdf
-lAr
+xqX
+bCQ
+wBb
tKI
veh
gzN
ajw
-vlN
+ajw
mmi
aUA
mmi
@@ -226934,14 +229269,14 @@ bln
bln
bln
bln
+stJ
bln
bln
bln
+mQb
bln
bln
-bln
-bln
-bln
+fsm
bln
hEI
hjI
@@ -226965,28 +229300,28 @@ lJO
lJO
lJO
lJO
-ukn
+gZc
aJA
gpp
qnj
-rOV
-awx
-rbW
-bkK
-mjj
-jHp
-tXW
-boL
-leI
-txh
+nct
+ykG
+tQS
+oWN
+pji
+apq
+eoY
+poK
+smn
+cUd
sIM
-sIM
-lAr
+yjn
+wBb
tKI
pVC
xdz
kXs
-vlN
+ajw
mmi
wiz
mmi
@@ -227188,17 +229523,17 @@ bln
vbG
bln
bln
+stJ
bln
bln
bln
bln
bln
+stJ
bln
bln
bln
-bln
-bln
-bln
+uer
bln
hEI
ndz
@@ -227222,7 +229557,7 @@ sDl
sDl
sDl
jOt
-wRU
+rWZ
auc
rWZ
sAS
@@ -227238,12 +229573,12 @@ tKI
tKI
kcE
pdf
-lAr
+aSI
tKI
ooR
ajw
ajw
-vlN
+ajw
mmi
wiz
mmi
@@ -227487,20 +229822,20 @@ nQv
nDY
tEu
tKI
-jun
-iJt
-hDj
-hDj
-hDj
-hDj
-hDj
-hDj
-cpj
+wuA
+nAr
+nAr
+nAr
+nAr
+nAr
+nAr
+nAr
+wNR
tKI
piX
ajw
ajw
-vlN
+ajw
mmi
wiz
mmi
@@ -227739,12 +230074,12 @@ jOt
ozw
aJA
oRM
-qIV
+oVG
pRL
gfF
hqm
tKI
-lAr
+wBb
tKI
tKI
tKI
@@ -227995,13 +230330,13 @@ jOt
jOt
ozw
aJA
-gpp
+xSL
gJz
uXy
imO
kGF
tKI
-lAr
+wBb
tKI
skw
ipF
@@ -228252,13 +230587,13 @@ ptk
lEE
idO
aJA
-asp
+wBT
tKI
tKI
tKI
tKI
tKI
-sdi
+qRR
tKI
aes
alT
@@ -228509,13 +230844,13 @@ jOt
jOt
ozw
aJA
-qRT
-kFU
-sIM
-sIM
-sIM
-sIM
-lAr
+gpp
+bpK
+pdf
+pdf
+pdf
+pdf
+wBb
tKI
cnU
alT
@@ -229031,7 +231366,7 @@ dBB
tKI
wBb
tKI
-xOm
+tKI
tKI
tKI
tKI
@@ -229278,7 +231613,7 @@ sDl
sDl
sDl
jOt
-ozw
+caH
ons
oRM
oRM
@@ -229286,10 +231621,10 @@ uLX
rmA
qGW
tKI
-mNE
-nAr
-nAr
+lGd
+wxy
nAr
+wxy
axz
dzl
tKI
@@ -229310,7 +231645,7 @@ qjQ
kQL
vgC
hoD
-flq
+dVs
nyB
dUK
hoD
@@ -229535,7 +231870,7 @@ hDU
hDU
hDU
hDU
-slI
+gRs
ons
gpp
tmw
@@ -229544,10 +231879,10 @@ bcT
iTy
tKI
afz
-iAy
+rvS
kfe
pdf
-tgu
+aCU
jJX
tKI
tKI
@@ -230565,7 +232900,7 @@ vPM
esI
cVz
ons
-gpp
+xSL
lnc
qRq
pNK
@@ -232889,7 +235224,7 @@ qjm
dxK
hbp
oyp
-doT
+phf
sEl
qRs
jST
@@ -233929,8 +236264,8 @@ rpu
ybI
nnR
tuz
-oPt
-bhK
+eRZ
+qpZ
rAA
cpm
mpy
@@ -234225,7 +236560,7 @@ mNY
gmR
tMD
rMG
-lui
+neF
twt
mwm
btC
@@ -234444,7 +236779,7 @@ nDA
vvi
xpJ
vYs
-nDA
+aol
gCn
pJN
dZQ
@@ -234689,7 +237024,7 @@ xKJ
rmM
pZh
oYI
-wzk
+utN
uPY
knU
kPv
@@ -237506,7 +239841,7 @@ dnq
nfk
utR
tmQ
-gZj
+qnV
gKk
kBr
lhv
@@ -237565,7 +239900,7 @@ bup
ojv
htc
mDw
-vTi
+jDT
qKQ
aTj
uif
@@ -238229,7 +240564,7 @@ tGr
tGr
lBD
bln
-jse
+mlS
bln
xAs
nXb
@@ -238297,7 +240632,7 @@ anu
jly
fXb
mhQ
-nKe
+eeq
jUD
nZb
lRf
@@ -238547,12 +240882,12 @@ xbo
anu
fue
dmG
-cyF
+uPB
xLF
lpM
oGQ
wKw
-kpp
+vFb
mhQ
hUV
aks
@@ -238745,7 +241080,7 @@ tGr
bln
lSu
xiI
-oxu
+mBh
oot
oot
kei
@@ -241104,7 +243439,7 @@ idw
eZj
iuE
bPg
-cKp
+uoz
kDP
kmQ
xgy
@@ -242645,13 +244980,13 @@ tGZ
tqZ
mrF
iFc
-wJd
+bJA
mIB
uUV
fmD
fmD
fmD
-iMh
+wyQ
lso
lso
lCi
@@ -245798,8 +248133,8 @@ iDQ
msN
gVC
lyH
-uxF
-bZf
+isu
+lmy
wvI
bln
bln
@@ -246054,9 +248389,9 @@ qSC
ldr
oOx
mgD
-pmb
-hPD
-haQ
+oKL
+elT
+kDc
pKY
tZa
bln
@@ -246562,7 +248897,7 @@ hRe
alq
dFA
sZF
-uNw
+nBQ
sZF
bln
bln
@@ -246819,7 +249154,7 @@ ves
dFA
iye
sZF
-nrf
+lNE
sZF
bln
bln
@@ -247076,7 +249411,7 @@ hRe
tbQ
iye
sZF
-sOo
+ddA
vjZ
bln
bln
@@ -247333,7 +249668,7 @@ fZT
dFA
axC
sZF
-iYq
+uNw
vjZ
bln
bln
@@ -247796,7 +250131,7 @@ xbf
kKL
rjP
qEM
-pxn
+xcJ
vBG
vBG
vBG
@@ -250670,7 +253005,7 @@ bCL
ofr
sBx
hfc
-hzV
+jCE
adY
tmR
sZF
@@ -251392,7 +253727,7 @@ pDS
sEi
bwl
hUD
-lso
+jyg
cYE
acw
ult
@@ -252168,7 +254503,7 @@ rNQ
lso
aop
yar
-kKI
+mdl
rIU
rCX
lWc
diff --git a/_maps/map_files/LimaStation/LimaStation.dmm b/_maps/map_files/LimaStation/LimaStation.dmm
index e00d55ba7fa..950e6d15237 100644
--- a/_maps/map_files/LimaStation/LimaStation.dmm
+++ b/_maps/map_files/LimaStation/LimaStation.dmm
@@ -1010,7 +1010,7 @@
pixel_y = -3
},
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"axb" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/iron,
@@ -1256,7 +1256,7 @@
/obj/structure/flora/bush/generic/style_random,
/obj/structure/window/reinforced/fulltile,
/turf/open/floor/grass,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"aDe" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -1715,7 +1715,7 @@
dir = 8
},
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"aNE" = (
/obj/structure/table/glass,
/obj/effect/landmark/start/hangover,
@@ -2243,7 +2243,7 @@
},
/obj/structure/sign/calendar/directional/east,
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"aYH" = (
/obj/machinery/airalarm/directional/south,
/obj/structure/closet/radiation,
@@ -2521,7 +2521,7 @@
"bek" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"bep" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/cable,
@@ -3798,7 +3798,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"bCr" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/cable,
@@ -3848,7 +3848,7 @@
pixel_y = 3
},
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"bDm" = (
/obj/effect/turf_decal/trimline/neutral/filled/line{
dir = 4
@@ -4284,7 +4284,7 @@
/area/station/medical/medbay/lobby)
"bMC" = (
/obj/structure/table/reinforced,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/effect/turf_decal/tile/neutral/opposingcorners,
/turf/open/floor/iron/dark,
/area/station/medical/morgue)
@@ -4702,7 +4702,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/sign/clock/directional/west,
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"bWc" = (
/obj/structure/table,
/obj/machinery/microwave,
@@ -9282,7 +9282,7 @@
},
/obj/machinery/airalarm/directional/east,
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"dNw" = (
/obj/structure/cable,
/obj/machinery/power/apc/auto_name/directional/east,
@@ -11397,7 +11397,7 @@
/obj/effect/turf_decal/siding/wood,
/obj/effect/turf_decal/bot,
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"eHE" = (
/obj/machinery/door/poddoor/shutters/preopen{
id = "SupermatterExternal";
@@ -12149,7 +12149,7 @@
},
/obj/effect/landmark/start/nanotrasen_consultant,
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"eUJ" = (
/obj/structure/table,
/turf/open/floor/plating,
@@ -12713,7 +12713,7 @@
/obj/structure/flora/bush/flowers_pp/style_random,
/obj/structure/window/reinforced/fulltile,
/turf/open/floor/grass,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"feT" = (
/obj/structure/table,
/obj/machinery/newscaster/directional/south,
@@ -17786,7 +17786,7 @@
pixel_y = 3
},
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"gXd" = (
/obj/machinery/door/airlock/maintenance,
/obj/structure/disposalpipe/segment,
@@ -19030,7 +19030,7 @@
/turf/open/floor/iron,
/area/station/maintenance/port/lower)
"hwV" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/turf/open/floor/iron/white,
/area/station/medical/treatment_center)
"hxb" = (
@@ -20982,7 +20982,7 @@
/area/station/hallway/secondary/command)
"ilb" = (
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"ils" = (
/obj/effect/landmark/start/hangover,
/turf/open/floor/iron,
@@ -22294,7 +22294,7 @@
dir = 1
},
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"iNV" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -26307,7 +26307,7 @@
/obj/machinery/light/directional/west,
/obj/machinery/newscaster/directional/west,
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"kkk" = (
/obj/structure/reagent_dispensers/plumbed,
/obj/effect/turf_decal/delivery/white{
@@ -27229,7 +27229,7 @@
},
/obj/structure/closet/crate/bin,
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"kAM" = (
/obj/structure/chair/sofa/left{
dir = 4
@@ -27664,7 +27664,7 @@
/obj/structure/flora/bush/flowers_yw/style_random,
/obj/structure/window/reinforced/fulltile,
/turf/open/floor/grass,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"kLe" = (
/obj/machinery/light/directional/south,
/obj/machinery/newscaster/directional/south,
@@ -28491,7 +28491,7 @@
/obj/structure/cable,
/obj/effect/turf_decal/siding/wood,
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"lbk" = (
/obj/structure/window/spawner/directional/west,
/obj/machinery/light/directional/east,
@@ -35779,7 +35779,7 @@
/area/station/service/chapel/funeral)
"nHz" = (
/turf/closed/wall/r_wall,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"nHA" = (
/obj/effect/turf_decal/stripes/line{
dir = 10
@@ -41260,7 +41260,7 @@
/obj/structure/flora/bush/flowers_br/style_random,
/obj/structure/window/reinforced/fulltile,
/turf/open/floor/grass,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"pJJ" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -45286,7 +45286,7 @@
},
/obj/effect/mapping_helpers/airlock/access/all/cent_com/rep_door,
/turf/open/floor/iron/dark,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"rii" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
@@ -47153,7 +47153,7 @@
/obj/item/storage/secure/briefcase/white,
/obj/item/clothing/accessory/medal/gold/ordom,
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"rSY" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -48670,7 +48670,7 @@
/obj/structure/filingcabinet/security,
/obj/effect/turf_decal/bot,
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"sul" = (
/turf/open/floor/engine,
/area/station/maintenance/starboard/lower)
@@ -51321,7 +51321,7 @@
pixel_y = 4
},
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"tpK" = (
/obj/machinery/status_display/ai/directional/south,
/obj/structure/closet/secure_closet/research_director,
@@ -51692,7 +51692,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/turf_decal/siding/wood,
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"tyq" = (
/obj/effect/turf_decal/delivery,
/obj/machinery/airalarm/directional/east,
@@ -53669,7 +53669,9 @@
/turf/open/floor/plating,
/area/station/maintenance/department/electrical)
"uni" = (
-/obj/machinery/recycler,
+/obj/machinery/recycler{
+ dir = 8
+ },
/obj/machinery/conveyor{
dir = 4;
id = "garbage"
@@ -56836,7 +56838,7 @@
id = "consultantdoor"
},
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"vyc" = (
/obj/effect/spawner/random/engineering/atmospherics_portable,
/turf/open/floor/plating,
@@ -57652,7 +57654,7 @@
dir = 10
},
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"vQb" = (
/obj/effect/landmark/start/cargo_technician,
/obj/structure/chair/office{
@@ -62905,7 +62907,7 @@
/obj/effect/turf_decal/bot,
/obj/machinery/photocopier,
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"xSD" = (
/obj/effect/landmark/start/hangover,
/obj/effect/turf_decal/siding/wood{
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 8d89ed86ee6..4b2fbfed3be 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -2419,7 +2419,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/cable,
-/obj/machinery/destructive_scanner,
/obj/effect/turf_decal/tile/purple/half/contrasted{
dir = 1
},
@@ -4684,6 +4683,7 @@
/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" = (
@@ -6459,6 +6459,7 @@
},
/obj/effect/mapping_helpers/airlock/access/any/engineering/general,
/obj/effect/mapping_helpers/airlock/access/any/engineering/construction,
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/iron,
/area/station/engineering/break_room)
"csz" = (
@@ -6971,10 +6972,10 @@
c_tag = "Science Lobby";
network = list("ss13","rd")
},
-/obj/machinery/vending/modularpc,
/obj/effect/turf_decal/tile/purple/half/contrasted{
dir = 1
},
+/obj/machinery/destructive_scanner,
/turf/open/floor/iron/white,
/area/station/science/lobby)
"cAG" = (
@@ -7472,6 +7473,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/mapping_helpers/airlock/access/all/medical/psychology,
/obj/effect/turf_decal/tile/blue/fourcorners,
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/iron/white,
/area/station/medical/psychology)
"cNk" = (
@@ -8266,7 +8268,7 @@
/obj/item/bedsheet/red,
/obj/machinery/airalarm/directional/east,
/obj/machinery/flasher/directional/north{
- id = "IsolationFlash"
+ id = "IsolationCell"
},
/obj/effect/turf_decal/tile/red/fourcorners,
/turf/open/floor/iron/white,
@@ -9103,6 +9105,7 @@
},
/obj/machinery/door/firedoor/heavy,
/obj/effect/mapping_helpers/airlock/access/all/science/ordnance_storage,
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/plating,
/area/station/science/ordnance/storage)
"dss" = (
@@ -9832,6 +9835,16 @@
/obj/structure/cable,
/turf/open/space/basic,
/area/space/nearstation)
+"dJP" = (
+/obj/structure/table/reinforced,
+/obj/item/clipboard,
+/obj/item/paper/monitorkey,
+/obj/item/computer_disk/engineering,
+/obj/item/computer_disk/engineering,
+/obj/item/computer_disk/engineering,
+/obj/effect/turf_decal/tile/neutral/half/contrasted,
+/turf/open/floor/iron,
+/area/station/command/heads_quarters/ce)
"dJT" = (
/obj/item/reagent_containers/cup/rag,
/obj/structure/table/wood,
@@ -11932,7 +11945,6 @@
/turf/open/floor/iron,
/area/station/maintenance/starboard/greater)
"esK" = (
-/obj/machinery/firealarm/directional/east,
/obj/structure/cable,
/obj/machinery/light/small/directional/east,
/turf/open/floor/iron/dark,
@@ -12985,7 +12997,7 @@
dir = 8
},
/obj/machinery/light/small/directional/north,
-/obj/item/storage/backpack/duffelbag/coroner/surgery,
+/obj/item/surgery_tray/full/morgue,
/turf/open/floor/iron/dark/smooth_edge{
dir = 8
},
@@ -13545,6 +13557,7 @@
/obj/structure/disposalpipe/segment,
/obj/effect/mapping_helpers/airlock/access/all/science/genetics,
/obj/effect/turf_decal/tile/purple/fourcorners,
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/iron/white,
/area/station/science/genetics)
"eZI" = (
@@ -15448,6 +15461,7 @@
name = "Customs Desk"
},
/obj/effect/mapping_helpers/airlock/access/all/security/general,
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/iron,
/area/station/security/checkpoint/customs)
"fKP" = (
@@ -16129,6 +16143,9 @@
/obj/structure/cable,
/obj/structure/disposalpipe/segment,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
/turf/open/floor/iron/white,
/area/station/medical/medbay/central)
"fYC" = (
@@ -16300,6 +16317,7 @@
},
/obj/machinery/door/firedoor,
/obj/structure/cable,
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/iron/white,
/area/station/science/robotics/lab)
"gcV" = (
@@ -18054,7 +18072,7 @@
/obj/item/paper/guides/jobs/medical/morgue{
pixel_y = 31
},
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/machinery/light/small/directional/north,
/turf/open/floor/iron/dark,
@@ -18192,8 +18210,8 @@
"gLY" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/rack,
-/obj/item/roller,
-/obj/item/roller,
+/obj/item/emergency_bed,
+/obj/item/emergency_bed,
/obj/item/toy/figure/md,
/turf/open/floor/iron/white,
/area/station/medical/abandoned)
@@ -18680,7 +18698,7 @@
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 8
},
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/turf/open/floor/iron/white,
/area/station/security/medical)
"gXd" = (
@@ -19206,13 +19224,9 @@
/area/station/security/brig)
"hgu" = (
/obj/machinery/defibrillator_mount/directional/south,
-/obj/structure/bed/pod{
- desc = "An old medical bed, just waiting for replacement with something up to date.";
- dir = 4;
- name = "medical bed"
- },
/obj/effect/turf_decal/tile/blue/fourcorners,
/obj/machinery/light/cold/directional/south,
+/obj/structure/bed/medical,
/turf/open/floor/iron/white,
/area/station/medical/treatment_center)
"hgA" = (
@@ -20000,6 +20014,7 @@
},
/obj/item/mod/module/plasma_stabilizer,
/obj/item/mod/module/thermal_regulator,
+/obj/item/mod/module/signlang_radio,
/turf/open/floor/iron/dark,
/area/station/medical/storage)
"hwg" = (
@@ -21091,6 +21106,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/mapping_helpers/airlock/access/all/engineering/general,
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/iron,
/area/station/engineering/main)
"hRv" = (
@@ -21224,6 +21240,11 @@
dir = 4
},
/area/station/medical/morgue)
+"hTb" = (
+/obj/effect/turf_decal/stripes/line,
+/obj/effect/landmark/navigate_destination,
+/turf/open/floor/iron,
+/area/station/command/gateway)
"hTn" = (
/obj/structure/disposalpipe/segment{
dir = 6
@@ -21362,6 +21383,7 @@
},
/obj/effect/mapping_helpers/airlock/access/all/medical/virology,
/obj/machinery/door/firedoor,
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/iron/white,
/area/station/medical/virology)
"hVW" = (
@@ -22072,6 +22094,7 @@
/obj/structure/disposalpipe/segment,
/obj/effect/mapping_helpers/airlock/access/all/science/rd,
/obj/effect/turf_decal/tile/purple/fourcorners,
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/iron,
/area/station/command/heads_quarters/rd)
"iix" = (
@@ -23842,7 +23865,9 @@
/turf/open/floor/carpet/red,
/area/station/command/heads_quarters/qm)
"iMd" = (
-/obj/structure/bed,
+/obj/structure/bed/medical/emergency{
+ dir = 4
+ },
/turf/open/floor/plating,
/area/station/maintenance/starboard/lesser)
"iMi" = (
@@ -25036,6 +25061,7 @@
},
/obj/effect/mapping_helpers/airlock/access/all/medical/general,
/obj/effect/turf_decal/tile/blue/fourcorners,
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/iron/white,
/area/station/medical/treatment_center)
"jfr" = (
@@ -26858,14 +26884,14 @@
/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
"jJp" = (
-/obj/machinery/button/flasher{
- id = "IsolationFlash";
- pixel_x = -23;
- pixel_y = 8
- },
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/status_display/door_timer{
+ id = "IsolationCell";
+ name = "Isolation Cell";
+ pixel_x = -32
+ },
/turf/open/floor/iron,
/area/station/security/execution/transfer)
"jJC" = (
@@ -30402,6 +30428,15 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/command/bridge)
+"kWZ" = (
+/obj/effect/turf_decal/trimline/neutral/warning{
+ dir = 1
+ },
+/obj/effect/landmark/navigate_destination,
+/turf/open/floor/iron/dark/smooth_half{
+ dir = 8
+ },
+/area/station/medical/morgue)
"kXa" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/cable,
@@ -30443,7 +30478,7 @@
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
"kXD" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/item/radio/intercom/directional/south,
/obj/machinery/camera/directional/south{
c_tag = "Medbay Foyer";
@@ -30891,8 +30926,8 @@
/turf/open/floor/iron,
/area/station/construction/storage_wing)
"lgj" = (
-/obj/structure/bed{
- dir = 4
+/obj/structure/bed/medical{
+ dir = 8
},
/obj/item/clothing/suit/jacket/straight_jacket,
/obj/item/clothing/glasses/blindfold,
@@ -31459,7 +31494,7 @@
/area/station/service/library)
"lrR" = (
/obj/machinery/light/directional/south,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/trimline/blue/filled/warning{
dir = 1
},
@@ -31810,7 +31845,7 @@
"lyx" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/light/cold/directional/north,
/turf/open/floor/iron/white,
/area/station/medical/medbay/central)
@@ -32412,6 +32447,7 @@
"lNF" = (
/obj/effect/turf_decal/tile/neutral/fourcorners,
/obj/effect/landmark/event_spawn,
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/iron/dark,
/area/station/engineering/storage/tech)
"lNH" = (
@@ -33554,6 +33590,20 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/command/heads_quarters/hop)
+"mij" = (
+/obj/machinery/door/airlock/research{
+ name = "Research Division Access"
+ },
+/obj/machinery/door/firedoor,
+/obj/effect/mapping_helpers/airlock/unres,
+/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
+ cycle_id = "sci-entrance"
+ },
+/obj/effect/mapping_helpers/airlock/access/all/science/general,
+/obj/effect/turf_decal/tile/purple/fourcorners,
+/obj/effect/landmark/navigate_destination,
+/turf/open/floor/iron/white,
+/area/station/science/research)
"mil" = (
/obj/structure/table/wood,
/obj/machinery/newscaster/directional/east,
@@ -34934,8 +34984,8 @@
/turf/open/floor/iron/dark/airless,
/area/station/science/ordnance/freezerchamber)
"mFu" = (
-/obj/structure/bed{
- dir = 4
+/obj/structure/bed/medical/anchored{
+ dir = 8
},
/obj/item/bedsheet/medical{
dir = 4
@@ -36545,6 +36595,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/light_switch/directional/east,
/obj/effect/mapping_helpers/airlock/access/all/engineering/ce,
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/iron,
/area/station/command/heads_quarters/ce)
"niw" = (
@@ -36954,7 +37005,7 @@
/obj/effect/turf_decal/tile/blue/half/contrasted{
dir = 1
},
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/item/clothing/gloves/latex,
/obj/item/clothing/suit/apron/surgical,
/turf/open/floor/iron/white,
@@ -37097,6 +37148,7 @@
/obj/machinery/door/firedoor,
/obj/effect/mapping_helpers/airlock/access/all/medical/cmo,
/obj/effect/turf_decal/tile/blue/fourcorners,
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/iron/white,
/area/station/command/heads_quarters/cmo)
"nse" = (
@@ -37213,6 +37265,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/mapping_helpers/airlock/access/all/science/general,
/obj/effect/turf_decal/tile/purple/fourcorners,
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/iron/white,
/area/station/science/lab)
"ntk" = (
@@ -37359,7 +37412,7 @@
/turf/open/floor/iron/dark,
/area/station/security/office)
"nvI" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/tile/blue/fourcorners,
/turf/open/floor/iron,
/area/station/hallway/primary/central)
@@ -37587,6 +37640,7 @@
},
/obj/structure/cable,
/obj/effect/mapping_helpers/airlock/access/any/supply/maintenance,
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/plating,
/area/station/cargo/drone_bay)
"nzo" = (
@@ -37608,6 +37662,10 @@
/obj/machinery/light/directional/east,
/turf/open/floor/iron,
/area/station/hallway/primary/port)
+"nzN" = (
+/obj/effect/landmark/navigate_destination,
+/turf/closed/wall/r_wall,
+/area/station/engineering/storage/tech)
"nzP" = (
/obj/machinery/atmospherics/pipe/smart/simple/purple/visible{
dir = 10
@@ -37615,8 +37673,8 @@
/turf/open/floor/iron,
/area/station/engineering/atmos)
"nzQ" = (
-/obj/structure/bed{
- dir = 4
+/obj/structure/bed/medical/anchored{
+ dir = 8
},
/obj/item/bedsheet/medical{
dir = 4
@@ -37921,7 +37979,9 @@
/turf/open/floor/carpet,
/area/station/command/bridge)
"nEF" = (
-/obj/structure/bed,
+/obj/structure/bed/medical/anchored{
+ dir = 4
+ },
/obj/item/clothing/suit/jacket/straight_jacket,
/obj/item/clothing/glasses/blindfold,
/obj/item/clothing/mask/muzzle,
@@ -38154,6 +38214,7 @@
dir = 4
},
/obj/structure/sign/poster/official/random/directional/north,
+/obj/item/mod/module/signlang_radio,
/turf/open/floor/iron/dark/corner{
dir = 1
},
@@ -39997,8 +40058,8 @@
/turf/open/floor/iron/dark/textured_large,
/area/station/science/cytology)
"ouj" = (
-/obj/structure/bed/roller,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/machinery/iv_drip,
/obj/effect/turf_decal/trimline/blue/filled/line{
@@ -41461,6 +41522,7 @@
/obj/structure/disposalpipe/segment{
dir = 4
},
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/iron/white,
/area/station/science/xenobiology)
"oWc" = (
@@ -41635,7 +41697,9 @@
/turf/open/floor/engine/cult,
/area/station/service/library)
"oZs" = (
-/obj/structure/bed,
+/obj/structure/bed/medical/emergency{
+ dir = 4
+ },
/obj/effect/decal/cleanable/blood/gibs/old,
/obj/effect/decal/cleanable/blood/old,
/obj/effect/turf_decal/tile/green/fourcorners,
@@ -41854,6 +41918,7 @@
/obj/effect/mapping_helpers/airlock/access/all/medical/coroner,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/dark,
/area/station/medical/morgue)
"pdX" = (
@@ -42725,6 +42790,7 @@
/area/station/science/research)
"pua" = (
/obj/machinery/vending/assist,
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/iron/dark,
/area/station/engineering/storage/tech)
"pui" = (
@@ -43633,7 +43699,7 @@
/area/station/command/bridge)
"pKa" = (
/obj/structure/cable,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/stripes/corner{
dir = 1
},
@@ -44507,7 +44573,9 @@
/turf/open/floor/plating,
/area/station/maintenance/department/medical/central)
"qbr" = (
-/obj/structure/bed,
+/obj/structure/bed/medical{
+ dir = 4
+ },
/obj/item/clothing/suit/jacket/straight_jacket,
/obj/item/clothing/glasses/blindfold,
/obj/item/clothing/mask/muzzle,
@@ -45231,7 +45299,6 @@
},
/obj/item/defibrillator/loaded,
/obj/structure/window/spawner/directional/west,
-/obj/machinery/status_display/evac/directional/east,
/turf/open/floor/iron/dark,
/area/station/medical/storage)
"qph" = (
@@ -48292,7 +48359,7 @@
"rtX" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/turf/open/floor/iron/white,
/area/station/medical/medbay/central)
"rul" = (
@@ -49983,6 +50050,7 @@
/obj/structure/cable,
/obj/effect/mapping_helpers/airlock/access/all/science/ordnance,
/obj/machinery/door/firedoor/heavy,
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/plating,
/area/station/science/ordnance/testlab)
"rXJ" = (
@@ -50164,6 +50232,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/mapping_helpers/airlock/access/all/supply/general,
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/iron,
/area/station/construction/storage_wing)
"sal" = (
@@ -52313,6 +52382,7 @@
dir = 4
},
/obj/effect/mapping_helpers/airlock/access/all/security/hos,
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/wood,
/area/station/command/heads_quarters/hos)
"sPq" = (
@@ -52594,7 +52664,7 @@
/turf/open/floor/iron/white,
/area/station/command/heads_quarters/cmo)
"sTQ" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/trimline/blue/filled/warning{
dir = 1
},
@@ -52884,6 +52954,7 @@
/obj/machinery/door/airlock/command{
name = "Quartermaster's Office"
},
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/iron,
/area/station/command/heads_quarters/qm)
"sXF" = (
@@ -54301,11 +54372,11 @@
/area/station/medical/medbay/central)
"tzI" = (
/obj/structure/table/reinforced,
-/obj/item/roller,
-/obj/item/roller{
+/obj/item/emergency_bed,
+/obj/item/emergency_bed{
pixel_y = 3
},
-/obj/item/roller{
+/obj/item/emergency_bed{
pixel_y = 6
},
/obj/structure/window/spawner/directional/west,
@@ -54479,13 +54550,9 @@
/turf/open/floor/iron,
/area/station/security/prison/garden)
"tCG" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/structure/cable,
/obj/effect/landmark/navigate_destination,
/turf/open/floor/iron,
-/area/station/security/brig)
+/area/station/engineering/atmos)
"tCJ" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -54841,6 +54908,9 @@
/obj/item/mod/module/plasma_stabilizer{
pixel_x = 16
},
+/obj/item/mod/module/signlang_radio{
+ pixel_x = 16
+ },
/obj/item/mod/module/thermal_regulator{
pixel_x = 16
},
@@ -56007,7 +56077,7 @@
c_tag = "Medbay Virology Wing";
network = list("ss13","medbay")
},
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/turf/open/floor/iron/white,
/area/station/medical/medbay/central)
"ucd" = (
@@ -56488,23 +56558,13 @@
/turf/open/floor/iron/white,
/area/station/medical/chemistry)
"ulX" = (
-/obj/machinery/lapvend,
/obj/structure/cable,
/obj/effect/turf_decal/tile/purple/half/contrasted{
dir = 1
},
+/obj/machinery/vending/modularpc,
/turf/open/floor/iron/white,
/area/station/science/lobby)
-"umA" = (
-/obj/machinery/defibrillator_mount/directional/south,
-/obj/structure/bed/pod{
- desc = "An old medical bed, just waiting for replacement with something up to date.";
- name = "medical bed"
- },
-/obj/effect/turf_decal/tile/blue/fourcorners,
-/obj/machinery/light/cold/directional/south,
-/turf/open/floor/iron/white,
-/area/station/medical/treatment_center)
"umS" = (
/obj/item/radio/intercom/directional/west,
/obj/machinery/computer/records/security{
@@ -56690,6 +56750,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/mapping_helpers/airlock/access/all/engineering/aux_base,
/obj/effect/turf_decal/tile/yellow/fourcorners,
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/iron,
/area/station/construction/mining/aux_base)
"uqp" = (
@@ -56753,6 +56814,7 @@
/obj/effect/turf_decal/tile/red/half/contrasted{
dir = 1
},
+/obj/machinery/firealarm/directional/east,
/turf/open/floor/iron/dark,
/area/station/security/execution/education)
"urs" = (
@@ -57079,7 +57141,7 @@
/obj/structure/chair/comfy{
dir = 1
},
-/obj/item/clothing/suit/costume/nerdshirt,
+/obj/item/clothing/suit/costume/wellworn_shirt/messy/graphic/gamer,
/obj/item/clothing/head/fedora,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
@@ -57510,7 +57572,9 @@
dir = 4;
id = "garbage"
},
-/obj/machinery/recycler,
+/obj/machinery/recycler{
+ dir = 8
+ },
/turf/open/floor/plating,
/area/station/maintenance/disposal)
"uEO" = (
@@ -59984,16 +60048,6 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/wood,
/area/station/service/lawoffice)
-"vuh" = (
-/obj/structure/table/reinforced,
-/obj/item/clipboard,
-/obj/item/paper/monitorkey,
-/obj/item/computer_disk/engineering,
-/obj/item/computer_disk/engineering,
-/obj/item/computer_disk/engineering,
-/obj/effect/turf_decal/tile/neutral/half/contrasted,
-/turf/open/floor/iron,
-/area/station/command/heads_quarters/ce)
"vun" = (
/turf/closed/wall,
/area/station/medical/storage)
@@ -60128,7 +60182,7 @@
/turf/open/floor/iron/white/corner,
/area/station/hallway/secondary/entry)
"vxB" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/camera/directional/west{
c_tag = "Gateway - Atrium"
},
@@ -61514,7 +61568,9 @@
/turf/open/floor/iron,
/area/station/cargo/drone_bay)
"vUC" = (
-/obj/structure/bed,
+/obj/structure/bed/medical/anchored{
+ dir = 4
+ },
/obj/item/bedsheet,
/obj/structure/disposalpipe/segment{
dir = 4
@@ -62295,6 +62351,7 @@
/obj/effect/mapping_helpers/airlock/access/any/medical/general,
/obj/effect/mapping_helpers/airlock/access/any/medical/pharmacy,
/obj/effect/turf_decal/tile/yellow/fourcorners,
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/iron/white,
/area/station/medical/pharmacy)
"why" = (
@@ -67301,6 +67358,7 @@
name = "Captain's Quarters"
},
/obj/effect/mapping_helpers/airlock/access/any/command/captain,
+/obj/effect/landmark/navigate_destination,
/turf/open/floor/iron/dark,
/area/station/command/heads_quarters/captain/private)
"xXW" = (
@@ -89854,7 +89912,7 @@ jpU
vJe
qXh
ehg
-umA
+hgu
vun
mWC
uTj
@@ -93728,7 +93786,7 @@ uiw
kys
kWE
eky
-vLo
+kWZ
wnW
tSw
oBD
@@ -97495,7 +97553,7 @@ lPl
prY
mLL
jxV
-tCG
+pXC
pHb
qwh
iQg
@@ -98074,7 +98132,7 @@ ljm
cOQ
mFQ
cOQ
-ezT
+mij
obN
gwf
dMz
@@ -98828,7 +98886,7 @@ fPh
kgr
mnq
mGh
-vYg
+hTb
kwp
wZw
htd
@@ -104202,7 +104260,7 @@ wzK
tCS
xww
hht
-xww
+nzN
xww
mEO
fRS
@@ -107797,7 +107855,7 @@ iBm
uXd
sqE
fOn
-vuh
+dJP
bfO
pCt
vYK
@@ -111419,7 +111477,7 @@ ahV
ruP
cyW
cyW
-cyW
+tCG
vlq
cyW
cyW
diff --git a/_maps/map_files/Mining/Lavaland.dmm b/_maps/map_files/Mining/Lavaland.dmm
index 98136e8fcfb..5f7a19198bb 100644
--- a/_maps/map_files/Mining/Lavaland.dmm
+++ b/_maps/map_files/Mining/Lavaland.dmm
@@ -69,7 +69,7 @@
/area/mine/maintenance/living/south)
"aq" = (
/obj/machinery/camera/autoname/directional/east{
- network = list("labor")
+ network = list("mine")
},
/obj/effect/turf_decal/trimline/brown/filled/line{
dir = 5
@@ -358,7 +358,7 @@
/turf/open/floor/plating,
/area/mine/maintenance/production)
"cy" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/turf_decal/trimline/blue/filled/line,
@@ -3724,7 +3724,7 @@
/turf/open/floor/plating,
/area/mine/hydroponics)
"vu" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/turf_decal/trimline/blue/filled/line,
/turf/open/floor/iron/white,
@@ -6773,7 +6773,9 @@
/turf/open/floor/plating,
/area/mine/production)
"PL" = (
-/obj/machinery/recycler,
+/obj/machinery/recycler{
+ dir = 8
+ },
/obj/machinery/conveyor{
dir = 4;
id = "mining_disposals"
diff --git a/_maps/map_files/NorthStar/north_star.dmm b/_maps/map_files/NorthStar/north_star.dmm
index c79d779b52d..d9fff1d8af0 100644
--- a/_maps/map_files/NorthStar/north_star.dmm
+++ b/_maps/map_files/NorthStar/north_star.dmm
@@ -937,12 +937,6 @@
},
/turf/open/floor/plating,
/area/station/science/xenobiology)
-"alE" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/brown/visible,
-/obj/effect/turf_decal/stripes/line,
-/obj/structure/cable,
-/turf/open/floor/engine,
-/area/station/engineering/supermatter/room)
"alK" = (
/obj/machinery/modular_computer/preset/id{
dir = 4
@@ -1601,12 +1595,14 @@
/area/station/construction)
"auv" = (
/obj/effect/turf_decal/bot,
-/obj/machinery/atmospherics/components/unary/outlet_injector{
- dir = 8
- },
/obj/effect/turf_decal/stripes{
dir = 8
},
+/obj/machinery/atmospherics/components/unary/outlet_injector/on{
+ volume_rate = 200;
+ dir = 8;
+ initialize_directions = 8
+ },
/turf/open/floor/engine,
/area/station/science/cytology)
"aux" = (
@@ -2102,6 +2098,7 @@
dir = 1
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/science/cytology)
"aCl" = (
@@ -2638,6 +2635,10 @@
/obj/machinery/light/floor,
/turf/open/floor/iron/dark/smooth_large,
/area/station/hallway/floor2/aft)
+"aIU" = (
+/obj/machinery/firealarm/directional/north,
+/turf/open/floor/pod/light,
+/area/station/maintenance/floor4/port)
"aIV" = (
/obj/structure/grille,
/turf/open/floor/plating,
@@ -3847,6 +3848,7 @@
/obj/effect/turf_decal/stripes{
dir = 5
},
+/obj/structure/cable,
/turf/open/floor/iron/dark,
/area/station/science/cytology)
"aYv" = (
@@ -4158,7 +4160,6 @@
/turf/open/floor/catwalk_floor,
/area/station/maintenance/floor3/port/aft)
"bcm" = (
-/obj/machinery/lapvend,
/obj/machinery/camera/autoname/directional/west,
/turf/open/floor/iron/dark/side{
dir = 8
@@ -4696,7 +4697,9 @@
/turf/open/floor/iron,
/area/station/science/robotics/lab)
"biF" = (
-/obj/machinery/recycler,
+/obj/machinery/recycler{
+ dir = 8
+ },
/obj/machinery/conveyor{
dir = 4;
id = "disposals"
@@ -6410,7 +6413,7 @@
/turf/open/floor/iron/dark/side,
/area/station/hallway/secondary/entry)
"bBg" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/effect/decal/cleanable/blood/old,
/obj/machinery/light/cold/directional/south,
@@ -6587,7 +6590,6 @@
dir = 4
},
/obj/machinery/status_display/evac/directional/north,
-/obj/structure/cable,
/turf/open/floor/engine,
/area/station/engineering/supermatter/room)
"bDU" = (
@@ -7097,7 +7099,7 @@
/obj/machinery/computer/security/telescreen/rd{
pixel_x = -30
},
-/obj/item/kirbyplants/random,
+/obj/machinery/pdapainter/research,
/turf/open/floor/iron/white,
/area/station/command/heads_quarters/rd)
"bMz" = (
@@ -7211,6 +7213,7 @@
/obj/machinery/atmospherics/components/binary/pump{
name = "Atmospherics-Supermatter Connection"
},
+/obj/structure/cable,
/turf/open/floor/engine,
/area/station/engineering/supermatter/room)
"bNU" = (
@@ -8022,8 +8025,8 @@
/turf/open/floor/iron/dark,
/area/station/hallway/floor3/aft)
"bYX" = (
-/obj/structure/bed{
- dir = 4
+/obj/structure/bed/medical/anchored{
+ dir = 8
},
/obj/item/bedsheet/medical{
dir = 4
@@ -8341,6 +8344,7 @@
/obj/machinery/light/cold/no_nightlight/directional/east,
/obj/machinery/power/shieldwallgen/xenobiologyaccess,
/obj/machinery/atmospherics/pipe/smart/manifold4w/general/hidden,
+/obj/structure/cable,
/turf/open/floor/iron/dark,
/area/station/science/cytology)
"cdf" = (
@@ -9274,8 +9278,8 @@
"coZ" = (
/obj/effect/turf_decal/tile/blue/fourcorners,
/obj/machinery/defibrillator_mount/directional/south,
-/obj/structure/bed{
- dir = 4
+/obj/structure/bed/medical{
+ dir = 8
},
/turf/open/floor/iron/white/textured,
/area/station/medical/treatment_center)
@@ -10542,6 +10546,7 @@
/obj/structure/disposalpipe/segment{
dir = 4
},
+/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/science/cytology)
"cHf" = (
@@ -12034,7 +12039,7 @@
/mob/living/basic/pet/penguin/baby/permanent{
dir = 8
},
-/turf/open/floor/fake_snow{
+/turf/open/misc/snow/actually_safe{
icon_state = "snow6"
},
/area/station/hallway/floor2/fore)
@@ -12711,7 +12716,6 @@
/turf/open/floor/iron,
/area/station/engineering/storage/tcomms)
"dlt" = (
-/obj/machinery/airalarm/directional/south,
/turf/open/floor/wood,
/area/station/command/heads_quarters/hos)
"dly" = (
@@ -16227,7 +16231,7 @@
/obj/machinery/elevator_control_panel/directional/west{
linked_elevator_id = "fore_vator";
pixel_x = -24;
- preset_destination_names = list("2"="Supply-Engi Floor","3"="Med-Sci Floor","4"="Service Floor")
+ preset_destination_names = list("2"="Supply-Engi Floor","3"="Med-Sci Floor","4"="Service Floor")
},
/obj/machinery/lift_indicator/directional/west{
linked_elevator_id = "fore_vator";
@@ -17951,8 +17955,6 @@
/turf/open/floor/plating,
/area/station/maintenance/floor1/starboard)
"eGl" = (
-/obj/machinery/space_heater,
-/obj/machinery/firealarm/directional/north,
/turf/open/floor/pod/light,
/area/station/maintenance/floor4/port)
"eGp" = (
@@ -18444,7 +18446,7 @@
/area/station/service/chapel)
"eNM" = (
/obj/structure/window/reinforced/spawner/directional/south,
-/turf/open/floor/fake_snow{
+/turf/open/misc/snow/actually_safe{
icon_state = "snow4"
},
/area/station/hallway/floor2/fore)
@@ -18570,6 +18572,11 @@
/obj/machinery/light/floor,
/turf/open/floor/pod,
/area/station/hallway/secondary/entry)
+"eQd" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/pdapainter/security,
+/turf/open/floor/iron/dark,
+/area/station/command/heads_quarters/hos)
"eQe" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -19344,6 +19351,7 @@
/obj/effect/turf_decal/stripes,
/obj/structure/window/reinforced/spawner/directional/south,
/obj/machinery/atmospherics/pipe/smart/manifold4w/general/hidden,
+/obj/structure/cable,
/turf/open/floor/iron/dark,
/area/station/science/cytology)
"fdr" = (
@@ -19976,6 +19984,14 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/pod/light,
/area/station/maintenance/floor3/port/fore)
+"fmG" = (
+/obj/effect/turf_decal/siding/wood{
+ dir = 1
+ },
+/obj/machinery/airalarm/directional/west,
+/obj/structure/window/reinforced/spawner/directional/north,
+/turf/open/floor/iron/dark,
+/area/station/command/heads_quarters/hos)
"fmK" = (
/obj/structure/mirror/directional/east,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
@@ -20811,14 +20827,9 @@
/obj/effect/turf_decal/trimline/yellow/corner{
dir = 1
},
-/obj/item/stock_parts/matter_bin{
- pixel_x = 2;
- pixel_y = -5
- },
-/obj/item/stock_parts/micro_laser{
- pixel_y = 7
- },
-/obj/item/trash/boritos/green,
+/obj/item/mod/module/plasma_stabilizer,
+/obj/item/mod/module/signlang_radio,
+/obj/item/mod/module/thermal_regulator,
/turf/open/floor/iron/corner{
dir = 1
},
@@ -21186,7 +21197,7 @@
/obj/effect/turf_decal/siding/white{
dir = 8
},
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/turf/open/floor/iron/dark/textured,
/area/station/medical/office)
@@ -24239,7 +24250,7 @@
/turf/open/floor/iron/textured_large,
/area/station/cargo/storage)
"gup" = (
-/obj/structure/frame{
+/obj/structure/frame/machine{
anchored = 1
},
/obj/structure/disposalpipe/segment,
@@ -25982,7 +25993,6 @@
/area/station/engineering/supermatter)
"gSf" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/brown/visible,
-/obj/structure/cable,
/obj/machinery/light/floor,
/turf/open/floor/iron/dark/textured_large,
/area/station/engineering/supermatter/room)
@@ -26313,7 +26323,7 @@
dir = 1
},
/obj/structure/table/reinforced/rglass,
-/obj/item/storage/backpack/duffelbag/coroner/surgery,
+/obj/item/surgery_tray/full/morgue,
/obj/machinery/digital_clock/directional/north,
/turf/open/floor/iron/dark,
/area/station/medical/morgue)
@@ -26967,7 +26977,7 @@
/turf/open/floor/plating,
/area/station/maintenance/floor3/starboard)
"hfd" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/machinery/firealarm/directional/south,
/turf/open/floor/iron/white,
@@ -29394,6 +29404,13 @@
},
/turf/open/floor/carpet/red,
/area/station/service/theater)
+"hLq" = (
+/obj/effect/turf_decal/siding/wood{
+ dir = 1
+ },
+/obj/structure/window/reinforced/spawner/directional/north,
+/turf/open/floor/iron/dark,
+/area/station/command/heads_quarters/hos)
"hLs" = (
/obj/structure/cable,
/turf/open/floor/iron/dark/smooth_half,
@@ -30248,7 +30265,7 @@
/turf/open/floor/iron/dark,
/area/station/security/interrogation)
"hXt" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/turf/open/floor/iron/dark,
/area/station/medical/morgue)
@@ -31258,7 +31275,9 @@
"ilI" = (
/obj/effect/turf_decal/tile/blue/fourcorners,
/obj/machinery/defibrillator_mount/directional/south,
-/obj/structure/bed,
+/obj/structure/bed/medical{
+ dir = 4
+ },
/turf/open/floor/iron/white/textured,
/area/station/medical/treatment_center)
"ilK" = (
@@ -31952,6 +31971,9 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/cable,
+/obj/item/mod/module/plasma_stabilizer,
+/obj/item/mod/module/signlang_radio,
+/obj/item/mod/module/thermal_regulator,
/turf/open/floor/iron/dark,
/area/station/security/eva)
"iuE" = (
@@ -32226,7 +32248,7 @@
/area/station/cargo/miningdock)
"iyZ" = (
/obj/structure/flora/bush/snow/style_random,
-/turf/open/floor/fake_snow{
+/turf/open/misc/snow/actually_safe{
icon_state = "snow8"
},
/area/station/hallway/floor2/fore)
@@ -33162,8 +33184,8 @@
/turf/open/floor/iron/white,
/area/station/science/ordnance/storage)
"iMF" = (
-/obj/structure/bed{
- dir = 4
+/obj/structure/bed/medical/anchored{
+ dir = 8
},
/obj/item/bedsheet/medical{
dir = 4
@@ -33212,7 +33234,6 @@
"iMV" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible,
/obj/machinery/status_display/evac/directional/south,
-/obj/structure/cable,
/turf/open/floor/engine,
/area/station/engineering/supermatter/room)
"iMX" = (
@@ -33573,6 +33594,11 @@
},
/turf/open/floor/iron/dark,
/area/station/hallway/floor3/fore)
+"iQB" = (
+/obj/machinery/space_heater,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/pod/light,
+/area/station/maintenance/floor4/port)
"iQF" = (
/obj/machinery/hydroponics/soil,
/obj/item/plant_analyzer,
@@ -35536,7 +35562,7 @@
/area/station/hallway/floor4/aft)
"jtJ" = (
/obj/structure/window/reinforced/spawner/directional/south,
-/turf/open/floor/fake_snow{
+/turf/open/misc/snow/actually_safe{
icon_state = "snow9"
},
/area/station/hallway/floor2/fore)
@@ -36432,7 +36458,7 @@
/area/station/security/prison)
"jEZ" = (
/obj/structure/window/spawner/directional/south,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/turf/open/floor/iron/dark/textured,
/area/station/commons/fitness)
"jFh" = (
@@ -42681,6 +42707,7 @@
/obj/structure/disposalpipe/segment{
dir = 4
},
+/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/science/cytology)
"lhT" = (
@@ -45864,6 +45891,10 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/dark,
/area/station/maintenance/floor2/starboard/aft)
+"lZi" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible,
+/turf/open/floor/engine,
+/area/station/engineering/supermatter/room)
"lZl" = (
/obj/structure/reagent_dispensers/plumbed,
/obj/effect/decal/cleanable/dirt,
@@ -46081,7 +46112,6 @@
},
/obj/structure/table/reinforced,
/obj/item/storage/medkit/regular,
-/obj/structure/window/reinforced/spawner/directional/east,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/door/window/right/directional/south{
name = "First Aid Supplies";
@@ -46218,7 +46248,7 @@
/turf/open/floor/iron,
/area/station/commons/fitness/recreation)
"mdC" = (
-/turf/open/floor/fake_snow{
+/turf/open/misc/snow/actually_safe{
icon_state = "snow7"
},
/area/station/hallway/floor2/fore)
@@ -47363,7 +47393,6 @@
/turf/open/floor/iron/dark,
/area/station/command/heads_quarters/hop)
"msf" = (
-/obj/machinery/lapvend,
/obj/machinery/light/directional/north,
/obj/effect/turf_decal/trimline/purple/filled/corner{
dir = 1
@@ -48408,7 +48437,10 @@
},
/obj/machinery/computer/pod/old/mass_driver_controller/ordnancedriver,
/obj/structure/table,
-/obj/item/binoculars,
+/obj/item/binoculars{
+ pixel_x = 6;
+ pixel_y = 6
+ },
/obj/effect/turf_decal/siding/thinplating/dark{
dir = 5
},
@@ -49083,6 +49115,7 @@
"mOT" = (
/obj/machinery/light/directional/north,
/obj/machinery/airalarm/directional/north,
+/obj/structure/cable,
/turf/open/floor/engine,
/area/station/engineering/supermatter/room)
"mPs" = (
@@ -50623,6 +50656,12 @@
dir = 5
},
/area/station/hallway/floor4/aft)
+"nhZ" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/structure/table,
+/obj/item/storage/fancy/donut_box,
+/turf/open/floor/iron/dark,
+/area/station/command/heads_quarters/hos)
"nih" = (
/obj/machinery/computer/communications,
/obj/item/radio/intercom/directional/north{
@@ -53518,7 +53557,7 @@
/obj/machinery/elevator_control_panel/directional/east{
linked_elevator_id = "aft_vator";
pixel_x = 24;
- preset_destination_names = list("2"="Supply-Engi Floor","3"="Med-Sci Floor","4"="Service Floor")
+ preset_destination_names = list("2"="Supply-Engi Floor","3"="Med-Sci Floor","4"="Service Floor")
},
/turf/open/floor/plating/elevatorshaft,
/area/station/hallway/floor1/aft)
@@ -54133,7 +54172,9 @@
/area/station/medical/psychology)
"ocO" = (
/obj/effect/turf_decal/tile/green/opposingcorners,
-/obj/structure/bed,
+/obj/structure/bed/medical/anchored{
+ dir = 4
+ },
/obj/item/bedsheet/green,
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/turf/open/floor/iron/white,
@@ -54194,11 +54235,8 @@
/obj/structure/window/reinforced/spawner/directional/west,
/obj/item/storage/medkit/regular,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/door/window/left/directional/south{
- name = "First Aid Supplies";
- req_access = list("medical")
- },
/obj/effect/turf_decal/tile/blue/fourcorners,
+/obj/structure/window/reinforced/spawner/directional/south,
/turf/open/floor/iron/white/textured,
/area/station/medical/storage)
"odz" = (
@@ -54921,7 +54959,7 @@
/turf/open/floor/iron,
/area/station/hallway/secondary/exit)
"onz" = (
-/obj/item/storage/backpack/duffelbag/med/surgery{
+/obj/item/surgery_tray/full{
pixel_y = 13
},
/obj/item/reagent_containers/medigel/sterilizine{
@@ -55020,7 +55058,6 @@
/turf/open/floor/pod/light,
/area/station/maintenance/floor3/starboard/fore)
"ooN" = (
-/obj/item/storage/fancy/donut_box,
/obj/effect/turf_decal/tile/neutral/fourcorners,
/obj/structure/table,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -55032,8 +55069,8 @@
dir = 4
},
/obj/effect/decal/cleanable/dirt,
-/obj/effect/spawner/random/structure/crate,
/obj/machinery/camera/autoname/directional/south,
+/obj/machinery/suit_storage_unit/industrial/loader,
/turf/open/floor/iron/smooth,
/area/station/cargo/warehouse)
"ooQ" = (
@@ -56150,7 +56187,7 @@
/turf/open/floor/iron/smooth_half,
/area/station/tcommsat/server)
"oFH" = (
-/obj/structure/frame{
+/obj/structure/frame/machine{
anchored = 1
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -57325,7 +57362,7 @@
/turf/closed/wall/r_wall,
/area/station/maintenance/disposal/incinerator)
"oVy" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/structure/sign/gym/mirrored/right{
pixel_y = 32
@@ -57527,6 +57564,7 @@
dir = 4
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/general/hidden,
+/obj/structure/cable,
/turf/open/floor/iron/dark,
/area/station/science/cytology)
"oYL" = (
@@ -57870,13 +57908,11 @@
/turf/open/floor/iron/white,
/area/station/medical/break_room)
"pdY" = (
-/obj/machinery/computer/crew{
- dir = 8
- },
/obj/structure/sign/painting/library{
pixel_y = 32
},
/obj/machinery/light/small/directional/east,
+/obj/machinery/pdapainter/medbay,
/turf/open/floor/iron/dark,
/area/station/command/heads_quarters/cmo)
"peg" = (
@@ -58259,7 +58295,7 @@
/turf/open/floor/plating,
/area/station/security/execution/transfer)
"pjR" = (
-/obj/item/storage/backpack/duffelbag/med/surgery{
+/obj/item/surgery_tray/full{
pixel_y = 13
},
/obj/item/reagent_containers/medigel/sterilizine{
@@ -59250,7 +59286,6 @@
/obj/effect/turf_decal/stripes/line{
dir = 1
},
-/obj/structure/cable,
/turf/open/floor/engine,
/area/station/engineering/supermatter/room)
"pxw" = (
@@ -59375,6 +59410,7 @@
/obj/effect/turf_decal/stripes{
dir = 4
},
+/obj/structure/cable,
/turf/open/floor/iron/dark,
/area/station/science/cytology)
"pyQ" = (
@@ -59449,8 +59485,8 @@
/area/station/service/hydroponics)
"pzm" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/orange/visible,
-/obj/structure/cable,
/obj/machinery/light/small/directional/north,
+/obj/structure/cable,
/turf/open/floor/plating,
/area/station/engineering/supermatter/room)
"pzu" = (
@@ -59535,7 +59571,7 @@
"pAy" = (
/obj/structure/window/reinforced/spawner/directional/south,
/obj/structure/flora/bush/snow/style_random,
-/turf/open/floor/fake_snow{
+/turf/open/misc/snow/actually_safe{
icon_state = "snow7"
},
/area/station/hallway/floor2/fore)
@@ -60300,7 +60336,6 @@
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/brown/visible,
/obj/machinery/camera/autoname/directional/west,
-/obj/structure/cable,
/turf/open/floor/iron/dark/textured_large,
/area/station/engineering/supermatter/room)
"pMe" = (
@@ -60863,6 +60898,7 @@
/obj/effect/turf_decal/siding/thinplating_new/dark{
dir = 9
},
+/obj/structure/cable,
/turf/open/floor/iron/dark/textured_corner,
/area/station/engineering/supermatter/room)
"pUl" = (
@@ -61450,8 +61486,8 @@
/turf/open/floor/iron,
/area/station/service/hydroponics/garden)
"qcI" = (
-/obj/structure/bed{
- dir = 1
+/obj/structure/bed/medical/anchored{
+ dir = 8
},
/obj/effect/turf_decal/tile/blue/fourcorners,
/obj/structure/sign/poster/official/random/directional/west,
@@ -63580,6 +63616,7 @@
/obj/effect/turf_decal/trimline/purple/line,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/science/cytology)
"qEe" = (
@@ -66323,8 +66360,8 @@
dir = 1
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/cable,
/obj/effect/mapping_helpers/airlock/access/any/engineering/general,
+/obj/structure/cable,
/turf/open/floor/plating,
/area/station/engineering/supermatter/room)
"rpA" = (
@@ -67080,11 +67117,6 @@
"rAy" = (
/turf/open/floor/pod/light,
/area/station/maintenance/floor4/starboard)
-"rAD" = (
-/obj/machinery/atmospherics/components/binary/valve,
-/obj/structure/cable,
-/turf/open/floor/engine,
-/area/station/engineering/supermatter/room)
"rAE" = (
/obj/machinery/computer/records/security{
dir = 4
@@ -68046,6 +68078,12 @@
"rOY" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/turf_decal/tile/blue/fourcorners,
+/obj/structure/window/reinforced/spawner/directional/east,
+/obj/structure/table/reinforced,
+/obj/structure/window/reinforced/spawner/directional/south,
+/obj/item/mod/module/plasma_stabilizer,
+/obj/item/mod/module/signlang_radio,
+/obj/item/mod/module/thermal_regulator,
/turf/open/floor/iron/white/textured,
/area/station/medical/storage)
"rPi" = (
@@ -68181,6 +68219,7 @@
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
/turf/open/floor/circuit,
/area/station/science/cytology)
"rQV" = (
@@ -68925,7 +68964,7 @@
/area/station/cargo/drone_bay)
"sbI" = (
/obj/structure/flora/bush/snow/style_random,
-/turf/open/floor/fake_snow{
+/turf/open/misc/snow/actually_safe{
icon_state = "snow5"
},
/area/station/hallway/floor2/fore)
@@ -69054,7 +69093,6 @@
"sdt" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/brown/visible,
/obj/machinery/meter,
-/obj/structure/cable,
/turf/open/floor/iron/dark/textured_half,
/area/station/engineering/supermatter/room)
"sdA" = (
@@ -71306,7 +71344,7 @@
/obj/effect/turf_decal/siding/white{
dir = 8
},
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/machinery/light/cold/directional/east,
/turf/open/floor/iron/dark/textured,
@@ -71561,7 +71599,7 @@
/obj/effect/turf_decal/siding/wood{
dir = 8
},
-/obj/machinery/suit_storage_unit/industrial/loader,
+/obj/machinery/pdapainter/supply,
/turf/open/floor/iron/textured,
/area/station/command/heads_quarters/qm)
"sMY" = (
@@ -72196,7 +72234,6 @@
/obj/effect/turf_decal/stripes/line,
/obj/effect/turf_decal/stripes/red/line,
/obj/machinery/atmospherics/pipe/smart/manifold4w/brown/visible,
-/obj/structure/cable,
/turf/open/floor/iron/dark/textured_large,
/area/station/engineering/supermatter/room)
"sWC" = (
@@ -72605,6 +72642,7 @@
/obj/machinery/button/door/directional/south{
id = "radshutnorth"
},
+/obj/structure/cable,
/turf/open/floor/engine,
/area/station/engineering/supermatter/room)
"tat" = (
@@ -74556,6 +74594,12 @@
dir = 8
},
/area/station/hallway/secondary/exit/departure_lounge)
+"tAC" = (
+/obj/machinery/power/apc/auto_name/directional/north,
+/obj/effect/turf_decal/stripes/end,
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/station/engineering/supermatter/room)
"tAE" = (
/obj/machinery/vending/cola/starkist,
/turf/open/floor/wood,
@@ -75891,7 +75935,7 @@
"tTB" = (
/obj/structure/window/reinforced/spawner/directional/south,
/obj/structure/statue/snow/snowman,
-/turf/open/floor/fake_snow,
+/turf/open/misc/snow/actually_safe,
/area/station/hallway/floor2/fore)
"tTC" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
@@ -76160,6 +76204,7 @@
/obj/structure/disposalpipe/segment{
dir = 6
},
+/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/science/cytology)
"tXF" = (
@@ -78260,8 +78305,8 @@
dir = 1
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/cable,
/obj/effect/mapping_helpers/airlock/access/any/engineering/general,
+/obj/structure/cable,
/turf/open/floor/plating,
/area/station/maintenance/floor1/port/aft)
"uCv" = (
@@ -78383,9 +78428,9 @@
/turf/open/floor/plating,
/area/station/hallway/secondary/exit/escape_pod)
"uDL" = (
-/obj/machinery/suit_storage_unit/hos,
/obj/effect/turf_decal/tile/neutral/fourcorners,
/obj/machinery/light/small/directional/south,
+/obj/machinery/suit_storage_unit/hos,
/turf/open/floor/iron/dark,
/area/station/command/heads_quarters/hos)
"uDN" = (
@@ -79063,8 +79108,9 @@
/area/station/maintenance/floor2/port/aft)
"uLB" = (
/obj/machinery/atmospherics/components/unary/outlet_injector/on{
+ volume_rate = 200;
dir = 8;
- volume_rate = 200
+ initialize_directions = 8
},
/obj/machinery/atmospherics/pipe/heat_exchanging/manifold/layer2{
dir = 8
@@ -79383,8 +79429,8 @@
/turf/open/floor/grass,
/area/station/science/cytology)
"uPc" = (
-/obj/structure/bed{
- dir = 1
+/obj/structure/bed/medical/anchored{
+ dir = 8
},
/obj/effect/turf_decal/tile/blue/fourcorners,
/obj/structure/sign/poster/official/random/directional/east,
@@ -84895,8 +84941,8 @@
/turf/open/floor/iron/dark,
/area/station/hallway/floor2/fore)
"wlo" = (
-/obj/structure/bed{
- dir = 1
+/obj/structure/bed/medical/anchored{
+ dir = 8
},
/obj/effect/turf_decal/tile/blue/fourcorners,
/obj/machinery/light/small/directional/south,
@@ -87345,14 +87391,6 @@
/obj/structure/grille,
/turf/open/floor/plating/airless,
/area/station/service/chapel/funeral)
-"wOP" = (
-/obj/structure/cable,
-/obj/machinery/power/apc/auto_name/directional/north,
-/obj/effect/turf_decal/stripes/line{
- dir = 6
- },
-/turf/open/floor/plating,
-/area/station/engineering/supermatter/room)
"wPn" = (
/obj/effect/turf_decal/trimline/green/filled/line{
dir = 4
@@ -87430,6 +87468,11 @@
dir = 1
},
/area/station/hallway/secondary/entry)
+"wQh" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/structure/sign/flag/nanotrasen/directional/south,
+/turf/open/floor/iron/dark,
+/area/station/command/heads_quarters/hos)
"wQo" = (
/turf/closed/wall,
/area/station/security/prison/garden)
@@ -87932,6 +87975,7 @@
dir = 5
},
/obj/item/radio/intercom/directional/east,
+/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/science/cytology)
"wXi" = (
@@ -116252,7 +116296,7 @@ rYA
eEB
lUY
bUC
-yiZ
+rYA
yiZ
mMH
ncc
@@ -137852,7 +137896,7 @@ rBP
jcr
rBP
rBP
-wOP
+xgW
xgW
xgW
xgW
@@ -138365,7 +138409,7 @@ oIy
oIy
tjV
xgW
-xgW
+mVF
pUf
eCQ
uyD
@@ -138622,7 +138666,7 @@ whF
oIy
aDf
xgW
-xgW
+mVF
wmC
sly
uyD
@@ -139391,7 +139435,7 @@ nIJ
uLB
rAm
sAH
-xgW
+tAC
jSD
fcp
iCk
@@ -139650,7 +139694,7 @@ qEw
sAH
xgW
kfo
-iyT
+lZi
kcB
ppO
fJE
@@ -139660,7 +139704,7 @@ wCu
vap
kBK
juf
-klY
+wOm
kfo
wfl
dEc
@@ -140164,17 +140208,17 @@ uEu
sAH
bQz
uCe
-iyT
-mVF
-alE
+lZi
+xgW
+pIZ
gSf
sWB
sdt
pMa
gSf
pxv
-rAD
-klY
+jER
+wOm
rpD
tyQ
dEc
@@ -315210,7 +315254,7 @@ vEa
vEa
vEa
vEa
-owb
+vEa
vEa
bAG
bAG
@@ -315466,10 +315510,10 @@ mau
hSD
raE
pke
+fmG
+nhZ
vEa
-owb
-vEa
-vEa
+aIU
wtL
bAG
wtL
@@ -315723,11 +315767,11 @@ lXx
ltD
nah
jLm
-vEa
-owb
-owb
+hLq
+eQd
vEa
eEN
+wtL
bAG
tqr
fXs
@@ -315980,10 +316024,10 @@ lXx
dAe
hhX
dlt
+hLq
+wQh
vEa
-vEa
-vEa
-vEa
+iQB
eGl
fPD
jbV
diff --git a/_maps/map_files/VoidRaptor/VoidRaptor.dmm b/_maps/map_files/VoidRaptor/VoidRaptor.dmm
index 1d8058205cb..1999bef2268 100644
--- a/_maps/map_files/VoidRaptor/VoidRaptor.dmm
+++ b/_maps/map_files/VoidRaptor/VoidRaptor.dmm
@@ -13,7 +13,7 @@
"aal" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/spawner/random/maintenance/two,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
"aau" = (
/obj/item/kirbyplants/random,
@@ -581,6 +581,11 @@
},
/turf/open/floor/iron/white,
/area/station/medical/storage)
+"aiq" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/spawner/random/trash/garbage,
+/turf/open/floor/plating,
+/area/station/maintenance/department/crew_quarters/bar)
"air" = (
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating/airless,
@@ -1278,6 +1283,9 @@
/obj/effect/turf_decal/bot_white,
/turf/open/floor/iron/grimy,
/area/station/service/library)
+"asX" = (
+/turf/closed/wall,
+/area/station/medical/office)
"atb" = (
/obj/effect/turf_decal/siding/wood{
dir = 8
@@ -2619,7 +2627,7 @@
"aNf" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/light/small/directional/west,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
"aNg" = (
/obj/machinery/computer/upload/ai{
@@ -2663,7 +2671,7 @@
/obj/machinery/light_switch/directional/north,
/obj/machinery/firealarm/directional/west,
/obj/item/storage/box/pdas,
-/obj/item/clothing/suit/costume/ianshirt,
+/obj/item/clothing/suit/costume/wellworn_shirt/graphic/ian,
/obj/effect/turf_decal/bot,
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -2887,7 +2895,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"aRc" = (
/obj/machinery/atmospherics/pipe/smart/simple/dark/hidden,
/turf/open/floor/iron/white/smooth_large,
@@ -3232,7 +3240,7 @@
/area/station/medical/chemistry)
"aWh" = (
/obj/effect/mapping_helpers/broken_floor,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/engine/atmos)
"aWs" = (
/obj/structure/rack,
@@ -3400,6 +3408,13 @@
/obj/structure/tank_holder/oxygen,
/turf/open/floor/iron/edge,
/area/station/commons/fitness/recreation)
+"aXl" = (
+/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,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/greater)
"aXm" = (
/obj/machinery/door/firedoor,
/obj/effect/mapping_helpers/airlock/access/all/service/general,
@@ -3440,6 +3455,10 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/catwalk_floor,
/area/station/hallway/secondary/construction)
+"aXG" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/aft)
"aXM" = (
/turf/closed/wall/mineral/plastitanium,
/area/station/science/research)
@@ -3622,7 +3641,7 @@
"bao" = (
/obj/structure/trash_pile,
/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/science/ordnance_maint)
"baw" = (
/obj/effect/turf_decal/trimline/brown/filled/line{
@@ -3660,7 +3679,7 @@
},
/obj/structure/sign/calendar/directional/north,
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"baU" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 4
@@ -3716,7 +3735,7 @@
/area/station/maintenance/solars/port/fore)
"bbN" = (
/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/engine/atmos/lesser)
"bbU" = (
/obj/effect/turf_decal/trimline/yellow/filled/line{
@@ -3953,6 +3972,10 @@
dir = 8
},
/area/station/science/ordnance)
+"beq" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/greater)
"bes" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -4017,16 +4040,25 @@
/turf/open/space,
/area/space/nearstation)
"bgo" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/spawner/random/structure/crate_empty,
-/obj/effect/spawner/random/maintenance/three,
-/turf/open/floor/iron/smooth,
+/obj/machinery/door/airlock/maintenance{
+ name = "Exam Room Maintenance"
+ },
+/obj/structure/disposalpipe/segment,
+/obj/structure/cable,
+/obj/effect/mapping_helpers/airlock/access/any/medical/general,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/catwalk_floor/iron_smooth,
/area/station/maintenance/department/medical/central)
"bgy" = (
/obj/structure/chair/wood,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/carpet/stellar,
/area/station/service/chapel/funeral)
+"bgz" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/aft)
"bgF" = (
/obj/effect/turf_decal/trimline/yellow/filled/corner{
dir = 8
@@ -4044,7 +4076,7 @@
pixel_y = 10
},
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"bhv" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/obj/machinery/airalarm/directional/west,
@@ -4898,6 +4930,13 @@
},
/turf/open/floor/wood,
/area/station/service/bar)
+"bvt" = (
+/obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible{
+ dir = 4
+ },
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port)
"bvv" = (
/obj/machinery/door/airlock/public/glass{
name = "Janitorial"
@@ -4943,10 +4982,6 @@
/obj/item/flashlight/lamp,
/turf/open/floor/iron/white,
/area/station/medical/virology)
-"bwm" = (
-/obj/structure/disposalpipe/segment,
-/turf/closed/wall/r_wall,
-/area/station/maintenance/department/medical/central)
"bwv" = (
/obj/effect/spawner/random/structure/crate,
/obj/effect/decal/cleanable/dirt,
@@ -5151,7 +5186,9 @@
/obj/effect/turf_decal/trimline/red/filled/line{
dir = 5
},
-/obj/structure/bed,
+/obj/structure/bed/medical/emergency{
+ dir = 4
+ },
/obj/item/clothing/suit/jacket/straight_jacket,
/obj/item/clothing/glasses/blindfold,
/obj/item/clothing/mask/muzzle,
@@ -5512,7 +5549,6 @@
},
/area/station/medical/medbay/lobby)
"bGd" = (
-/obj/machinery/iv_drip,
/obj/effect/turf_decal/tile/blue/fourcorners,
/obj/structure/cable,
/turf/open/floor/iron/freezer,
@@ -5797,7 +5833,7 @@
"bLv" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/sign/poster/random/directional/south,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/aft)
"bLx" = (
/obj/structure/cable,
@@ -5888,7 +5924,9 @@
name = "medbay camera";
network = list("ss13","medbay")
},
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 1
+ },
/turf/open/floor/iron/showroomfloor,
/area/station/medical/coldroom)
"bMR" = (
@@ -5922,7 +5960,9 @@
/turf/open/floor/iron/smooth_edge,
/area/station/cargo/storage)
"bNs" = (
-/obj/structure/bed,
+/obj/structure/bed/medical/anchored{
+ dir = 4
+ },
/obj/machinery/iv_drip,
/obj/item/bedsheet/medical,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
@@ -6197,7 +6237,7 @@
dir = 8
},
/turf/open/floor/wood/large,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"bRM" = (
/obj/effect/turf_decal/trimline/green/filled/line{
dir = 1
@@ -6372,7 +6412,7 @@
"bUl" = (
/obj/structure/sign/departments/custodian/directional/west,
/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"bUt" = (
/obj/effect/turf_decal/siding/wood{
@@ -6642,7 +6682,7 @@
/turf/open/floor/carpet/royalblue,
/area/station/command/heads_quarters/captain/private)
"cad" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 8
@@ -7028,7 +7068,7 @@
/turf/open/floor/iron/dark,
/area/station/security/execution/education)
"cfH" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 8
@@ -7110,6 +7150,13 @@
/obj/machinery/status_display/ai,
/turf/closed/wall,
/area/station/engineering/atmos)
+"cgH" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"cgT" = (
/obj/effect/turf_decal/trimline/blue/line,
/obj/effect/landmark/start/medical_doctor,
@@ -7423,7 +7470,7 @@
/area/station/engineering/supermatter/room)
"cmH" = (
/turf/closed/wall/r_wall,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"cmM" = (
/obj/structure/chair/office/light{
dir = 4
@@ -7660,7 +7707,7 @@
},
/obj/effect/turf_decal/box,
/turf/open/floor/wood/large,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"cpP" = (
/obj/structure/lattice/catwalk,
/obj/machinery/camera/directional/west{
@@ -8269,7 +8316,7 @@
/turf/open/floor/catwalk_floor,
/area/station/security/execution/transfer)
"czs" = (
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/engine)
"czC" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -8321,7 +8368,7 @@
/obj/item/storage/secure/safe/directional/east,
/obj/machinery/newscaster/directional/south,
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"cAQ" = (
/obj/machinery/computer/operating,
/obj/effect/turf_decal/trimline/blue/filled/warning{
@@ -8553,6 +8600,22 @@
/obj/structure/cable,
/turf/open/floor/iron/solarpanel/airless,
/area/station/solars/port/aft)
+"cEB" = (
+/obj/machinery/digital_clock/directional/north,
+/obj/structure/table/glass,
+/obj/item/paper_bin{
+ pixel_x = -3;
+ pixel_y = 4
+ },
+/obj/item/pen{
+ pixel_x = -3;
+ pixel_y = 4
+ },
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 1
+ },
+/turf/open/floor/iron/white/smooth_edge,
+/area/station/medical/office)
"cEE" = (
/obj/effect/turf_decal/trimline/yellow/filled/line{
dir = 4
@@ -8566,6 +8629,16 @@
dir = 8
},
/area/station/engineering/lobby)
+"cEL" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/port)
"cEP" = (
/obj/effect/spawner/random/structure/girder,
/turf/open/floor/iron/smooth,
@@ -8653,6 +8726,19 @@
},
/turf/open/floor/iron/dark/smooth_large,
/area/station/command/bridge)
+"cGu" = (
+/obj/machinery/firealarm/directional/east{
+ pixel_y = 5
+ },
+/obj/machinery/light_switch/directional/east{
+ pixel_y = 6;
+ pixel_x = 23
+ },
+/obj/effect/turf_decal/trimline/blue/filled/warning{
+ dir = 5
+ },
+/turf/open/floor/iron/white,
+/area/station/medical/office)
"cGw" = (
/obj/machinery/atmospherics/components/unary/outlet_injector/monitored/air_input{
dir = 4
@@ -8812,7 +8898,7 @@
"cIc" = (
/obj/machinery/light/small/directional/north,
/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/science/ordnance_maint)
"cIr" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
@@ -8934,7 +9020,7 @@
"cJm" = (
/obj/effect/decal/cleanable/dirt,
/obj/item/stack/sheet/cardboard,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/greater)
"cJo" = (
/obj/structure/chair/office{
@@ -9576,7 +9662,7 @@
pixel_x = -32
},
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"cTO" = (
/obj/structure/trash_pile,
/turf/open/floor/iron/smooth,
@@ -9602,7 +9688,7 @@
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/dirt,
/obj/effect/spawner/random/trash/garbage,
-/turf/open/floor/catwalk_floor/iron_smooth,
+/turf/open/floor/plating,
/area/station/maintenance/aft)
"cUH" = (
/obj/effect/turf_decal/trimline/blue/filled/warning{
@@ -9668,7 +9754,7 @@
/obj/item/stack/sheet/glass{
amount = 4
},
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/fore)
"cVI" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -9723,7 +9809,7 @@
/obj/machinery/power/apc/auto_name/directional/east,
/obj/structure/chair/comfy,
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"cXd" = (
/obj/effect/turf_decal/stripes/line{
dir = 9
@@ -10056,7 +10142,7 @@
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/spawner/random/trash/garbage,
-/turf/open/floor/catwalk_floor/iron_smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/aft)
"dbQ" = (
/obj/effect/turf_decal/trimline/purple/filled/line{
@@ -10145,6 +10231,12 @@
dir = 8
},
/area/station/commons/fitness/recreation)
+"dcL" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/plating,
+/area/station/maintenance/aft/greater)
"dcR" = (
/obj/machinery/door/airlock/external{
name = "External Solar Access"
@@ -10194,15 +10286,12 @@
/turf/open/floor/catwalk_floor/iron_smooth,
/area/station/maintenance/aft/greater)
"ddB" = (
-/obj/structure/table,
-/obj/machinery/computer/records/security/laptop{
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/purple/fourcorners,
+/obj/machinery/computer/records/security{
dir = 4
},
-/obj/structure/cable,
-/obj/item/storage/fancy/donut_box{
- pixel_y = 17
- },
-/obj/effect/turf_decal/tile/purple/fourcorners,
+/obj/effect/turf_decal/bot,
/turf/open/floor/iron/dark,
/area/station/security/corrections_officer)
"ddH" = (
@@ -11045,6 +11134,13 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/fore)
+"dqM" = (
+/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,
+/turf/open/floor/plating,
+/area/station/maintenance/department/crew_quarters/bar)
"dqT" = (
/obj/structure/railing/corner,
/obj/structure/cable/layer3,
@@ -11311,7 +11407,7 @@
"dul" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/trash_pile,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/aft)
"duq" = (
/obj/structure/window/reinforced/spawner/directional/north,
@@ -11347,6 +11443,10 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/iron/smooth_large,
/area/station/hallway/secondary/entry)
+"duy" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/aft)
"duG" = (
/obj/structure/cable/multilayer/connected,
/turf/open/floor/circuit,
@@ -11666,7 +11766,7 @@
/obj/machinery/photocopier,
/obj/effect/turf_decal/bot,
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"dzy" = (
/obj/effect/turf_decal/trimline/yellow/filled/line{
dir = 9
@@ -11678,7 +11778,7 @@
/area/station/hallway/primary/aft)
"dzC" = (
/obj/effect/decal/cleanable/glass,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/aft/lesser)
"dzE" = (
/obj/structure/chair/comfy/beige{
@@ -12024,13 +12124,13 @@
/area/station/maintenance/port/fore)
"dDR" = (
/obj/effect/turf_decal/tile/blue/fourcorners,
-/obj/structure/bed/pod{
- desc = "An old medical bed, just waiting for replacement with something up to date.";
- name = "medical bed"
+/obj/structure/bed/medical{
+ dir = 4
},
/obj/machinery/newscaster/directional/east,
/obj/machinery/duct,
/obj/effect/turf_decal/box/blue,
+/obj/item/bedsheet/medical,
/turf/open/floor/iron/freezer,
/area/station/medical/treatment_center)
"dEb" = (
@@ -12156,6 +12256,15 @@
},
/obj/structure/closet/crate/internals,
/obj/effect/turf_decal/bot,
+/obj/item/tank/internals/emergency_oxygen,
+/obj/item/tank/internals/emergency_oxygen,
+/obj/item/tank/internals/nitrogen/belt,
+/obj/item/tank/internals/nitrogen/belt,
+/obj/item/clothing/mask/breath/vox,
+/obj/item/clothing/mask/breath/vox,
+/obj/item/clothing/mask/breath/vox,
+/obj/item/clothing/mask/breath/vox,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/hidden,
/turf/open/floor/iron/showroomfloor,
/area/station/medical/coldroom)
"dGw" = (
@@ -12256,7 +12365,7 @@
dir = 8
},
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"dHa" = (
/obj/structure/bookcase/random/religion,
/obj/effect/turf_decal/siding/wood{
@@ -12970,10 +13079,12 @@
/area/station/service/chapel/office)
"dQq" = (
/obj/effect/decal/cleanable/glass,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/fore)
"dQr" = (
-/obj/structure/bed,
+/obj/structure/bed/medical{
+ dir = 4
+ },
/obj/item/bedsheet/medical,
/obj/machinery/iv_drip,
/obj/effect/turf_decal/trimline/red/filled/line{
@@ -13103,7 +13214,7 @@
/obj/effect/spawner/random/structure/steam_vent,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/catwalk_floor/iron_smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/engine/atmos/lesser)
"dSI" = (
/obj/effect/turf_decal/trimline/yellow/filled/line{
@@ -13466,7 +13577,7 @@
/area/station/engineering/supermatter/room)
"dXM" = (
/obj/effect/spawner/random/trash/grime,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/aft)
"dXU" = (
/obj/effect/spawner/structure/window/reinforced/plasma,
@@ -13709,7 +13820,7 @@
/area/station/ai_monitored/turret_protected/ai)
"eak" = (
/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/medical/central)
"eam" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -13830,6 +13941,11 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/kitchen,
/area/station/service/kitchen/abandoned)
+"ebS" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/spawner/random/trash/mess,
+/turf/open/floor/plating,
+/area/station/maintenance/department/engine/atmos)
"eci" = (
/obj/effect/landmark/event_spawn,
/turf/open/floor/iron/smooth_large,
@@ -14116,6 +14232,12 @@
/obj/effect/turf_decal/bot,
/turf/open/floor/iron/dark/smooth_edge,
/area/station/hallway/secondary/command)
+"efn" = (
+/obj/structure/disposalpipe/segment,
+/obj/machinery/holopad,
+/obj/effect/turf_decal/bot,
+/turf/open/floor/iron/white/smooth_large,
+/area/station/medical/exam_room)
"efo" = (
/obj/structure/chair/sofa/bench/left{
dir = 1
@@ -14302,7 +14424,7 @@
/turf/open/floor/wood/parquet,
/area/station/common/night_club)
"ehl" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/bot,
/obj/machinery/vending/wallmed/directional/east,
/obj/effect/turf_decal/trimline/blue/filled/line{
@@ -14596,7 +14718,7 @@
pixel_y = 3
},
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"elo" = (
/obj/effect/decal/cleanable/dirt,
/obj/item/chair/stool,
@@ -14643,7 +14765,7 @@
/area/station/maintenance/aft/greater)
"emd" = (
/obj/effect/spawner/random/structure/crate_abandoned,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/aft/greater)
"eme" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -15639,6 +15761,13 @@
/obj/effect/turf_decal/delivery,
/turf/open/floor/iron/smooth_large,
/area/station/cargo/sorting)
+"eBy" = (
+/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/plating,
+/area/station/maintenance/aft/greater)
"eBD" = (
/obj/effect/turf_decal/trimline/green/filled/line{
dir = 8
@@ -15971,7 +16100,7 @@
dir = 8
},
/turf/open/floor/iron/dark/smooth_large,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"eFg" = (
/obj/structure/chair/comfy/beige{
dir = 1
@@ -16098,7 +16227,7 @@
/area/station/maintenance/department/science/ordnance_maint)
"eGo" = (
/obj/effect/mapping_helpers/broken_floor,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/aft)
"eGs" = (
/obj/effect/turf_decal/siding/thinplating/corner{
@@ -16367,6 +16496,13 @@
dir = 1
},
/area/station/maintenance/disposal/incinerator)
+"eKs" = (
+/obj/structure/filingcabinet/medical,
+/obj/effect/turf_decal/trimline/blue/filled/line,
+/turf/open/floor/iron/white/smooth_edge{
+ dir = 1
+ },
+/area/station/medical/office)
"eKx" = (
/obj/effect/landmark/blobstart,
/obj/effect/landmark/event_spawn,
@@ -16489,7 +16625,7 @@
/turf/open/floor/iron/smooth,
/area/station/maintenance/department/science/ordnance_maint)
"eMd" = (
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/aft)
"eMe" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -16629,7 +16765,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/landmark/start/blueshield,
/turf/open/floor/carpet/cyan,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"ePm" = (
/obj/machinery/holopad,
/obj/effect/turf_decal/box,
@@ -16766,7 +16902,7 @@
},
/obj/machinery/digital_clock/directional/west,
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"eRt" = (
/obj/machinery/airalarm/directional/north,
/obj/effect/turf_decal/trimline/yellow/filled/warning{
@@ -16801,7 +16937,7 @@
dir = 4
},
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"eSb" = (
/obj/machinery/conveyor/inverted{
dir = 10;
@@ -16867,7 +17003,7 @@
/area/station/security/prison/garden)
"eTo" = (
/obj/effect/spawner/random/structure/closet_maintenance,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"eTD" = (
/obj/effect/turf_decal/weather/sand{
@@ -16915,7 +17051,7 @@
dir = 8
},
/turf/open/floor/iron/dark/smooth_large,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"eUm" = (
/obj/structure/bed,
/obj/item/bedsheet/yellow,
@@ -17220,7 +17356,7 @@
/obj/structure/chair/comfy{
dir = 1
},
-/obj/item/clothing/suit/costume/nerdshirt,
+/obj/item/clothing/suit/costume/wellworn_shirt/messy/graphic/gamer,
/obj/item/clothing/head/fedora,
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/smooth,
@@ -17684,7 +17820,7 @@
"fgd" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"fgh" = (
/obj/effect/turf_decal/tile/blue{
dir = 8
@@ -17911,7 +18047,7 @@
"fkI" = (
/obj/structure/railing,
/obj/structure/table/glass,
-/obj/structure/bedsheetbin,
+/obj/structure/towel_bin,
/turf/open/floor/iron/white/small,
/area/station/common/pool)
"fkM" = (
@@ -18355,6 +18491,11 @@
dir = 4
},
/area/station/engineering/atmos/storage/gas)
+"fpE" = (
+/obj/structure/cable,
+/obj/effect/spawner/random/trash/garbage,
+/turf/open/floor/plating,
+/area/station/maintenance/department/security/brig)
"fpH" = (
/turf/closed/wall/r_wall,
/area/station/engineering/atmos/storage)
@@ -18664,6 +18805,7 @@
dir = 9
},
/obj/effect/turf_decal/stripes/red/box,
+/obj/structure/sign/delam_procedure/directional/east,
/turf/open/floor/engine,
/area/station/engineering/supermatter/room)
"fvr" = (
@@ -18729,7 +18871,7 @@
},
/obj/effect/turf_decal/tile/dark_blue/full,
/turf/open/floor/iron/dark/smooth_large,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"fwW" = (
/obj/effect/turf_decal/trimline/brown/filled/warning{
dir = 1
@@ -19519,7 +19661,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/cable,
-/turf/open/floor/catwalk_floor/iron_smooth,
+/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
"fKt" = (
/obj/machinery/atmospherics/pipe/smart/simple/purple/visible{
@@ -19678,7 +19820,7 @@
"fMW" = (
/obj/effect/landmark/start/janitor,
/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"fNt" = (
/obj/effect/decal/cleanable/dirt,
@@ -20006,7 +20148,6 @@
/area/station/commons/dorms)
"fTs" = (
/obj/effect/turf_decal/box,
-/obj/machinery/light/small/directional/west,
/turf/open/floor/iron/smooth,
/area/station/science/research/abandoned)
"fTA" = (
@@ -20110,10 +20251,10 @@
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 5
},
-/obj/structure/closet/crate/medical,
/obj/machinery/light_switch/directional/east,
/obj/effect/turf_decal/bot,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/closet/crate/freezer/surplus_limbs,
/turf/open/floor/iron/showroomfloor,
/area/station/medical/coldroom)
"fUB" = (
@@ -20650,7 +20791,7 @@
/obj/structure/cable,
/obj/effect/decal/cleanable/dirt,
/obj/structure/sign/poster/random/directional/east,
-/turf/open/floor/catwalk_floor/iron_smooth,
+/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
"gcg" = (
/obj/structure/closet/crate/goldcrate,
@@ -20858,6 +20999,9 @@
/obj/machinery/telecomms/bus/preset_one,
/turf/open/floor/circuit/telecomms/server,
/area/station/tcommsat/server)
+"gfv" = (
+/turf/open/floor/plating,
+/area/station/maintenance/aft/greater)
"gfw" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 8
@@ -21044,14 +21188,15 @@
/area/station/hallway/secondary/exit/departure_lounge)
"giB" = (
/obj/effect/turf_decal/tile/blue/fourcorners,
-/obj/structure/bed/pod{
- desc = "An old medical bed, just waiting for replacement with something up to date.";
- dir = 4;
- name = "medical bed"
+/obj/structure/bed/medical{
+ dir = 8
},
/obj/machinery/newscaster/directional/west,
/obj/machinery/duct,
/obj/effect/turf_decal/box/blue,
+/obj/item/bedsheet/medical{
+ dir = 4
+ },
/turf/open/floor/iron/freezer,
/area/station/medical/treatment_center)
"giC" = (
@@ -21265,8 +21410,8 @@
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 1
},
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
- dir = 4
+/obj/machinery/atmospherics/pipe/layer_manifold/supply/hidden{
+ dir = 8
},
/turf/open/floor/iron/showroomfloor,
/area/station/medical/coldroom)
@@ -21473,7 +21618,7 @@
/area/station/science/ordnance)
"gmJ" = (
/obj/effect/spawner/random/structure/crate,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/greater)
"gmL" = (
/obj/machinery/door/firedoor,
@@ -22056,7 +22201,6 @@
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/duct,
-/obj/item/kirbyplants/random,
/turf/open/floor/iron/white/smooth_large,
/area/station/medical/storage)
"gwc" = (
@@ -22830,7 +22974,7 @@
/obj/structure/cable,
/obj/structure/sign/calendar/directional/south,
/turf/open/floor/wood/large,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"gHG" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -22852,6 +22996,10 @@
/obj/effect/landmark/start/roboticist,
/turf/open/floor/wood/large,
/area/station/science/research)
+"gHM" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/hidden,
+/turf/open/floor/catwalk_floor/iron_smooth,
+/area/station/maintenance/department/medical/central)
"gHW" = (
/obj/structure/table/optable{
desc = "A cold, hard place for your final rest.";
@@ -23489,7 +23637,7 @@
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -23723,7 +23871,15 @@
pixel_y = 5
},
/turf/closed/wall/r_wall,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
+"gTk" = (
+/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,
+/turf/open/floor/plating,
+/area/station/maintenance/department/crew_quarters/bar)
"gTJ" = (
/obj/effect/mapping_helpers/airlock/unres{
dir = 1
@@ -23774,7 +23930,7 @@
dir = 1
},
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"gUC" = (
/obj/machinery/power/shuttle_engine/heater,
/obj/effect/turf_decal/stripes/line{
@@ -24170,7 +24326,7 @@
/turf/open/floor/engine,
/area/station/engineering/supermatter)
"haq" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/effect/landmark/event_spawn,
/turf/open/floor/iron/white/smooth_large,
@@ -24230,10 +24386,6 @@
},
/turf/open/floor/wood,
/area/station/maintenance/department/engine/atmos)
-"hbc" = (
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/catwalk_floor/iron_smooth,
-/area/station/maintenance/department/security/brig)
"hbf" = (
/obj/effect/turf_decal/tile/yellow/opposingcorners,
/obj/effect/turf_decal/tile/red/opposingcorners{
@@ -24259,8 +24411,11 @@
/obj/effect/turf_decal/box/white{
color = "#52B4E9"
},
-/obj/machinery/portable_atmospherics/canister/oxygen,
/obj/machinery/light/cold/directional/south,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 8
+ },
+/obj/machinery/portable_atmospherics/canister/anesthetic_mix,
/turf/open/floor/iron/showroomfloor,
/area/station/medical/coldroom)
"hbG" = (
@@ -24592,7 +24747,7 @@
"hfT" = (
/obj/structure/trash_pile,
/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/crew_quarters/bar)
"hfU" = (
/turf/closed/wall,
@@ -24732,7 +24887,7 @@
"hhQ" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/light/small/directional/north,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/aft)
"hhT" = (
/obj/structure/cable,
@@ -25086,7 +25241,7 @@
"hnn" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/trash_pile,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/aft/greater)
"hns" = (
/obj/machinery/door/firedoor,
@@ -25189,7 +25344,7 @@
"hpq" = (
/obj/effect/spawner/random/maintenance/two,
/obj/item/stack/sheet/iron/five,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/fore)
"hpE" = (
/obj/structure/disposalpipe/segment{
@@ -25207,7 +25362,7 @@
/area/station/maintenance/starboard/aft)
"hqd" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/catwalk_floor/iron_smooth,
+/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"hqe" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -25463,7 +25618,7 @@
"hut" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/spawner/random/trash/garbage,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
"huv" = (
/obj/machinery/airalarm/directional/west,
@@ -25935,7 +26090,7 @@
/area/station/engineering/supermatter/room)
"hAp" = (
/obj/structure/trash_pile,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/medical/central)
"hAu" = (
/obj/structure/table/glass,
@@ -26225,7 +26380,7 @@
"hDI" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/spawner/random/medical/minor_healing,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/aft)
"hDY" = (
/obj/machinery/computer/atmos_control/mix_tank{
@@ -26352,7 +26507,7 @@
"hEZ" = (
/obj/effect/spawner/random/trash/mess,
/obj/structure/sign/poster/random/directional/west,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/fore)
"hFa" = (
/obj/effect/turf_decal/trimline/yellow/filled/line{
@@ -26971,7 +27126,7 @@
pixel_y = 7
},
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"hQW" = (
/obj/effect/turf_decal/trimline/red/filled/line,
/obj/structure/disposalpipe/segment{
@@ -27182,11 +27337,6 @@
},
/turf/open/floor/pod/dark,
/area/station/service/chapel/office)
-"hTn" = (
-/obj/effect/spawner/structure/window/reinforced/plasma,
-/obj/item/folder/biscuit/confidential/delam,
-/turf/open/floor/plating/airless,
-/area/station/engineering/supermatter/room)
"hTr" = (
/obj/effect/turf_decal/trimline/yellow/filled/warning{
dir = 10
@@ -27587,6 +27737,13 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/kitchen,
/area/station/service/kitchen/abandoned)
+"hYA" = (
+/obj/structure/cable,
+/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/plating,
+/area/station/maintenance/department/engine/atmos/lesser)
"hYJ" = (
/obj/structure/bed,
/obj/structure/railing,
@@ -27697,9 +27854,8 @@
/turf/open/floor/wood/large,
/area/station/science/research)
"iaq" = (
-/obj/machinery/light/small/directional/south,
/obj/structure/extinguisher_cabinet/directional/south,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/aft)
"iay" = (
/turf/closed/wall,
@@ -27737,13 +27893,13 @@
},
/obj/effect/turf_decal/bot,
/obj/machinery/button/door/directional/east{
- id = "cargounload";
+ id = 68;
layer = 4;
- name = "Loading Doors";
+ name = "Unloading Doors";
pixel_y = 6
},
/obj/machinery/button/door/directional/east{
- id = "cargoload";
+ id = 69;
layer = 4;
name = "Loading Doors";
pixel_y = -6
@@ -27829,6 +27985,20 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/maintenance/department/engine)
+"icH" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/structure/cable,
+/obj/effect/turf_decal/trimline/blue/filled/line,
+/obj/machinery/light/cold/directional/south,
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 4
+ },
+/turf/open/floor/iron/white/smooth_edge{
+ dir = 1
+ },
+/area/station/medical/exam_room)
"icI" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -27838,6 +28008,16 @@
"icP" = (
/turf/open/floor/glass/reinforced,
/area/station/medical/medbay/central)
+"idg" = (
+/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/machinery/power/apc/auto_name/directional/north,
+/turf/open/floor/plating,
+/area/station/maintenance/department/medical/central)
"idl" = (
/obj/structure/chair/sofa/right/maroon{
dir = 1
@@ -28128,6 +28308,13 @@
/obj/item/radio,
/turf/open/floor/iron/smooth,
/area/station/security/checkpoint/supply)
+"ijj" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port)
"ijw" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -28168,11 +28355,13 @@
/turf/open/floor/pod/dark,
/area/station/service/chapel)
"ikc" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/structure/disposalpipe/segment{
+/obj/structure/disposalpipe/junction/flip{
dir = 4
},
-/turf/open/floor/iron/smooth,
+/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/iron_smooth,
/area/station/maintenance/department/medical/central)
"ike" = (
/obj/effect/turf_decal/box/corners{
@@ -28299,7 +28488,7 @@
dir = 4
},
/turf/open/floor/carpet/cyan,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"ilY" = (
/obj/effect/turf_decal/trimline/yellow/filled/line,
/obj/effect/turf_decal/trimline/blue/filled/line,
@@ -28315,6 +28504,12 @@
/obj/machinery/atmospherics/pipe/smart/manifold/dark/hidden,
/turf/open/floor/iron/white/smooth_large,
/area/station/science/xenobiology)
+"imc" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/port)
"imd" = (
/obj/effect/turf_decal/siding/wood{
dir = 10
@@ -28383,7 +28578,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/carpet/cyan,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"inc" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/door/window/left/directional/west{
@@ -28777,10 +28972,10 @@
/area/station/maintenance/port/central)
"irm" = (
/obj/structure/cable,
-/obj/structure/closet/secure_closet/medical2,
/obj/machinery/power/apc/auto_name/directional/west,
/obj/effect/turf_decal/tile/blue/fourcorners,
/obj/effect/turf_decal/bot,
+/obj/machinery/iv_drip,
/turf/open/floor/iron/freezer,
/area/station/medical/treatment_center)
"iru" = (
@@ -28829,6 +29024,18 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/smooth_edge,
/area/station/engineering/atmos)
+"irU" = (
+/obj/structure/disposalpipe/segment{
+ dir = 10
+ },
+/obj/structure/cable,
+/obj/effect/turf_decal/trimline/blue/filled/warning{
+ dir = 6
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/iron/white,
+/area/station/medical/exam_room)
"irZ" = (
/obj/effect/turf_decal/trimline/neutral/filled/warning{
dir = 4
@@ -28855,6 +29062,10 @@
},
/turf/open/floor/engine,
/area/station/engineering/supermatter/room)
+"ish" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/aft/greater)
"isk" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/table/wood,
@@ -28869,6 +29080,11 @@
},
/turf/open/floor/iron/dark/smooth_large,
/area/station/security/prison)
+"isr" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/trash_pile,
+/turf/open/floor/plating,
+/area/station/maintenance/department/engine)
"iss" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -29095,7 +29311,7 @@
},
/obj/structure/cable,
/turf/open/floor/plating,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"iuX" = (
/obj/structure/sign/nanotrasen{
pixel_x = 32
@@ -29657,7 +29873,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"iCx" = (
/obj/structure/chair/plastic{
dir = 4
@@ -29721,7 +29937,7 @@
"iDu" = (
/obj/effect/spawner/random/trash/garbage,
/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/engine/atmos)
"iDC" = (
/obj/effect/turf_decal/stripes/line{
@@ -29890,7 +30106,7 @@
dir = 4
},
/turf/open/floor/iron/dark/smooth_large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"iGy" = (
/obj/structure/sign/logo{
icon_state = "nanotrasen_sign3";
@@ -30069,7 +30285,7 @@
"iJi" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/trash_pile,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/engine/atmos)
"iJn" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
@@ -30121,13 +30337,6 @@
/obj/effect/spawner/random/structure/grille,
/turf/open/floor/iron/smooth,
/area/station/maintenance/port/fore)
-"iJJ" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/structure/closet/emcloset,
-/obj/effect/turf_decal/bot,
-/obj/machinery/light/small/directional/south,
-/turf/open/floor/iron/smooth,
-/area/station/maintenance/department/science/ordnance_maint)
"iJR" = (
/obj/effect/turf_decal/stripes/red/full,
/obj/effect/turf_decal/stripes/line{
@@ -30886,7 +31095,7 @@
/obj/structure/filingcabinet/employment,
/obj/effect/turf_decal/bot,
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"iVS" = (
/obj/structure/disposaloutlet{
dir = 8
@@ -31070,7 +31279,7 @@
dir = 6
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/catwalk_floor/iron_smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port)
"iXB" = (
/obj/structure/chair/stool/bar,
@@ -31147,7 +31356,7 @@
dir = 10
},
/turf/open/floor/iron/dark/smooth_large,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"iYz" = (
/obj/machinery/holopad,
/obj/effect/turf_decal/bot,
@@ -31212,7 +31421,7 @@
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/cable,
/turf/open/floor/plating,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"iZs" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -32032,7 +32241,7 @@
/area/station/command/gateway)
"jlB" = (
/turf/closed/wall,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"jlD" = (
/obj/machinery/ore_silo,
/obj/effect/turf_decal/bot,
@@ -32336,6 +32545,18 @@
"jqn" = (
/turf/closed/wall,
/area/station/maintenance/port/upper)
+"jqH" = (
+/obj/machinery/power/apc/auto_name/directional/east,
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 4
+ },
+/obj/structure/cable,
+/turf/open/floor/iron/white/smooth_edge{
+ dir = 8
+ },
+/area/station/medical/office)
"jqL" = (
/obj/structure/disposalpipe/segment,
/obj/effect/turf_decal/skyrat_decals/enclave/middle/right{
@@ -32533,10 +32754,19 @@
"jtc" = (
/turf/open/floor/carpet,
/area/station/commons/dorms)
+"jte" = (
+/turf/open/floor/plating,
+/area/station/maintenance/department/engine/atmos)
"jtf" = (
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/large,
/area/station/hallway/primary/central/aft)
+"jtq" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"jty" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -33216,6 +33446,13 @@
/obj/structure/cable,
/turf/open/floor/iron/smooth,
/area/station/engineering/atmos/hfr_room)
+"jCq" = (
+/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/plating,
+/area/station/maintenance/aft/lesser)
"jCv" = (
/obj/machinery/atmospherics/components/binary/pump/on{
dir = 8
@@ -33874,7 +34111,7 @@
/area/station/service/theater)
"jKu" = (
/obj/structure/trash_pile,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/engine/atmos/lesser)
"jKx" = (
/obj/effect/turf_decal/trimline/yellow/filled/line{
@@ -33932,7 +34169,7 @@
/area/station/commons/vacant_room/office)
"jLi" = (
/obj/effect/turf_decal/trimline/yellow/filled/line,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/turf/open/floor/iron/white/smooth_edge{
dir = 1
},
@@ -33962,7 +34199,7 @@
/area/station/cargo/office)
"jLS" = (
/obj/structure/trash_pile,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/greater)
"jMc" = (
/obj/effect/turf_decal/trimline/brown/filled/line{
@@ -34562,7 +34799,7 @@
/obj/machinery/status_display/ai/directional/north,
/obj/effect/turf_decal/bot,
/turf/open/floor/carpet/cyan,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"jVx" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -34576,6 +34813,16 @@
/obj/effect/spawner/random/trash/garbage,
/turf/open/floor/catwalk_floor/iron_smooth,
/area/station/maintenance/port/central)
+"jVE" = (
+/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,
+/turf/open/floor/plating,
+/area/station/maintenance/department/medical)
"jVG" = (
/obj/machinery/computer/security/qm{
dir = 1
@@ -34650,7 +34897,7 @@
},
/mob/living/basic/pet/dog/dobermann/walter,
/turf/open/floor/wood/large,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"jXc" = (
/obj/effect/turf_decal/siding/wood{
dir = 6
@@ -35484,7 +35731,7 @@
/obj/effect/turf_decal/siding/wood,
/obj/structure/cable,
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"kjl" = (
/obj/effect/landmark/start/hangover,
/obj/effect/spawner/random/engineering/tracking_beacon,
@@ -35732,6 +35979,9 @@
},
/turf/open/floor/iron/large,
/area/station/commons/vacant_room/commissary)
+"knn" = (
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"knu" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 4
@@ -35937,6 +36187,13 @@
/obj/effect/turf_decal/delivery,
/turf/open/floor/iron/smooth_large,
/area/station/cargo/sorting)
+"kpB" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/aft)
"kpG" = (
/obj/machinery/airalarm/directional/north,
/obj/effect/turf_decal/siding/wood{
@@ -36197,6 +36454,12 @@
dir = 4
},
/area/station/engineering/atmos)
+"kux" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/plating,
+/area/station/maintenance/department/engine)
"kuF" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -36244,7 +36507,7 @@
/obj/item/stack/sheet/glass{
amount = 4
},
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"kvj" = (
/obj/machinery/light/floor,
@@ -36646,7 +36909,7 @@
/obj/effect/turf_decal/siding/wood/end,
/obj/effect/turf_decal/box,
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"kzM" = (
/obj/machinery/field/generator,
/obj/effect/turf_decal/stripes/line,
@@ -36665,6 +36928,20 @@
},
/turf/open/floor/iron/freezer,
/area/station/medical/treatment_center)
+"kzV" = (
+/obj/structure/chair/office{
+ dir = 8
+ },
+/obj/structure/disposalpipe/segment{
+ dir = 5
+ },
+/obj/machinery/airalarm/directional/south,
+/obj/structure/cable,
+/obj/effect/turf_decal/trimline/blue/filled/line,
+/turf/open/floor/iron/white/smooth_edge{
+ dir = 1
+ },
+/area/station/medical/exam_room)
"kAd" = (
/obj/effect/turf_decal/stripes/end,
/obj/effect/turf_decal/siding/thinplating/dark/end,
@@ -36700,7 +36977,7 @@
/area/station/ai_monitored/turret_protected/aisat/foyer)
"kAm" = (
/turf/closed/wall,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"kAq" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -37095,7 +37372,7 @@
dir = 4
},
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"kFf" = (
/obj/machinery/holopad/secure,
/obj/effect/turf_decal/siding/wood,
@@ -37162,7 +37439,7 @@
"kFT" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/spawner/random/trash/garbage,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/aft/lesser)
"kFW" = (
/obj/effect/turf_decal/trimline/purple/filled/warning{
@@ -37609,6 +37886,10 @@
/obj/effect/landmark/generic_maintenance_landmark,
/turf/open/floor/iron/smooth,
/area/station/maintenance/port/fore)
+"kLl" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/science/research/abandoned)
"kLz" = (
/turf/open/floor/iron/cafeteria,
/area/station/service/cafeteria)
@@ -37715,7 +37996,6 @@
/area/station/engineering/atmos/storage)
"kMI" = (
/obj/structure/tank_holder/extinguisher,
-/obj/machinery/light/small/directional/south,
/turf/open/floor/iron/smooth,
/area/station/maintenance/port)
"kMM" = (
@@ -37976,7 +38256,7 @@
/area/station/command/heads_quarters/captain/private)
"kRg" = (
/obj/structure/table/reinforced,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/machinery/status_display/evac/directional/south,
/obj/item/reagent_containers/spray/cleaner,
/turf/open/floor/iron/dark/smooth_large,
@@ -38058,7 +38338,7 @@
specialfunctions = 4
},
/turf/open/floor/carpet/cyan,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"kSA" = (
/obj/effect/turf_decal/bot,
/obj/effect/landmark/event_spawn,
@@ -38757,6 +39037,7 @@
/area/station/hallway/secondary/entry)
"lcd" = (
/obj/structure/table,
+/obj/item/storage/fancy/donut_box,
/turf/open/floor/glass/reinforced,
/area/station/security/execution/transfer)
"lcf" = (
@@ -38773,6 +39054,7 @@
/area/station/engineering/atmos/hfr_room)
"lcn" = (
/obj/effect/turf_decal/stripes/red/box,
+/obj/structure/sign/delam_procedure/directional/east,
/turf/open/floor/iron/smooth,
/area/station/engineering/main)
"lcr" = (
@@ -39108,7 +39390,7 @@
/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/catwalk_floor/iron_smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/medical/central)
"lgZ" = (
/obj/machinery/door/airlock/security{
@@ -39212,6 +39494,7 @@
},
/obj/structure/extinguisher_cabinet/directional/west,
/obj/effect/turf_decal/bot,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
/obj/structure/rack,
/turf/open/floor/iron/showroomfloor,
/area/station/medical/coldroom)
@@ -39219,7 +39502,6 @@
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/item/kirbyplants/random,
/obj/machinery/duct,
/turf/open/floor/iron/white/smooth_large,
/area/station/medical/storage)
@@ -39278,7 +39560,7 @@
pixel_y = 5
},
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"lji" = (
/obj/structure/window/reinforced/plasma/spawner/directional/west,
/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible,
@@ -39293,14 +39575,6 @@
"ljI" = (
/turf/closed/wall,
/area/station/medical/morgue)
-"ljL" = (
-/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,
-/obj/machinery/light/small/directional/east,
-/turf/open/floor/catwalk_floor/iron_smooth,
-/area/station/maintenance/department/science/ordnance_maint)
"ljV" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -39626,6 +39900,12 @@
},
/turf/open/floor/iron/grimy,
/area/station/commons/lounge)
+"lnU" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/port/greater)
"lnX" = (
/obj/effect/turf_decal/trimline/dark_red/warning{
dir = 1
@@ -39768,6 +40048,14 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/smooth_large,
/area/station/engineering/lobby)
+"lqL" = (
+/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,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/greater)
"lqR" = (
/obj/item/folder/red{
pixel_x = -3;
@@ -39803,7 +40091,7 @@
/obj/item/bedsheet/nanotrasen/double,
/obj/machinery/newscaster/directional/west,
/turf/open/floor/carpet/cyan,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"lrh" = (
/obj/effect/turf_decal/trimline/blue/filled/warning{
dir = 10
@@ -40317,6 +40605,10 @@
dir = 1
},
/area/station/hallway/secondary/command)
+"lyJ" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/department/science/ordnance_maint)
"lyY" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/door/poddoor/preopen{
@@ -40780,7 +41072,7 @@
"lFl" = (
/obj/effect/spawner/random/trash/garbage,
/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/science/ordnance_maint)
"lFE" = (
/obj/structure/lattice/catwalk,
@@ -40882,6 +41174,15 @@
/obj/effect/mapping_helpers/airlock/access/any/science/xenobio,
/turf/open/floor/iron/white/smooth_large,
/area/station/science/xenobiology)
+"lGy" = (
+/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/plating,
+/area/station/maintenance/department/crew_quarters/bar)
"lGB" = (
/obj/structure/table/reinforced,
/turf/open/floor/iron/dark/textured_large,
@@ -40902,7 +41203,7 @@
dir = 6
},
/obj/effect/turf_decal/tile/blue/full,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/structure/sign/poster/official/random/directional/south,
/obj/structure/sign/nanotrasen{
pixel_x = 32
@@ -41316,6 +41617,9 @@
name = "Cold Room Maintenance"
},
/obj/effect/mapping_helpers/airlock/access/all/medical/surgery,
+/obj/machinery/atmospherics/pipe/heat_exchanging/junction{
+ dir = 1
+ },
/turf/open/floor/catwalk_floor/iron_smooth,
/area/station/maintenance/department/medical/central)
"lMC" = (
@@ -41437,7 +41741,7 @@
"lOd" = (
/obj/effect/spawner/random/maintenance/four,
/obj/effect/spawner/random/entertainment/money,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/medical)
"lOi" = (
/obj/effect/turf_decal/tile/red/anticorner{
@@ -41545,6 +41849,10 @@
/obj/structure/window/reinforced/fulltile,
/turf/open/misc/asteroid,
/area/station/engineering/lobby)
+"lQf" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/department/crew_quarters/bar)
"lQh" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -43162,6 +43470,9 @@
/obj/effect/turf_decal/tile/dark_blue/fourcorners,
/turf/open/floor/iron/dark,
/area/station/medical/medbay/central)
+"mlv" = (
+/turf/open/floor/plating,
+/area/station/maintenance/department/crew_quarters/bar)
"mlP" = (
/obj/structure/disposalpipe/segment{
dir = 9
@@ -44651,6 +44962,12 @@
},
/turf/open/floor/iron/white/smooth_large,
/area/station/science/auxlab)
+"mJA" = (
+/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on/coldroom{
+ dir = 4
+ },
+/turf/open/floor/catwalk_floor/iron_smooth,
+/area/station/maintenance/department/medical/central)
"mJB" = (
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/freezer,
@@ -44773,7 +45090,7 @@
/turf/open/floor/wood/large,
/area/station/service/library)
"mLy" = (
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"mLz" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -44992,7 +45309,7 @@
},
/obj/effect/turf_decal/tile/dark_blue/full,
/turf/open/floor/iron/dark/smooth_large,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"mOa" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 4
@@ -45349,6 +45666,10 @@
},
/turf/open/floor/engine,
/area/station/ai_monitored/security/armory)
+"mTl" = (
+/obj/effect/landmark/event_spawn,
+/turf/open/floor/iron/white/smooth_large,
+/area/station/medical/exam_room)
"mTv" = (
/obj/effect/spawner/random/structure/girder,
/turf/open/floor/iron/smooth,
@@ -45404,7 +45725,7 @@
"mUE" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/cobweb,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/aft)
"mUF" = (
/obj/structure/chair/stool/directional/west,
@@ -45765,6 +46086,9 @@
},
/turf/open/floor/iron/smooth_large,
/area/station/command/cc_dock)
+"mYn" = (
+/turf/open/floor/plating,
+/area/station/maintenance/department/science/ordnance_maint)
"mYv" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/structure/cable,
@@ -45796,7 +46120,7 @@
dir = 1
},
/turf/open/floor/iron/dark/smooth_large,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"mYL" = (
/obj/effect/turf_decal/trimline/red/filled/warning{
dir = 1
@@ -45937,7 +46261,7 @@
/area/station/engineering/atmos)
"naG" = (
/obj/structure/reagent_dispensers/fueltank,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/greater)
"naI" = (
/obj/item/radio/intercom/directional/east,
@@ -46186,7 +46510,7 @@
},
/obj/structure/table/wood,
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"ngt" = (
/obj/machinery/power/shuttle_engine/heater,
/obj/effect/turf_decal/stripes/line{
@@ -46214,6 +46538,15 @@
dir = 4
},
/area/station/hallway/secondary/command)
+"ngZ" = (
+/obj/structure/disposalpipe/segment{
+ dir = 10
+ },
+/obj/effect/turf_decal/trimline/blue/filled/warning{
+ dir = 1
+ },
+/turf/open/floor/iron/white/smooth_edge,
+/area/station/medical/exam_room)
"nhc" = (
/obj/structure/grille,
/turf/closed/wall/r_wall/rust,
@@ -46874,7 +47207,7 @@
pixel_y = 5
},
/turf/closed/wall/r_wall,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"npP" = (
/obj/effect/turf_decal/siding/wood{
dir = 6
@@ -47080,7 +47413,6 @@
"ntn" = (
/obj/structure/table,
/obj/effect/spawner/random/maintenance,
-/obj/machinery/light/small/directional/east,
/obj/item/storage/box,
/turf/open/floor/iron/smooth,
/area/station/maintenance/aft/lesser)
@@ -47196,7 +47528,6 @@
"nub" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/spawner/random/trash/mopbucket,
-/obj/machinery/light/small/directional/east,
/turf/open/floor/iron/smooth,
/area/station/maintenance/aft/greater)
"nuf" = (
@@ -47408,6 +47739,9 @@
},
/turf/open/floor/engine/vacuum,
/area/station/science/ordnance/burnchamber)
+"nwW" = (
+/turf/closed/wall,
+/area/station/medical/exam_room)
"nwY" = (
/obj/item/kirbyplants/random,
/obj/structure/sign/poster/official/random/directional/west,
@@ -47542,7 +47876,7 @@
"nzb" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/spawner/random/trash/caution_sign,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/engine)
"nzh" = (
/obj/effect/turf_decal/siding/wood{
@@ -47585,7 +47919,7 @@
/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/iron_smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/medical/central)
"nzD" = (
/obj/effect/turf_decal/trimline/red/filled/warning{
@@ -47662,7 +47996,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/spawner/random/trash/garbage,
-/turf/open/floor/catwalk_floor/iron_smooth,
+/turf/open/floor/plating,
/area/station/maintenance/aft/lesser)
"nAw" = (
/obj/effect/spawner/structure/window/reinforced,
@@ -47835,6 +48169,11 @@
/obj/effect/turf_decal/bot,
/turf/open/floor/glass/reinforced,
/area/station/security/office)
+"nES" = (
+/obj/structure/cable,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/department/engine/atmos/lesser)
"nEW" = (
/obj/machinery/atmospherics/pipe/smart/simple/orange/visible{
dir = 4
@@ -47931,6 +48270,13 @@
/obj/machinery/atmospherics/pipe/smart/manifold/cyan/visible/layer2,
/turf/open/floor/iron/smooth,
/area/station/hallway/primary/aft)
+"nGb" = (
+/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/plating,
+/area/station/maintenance/aft)
"nGg" = (
/obj/structure/closet/radiation,
/obj/effect/turf_decal/box,
@@ -48004,7 +48350,7 @@
/area/station/service/hydroponics)
"nHD" = (
/obj/effect/spawner/random/structure/crate,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/security/brig)
"nHY" = (
/obj/structure/fluff/arc,
@@ -48721,7 +49067,7 @@
/area/station/commons/dorms)
"nRd" = (
/obj/effect/spawner/random/structure/crate_abandoned,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/crew_quarters/bar)
"nRo" = (
/obj/structure/cable,
@@ -49487,7 +49833,7 @@
pixel_y = 32
},
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"oaD" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -49506,7 +49852,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 1
},
-/obj/effect/mapping_helpers/airlock/access/all/security/general,
+/obj/effect/mapping_helpers/airlock/access/all/security/entrance,
/turf/open/floor/iron/dark/smooth_large,
/area/station/security/brig)
"oaL" = (
@@ -49789,7 +50135,7 @@
dir = 5
},
/obj/effect/turf_decal/tile/blue/full,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/structure/sign/nanotrasen{
pixel_x = 32
},
@@ -49804,6 +50150,19 @@
/obj/effect/decal/cleanable/cobweb,
/turf/open/floor/iron/smooth,
/area/station/maintenance/department/engine/atmos/lesser)
+"ofF" = (
+/obj/structure/trash_pile,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/greater)
+"ofG" = (
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 1
+ },
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 4
+ },
+/turf/open/floor/iron/white/smooth_edge,
+/area/station/medical/exam_room)
"ofY" = (
/obj/structure/table/reinforced,
/obj/effect/turf_decal/bot,
@@ -49822,6 +50181,7 @@
/obj/structure/disposalpipe/segment{
dir = 4
},
+/obj/machinery/light/cold/directional/south,
/turf/open/floor/iron/white/smooth_edge{
dir = 1
},
@@ -49922,7 +50282,7 @@
},
/obj/structure/table/wood,
/turf/open/floor/carpet/cyan,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"ohz" = (
/obj/machinery/light/cold/directional/north,
/obj/effect/turf_decal/trimline/white/end,
@@ -50411,6 +50771,18 @@
/obj/structure/window/spawner/directional/north,
/turf/open/floor/grass,
/area/station/hallway/secondary/exit/departure_lounge)
+"ooU" = (
+/obj/machinery/door/airlock/medical{
+ name = "Exam Room"
+ },
+/obj/effect/mapping_helpers/airlock/access/any/medical/general,
+/obj/machinery/door/firedoor,
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/effect/turf_decal/stripes/line,
+/turf/open/floor/iron/white/smooth_large,
+/area/station/medical/exam_room)
"ooW" = (
/obj/effect/turf_decal/trimline/dark_red/arrow_cw{
dir = 1
@@ -50857,6 +51229,11 @@
dir = 4
},
/area/station/cargo/drone_bay)
+"ouX" = (
+/obj/structure/cable,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/department/security/brig)
"ovf" = (
/obj/effect/turf_decal/trimline/blue/filled/warning{
dir = 4
@@ -50886,7 +51263,7 @@
dir = 9
},
/turf/open/floor/iron/dark/smooth_large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"ovT" = (
/obj/effect/turf_decal/trimline/yellow/filled/line,
/obj/effect/turf_decal/trimline/blue/filled/line,
@@ -51018,6 +51395,10 @@
},
/turf/open/floor/plating,
/area/station/science/research)
+"oxA" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/aft)
"oxE" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/mech_bay_recharge_port,
@@ -51327,7 +51708,7 @@
/area/station/hallway/primary/central/fore)
"oBW" = (
/obj/effect/spawner/random/trash/garbage,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/medical/morgue)
"oCl" = (
/turf/closed/wall/r_wall,
@@ -51393,7 +51774,7 @@
},
/area/station/hallway/primary/aft)
"oDz" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 8
@@ -51429,10 +51810,6 @@
},
/turf/open/floor/iron/dark,
/area/station/science/robotics/lab)
-"oEf" = (
-/obj/machinery/light/small/directional/west,
-/turf/open/floor/iron/smooth,
-/area/station/maintenance/port/aft)
"oEk" = (
/obj/machinery/airalarm/directional/east,
/obj/machinery/light/small/directional/east,
@@ -51778,7 +52155,7 @@
},
/obj/machinery/light_switch/directional/north,
/turf/open/floor/carpet/cyan,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"oIp" = (
/obj/machinery/camera/directional/north{
c_tag = "Prison - Pool";
@@ -51980,7 +52357,9 @@
/turf/open/floor/catwalk_floor/iron_smooth,
/area/station/maintenance/department/science/ordnance_maint)
"oLN" = (
-/obj/structure/bed,
+/obj/structure/bed/medical/anchored{
+ dir = 4
+ },
/obj/machinery/iv_drip,
/obj/item/bedsheet/medical,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
@@ -51991,6 +52370,7 @@
/area/station/medical/virology)
"oLS" = (
/obj/effect/landmark/event_spawn,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/showroomfloor,
/area/station/medical/coldroom)
"oLT" = (
@@ -52837,13 +53217,13 @@
name = "curtain"
},
/turf/open/floor/grass,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"oXG" = (
/obj/effect/decal/cleanable/dirt,
/obj/item/trash/popcorn,
/obj/effect/landmark/generic_maintenance_landmark,
/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/aft/lesser)
"oXI" = (
/turf/closed/wall,
@@ -52875,7 +53255,7 @@
/turf/open/floor/circuit/telecomms/server,
/area/station/tcommsat/server)
"oXT" = (
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/greater)
"oXW" = (
/obj/structure/cable,
@@ -52999,6 +53379,14 @@
"oZv" = (
/turf/open/floor/iron/smooth_large,
/area/station/science/ordnance)
+"oZB" = (
+/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/spawner/random/structure/steam_vent,
+/turf/open/floor/plating,
+/area/station/maintenance/department/crew_quarters/bar)
"oZE" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -53249,6 +53637,25 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/catwalk_floor/iron_smooth,
/area/station/maintenance/eva_shed/port)
+"pcS" = (
+/obj/structure/table/glass,
+/obj/machinery/computer/records/medical/laptop{
+ dir = 4;
+ pixel_x = 3;
+ pixel_y = 2
+ },
+/obj/machinery/power/apc/auto_name/directional/south,
+/obj/structure/cable,
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 10
+ },
+/obj/machinery/camera/directional/west{
+ c_tag = "Medbay - Exam Room";
+ name = "medical camera";
+ network = list("ss13","medical")
+ },
+/turf/open/floor/iron/white,
+/area/station/medical/exam_room)
"pdc" = (
/obj/structure/disposalpipe/segment,
/obj/structure/extinguisher_cabinet/directional/east,
@@ -53692,7 +54099,7 @@
"phK" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/sign/poster/random/directional/west,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
"pic" = (
/obj/structure/flora/grass/jungle,
@@ -53936,6 +54343,23 @@
dir = 8
},
/area/station/hallway/primary/fore)
+"plo" = (
+/obj/structure/table/glass,
+/obj/item/paper_bin/carbon{
+ pixel_x = -3;
+ pixel_y = 5
+ },
+/obj/item/pen{
+ pixel_x = -3;
+ pixel_y = 7
+ },
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 8
+ },
+/turf/open/floor/iron/white/smooth_edge{
+ dir = 4
+ },
+/area/station/medical/exam_room)
"plF" = (
/obj/machinery/photocopier,
/obj/machinery/power/apc/auto_name/directional/north,
@@ -54145,6 +54569,10 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/iron/smooth_large,
/area/station/engineering/atmos/storage/gas)
+"pnU" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"pnV" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/disposalpipe/segment{
@@ -54506,7 +54934,7 @@
id = "cargounload"
},
/obj/machinery/door/poddoor{
- id = "cargounload";
+ id = 68;
name = "Supply Dock Unloading Door"
},
/turf/open/floor/iron/smooth_large,
@@ -54904,6 +55332,25 @@
},
/turf/open/floor/iron/dark/smooth_large,
/area/station/service/hydroponics/garden)
+"pAE" = (
+/obj/structure/table/glass,
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 5
+ },
+/obj/item/folder/white{
+ pixel_y = 4
+ },
+/obj/item/flashlight/pen{
+ pixel_y = 4
+ },
+/obj/item/clothing/neck/stethoscope{
+ pixel_y = 4
+ },
+/obj/machinery/firealarm/directional/east,
+/obj/machinery/light/cold/directional/east,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/iron/white,
+/area/station/medical/exam_room)
"pAI" = (
/obj/effect/turf_decal/trimline/yellow/filled/warning,
/obj/effect/turf_decal/trimline/blue/filled/warning,
@@ -55013,7 +55460,7 @@
/area/station/engineering/lobby)
"pBZ" = (
/obj/effect/spawner/random/maintenance/two,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/engine/atmos)
"pCd" = (
/obj/machinery/duct,
@@ -55056,7 +55503,7 @@
dir = 1
},
/turf/open/floor/iron/dark/smooth_large,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"pCA" = (
/obj/structure/fans/tiny/forcefield{
dir = 4
@@ -55169,7 +55616,7 @@
/obj/structure/disposalpipe/segment{
dir = 5
},
-/turf/open/floor/catwalk_floor/iron_smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/crew_quarters/bar)
"pDV" = (
/turf/open/floor/iron/white/smooth_large,
@@ -55270,7 +55717,7 @@
},
/obj/machinery/firealarm/directional/south,
/turf/open/floor/carpet/cyan,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"pGl" = (
/obj/effect/mapping_helpers/airlock/access/all/science/general,
/obj/machinery/door/airlock/maintenance_hatch{
@@ -55447,7 +55894,7 @@
/obj/machinery/holopad,
/obj/effect/turf_decal/bot,
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"pIm" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -55721,6 +56168,15 @@
},
/turf/open/floor/carpet,
/area/station/commons/dorms)
+"pMG" = (
+/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/plating,
+/area/station/maintenance/starboard/greater)
"pMO" = (
/obj/machinery/newscaster/directional/north,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -56128,7 +56584,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/spawner/random/structure/steam_vent,
-/turf/open/floor/catwalk_floor/iron_smooth,
+/turf/open/floor/plating,
/area/station/maintenance/aft/greater)
"pSX" = (
/obj/machinery/door/firedoor,
@@ -56236,7 +56692,7 @@
/turf/closed/wall,
/area/station/maintenance/aft/upper)
"pUJ" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/turf/open/floor/iron/white/smooth_large,
/area/station/medical/medbay/lobby)
@@ -57353,14 +57809,15 @@
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 8
},
-/obj/structure/closet/crate/freezer/blood,
/obj/effect/turf_decal/bot,
+/obj/machinery/atmospherics/components/binary/pump/on,
+/obj/structure/closet/crate/freezer/blood,
/turf/open/floor/iron/showroomfloor,
/area/station/medical/coldroom)
"qgK" = (
-/obj/structure/closet/secure_closet/medical2,
/obj/effect/turf_decal/tile/blue/fourcorners,
/obj/effect/turf_decal/bot,
+/obj/machinery/iv_drip,
/turf/open/floor/iron/freezer,
/area/station/medical/treatment_center)
"qgS" = (
@@ -57374,7 +57831,6 @@
},
/area/station/science/xenobiology)
"qgT" = (
-/obj/machinery/lapvend,
/turf/open/floor/iron/white,
/area/station/hallway/primary/fore)
"qha" = (
@@ -57470,7 +57926,7 @@
},
/obj/effect/turf_decal/bot,
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"qhT" = (
/obj/machinery/door/airlock/external{
name = "Departure Shuttle Airlock";
@@ -57592,6 +58048,20 @@
},
/turf/open/floor/plating,
/area/space/nearstation)
+"qkb" = (
+/obj/structure/bed/pod{
+ desc = "An old medical bed, just waiting for replacement with something up to date.";
+ name = "medical bed"
+ },
+/obj/item/bedsheet/medical,
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/iron/white/smooth_edge{
+ dir = 8
+ },
+/area/station/medical/exam_room)
"qki" = (
/obj/structure/table/reinforced,
/obj/item/assembly/voice{
@@ -57725,7 +58195,7 @@
"qmk" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/spawner/random/trash/moisture_trap,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/crew_quarters/bar)
"qmn" = (
/obj/effect/decal/cleanable/dirt,
@@ -57949,7 +58419,7 @@
pixel_x = 16
},
/turf/open/floor/wood/large,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"qpe" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 1
@@ -58054,7 +58524,7 @@
"qqg" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/sign/poster/random/directional/west,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/aft/lesser)
"qqs" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -58709,7 +59179,7 @@
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/catwalk_floor/iron_smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/aft)
"qAu" = (
/obj/machinery/conveyor{
@@ -58720,7 +59190,7 @@
/area/station/cargo/storage)
"qAD" = (
/obj/effect/spawner/random/trash/mess,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/engine/atmos)
"qAI" = (
/obj/structure/table/glass,
@@ -58762,7 +59232,7 @@
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/spawner/random/structure/steam_vent,
-/turf/open/floor/catwalk_floor/iron_smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/aft)
"qBp" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -59564,7 +60034,7 @@
/area/station/engineering/atmos/storage/gas)
"qMB" = (
/obj/effect/spawner/random/trash/mess,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/aft)
"qMC" = (
/obj/effect/turf_decal/trimline/green/filled/warning{
@@ -59748,7 +60218,7 @@
"qQC" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/plastic,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/aft)
"qQJ" = (
/obj/machinery/status_display/ai/directional/north,
@@ -60090,6 +60560,12 @@
dir = 4
},
/area/station/security/prison)
+"qUt" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/department/crew_quarters/bar)
"qUF" = (
/obj/effect/turf_decal/trimline/purple/filled/line{
dir = 8
@@ -60274,7 +60750,7 @@
dir = 4
},
/obj/effect/spawner/random/structure/steam_vent,
-/turf/open/floor/catwalk_floor/iron_smooth,
+/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"qXm" = (
/obj/structure/trash_pile,
@@ -60996,7 +61472,8 @@
/area/station/commons/fitness/recreation/entertainment)
"riy" = (
/obj/structure/closet/secure_closet/evidence{
- name = "Brig Officer's Locker"
+ name = "Brig Officer's Locker";
+ req_one_access = list("brig")
},
/obj/machinery/requests_console/auto_name/directional/west,
/obj/machinery/light_switch/directional/south,
@@ -61386,7 +61863,7 @@
/area/station/security/detectives_office)
"rnL" = (
/obj/effect/spawner/random/trash/garbage,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port)
"rnR" = (
/obj/structure/rack,
@@ -61399,7 +61876,7 @@
"rnV" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/spawner/random/trash/hobo_squat,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/aft/lesser)
"rog" = (
/obj/effect/turf_decal/trimline/green/filled/line{
@@ -61413,7 +61890,7 @@
/area/station/hallway/primary/aft)
"rol" = (
/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/greater)
"ron" = (
/obj/machinery/atmospherics/components/binary/pump/off,
@@ -61594,7 +62071,7 @@
/area/station/engineering/power_room)
"rrb" = (
/obj/structure/trash_pile,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/medical)
"rrg" = (
/obj/effect/turf_decal/trimline/blue/filled/warning{
@@ -62057,7 +62534,7 @@
dir = 4
},
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"rzh" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/siding/wood,
@@ -62099,7 +62576,7 @@
/area/station/engineering/atmos)
"rzT" = (
/obj/effect/mapping_helpers/burnt_floor,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/aft)
"rAh" = (
/obj/effect/turf_decal/bot,
@@ -62446,7 +62923,7 @@
dir = 8
},
/turf/open/floor/iron/dark/smooth_large,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"rDP" = (
/obj/machinery/computer/shuttle/mining{
dir = 1;
@@ -62461,7 +62938,7 @@
"rDU" = (
/obj/effect/decal/cleanable/dirt,
/obj/item/storage/box/lights/mixed,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/greater)
"rEe" = (
/obj/machinery/status_display/evac/directional/west,
@@ -62763,6 +63240,10 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/checker,
/area/station/science/lab)
+"rJa" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/department/engine/atmos)
"rJe" = (
/obj/effect/turf_decal/vg_decals/atmos/carbon_dioxide,
/turf/open/floor/engine/co2,
@@ -63347,6 +63828,10 @@
/obj/structure/lattice/catwalk,
/turf/open/space,
/area/station/solars/starboard/aft)
+"rSG" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port)
"rSO" = (
/obj/structure/table,
/obj/item/plate,
@@ -63742,7 +64227,7 @@
"rXL" = (
/obj/effect/spawner/random/trash/garbage,
/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/crew_quarters/bar)
"rXU" = (
/obj/effect/turf_decal/trimline/yellow/filled/line,
@@ -63799,7 +64284,7 @@
/area/station/hallway/primary/aft)
"rYT" = (
/obj/item/robot_suit,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/science/research/abandoned)
"rYX" = (
/obj/structure/cable,
@@ -64105,7 +64590,7 @@
name = "command camera"
},
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"sfc" = (
/obj/effect/spawner/structure/window,
/turf/open/floor/plating,
@@ -64150,7 +64635,7 @@
pixel_y = 10
},
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"sfx" = (
/obj/effect/turf_decal/tile/neutral{
dir = 8
@@ -64222,7 +64707,7 @@
/obj/effect/decal/cleanable/dirt,
/obj/effect/spawner/random/structure/crate_empty,
/obj/effect/spawner/random/maintenance/three,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/greater)
"sgn" = (
/obj/effect/spawner/structure/window/reinforced,
@@ -64346,7 +64831,7 @@
/area/station/medical/medbay/central)
"shE" = (
/obj/effect/mapping_helpers/broken_floor,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/aft/lesser)
"shM" = (
/obj/structure/closet/crate/bin,
@@ -64805,14 +65290,6 @@
/obj/effect/turf_decal/trimline/blue/mid_joiner,
/turf/open/floor/iron/dark/smooth_large,
/area/station/hallway/secondary/command)
-"spf" = (
-/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,
-/obj/machinery/light/small/directional/south,
-/turf/open/floor/catwalk_floor/iron_smooth,
-/area/station/maintenance/aft/greater)
"spi" = (
/obj/structure/table,
/obj/item/flashlight{
@@ -64908,7 +65385,7 @@
name = "curtain"
},
/turf/open/floor/grass,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"spQ" = (
/obj/item/stack/sheet/iron/fifty{
pixel_y = 3
@@ -65071,6 +65548,12 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/smooth_edge,
/area/station/cargo/lobby)
+"ssU" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/plating,
+/area/station/maintenance/department/engine/atmos)
"ssV" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -65633,7 +66116,7 @@
},
/obj/effect/turf_decal/tile/dark_blue/full,
/turf/open/floor/iron/dark/smooth_large,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"sCw" = (
/obj/machinery/door/airlock/maintenance_hatch,
/obj/effect/mapping_helpers/airlock/abandoned,
@@ -65656,7 +66139,7 @@
/area/station/medical/psychology)
"sCN" = (
/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/security/brig)
"sCO" = (
/obj/structure/table/reinforced,
@@ -65804,7 +66287,7 @@
},
/obj/effect/decal/cleanable/dirt,
/obj/machinery/door/poddoor{
- id = "cargoload";
+ id = 69;
name = "Supply Dock Loading Door"
},
/turf/open/floor/iron/smooth_large,
@@ -66465,7 +66948,7 @@
},
/obj/structure/cable,
/turf/open/floor/plating,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"sLa" = (
/obj/machinery/nuclearbomb/selfdestruct,
/obj/item/toy/figure/syndie{
@@ -66735,8 +67218,11 @@
/obj/effect/turf_decal/box/white{
color = "#52B4E9"
},
-/obj/machinery/portable_atmospherics/canister/oxygen,
/obj/structure/sign/poster/official/science/directional/south,
+/obj/machinery/atmospherics/pipe/heat_exchanging/junction{
+ dir = 4
+ },
+/obj/machinery/portable_atmospherics/canister/anesthetic_mix,
/turf/open/floor/iron/showroomfloor,
/area/station/medical/coldroom)
"sNz" = (
@@ -67710,6 +68196,13 @@
dir = 8
},
/area/station/hallway/secondary/command)
+"taC" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/spawner/random/trash/garbage,
+/turf/open/floor/plating,
+/area/station/maintenance/department/engine)
"taK" = (
/obj/effect/turf_decal/bot,
/obj/structure/closet/secure_closet/engineering_personal,
@@ -67919,7 +68412,7 @@
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/spawner/random/trash/garbage,
-/turf/open/floor/catwalk_floor/iron_smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port)
"tdO" = (
/obj/machinery/door/firedoor,
@@ -68147,6 +68640,10 @@
/obj/effect/spawner/random/structure/table_or_rack,
/turf/open/floor/iron/smooth,
/area/station/maintenance/department/science/xenobiology)
+"tgU" = (
+/obj/effect/spawner/random/trash/garbage,
+/turf/open/floor/plating,
+/area/station/maintenance/port/aft)
"thd" = (
/obj/structure/cable,
/obj/effect/turf_decal/trimline/yellow/filled/warning{
@@ -68546,6 +69043,15 @@
dir = 4
},
/area/station/engineering/atmos/pumproom)
+"tme" = (
+/obj/structure/table/glass,
+/obj/structure/sign/calendar/directional/north,
+/obj/machinery/computer/records/medical/laptop,
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 9
+ },
+/turf/open/floor/iron/white,
+/area/station/medical/office)
"tmu" = (
/obj/structure/window/reinforced/spawner/directional/west,
/obj/effect/landmark/secequipment,
@@ -69195,6 +69701,24 @@
},
/turf/open/floor/iron/dark/smooth_large,
/area/station/command/bridge)
+"tvc" = (
+/obj/structure/disposalpipe/trunk{
+ dir = 4
+ },
+/obj/machinery/disposal/bin,
+/obj/effect/turf_decal/box,
+/obj/machinery/light_switch/directional/west{
+ pixel_y = -15
+ },
+/obj/machinery/button/door/directional/west{
+ id = "medexamshutter";
+ name = "Privacy Shutter Control"
+ },
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 9
+ },
+/turf/open/floor/iron/white,
+/area/station/medical/exam_room)
"tve" = (
/obj/machinery/portable_atmospherics/canister,
/obj/effect/turf_decal/box,
@@ -69623,6 +70147,11 @@
},
/turf/open/floor/iron/dark/smooth_large,
/area/station/hallway/secondary/exit/departure_lounge)
+"tzN" = (
+/obj/machinery/holopad,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/iron/white/smooth_large,
+/area/station/medical/office)
"tzT" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -69824,11 +70353,6 @@
/obj/structure/sign/warning/vacuum,
/turf/closed/wall/r_wall,
/area/station/science/ordnance/testlab)
-"tCp" = (
-/obj/machinery/light/small/directional/east,
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/smooth,
-/area/station/maintenance/aft/lesser)
"tCx" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -71196,6 +71720,10 @@
},
/turf/open/floor/carpet/orange,
/area/station/command/heads_quarters/ce)
+"tYr" = (
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/station/maintenance/department/security/brig)
"tYS" = (
/obj/structure/railing{
dir = 5
@@ -71340,7 +71868,7 @@
pixel_y = 4
},
/turf/open/floor/carpet/cyan,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"uaE" = (
/obj/effect/turf_decal/trimline/yellow/filled/line{
dir = 4
@@ -71559,6 +72087,12 @@
/obj/effect/turf_decal/loading_area,
/turf/open/floor/iron/smooth_large,
/area/station/cargo/storage)
+"udp" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/plating,
+/area/station/maintenance/aft)
"uds" = (
/obj/structure/disposalpipe/segment,
/obj/effect/turf_decal/trimline/red/filled/warning{
@@ -71957,7 +72491,7 @@
},
/obj/effect/turf_decal/bot,
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"ujK" = (
/obj/structure/window/reinforced/spawner/directional/north{
pixel_y = 1
@@ -71978,6 +72512,9 @@
},
/turf/open/floor/iron/dark,
/area/station/security/brig)
+"ukh" = (
+/turf/open/floor/plating,
+/area/station/maintenance/port)
"ukB" = (
/obj/structure/table/reinforced,
/obj/item/pipe_dispenser,
@@ -72301,7 +72838,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/decal/cleanable/dirt,
/obj/structure/sign/poster/random/directional/south,
-/turf/open/floor/catwalk_floor/iron_smooth,
+/turf/open/floor/plating,
/area/station/maintenance/aft/greater)
"uon" = (
/obj/structure/cable,
@@ -72719,6 +73256,12 @@
dir = 4
},
/area/station/commons/fitness/recreation/entertainment)
+"utq" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/spawner/random/structure/crate_empty,
+/obj/effect/spawner/random/maintenance/three,
+/turf/open/floor/plating,
+/area/station/maintenance/department/medical/central)
"utx" = (
/obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible{
dir = 9
@@ -72909,6 +73452,13 @@
dir = 1
},
/area/station/engineering/atmos)
+"uvB" = (
+/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/plating,
+/area/station/maintenance/department/engine/atmos)
"uvC" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
@@ -72936,7 +73486,7 @@
dir = 4
},
/turf/open/floor/carpet/cyan,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"uvX" = (
/obj/item/radio/intercom/directional/east,
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
@@ -74186,7 +74736,7 @@
},
/obj/effect/turf_decal/stripes/line,
/turf/open/floor/wood/large,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"uNs" = (
/obj/structure/table,
/obj/item/kitchen/rollingpin{
@@ -74396,7 +74946,9 @@
/turf/open/floor/wood/large,
/area/station/service/theater)
"uPL" = (
-/obj/structure/bed,
+/obj/structure/bed/medical{
+ dir = 4
+ },
/obj/item/bedsheet/medical,
/obj/machinery/iv_drip,
/obj/effect/turf_decal/trimline/red/filled/line{
@@ -74659,7 +75211,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"uTD" = (
/obj/machinery/holopad,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -74819,6 +75371,10 @@
},
/turf/open/floor/iron/smooth,
/area/station/command/cc_dock)
+"uVV" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/aft/lesser)
"uVW" = (
/obj/structure/table/wood,
/obj/machinery/power/apc/auto_name/directional/east,
@@ -74914,7 +75470,9 @@
/turf/open/floor/iron/dark/smooth_large,
/area/station/medical/morgue)
"uXb" = (
-/obj/structure/bed,
+/obj/structure/bed/medical{
+ dir = 4
+ },
/obj/item/clothing/glasses/blindfold,
/obj/effect/turf_decal/trimline/dark/filled/line{
dir = 5
@@ -75185,7 +75743,9 @@
/turf/open/floor/iron/grimy,
/area/station/commons/lounge)
"vck" = (
-/obj/machinery/recycler,
+/obj/machinery/recycler{
+ dir = 8
+ },
/obj/machinery/conveyor{
dir = 4;
id = "garbage"
@@ -75384,6 +75944,13 @@
/obj/structure/reagent_dispensers/fueltank,
/turf/open/floor/iron/smooth,
/area/station/maintenance/department/science/xenobiology)
+"vfE" = (
+/obj/structure/table,
+/obj/structure/towel_bin,
+/turf/open/floor/iron/dark/smooth_edge{
+ dir = 4
+ },
+/area/station/security/prison)
"vfJ" = (
/obj/structure/sign/departments/security/directional/east,
/obj/effect/turf_decal/trimline/red/filled/line{
@@ -75502,6 +76069,22 @@
/obj/structure/cable,
/turf/open/space/basic,
/area/station/solars/aisat)
+"vij" = (
+/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/plating,
+/area/station/maintenance/port/greater)
+"vik" = (
+/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/plating,
+/area/station/maintenance/department/medical)
"vio" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -76621,7 +77204,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/cable,
-/turf/open/floor/catwalk_floor/iron_smooth,
+/turf/open/floor/plating,
/area/station/maintenance/aft/greater)
"vxv" = (
/mob/living/basic/butterfly,
@@ -76732,6 +77315,11 @@
dir = 8
},
/area/station/medical/virology)
+"vzg" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/spawner/random/trash/garbage,
+/turf/open/floor/plating,
+/area/station/maintenance/department/science/ordnance_maint)
"vzj" = (
/obj/structure/closet/firecloset/wall{
pixel_x = -32
@@ -76813,10 +77401,24 @@
/obj/machinery/power/shuttle_engine/heater,
/turf/open/floor/plating,
/area/space/nearstation)
+"vAC" = (
+/obj/structure/chair/office{
+ dir = 1
+ },
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 4
+ },
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 8
+ },
+/turf/open/floor/iron/white/smooth_edge{
+ dir = 4
+ },
+/area/station/medical/office)
"vAT" = (
/obj/effect/spawner/random/structure/crate,
/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/aft/lesser)
"vAX" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -77009,7 +77611,7 @@
pixel_y = 32
},
/turf/open/floor/carpet/cyan,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"vEx" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -77171,7 +77773,7 @@
/obj/effect/landmark/start/nanotrasen_consultant,
/obj/structure/cable,
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"vGs" = (
/obj/effect/turf_decal/arrows/white,
/turf/open/floor/iron/dark/smooth_large,
@@ -77343,6 +77945,21 @@
},
/turf/open/floor/iron/small,
/area/station/hallway/primary/central)
+"vIY" = (
+/obj/machinery/camera/directional/east{
+ c_tag = "Medbay - Charting Office";
+ name = "medbay camera";
+ network = list("ss13","medbay")
+ },
+/obj/machinery/airalarm/directional/east,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/cable,
+/obj/effect/turf_decal/trimline/blue/filled/warning{
+ dir = 6
+ },
+/turf/open/floor/iron/white,
+/area/station/medical/office)
"vJm" = (
/obj/effect/turf_decal/siding/wood{
dir = 10
@@ -77377,7 +77994,7 @@
name = "curtain"
},
/turf/open/floor/grass,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"vJI" = (
/obj/structure/chair/office,
/obj/machinery/newscaster/directional/east,
@@ -77779,6 +78396,9 @@
dir = 8
},
/area/station/science/robotics/lab)
+"vOX" = (
+/turf/closed/wall/r_wall,
+/area/station/medical/exam_room)
"vOZ" = (
/obj/effect/turf_decal/tile/green/diagonal_centre,
/turf/open/floor/iron/diagonal,
@@ -78502,7 +79122,7 @@
"vYT" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/spawner/random/trash/moisture_trap,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"vZa" = (
/obj/effect/turf_decal/stripes/corner{
@@ -78897,11 +79517,6 @@
/obj/effect/turf_decal/trimline/blue/mid_joiner,
/turf/open/space/basic,
/area/space)
-"wen" = (
-/obj/machinery/iv_drip,
-/obj/effect/turf_decal/tile/blue/fourcorners,
-/turf/open/floor/iron/freezer,
-/area/station/medical/treatment_center)
"wev" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -78959,6 +79574,18 @@
/obj/machinery/light/cold/directional/south,
/turf/open/floor/iron/white,
/area/station/medical/storage)
+"wfk" = (
+/obj/machinery/door/airlock/medical{
+ name = "Medbay Office"
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/effect/turf_decal/stripes/line,
+/obj/machinery/door/firedoor,
+/obj/effect/mapping_helpers/airlock/access/any/medical/general,
+/turf/open/floor/iron/white/smooth_large,
+/area/station/medical/office)
"wfp" = (
/obj/structure/closet,
/obj/structure/window/spawner/directional/south,
@@ -79277,7 +79904,6 @@
"wkc" = (
/obj/machinery/portable_atmospherics/scrubber,
/obj/effect/turf_decal/delivery,
-/obj/machinery/light/small/directional/east,
/turf/open/floor/iron/smooth,
/area/station/maintenance/aft/lesser)
"wkj" = (
@@ -79376,7 +80002,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 1
},
-/obj/effect/mapping_helpers/airlock/access/all/security/general,
+/obj/effect/mapping_helpers/airlock/access/all/security/entrance,
/turf/open/floor/iron/dark/smooth_large,
/area/station/security/brig)
"wlV" = (
@@ -79418,7 +80044,7 @@
/obj/machinery/light/warm/directional/north,
/obj/effect/landmark/start/nanotrasen_consultant,
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"wmv" = (
/obj/structure/flora/grass/jungle,
/obj/structure/window/fulltile,
@@ -79655,6 +80281,12 @@
},
/turf/open/floor/circuit/green,
/area/station/ai_monitored/turret_protected/ai)
+"wpK" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/port/aft)
"wpL" = (
/obj/effect/turf_decal/trimline/yellow/filled/corner,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
@@ -79667,13 +80299,6 @@
/obj/effect/landmark/start/hangover,
/turf/open/floor/iron/smooth_large,
/area/station/hallway/primary/aft)
-"wpU" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/power/apc/auto_name/directional/north,
-/turf/open/floor/catwalk_floor/iron_smooth,
-/area/station/maintenance/department/medical/central)
"wqd" = (
/turf/closed/wall,
/area/station/service/kitchen/abandoned)
@@ -79947,6 +80572,9 @@
/turf/open/floor/glass/reinforced,
/area/station/medical/medbay/central)
"wtc" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 4
+ },
/turf/open/floor/iron/showroomfloor,
/area/station/medical/coldroom)
"wtg" = (
@@ -80250,6 +80878,15 @@
},
/turf/open/floor/engine,
/area/station/science/xenobiology)
+"wxG" = (
+/obj/effect/spawner/structure/window/reinforced,
+/obj/machinery/door/poddoor/shutters/preopen{
+ dir = 1;
+ name = "Exam Room Shutters";
+ id = "medexamshutter"
+ },
+/turf/open/floor/plating,
+/area/station/medical/exam_room)
"wxO" = (
/obj/structure/chair,
/obj/effect/turf_decal/stripes/line{
@@ -80629,7 +81266,7 @@
/area/station/common/pool)
"wCb" = (
/obj/effect/spawner/random/trash/mopbucket,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/medical/central)
"wCh" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
@@ -80803,7 +81440,7 @@
/obj/structure/extinguisher_cabinet/directional/south,
/obj/effect/landmark/event_spawn,
/turf/open/floor/carpet/cyan,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"wEC" = (
/obj/structure/table,
/obj/item/stock_parts/subspace/analyzer,
@@ -80857,6 +81494,15 @@
/obj/machinery/door/firedoor,
/turf/open/floor/iron/smooth_large,
/area/station/hallway/primary/aft)
+"wFc" = (
+/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/plating,
+/area/station/maintenance/department/medical/central)
"wFd" = (
/obj/structure/railing,
/obj/structure/disposalpipe/segment{
@@ -80935,6 +81581,16 @@
dir = 1
},
/area/station/engineering/atmos/storage)
+"wGg" = (
+/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/machinery/atmospherics/pipe/smart/manifold4w/dark/hidden,
+/turf/open/floor/plating,
+/area/station/maintenance/department/medical/central)
"wGw" = (
/obj/machinery/holopad,
/obj/effect/turf_decal/bot,
@@ -81401,7 +82057,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/carpet/green,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"wMI" = (
/obj/structure/fluff/paper/stack,
/obj/item/paper/crumpled{
@@ -81527,8 +82183,8 @@
},
/obj/machinery/airalarm/directional/east,
/obj/effect/mapping_helpers/airalarm/tlv_cold_room,
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
- dir = 1
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 10
},
/turf/open/floor/iron/showroomfloor,
/area/station/medical/coldroom)
@@ -81740,7 +82396,7 @@
dir = 9
},
/turf/open/floor/iron/dark/smooth_large,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"wSg" = (
/obj/machinery/computer/communications,
/obj/structure/cable,
@@ -82352,7 +83008,7 @@
/obj/item/radio/intercom/directional/south,
/obj/machinery/airalarm/directional/west,
/turf/open/floor/carpet/cyan,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"xfx" = (
/obj/structure/railing{
dir = 6
@@ -82462,6 +83118,10 @@
},
/turf/open/floor/iron/dark/smooth_large,
/area/station/medical/chemistry)
+"xgK" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/department/engine)
"xgQ" = (
/obj/structure/table/reinforced/plastitaniumglass,
/obj/item/toy/captainsaid/collector,
@@ -82480,7 +83140,7 @@
/obj/structure/grandfatherclock,
/obj/structure/cable,
/turf/open/floor/wood/large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"xhb" = (
/obj/structure/window/reinforced/spawner/directional/south,
/obj/structure/table,
@@ -82513,7 +83173,7 @@
/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/catwalk_floor/iron_smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/engine)
"xhS" = (
/obj/structure/reagent_dispensers/fueltank,
@@ -82543,6 +83203,17 @@
},
/turf/open/floor/iron/dark/smooth_large,
/area/station/security/execution/education)
+"xim" = (
+/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/machinery/atmospherics/pipe/smart/manifold4w/dark/hidden,
+/turf/open/floor/plating,
+/area/station/maintenance/department/medical/central)
"xir" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/carpet/black,
@@ -82762,7 +83433,7 @@
/area/station/commons/dorms)
"xlE" = (
/turf/closed/wall/r_wall,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"xlM" = (
/obj/structure/table/reinforced,
/obj/machinery/door/firedoor,
@@ -82822,6 +83493,16 @@
dir = 1
},
/area/station/commons/dorms/laundry)
+"xmF" = (
+/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,
+/turf/open/floor/plating,
+/area/station/maintenance/department/medical/central)
"xmH" = (
/obj/effect/spawner/random/engineering/atmospherics_portable,
/obj/effect/turf_decal/delivery,
@@ -82923,7 +83604,7 @@
"xnR" = (
/obj/structure/cable,
/obj/item/stack/sheet/cardboard,
-/turf/open/floor/catwalk_floor/iron_smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/security/brig)
"xnU" = (
/obj/machinery/door/airlock/public/glass{
@@ -82947,6 +83628,14 @@
},
/turf/open/floor/iron/smooth,
/area/station/maintenance/port/central)
+"xof" = (
+/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,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/aft/lesser)
"xoG" = (
/obj/machinery/biogenerator,
/obj/item/reagent_containers/cup/beaker{
@@ -83259,6 +83948,16 @@
dir = 8
},
/area/station/medical/medbay/central)
+"xrG" = (
+/obj/machinery/door/airlock/maintenance{
+ name = "Medical Office Maintenance"
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/effect/mapping_helpers/airlock/access/any/medical/general,
+/turf/open/floor/catwalk_floor/iron_smooth,
+/area/station/maintenance/department/medical/central)
"xrH" = (
/obj/effect/spawner/random/engineering/tracking_beacon,
/obj/machinery/holopad,
@@ -83491,7 +84190,7 @@
amount = 4
},
/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port)
"xvt" = (
/obj/effect/turf_decal/weather/sand,
@@ -83561,6 +84260,10 @@
},
/turf/open/floor/iron/dark/smooth_edge,
/area/station/hallway/secondary/command)
+"xwf" = (
+/obj/structure/trash_pile,
+/turf/open/floor/plating,
+/area/station/maintenance/port/aft)
"xwm" = (
/obj/structure/cable,
/obj/structure/disposalpipe/junction/flip{
@@ -83571,6 +84274,15 @@
/obj/machinery/duct,
/turf/open/floor/iron/smooth_large,
/area/station/engineering/power_room)
+"xwC" = (
+/obj/machinery/photocopier,
+/obj/effect/turf_decal/bot,
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 10
+ },
+/obj/machinery/light/cold/directional/south,
+/turf/open/floor/iron/white,
+/area/station/medical/office)
"xwO" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -83739,7 +84451,7 @@
dir = 8
},
/turf/open/floor/carpet/cyan,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"xyX" = (
/obj/effect/mapping_helpers/airlock/locked,
/obj/effect/turf_decal/stripes/line{
@@ -83784,8 +84496,8 @@
id_tag = "MedbayFoyer";
name = "Emergency Medical Entrance"
},
-/obj/effect/mapping_helpers/airlock/access/any/medical/morgue,
/obj/effect/mapping_helpers/airlock/unres,
+/obj/effect/mapping_helpers/airlock/access/any/medical/general,
/turf/open/floor/iron/white/smooth_large,
/area/station/medical/treatment_center)
"xzN" = (
@@ -83818,7 +84530,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/decal/cleanable/dirt,
/obj/machinery/power/apc/auto_name/directional/north,
-/turf/open/floor/catwalk_floor/iron_smooth,
+/turf/open/floor/plating,
/area/station/maintenance/aft/lesser)
"xAo" = (
/obj/structure/cable,
@@ -84070,7 +84782,7 @@
/turf/open/floor/iron/small,
/area/station/hallway/primary/central)
"xFo" = (
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/department/medical/morgue)
"xFt" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
@@ -84217,7 +84929,7 @@
"xGr" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/spawner/random/trash/garbage,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/aft)
"xGv" = (
/obj/effect/turf_decal/trimline/purple/filled/corner{
@@ -84504,7 +85216,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/disposalpipe/segment,
/obj/structure/sign/poster/contraband/random/directional/east,
-/turf/open/floor/catwalk_floor/iron_smooth,
+/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
"xLX" = (
/obj/effect/decal/cleanable/dirt,
@@ -85090,7 +85802,7 @@
/obj/effect/turf_decal/bot,
/obj/machinery/holopad,
/turf/open/floor/wood/large,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"xTN" = (
/obj/effect/turf_decal/trimline/brown/filled/corner{
dir = 8
@@ -85718,7 +86430,7 @@
"ydA" = (
/obj/effect/mapping_helpers/broken_floor,
/obj/effect/spawner/random/trash/grime,
-/turf/open/floor/iron/smooth,
+/turf/open/floor/plating,
/area/station/maintenance/port/aft)
"ydE" = (
/obj/structure/cable,
@@ -105652,7 +106364,7 @@ ttw
ttw
ttw
sAM
-fDA
+jVE
cvH
knY
xhU
@@ -105665,10 +106377,10 @@ cvH
grR
mUM
rcl
-rcl
-rcl
-rcl
-rcl
+pxe
+pxe
+pxe
+pxe
oQo
pxe
ttw
@@ -105909,7 +106621,7 @@ ttw
ttw
ttw
sAM
-fDA
+jVE
cvH
cvH
cvH
@@ -105925,10 +106637,10 @@ rcl
liB
qgv
dGj
-rcl
-oQo
pxe
-ttw
+wFc
+pxe
+pxe
ttw
ttw
ttw
@@ -106166,7 +106878,7 @@ ttw
ttw
sAM
sAM
-nvM
+vik
qFH
sAM
oXc
@@ -106182,10 +106894,10 @@ pcx
gjT
wtc
sNq
-rcl
-oQo
pxe
-ttw
+wFc
+mJA
+pxe
ttw
ttw
ttw
@@ -106235,7 +106947,7 @@ ydA
sWI
ron
lQt
-pZH
+oxA
ipJ
dwi
vPk
@@ -106439,10 +107151,10 @@ flH
mdK
oLS
hbE
-rcl
-oQo
pxe
-ttw
+wGg
+gHM
+pxe
ttw
ttw
ttw
@@ -106490,9 +107202,9 @@ xtV
dUO
lQt
eMd
-pZH
-pZH
-pZH
+oxA
+oxA
+oxA
uUU
ptY
voU
@@ -106697,9 +107409,9 @@ fUy
bMN
wNJ
lMx
-xNL
+xim
+pxe
pxe
-ttw
ttw
ttw
ttw
@@ -106747,7 +107459,7 @@ xtV
aDC
qQC
qMB
-spp
+xwf
yaE
oNW
uUU
@@ -106953,8 +107665,8 @@ rcl
rcl
rcl
rcl
-rcl
-xNL
+pxe
+xmF
pxe
ttw
ttw
@@ -106976,7 +107688,7 @@ nhU
vAk
qbS
xiD
-vAk
+rSG
vAk
ryX
kMf
@@ -106988,16 +107700,16 @@ uUU
uUU
uUU
uUU
-spp
+xwf
eWw
uUU
oNW
lUi
pZH
-tqv
-pZH
-pZH
-pZH
+tgU
+oxA
+oxA
+oxA
nSF
bcq
uUU
@@ -107206,12 +107918,12 @@ hIh
abQ
aCm
xZk
-abQ
-ttw
-ttw
-ttw
-hxT
-xNL
+asX
+tme
+vAC
+xwC
+pxe
+xmF
hxT
ttw
ttw
@@ -107230,44 +107942,44 @@ sEq
sEq
pkR
nhU
-qbS
-vAk
-xiD
-qbS
-qbS
+ukh
+rSG
+bvt
+ukh
+ukh
vAk
qbS
-vAk
-vAk
+rSG
+rSG
qbS
uUU
qmn
dul
xGr
pZH
-pZH
+oxA
+eMd
eMd
-oEf
tqv
-pZH
-pZH
-pZH
-pZH
+oxA
+oxA
+oxA
+oxA
pZH
eMd
nSF
pZH
uUU
mUE
-pZH
+oxA
hDI
dul
ptX
sSH
qIS
-pZH
+oxA
dXM
-pZH
+oxA
iaq
uUU
jwC
@@ -107412,7 +108124,7 @@ paS
eyy
rcr
nFs
-bQF
+mYn
oKR
oBd
uvj
@@ -107463,10 +108175,10 @@ bxX
rFD
jzo
xry
-rFD
-ttw
-ttw
-ttw
+asX
+cEB
+tzN
+eKs
pxe
xNL
pxe
@@ -107486,9 +108198,9 @@ kZJ
kZJ
kRE
pkR
-nhU
-nhU
-nhU
+imc
+imc
+imc
nMv
nhU
nhU
@@ -107501,14 +108213,14 @@ pGY
kUr
tjw
dbP
+wpK
eLz
-eLz
-eLz
-eLz
-eLz
-eLz
-eLz
-eLz
+wpK
+wpK
+wpK
+wpK
+wpK
+wpK
eLz
eLz
eLz
@@ -107518,8 +108230,8 @@ gEq
eLz
eLz
qAt
-eLz
-eLz
+wpK
+wpK
qBl
eLz
eLz
@@ -107669,8 +108381,8 @@ xyX
eyy
kJq
nFs
-oKR
-hAA
+lyJ
+vzg
rcf
mbJ
odJ
@@ -107720,11 +108432,11 @@ abQ
rFD
icP
icP
-rFD
-ttw
-ttw
-ttw
-hxT
+wfk
+cGu
+jqH
+vIY
+xrG
oQo
fUk
ttw
@@ -107735,7 +108447,7 @@ lvJ
cJm
xWK
hbp
-vGO
+cgH
cgZ
wxn
qlA
@@ -107743,7 +108455,7 @@ qFA
qFA
rDm
pkR
-nhU
+imc
vAk
lMS
alm
@@ -107926,7 +108638,7 @@ wlV
eyy
qtl
nFs
-oKR
+lyJ
oKR
ixT
uvj
@@ -107977,10 +108689,10 @@ abQ
ybI
icP
icP
-rFD
-ttw
-ttw
-ttw
+asX
+asX
+asX
+asX
pxe
oQo
pxe
@@ -107992,7 +108704,7 @@ rol
rol
sgk
kIm
-vGO
+cgH
cgZ
wNh
qlA
@@ -108000,7 +108712,7 @@ qFA
krh
fZT
pkR
-nhU
+imc
eVW
lMS
ipg
@@ -108234,11 +108946,11 @@ dMY
icP
rBo
icP
-rFD
-ttw
-ttw
-ttw
-hxT
+wxG
+tvc
+plo
+pcS
+pxe
oQo
hxT
ttw
@@ -108257,8 +108969,8 @@ qFA
krh
oJG
pkR
-pXE
-vAk
+ijj
+rSG
lMS
ipg
fSa
@@ -108491,10 +109203,10 @@ abQ
wsZ
icP
icP
-rFD
-ttw
-ttw
-pxe
+ooU
+ngZ
+efn
+kzV
pxe
wSR
pxe
@@ -108506,7 +109218,7 @@ cgZ
qHg
xMk
cgZ
-sYt
+lnU
cgZ
wNh
oMd
@@ -108515,7 +109227,7 @@ krh
xOz
pkR
nhU
-vAk
+rSG
lMS
ipg
fSa
@@ -108748,12 +109460,12 @@ abQ
rFD
icP
icP
-rFD
-ttw
-ttw
+wxG
+ofG
+mTl
+icH
pxe
-wpU
-oQo
+idg
lgX
lgX
lgX
@@ -108763,7 +109475,7 @@ sud
iii
jom
wKf
-sYt
+lnU
cgZ
wNh
oMd
@@ -108952,7 +109664,7 @@ aFO
mSI
enW
dUw
-oKR
+lyJ
uss
wqg
wqg
@@ -109005,14 +109717,14 @@ xMq
rFD
pyQ
pyQ
-rFD
-ttw
-ttw
-hxT
+wxG
+pAE
+qkb
+irU
bgo
ikc
jwV
-eak
+utq
lgX
gMx
wKf
@@ -109020,7 +109732,7 @@ ryt
olf
rLZ
wKf
-sYt
+lnU
cgZ
wxn
oMd
@@ -109262,10 +109974,10 @@ sAM
sAM
rNH
hEf
-abQ
-lAB
-lAB
-lAB
+nwW
+vOX
+vOX
+vOX
lAB
mDL
lAB
@@ -109277,7 +109989,7 @@ gQi
qaN
kEw
wKf
-vGO
+cgH
cgZ
wNh
qFA
@@ -109467,7 +110179,7 @@ btZ
enW
lpz
qwH
-oKR
+lyJ
bao
uvj
uvj
@@ -109526,7 +110238,7 @@ erF
gzy
xWN
lpZ
-bwm
+lAB
duU
eak
ukV
@@ -109534,7 +110246,7 @@ iSK
bDF
coR
cgZ
-vGO
+cgH
cgZ
wNh
qFA
@@ -109799,7 +110511,7 @@ oON
krh
xZo
pkR
-nhU
+imc
nQG
lMS
deE
@@ -110056,8 +110768,8 @@ qFA
hzD
kXW
pkR
-nhU
-vAk
+imc
+rSG
lMS
wMb
jmT
@@ -110750,7 +111462,7 @@ eFQ
fLX
eFQ
qwH
-ljL
+eFQ
uRe
ekX
uvj
@@ -111083,7 +111795,7 @@ fia
jNA
tAw
pkR
-vAk
+rSG
nhU
hCL
twe
@@ -111259,7 +111971,7 @@ xsF
xMq
uvj
lKX
-iJJ
+oBd
uvj
uvj
iIq
@@ -111520,8 +112232,8 @@ rcf
uvj
ioI
nGH
-nGH
-eWu
+lQf
+mlv
kIf
wjI
ffz
@@ -111597,7 +112309,7 @@ kbV
vco
wLc
pkR
-lGH
+cEL
xvp
lMS
nXs
@@ -111776,9 +112488,9 @@ rWs
uvj
uvj
xmH
-nGH
+lQf
rXL
-nGH
+lQf
nRd
wjI
nSU
@@ -112030,12 +112742,12 @@ ttw
ttw
rpk
aUu
-gGT
+aiq
wjI
gwZ
nGH
ayc
-eWu
+mlv
lsn
wjI
vSj
@@ -112150,7 +112862,7 @@ tBC
luV
toq
jKu
-fpk
+nES
xVm
iHL
eJf
@@ -112287,7 +112999,7 @@ wjI
wjI
wjI
dTz
-nGH
+lQf
wjI
wjI
wjI
@@ -112407,7 +113119,7 @@ rOM
vIt
toq
jKu
-fpk
+nES
xVm
eRt
izg
@@ -112551,9 +113263,9 @@ pKM
oqF
pKM
pKM
-pKM
+dqM
pDx
-see
+qUt
see
wjI
mhe
@@ -112765,10 +113477,10 @@ oQh
veh
veh
hpq
-gQh
+knn
eSD
gQh
-aXD
+pnU
xsZ
gQh
lrY
@@ -112781,11 +113493,11 @@ lrY
hml
vHV
dQq
-gQh
+knn
gbM
jYe
mPw
-aXD
+pnU
bcf
vtD
wPO
@@ -112807,8 +113519,8 @@ vew
clk
gAG
bnJ
-nGH
-nGH
+lQf
+lQf
vWf
nGH
lbi
@@ -112850,7 +113562,7 @@ etW
rMu
ups
ufc
-wen
+ufc
jRj
rnF
kUZ
@@ -112878,7 +113590,7 @@ aFU
sHv
wiz
rol
-bXt
+jtq
sHv
mjM
biU
@@ -112921,7 +113633,7 @@ dYh
xtF
toq
nFg
-wme
+hYA
xVm
tXe
kth
@@ -113020,8 +113732,8 @@ veh
vlt
tTQ
aXD
-gQh
-gQh
+knn
+knn
tTQ
pCm
pCm
@@ -113135,7 +113847,7 @@ sea
sHv
naG
rol
-bXt
+jtq
sHv
dWt
eUH
@@ -113323,7 +114035,7 @@ lov
jFt
ydK
wjI
-vWf
+lGy
eWu
nPV
wjI
@@ -113391,7 +114103,7 @@ jpF
uUS
sHv
pRv
-pIN
+vij
bXt
sHv
thY
@@ -113580,8 +114292,8 @@ gNh
rUo
wQg
wjI
-vWf
-nGH
+lGy
+lQf
omw
wjI
mhe
@@ -113648,7 +114360,7 @@ ads
vxT
sHv
jLS
-bXt
+jtq
sHv
sHv
fXP
@@ -113837,8 +114549,8 @@ iVy
jQM
moF
wjI
-vWf
-eWu
+lGy
+mlv
jFH
wjI
nqC
@@ -114195,16 +114907,16 @@ tFt
qAN
xJH
svC
-svC
-svC
-svC
-svC
+rJa
+rJa
+rJa
+rJa
juO
-svC
+rJa
qqa
-svC
+rJa
aWh
-svC
+rJa
oza
cwa
brI
@@ -114453,9 +115165,9 @@ pLI
fwB
fwB
fwB
-fwB
-fwB
-fwB
+ssU
+ssU
+ssU
fwB
fwB
brI
@@ -114609,7 +115321,7 @@ cgx
rIQ
wjI
vWf
-eWu
+mlv
xOR
wjI
wjI
@@ -114707,18 +115419,18 @@ qUI
kbv
tFt
dHe
-fbY
+ebS
pBZ
hQp
btf
lDP
iDu
-rOQ
+jte
wrg
brI
brI
mrV
-cwa
+uvB
fbY
wRj
brI
@@ -114867,10 +115579,10 @@ xWf
wjI
uZo
oqF
-pKM
-ucl
-pKM
-pKM
+dqM
+oZB
+dqM
+dqM
pVu
vmf
dPm
@@ -114964,7 +115676,7 @@ crK
ubZ
tFt
pLI
-svC
+rJa
gjs
brI
brI
@@ -114975,8 +115687,8 @@ fwB
iUL
brI
dVe
-cwa
-rOQ
+uvB
+jte
hUR
brI
xMq
@@ -115233,7 +115945,7 @@ rOQ
svC
frl
cwa
-rOQ
+jte
brI
brI
brI
@@ -115485,10 +116197,10 @@ eYM
brI
iJi
svC
-cwa
-cwa
-cwa
-cwa
+uvB
+uvB
+uvB
+uvB
cwa
xRu
gls
@@ -115643,7 +116355,7 @@ rWc
poX
leB
uZo
-oqF
+gTk
kZX
pKM
nvZ
@@ -117027,7 +117739,7 @@ rin
lFE
pEt
rgE
-eUp
+kux
owF
puj
kCR
@@ -117284,7 +117996,7 @@ rin
lFE
pEt
veD
-eUp
+kux
cGZ
kzc
vQS
@@ -117541,7 +118253,7 @@ kmZ
lFE
pEt
evE
-eUp
+kux
qbp
qbp
gmz
@@ -117797,7 +118509,7 @@ tZZ
xMq
lFE
pEt
-awv
+isr
xhr
lhE
qbp
@@ -118055,7 +118767,7 @@ xMq
lFE
pEt
awv
-eUp
+kux
jfq
qbp
nIl
@@ -118827,7 +119539,7 @@ vVU
egH
hAk
ulH
-gXR
+xgK
qbp
nIl
pkp
@@ -120112,7 +120824,7 @@ hUc
aEC
pEt
eUp
-gXR
+xgK
vau
qbp
rTG
@@ -121120,7 +121832,7 @@ xMx
iPJ
mTO
hYs
-hTn
+hLh
cju
tUK
orq
@@ -121139,7 +121851,7 @@ oCl
oCl
pEt
pEt
-eUp
+kux
koQ
qbp
nIl
@@ -121396,7 +122108,7 @@ xMq
xMq
pEt
eRP
-ycu
+taC
rfk
qbp
nIl
@@ -121633,7 +122345,7 @@ jEj
hxy
uxG
trA
-uxG
+sRR
oCl
oCl
hLh
@@ -121653,8 +122365,8 @@ svT
xMq
dXU
awv
-ycu
-gXR
+taC
+xgK
qbp
nIl
pkp
@@ -121910,8 +122622,8 @@ xMq
xMq
pEt
qXm
-eUp
-gXR
+kux
+xgK
qbp
rTG
pkp
@@ -122139,11 +122851,11 @@ tpL
dAD
kGP
phK
-cCJ
+duy
tTt
agW
mto
-cCJ
+duy
vlh
dZH
kbf
@@ -122167,7 +122879,7 @@ oCl
oCl
pEt
gug
-eUp
+kux
wHN
qbp
qbp
@@ -122424,7 +123136,7 @@ fzm
nUU
pEt
nMu
-eUp
+kux
eUp
eUp
dyl
@@ -122654,9 +123366,9 @@ fAJ
fAJ
hgW
hOj
-cCJ
-cCJ
-cCJ
+duy
+duy
+duy
jnT
vlh
bSV
@@ -122681,8 +123393,8 @@ ldR
bru
sAx
xck
-gXR
-gXR
+xgK
+xgK
eUp
evE
qbp
@@ -122913,7 +123625,7 @@ fAJ
fAJ
aGq
iyw
-cCJ
+duy
jnT
vlh
mWF
@@ -123455,7 +124167,7 @@ iBF
iBF
fer
fqz
-jnZ
+aXG
xGA
gdu
pkp
@@ -123712,7 +124424,7 @@ avf
iBF
clM
sLc
-jnZ
+aXG
xGA
myC
pkp
@@ -124227,7 +124939,7 @@ iBF
bxt
sLc
kVU
-tER
+bgz
tER
iPh
vPx
@@ -124482,9 +125194,9 @@ jDY
vWd
iBF
ygc
-jnZ
-sLc
-jnZ
+aXG
+udp
+aXG
sJd
sJd
sJd
@@ -124650,10 +125362,10 @@ vLO
dUD
ecR
ecR
-ssV
-ssV
-ecR
-ecR
+aXl
+aXl
+lqL
+lqL
nRG
ssV
ecR
@@ -125150,8 +125862,8 @@ kit
xQj
iNV
iNV
-rIe
-qGT
+ofF
+pMG
vLe
rne
egh
@@ -125407,8 +126119,8 @@ pAD
cuF
iNV
dzp
-gYP
-qGT
+beq
+pMG
vLe
hlD
dnq
@@ -125511,7 +126223,7 @@ hNu
uAD
iPZ
obh
-nnm
+nGb
fPm
sJd
jOm
@@ -125768,7 +126480,7 @@ jwq
pRr
iPZ
hhQ
-nnm
+nGb
mUp
sJd
xmL
@@ -125922,7 +126634,7 @@ hRp
iFc
qXe
iNV
-qGT
+pMG
bSp
aoD
gYP
@@ -126026,7 +126738,7 @@ weW
iPZ
rzT
cUA
-nnm
+nGb
ptO
jKW
sPT
@@ -126183,10 +126895,10 @@ sJy
ssV
ssV
xLQ
-ssV
-ssV
-ssV
-ssV
+aXl
+aXl
+aXl
+aXl
nRG
uEF
ykh
@@ -126520,7 +127232,7 @@ qeS
fKq
fKq
gcc
-kAL
+kpB
sID
kAL
uXM
@@ -126933,9 +127645,9 @@ afj
ndR
fTi
fTi
-hmN
-fTi
-oUo
+ouX
+tYr
+fpE
hmN
hmN
pWC
@@ -127296,7 +128008,7 @@ pEn
scP
mpm
fuK
-jya
+ish
ktu
pEn
sDL
@@ -127472,7 +128184,7 @@ pzh
pzh
vRf
pzh
-pzh
+mLy
ykh
irO
bcY
@@ -127551,9 +128263,9 @@ tKV
tKV
pEn
oec
-hyV
-tJj
-jya
+gfv
+dcL
+ish
aVb
yiU
dJY
@@ -127567,7 +128279,7 @@ sak
sak
sak
sak
-aEH
+uVV
qaO
kLc
unI
@@ -127729,7 +128441,7 @@ wqd
ePH
ePH
wqd
-pzh
+mLy
ykh
ykh
ykh
@@ -127809,7 +128521,7 @@ tKV
pEn
pEn
jya
-tJj
+dcL
aPu
yiU
yiU
@@ -127817,7 +128529,7 @@ pEn
xlM
oIw
pEn
-jya
+ish
noI
sak
hCA
@@ -127826,7 +128538,7 @@ kcW
sak
kFT
eWs
-aEH
+uVV
djs
hMy
olE
@@ -127986,7 +128698,7 @@ wcb
sEc
jhT
gap
-pzh
+mLy
eTo
iNV
tzI
@@ -128066,15 +128778,15 @@ tKV
pEn
ipp
jya
-tJj
-jya
+dcL
+ish
hnn
pEn
fXG
lUm
pit
jya
-jya
+ish
noI
vmX
wLt
@@ -128243,7 +128955,7 @@ qRv
hrZ
idl
ePH
-pzh
+mLy
pzh
wgI
hyf
@@ -128340,7 +129052,7 @@ bWt
sak
kFh
eWs
-aEH
+uVV
djs
ltn
olE
@@ -128580,7 +129292,7 @@ tKV
pEn
xOh
jya
-spf
+nrb
iay
iay
iay
@@ -128596,8 +129308,8 @@ aLU
oVX
sak
tuk
-qaO
-aEH
+jCq
+uVV
unI
uXf
xnu
@@ -129093,14 +129805,14 @@ tKV
tKV
pEn
frV
-jya
-tJj
+ish
+dcL
vBb
bjg
kAN
-vty
-vty
-vty
+kLl
+kLl
+kLl
pSJ
vty
rgH
@@ -129110,7 +129822,7 @@ ufe
ntn
gLb
lAi
-eWs
+xof
aEH
unI
dNL
@@ -129350,21 +130062,21 @@ kEm
kEm
pEn
pEn
-jya
+ish
pSK
iay
dBC
-vty
-vty
+kLl
+kLl
rYT
mPs
dNh
-vty
+kLl
cQb
iay
dzC
oXG
-aEH
+uVV
xRx
wIM
eWs
@@ -129616,12 +130328,12 @@ oSa
dDq
dsL
pSJ
-vty
+kLl
eQi
iay
tnp
-aEH
-aEH
+uVV
+uVV
shE
lAi
dsg
@@ -130275,10 +130987,10 @@ mrZ
fTi
oUo
fTi
-hbc
-fTi
+sCN
+tYr
xnR
-fTi
+tYr
fTi
iwq
rCm
@@ -130393,8 +131105,8 @@ aBh
mqd
iiO
qqg
-aEH
-aEH
+uVV
+uVV
qaO
hmY
unI
@@ -130636,21 +131348,21 @@ fyy
kEm
pEn
hyV
-nrb
-nrb
+eBy
+eBy
xJr
nrb
-nrb
+eBy
nrb
vHa
qaO
qaO
qaO
qaO
-qaO
-qaO
+jCq
+jCq
nAp
-qaO
+jCq
qaO
qaO
wsc
@@ -130894,10 +131606,10 @@ gNu
pEn
bKE
jya
-jya
-jya
-jya
-jya
+ish
+ish
+ish
+ish
rtr
pEn
dFG
@@ -130909,7 +131621,7 @@ lAi
lAi
kLc
tyt
-aEH
+uVV
ajL
lAi
uLA
@@ -131153,8 +131865,8 @@ bKE
wrR
emd
nub
-jya
-hyV
+ish
+gfv
pEn
pEn
pIm
@@ -131418,7 +132130,7 @@ cDs
lOz
lAi
sdb
-tCp
+uVV
jDi
lAi
lAi
@@ -134386,7 +135098,7 @@ iID
kFZ
kFZ
tyY
-kFZ
+vfE
mxe
pEu
pEu
diff --git a/_maps/map_files/biodome/biodome.dmm b/_maps/map_files/biodome/biodome.dmm
index f9aee4d6f2e..65e728001b5 100644
--- a/_maps/map_files/biodome/biodome.dmm
+++ b/_maps/map_files/biodome/biodome.dmm
@@ -1279,7 +1279,6 @@
/turf/open/floor/iron,
/area/station/engineering/storage)
"avI" = (
-/obj/machinery/lapvend,
/obj/effect/turf_decal/tile/purple/anticorner{
dir = 1
},
@@ -4200,7 +4199,7 @@
/obj/item/assembly/flash/handheld,
/obj/structure/cable,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"bwK" = (
/obj/structure/closet/secure_closet/medical3,
/obj/item/clothing/gloves/latex/nitrile,
@@ -4680,7 +4679,7 @@
},
/obj/effect/landmark/start/nanotrasen_consultant,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"bES" = (
/obj/item/plate,
/obj/item/food/meat/slab,
@@ -12080,7 +12079,7 @@
},
/obj/item/pen/fountain,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"ehD" = (
/obj/machinery/door/airlock/maintenance_hatch{
name = "Maintenance Hatch"
@@ -15744,7 +15743,7 @@
"fuh" = (
/obj/machinery/photocopier,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"fuj" = (
/obj/effect/mapping_helpers/burnt_floor,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -16150,7 +16149,7 @@
},
/obj/machinery/door/firedoor,
/turf/open/floor/iron,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"fAY" = (
/turf/closed/wall/r_wall/fakewood,
/area/station/command/heads_quarters/hop)
@@ -16505,7 +16504,7 @@
name = "Privacy Shutter"
},
/turf/open/floor/plating,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"fIZ" = (
/obj/machinery/light/directional/east,
/obj/effect/turf_decal/siding/yellow,
@@ -17649,7 +17648,7 @@
"gak" = (
/obj/machinery/light_switch/directional/south,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"gan" = (
/obj/machinery/door/airlock/public/glass{
name = "Funeral Parlour"
@@ -23584,7 +23583,7 @@
},
/obj/machinery/newscaster/directional/south,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"imi" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -26902,7 +26901,7 @@
/obj/machinery/power/apc/auto_name/directional/south,
/obj/structure/cable,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"jyh" = (
/obj/structure/closet/emcloset,
/obj/machinery/camera/directional/east{
@@ -29319,7 +29318,7 @@
"knH" = (
/obj/item/kirbyplants/random,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"knN" = (
/obj/machinery/atmospherics/pipe/smart/manifold/general/visible{
dir = 8
@@ -34418,7 +34417,7 @@
dir = 8
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"lVb" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/obj/effect/turf_decal/tile/red/half/contrasted{
@@ -35066,7 +35065,7 @@
/area/station/medical/medbay/central)
"meq" = (
/obj/item/radio/intercom/directional/north,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/turf/open/floor/iron/dark/smooth_large,
/area/station/medical/morgue)
@@ -35930,7 +35929,7 @@
/area/station/security/detectives_office)
"mtL" = (
/obj/structure/table/glass,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/effect/turf_decal/tile/blue/fourcorners,
/turf/open/floor/iron/white,
/area/station/medical/surgery/fore)
@@ -36147,7 +36146,7 @@
/area/station/science/ordnance/office)
"mxY" = (
/obj/structure/table/glass,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/effect/turf_decal/tile/blue/fourcorners,
/turf/open/floor/iron/white,
/area/station/medical/surgery/aft)
@@ -38165,7 +38164,7 @@
/obj/structure/filingcabinet/chestdrawer,
/obj/machinery/airalarm/directional/north,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"nhj" = (
/obj/structure/chair/stool/directional/north,
/turf/open/floor/iron,
@@ -39316,7 +39315,9 @@
dir = 4;
id = "garbage"
},
-/obj/machinery/recycler,
+/obj/machinery/recycler{
+ dir = 8
+ },
/turf/open/floor/plating,
/area/station/maintenance/disposal)
"nCE" = (
@@ -39419,9 +39420,6 @@
/obj/effect/turf_decal/tile/yellow/opposingcorners,
/turf/open/floor/iron/dark/textured,
/area/station/engineering/atmos/mix)
-"nEB" = (
-/turf/open/misc/asteroid,
-/area/station/maintenance/central/greater)
"nEO" = (
/obj/item/gun/energy/recharge/kinetic_accelerator{
color = "#FFFF00";
@@ -39566,7 +39564,7 @@
/turf/open/floor/iron,
/area/station/hallway/secondary/exit/departure_lounge)
"nHf" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/bot,
/obj/effect/turf_decal/tile/blue/half/contrasted,
/turf/open/floor/iron/white,
@@ -39899,7 +39897,7 @@
},
/obj/structure/cable,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"nMG" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -41067,7 +41065,7 @@
"ofl" = (
/obj/structure/falsewall,
/turf/open/floor/plating,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"ofo" = (
/obj/effect/turf_decal/arrows/white{
dir = 4
@@ -41320,7 +41318,7 @@
"ojO" = (
/obj/structure/filingcabinet/employment,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"ojX" = (
/obj/structure/table,
/obj/machinery/microwave,
@@ -43801,7 +43799,7 @@
/obj/machinery/light/directional/east,
/obj/structure/cable,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"pdW" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/turf_decal/stripes/corner{
@@ -43897,7 +43895,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/turf_decal/bot,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/landmark/start/hangover,
/turf/open/floor/iron/dark,
/area/station/medical/medbay/central)
@@ -45972,7 +45970,7 @@
/area/station/commons/dorms)
"pTm" = (
/obj/structure/window/spawner/directional/south,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/tile/red/half/contrasted{
dir = 8
},
@@ -46679,7 +46677,7 @@
dir = 1
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"qgY" = (
/obj/machinery/airalarm/directional/south,
/obj/effect/decal/cleanable/dirt,
@@ -48545,7 +48543,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/turf_decal/bot,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/turf/open/floor/iron/dark,
/area/station/medical/medbay/central)
"qNM" = (
@@ -50709,7 +50707,7 @@
dir = 4
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"rwT" = (
/obj/structure/closet/firecloset,
/turf/open/floor/plating,
@@ -52316,7 +52314,7 @@
},
/obj/structure/cable,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"sac" = (
/obj/item/grown/bananapeel,
/obj/effect/turf_decal/siding/wood{
@@ -54787,7 +54785,7 @@
"sUU" = (
/obj/structure/disposalpipe/segment,
/obj/effect/turf_decal/bot,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/turf/open/floor/iron/dark,
/area/station/medical/medbay/central)
"sUZ" = (
@@ -54857,7 +54855,7 @@
"sWw" = (
/obj/structure/window/reinforced/spawner/directional/north,
/obj/structure/table/reinforced,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/item/table_clock{
pixel_y = 8
},
@@ -57665,7 +57663,7 @@
/obj/effect/landmark/start/nanotrasen_consultant,
/obj/item/radio/intercom/directional/south,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"tUf" = (
/obj/structure/railing{
dir = 4
@@ -59132,7 +59130,7 @@
pixel_y = 8
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"uyX" = (
/obj/effect/turf_decal/siding/dark{
dir = 8
@@ -62654,7 +62652,7 @@
},
/obj/structure/cable,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"vMH" = (
/obj/effect/turf_decal/tile/yellow/diagonal_edge,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -63414,7 +63412,7 @@
/turf/open/misc/asteroid/airless,
/area/station/asteroid)
"waq" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/effect/turf_decal/bot,
/turf/open/floor/iron/dark,
@@ -66208,7 +66206,7 @@
/area/station/maintenance/aft/upper)
"wSw" = (
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"wSx" = (
/obj/structure/chair/sofa/corp/right{
dir = 8
@@ -69516,7 +69514,7 @@
"xZc" = (
/obj/effect/turf_decal/bot,
/obj/effect/turf_decal/tile/blue/half/contrasted,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/turf/open/floor/iron/white,
/area/station/medical/medbay/lobby)
"xZh" = (
@@ -69547,7 +69545,7 @@
/obj/structure/disposalpipe/trunk,
/obj/machinery/firealarm/directional/north,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"xZF" = (
/obj/structure/disposalpipe/trunk/multiz{
dir = 4
@@ -69659,7 +69657,7 @@
/area/station/hallway/secondary/entry)
"ybl" = (
/turf/closed/wall,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"ybs" = (
/turf/open/misc/beach/sand,
/area/station/maintenance/starboard/lesser)
@@ -94085,7 +94083,7 @@ hNy
hNy
hNy
owr
-nEB
+fTB
xWj
hNy
hNy
diff --git a/_maps/map_files/burgerstation/burgerstation.dmm b/_maps/map_files/burgerstation/burgerstation.dmm
index 9b4eac4b646..808d4110943 100644
--- a/_maps/map_files/burgerstation/burgerstation.dmm
+++ b/_maps/map_files/burgerstation/burgerstation.dmm
@@ -51,7 +51,7 @@
dir = 8
},
/turf/open/floor/carpet/blue,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"aaY" = (
/obj/machinery/computer/records/security,
/obj/effect/turf_decal/tile/red/half/contrasted{
@@ -3519,7 +3519,7 @@
},
/obj/item/radio/intercom/command/directional/west,
/turf/open/floor/wood,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"boA" = (
/obj/effect/turf_decal/tile/purple/half/contrasted{
dir = 1
@@ -4189,7 +4189,7 @@
dir = 6
},
/turf/open/floor/wood,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"bDh" = (
/obj/effect/turf_decal/tile/yellow/opposingcorners,
/obj/effect/turf_decal/tile/red/opposingcorners{
@@ -5234,7 +5234,7 @@
/obj/structure/disposalpipe/segment,
/obj/machinery/airalarm/directional/east,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/turf/open/floor/plating,
/area/station/maintenance/disposal)
"bXC" = (
@@ -6287,7 +6287,7 @@
"crv" = (
/obj/structure/cable,
/turf/open/floor/carpet/blue,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"crI" = (
/obj/structure/table/wood,
/obj/machinery/requests_console/auto_name/directional/north,
@@ -6682,7 +6682,7 @@
dir = 5
},
/turf/open/floor/carpet/blue,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"cCU" = (
/obj/structure/table/wood,
/obj/item/reagent_containers/cup/soup_pot/material,
@@ -6747,7 +6747,7 @@
dir = 4
},
/turf/open/floor/iron/dark,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"cDI" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -10738,12 +10738,6 @@
/obj/effect/landmark/start/cyborg,
/turf/open/floor/glass/reinforced,
/area/station/ai_monitored/turret_protected/ai_upload)
-"edL" = (
-/obj/machinery/lapvend,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron/white,
-/area/station/hallway/secondary/exit)
"edN" = (
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
@@ -10779,7 +10773,7 @@
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/cable,
/turf/open/floor/plating,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"eeD" = (
/obj/effect/landmark/start/chief_medical_officer,
/obj/structure/cable,
@@ -13230,7 +13224,7 @@
/obj/structure/cable,
/obj/machinery/door/firedoor,
/turf/open/floor/plating,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"eRL" = (
/obj/structure/cable,
/obj/effect/turf_decal/tile/purple/half/contrasted,
@@ -15335,7 +15329,7 @@
"fDq" = (
/obj/structure/closet/secure_closet/blueshield,
/turf/open/floor/wood,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"fDu" = (
/obj/structure/cable,
/obj/effect/mapping_helpers/broken_floor,
@@ -18083,7 +18077,7 @@
/obj/effect/turf_decal/tile/blue/anticorner/contrasted{
dir = 4
},
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/item/radio/intercom/directional/east,
/turf/open/floor/iron/dark,
/area/station/medical/surgery/aft)
@@ -19998,7 +19992,7 @@
name = "Blueshield's Fax Machine"
},
/turf/open/floor/wood,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"hnH" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -22227,7 +22221,7 @@
/area/station/medical/pharmacy)
"ifl" = (
/obj/structure/table,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/machinery/airalarm/directional/east,
/obj/effect/turf_decal/tile/red/half/contrasted{
dir = 4
@@ -24934,7 +24928,7 @@
/obj/structure/cable,
/obj/machinery/holopad,
/turf/open/floor/carpet/blue,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"jgt" = (
/obj/effect/mapping_helpers/airlock/access/all/security/hos,
/obj/structure/disposalpipe/segment{
@@ -25505,7 +25499,7 @@
/obj/item/pen,
/obj/structure/cable,
/turf/open/floor/wood,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"jpQ" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -27189,11 +27183,11 @@
"jWi" = (
/obj/effect/turf_decal/tile/dark_blue/half,
/obj/structure/rack,
-/obj/item/roller,
-/obj/item/roller{
+/obj/item/emergency_bed,
+/obj/item/emergency_bed{
pixel_y = 4
},
-/obj/item/roller{
+/obj/item/emergency_bed{
pixel_y = 8
},
/obj/effect/turf_decal/tile/blue/half/contrasted{
@@ -27928,7 +27922,7 @@
dir = 1
},
/turf/open/floor/wood,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"kkf" = (
/obj/effect/turf_decal/tile/purple/half/contrasted{
dir = 1
@@ -31066,7 +31060,7 @@
dir = 1
},
/turf/open/floor/wood,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"lmv" = (
/obj/machinery/porta_turret/ai,
/turf/open/floor/circuit/red,
@@ -32868,7 +32862,9 @@
/turf/open/floor/iron/white,
/area/station/medical/storage)
"lWj" = (
-/obj/machinery/recycler,
+/obj/machinery/recycler{
+ dir = 8
+ },
/obj/structure/disposalpipe/segment{
dir = 10
},
@@ -38839,7 +38835,7 @@
/obj/structure/sign/poster/official/random/directional/east,
/obj/item/kirbyplants/random,
/turf/open/floor/wood,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"odz" = (
/obj/effect/turf_decal/tile/purple/half/contrasted{
dir = 8
@@ -42679,7 +42675,7 @@
/turf/open/floor/iron/dark,
/area/station/security/eva)
"pBE" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/machinery/power/apc/auto_name/directional/west,
/obj/effect/turf_decal/tile/red/half/contrasted{
@@ -47169,7 +47165,7 @@
/obj/effect/turf_decal/tile/blue/anticorner/contrasted{
dir = 4
},
-/obj/item/roller,
+/obj/item/emergency_bed,
/turf/open/floor/iron/white,
/area/station/medical/medbay/lobby)
"rdk" = (
@@ -50339,7 +50335,7 @@
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/obj/machinery/firealarm/directional/east,
/turf/open/floor/wood,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"ske" = (
/obj/effect/turf_decal/tile/red/half/contrasted{
dir = 1
@@ -52426,7 +52422,7 @@
"sYp" = (
/obj/structure/sign/flag/nanotrasen/directional/south,
/turf/open/floor/carpet/blue,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"sYq" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -54080,7 +54076,7 @@
dir = 9
},
/obj/structure/table,
-/obj/item/storage/backpack/duffelbag/coroner/surgery,
+/obj/item/surgery_tray/full/morgue,
/obj/machinery/airalarm/directional/north,
/turf/open/floor/iron/dark,
/area/station/medical/office)
@@ -55053,7 +55049,7 @@
/area/station/hallway/primary/starboard)
"tUX" = (
/turf/closed/wall,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"tUY" = (
/obj/effect/spawner/random/structure/table_or_rack,
/obj/effect/spawner/costume/madscientist,
@@ -55949,7 +55945,7 @@
/area/station/service/hydroponics)
"ulZ" = (
/turf/open/floor/carpet/blue,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"umh" = (
/obj/effect/mapping_helpers/airlock/access/all/command/gateway,
/obj/machinery/door/airlock/command/glass{
@@ -58585,7 +58581,7 @@
/obj/effect/turf_decal/tile/blue/anticorner/contrasted{
dir = 4
},
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/item/radio/intercom/directional/east,
/turf/open/floor/iron/dark,
/area/station/medical/surgery/fore)
@@ -59245,7 +59241,7 @@
/obj/effect/spawner/random/entertainment/cigar,
/obj/machinery/newscaster/directional/west,
/turf/open/floor/wood,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"vvP" = (
/obj/structure/chair/sofa/corp{
dir = 1
@@ -65918,7 +65914,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/structure/cable,
/turf/open/floor/carpet/blue,
-/area/blueshield)
+/area/station/command/heads_quarters/blueshield)
"xSV" = (
/obj/effect/turf_decal/bot,
/obj/effect/decal/cleanable/dirt/dust,
@@ -108506,7 +108502,7 @@ aTv
gzD
giW
gTp
-edL
+giW
phE
pBG
gRR
diff --git a/_maps/map_files/debug/runtimestation.dmm b/_maps/map_files/debug/runtimestation.dmm
index 4072ee21a70..a475bd64013 100644
--- a/_maps/map_files/debug/runtimestation.dmm
+++ b/_maps/map_files/debug/runtimestation.dmm
@@ -662,6 +662,7 @@
"cK" = (
/obj/machinery/light/directional/south,
/obj/structure/table/glass,
+/obj/item/disk/surgery/debug,
/obj/item/storage/box/monkeycubes{
pixel_x = 6;
pixel_y = 1
@@ -676,8 +677,7 @@
/turf/open/floor/iron/white/corner,
/area/station/medical/medbay)
"cL" = (
-/obj/item/storage/backpack/duffelbag/syndie/surgery,
-/obj/item/disk/surgery/debug,
+/obj/item/surgery_tray/full/advanced,
/obj/structure/table/glass,
/obj/effect/turf_decal/tile/blue{
dir = 8
diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm
index 70907224e40..9b6c1b6d5d5 100644
--- a/_maps/map_files/generic/CentCom.dmm
+++ b/_maps/map_files/generic/CentCom.dmm
@@ -487,7 +487,7 @@
/turf/open/floor/iron,
/area/centcom/tdome/observation)
"cl" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/effect/turf_decal/tile/blue/fourcorners,
/obj/effect/decal/cleanable/cobweb,
@@ -5600,7 +5600,7 @@
/turf/open/floor/iron/white,
/area/centcom/central_command_areas/control)
"zI" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/effect/turf_decal/tile/blue/opposingcorners{
dir = 1
@@ -6193,6 +6193,19 @@
},
/turf/open/floor/iron/dark,
/area/centcom/central_command_areas/evacuation)
+"Ci" = (
+/obj/structure/table/reinforced,
+/obj/item/surgery_tray/full{
+ pixel_y = 10;
+ pixel_x = 2
+ },
+/obj/item/storage/box/masks{
+ pixel_x = -6;
+ pixel_y = 4
+ },
+/obj/effect/turf_decal/stripes/line,
+/turf/open/floor/iron/white,
+/area/centcom/central_command_areas/evacuation/ship)
"Co" = (
/obj/effect/turf_decal/tile/brown/half/contrasted{
dir = 4
@@ -7002,18 +7015,6 @@
/obj/machinery/light/small/directional/east,
/turf/open/floor/iron/smooth_edge,
/area/centcom/central_command_areas/evacuation/ship)
-"Hh" = (
-/obj/structure/table/wood,
-/obj/item/flashlight/lamp,
-/obj/machinery/requests_console/directional/north{
- department = "Captain's Desk";
- name = "CentCom Requests Console"
- },
-/obj/effect/mapping_helpers/requests_console/announcement,
-/obj/effect/mapping_helpers/requests_console/information,
-/obj/effect/mapping_helpers/requests_console/assistance,
-/turf/open/floor/iron/grimy,
-/area/centcom/central_command_areas/admin)
"Hi" = (
/obj/effect/turf_decal/tile/green,
/obj/machinery/light/directional/south,
@@ -7135,7 +7136,7 @@
/turf/open/floor/iron/dark,
/area/centcom/central_command_areas/courtroom)
"HR" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/effect/turf_decal/tile/blue/fourcorners,
/obj/machinery/light/directional/west,
@@ -9678,19 +9679,6 @@
},
/turf/open/floor/iron,
/area/centcom/central_command_areas/armory)
-"Vh" = (
-/obj/structure/table/reinforced,
-/obj/item/storage/backpack/duffelbag/med/surgery{
- pixel_y = 10;
- pixel_x = 2
- },
-/obj/item/storage/box/masks{
- pixel_x = -6;
- pixel_y = 4
- },
-/obj/effect/turf_decal/stripes/line,
-/turf/open/floor/iron/white,
-/area/centcom/central_command_areas/evacuation/ship)
"Vi" = (
/obj/item/book/manual/wiki/security_space_law,
/obj/structure/table/wood,
@@ -10547,6 +10535,18 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/centcom/central_command_areas/armory)
+"Zw" = (
+/obj/structure/table/wood,
+/obj/item/flashlight/lamp,
+/obj/machinery/requests_console/directional/north{
+ department = "Captain's Desk";
+ name = "CentCom Requests Console"
+ },
+/obj/effect/mapping_helpers/requests_console/announcement,
+/obj/effect/mapping_helpers/requests_console/information,
+/obj/effect/mapping_helpers/requests_console/assistance,
+/turf/open/floor/iron/grimy,
+/area/centcom/central_command_areas/admin)
"Zx" = (
/obj/machinery/computer/records/security{
dir = 8
@@ -37631,7 +37631,7 @@ Lt
aa
aa
Lt
-Vh
+Ci
LI
CH
CH
@@ -48880,7 +48880,7 @@ On
vo
fP
On
-Hh
+Zw
XV
hd
To
diff --git a/_maps/map_files/generic/CentCom_skyrat_z2.dmm b/_maps/map_files/generic/CentCom_skyrat_z2.dmm
index 4ee78940736..d187e5f5dac 100644
--- a/_maps/map_files/generic/CentCom_skyrat_z2.dmm
+++ b/_maps/map_files/generic/CentCom_skyrat_z2.dmm
@@ -376,7 +376,7 @@
/turf/open/indestructible/hotelwood,
/area/centcom/holding/cafe)
"aiw" = (
-/obj/structure/bed,
+/obj/structure/bed/pod,
/obj/machinery/light/directional/east,
/turf/open/indestructible/cobble/side{
dir = 4
@@ -2288,7 +2288,7 @@
},
/area/centcom/holding/cafe)
"aEa" = (
-/obj/structure/bed,
+/obj/structure/bed/pod,
/turf/open/indestructible/cobble/corner,
/area/centcom/holding/cafepark)
"aEf" = (
@@ -2682,11 +2682,11 @@
/obj/item/reagent_containers/condiment/yoghurt,
/obj/item/reagent_containers/condiment/yoghurt,
/obj/item/reagent_containers/condiment/yoghurt,
-/obj/item/reagent_containers/condiment/quality_oil,
-/obj/item/reagent_containers/condiment/quality_oil,
-/obj/item/reagent_containers/condiment/quality_oil,
-/obj/item/reagent_containers/condiment/quality_oil,
-/obj/item/reagent_containers/condiment/quality_oil,
+/obj/item/reagent_containers/condiment/olive_oil,
+/obj/item/reagent_containers/condiment/olive_oil,
+/obj/item/reagent_containers/condiment/olive_oil,
+/obj/item/reagent_containers/condiment/olive_oil,
+/obj/item/reagent_containers/condiment/olive_oil,
/obj/item/food/canned/larvae,
/obj/item/food/canned/larvae,
/obj/item/food/canned/larvae,
@@ -4201,7 +4201,7 @@
/turf/open/floor/iron/dark,
/area/centcom/interlink)
"aYA" = (
-/obj/structure/bed,
+/obj/structure/bed/pod,
/turf/open/indestructible/cobble/side{
dir = 4
},
@@ -4390,7 +4390,7 @@
dir = 8
},
/obj/machinery/light/directional/west,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/turf/open/floor/iron/white,
/area/centcom/holding/cafe)
@@ -6398,7 +6398,7 @@
/turf/open/floor/iron,
/area/centcom/holding/cafe)
"goK" = (
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/effect/turf_decal/tile/blue{
dir = 8
},
@@ -7711,7 +7711,7 @@
/turf/open/floor/wood,
/area/centcom/holding/cafedorms)
"jKj" = (
-/obj/structure/bed,
+/obj/structure/bed/pod,
/turf/open/floor/iron,
/area/centcom/interlink)
"jNs" = (
@@ -9493,7 +9493,7 @@
/turf/open/floor/iron/dark,
/area/centcom/interlink)
"ovH" = (
-/obj/machinery/vending/wardrobe/syndie_wardrobe{
+/obj/machinery/vending/wardrobe/syndie_wardrobe/ghost_cafe{
default_price = 0;
extra_price = 0;
fair_market_price = 0
@@ -10877,7 +10877,7 @@
},
/area/cruiser_dock)
"rMy" = (
-/obj/structure/bed{
+/obj/structure/bed/pod{
dir = 4
},
/turf/open/floor/iron,
@@ -10947,7 +10947,7 @@
/obj/item/clothing/glasses/sunglasses,
/obj/item/clothing/glasses/sunglasses/big,
/obj/item/clothing/glasses/sunglasses,
-/obj/item/clothing/suit/costume/ianshirt,
+/obj/item/clothing/suit/costume/wellworn_shirt/graphic/ian,
/obj/item/clothing/suit/costume/hawaiian,
/turf/open/misc/beach/sand,
/area/centcom/holding/cafepark)
@@ -12953,7 +12953,7 @@
/obj/effect/turf_decal/tile/blue{
dir = 8
},
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/turf/open/floor/iron/white,
/area/centcom/holding/cafe)
@@ -13429,7 +13429,7 @@
/area/centcom/holding/cafe)
"ycL" = (
/obj/structure/table/optable,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/effect/turf_decal/bot_blue,
/turf/open/floor/iron/white,
/area/centcom/interlink)
diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm
index d3fa5b0ed0d..4ef52187a09 100644
--- a/_maps/map_files/tramstation/tramstation.dmm
+++ b/_maps/map_files/tramstation/tramstation.dmm
@@ -2578,7 +2578,7 @@
/turf/open/floor/wood/large,
/area/station/service/theater)
"aka" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/bot,
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 8
@@ -3806,6 +3806,23 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/hallway/secondary/service)
+"axh" = (
+/obj/structure/rack,
+/obj/item/clothing/glasses/meson{
+ pixel_y = 4
+ },
+/obj/item/lighter,
+/obj/item/reagent_containers/pill/patch/aiuri,
+/obj/item/stock_parts/cell/high,
+/obj/effect/turf_decal/trimline/yellow/filled/line{
+ dir = 1
+ },
+/obj/structure/window/reinforced/spawner/directional/west,
+/obj/item/computer_disk/engineering,
+/obj/item/computer_disk/engineering,
+/obj/item/computer_disk/engineering,
+/turf/open/floor/iron,
+/area/station/command/heads_quarters/ce)
"axp" = (
/obj/effect/turf_decal/trimline/red/filled/line{
dir = 8
@@ -12096,8 +12113,8 @@
/obj/effect/turf_decal/trimline/green/filled/line{
dir = 4
},
-/obj/structure/bed{
- dir = 4
+/obj/structure/bed/medical/anchored{
+ dir = 8
},
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
@@ -13432,7 +13449,7 @@
dir = 1
},
/obj/item/radio/intercom/directional/north,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/turf/open/floor/iron/white,
/area/station/medical/surgery/aft)
"dCG" = (
@@ -18115,6 +18132,17 @@
/obj/machinery/light/warm/directional/east,
/turf/open/floor/iron/dark,
/area/station/service/chapel)
+"frL" = (
+/obj/effect/turf_decal/trimline/red/filled/line{
+ dir = 9
+ },
+/obj/machinery/status_display/door_timer{
+ id = "Isolation_C";
+ name = "Isolation Cell C";
+ pixel_y = 32
+ },
+/turf/open/floor/iron,
+/area/station/security/execution/transfer)
"frN" = (
/obj/effect/spawner/structure/window/reinforced/plasma,
/turf/open/floor/plating,
@@ -20724,7 +20752,9 @@
dir = 4;
id = "cargolower"
},
-/obj/machinery/recycler,
+/obj/machinery/recycler{
+ dir = 8
+ },
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/maintenance/disposal)
@@ -21911,10 +21941,8 @@
/turf/open/floor/iron/dark/herringbone,
/area/station/commons/vacant_room)
"gNE" = (
-/obj/structure/bed/pod{
- desc = "An old medical bed, just waiting for replacement with something up to date.";
- dir = 8;
- name = "medical bed"
+/obj/structure/bed/medical{
+ dir = 4
},
/obj/machinery/defibrillator_mount/directional/east,
/obj/effect/turf_decal/trimline/blue/filled/line{
@@ -23579,7 +23607,7 @@
/area/station/maintenance/tram/left)
"hvt" = (
/obj/effect/turf_decal/trimline/blue/filled/line,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/bot,
/obj/structure/disposalpipe/segment{
dir = 9
@@ -27717,9 +27745,7 @@
/turf/open/floor/iron,
/area/station/hallway/primary/tram/center)
"iZY" = (
-/obj/structure/bed{
- dir = 4
- },
+/obj/structure/bed/medical/anchored,
/obj/machinery/light/red/directional/west,
/turf/open/floor/iron/textured_large,
/area/station/security/execution/education)
@@ -28863,10 +28889,8 @@
/turf/closed/wall,
/area/station/medical/treatment_center)
"jts" = (
-/obj/structure/bed/pod{
- desc = "An old medical bed, just waiting for replacement with something up to date.";
- dir = 4;
- name = "medical bed"
+/obj/structure/bed/medical{
+ dir = 8
},
/obj/machinery/defibrillator_mount/directional/west,
/obj/effect/turf_decal/trimline/blue/filled/line{
@@ -30447,7 +30471,9 @@
/turf/open/floor/iron,
/area/station/hallway/secondary/entry)
"jWn" = (
-/obj/structure/bed,
+/obj/structure/bed/medical/emergency{
+ dir = 4
+ },
/obj/effect/turf_decal/trimline/red/filled/line{
dir = 6
},
@@ -32045,6 +32071,7 @@
/area/station/hallway/primary/tram/center)
"kwG" = (
/obj/effect/turf_decal/trimline/red/filled/line,
+/obj/machinery/airalarm/directional/south,
/turf/open/floor/iron,
/area/station/security/execution/transfer)
"kwN" = (
@@ -32478,8 +32505,6 @@
},
/obj/item/storage/box/syringes,
/obj/item/mod/module/plasma_stabilizer,
-/obj/item/mod/module/thermal_regulator,
-/obj/item/gun/syringe,
/obj/machinery/door/window/left/directional/west{
name = "Secure Medical Storage";
req_access = list("medical")
@@ -32487,6 +32512,9 @@
/obj/effect/turf_decal/siding/white{
dir = 8
},
+/obj/item/mod/module/signlang_radio,
+/obj/item/mod/module/thermal_regulator,
+/obj/item/gun/syringe,
/turf/open/floor/iron/dark,
/area/station/medical/storage)
"kGo" = (
@@ -37265,23 +37293,6 @@
"mjM" = (
/turf/closed/wall,
/area/station/security/medical)
-"mjX" = (
-/obj/structure/rack,
-/obj/item/clothing/glasses/meson{
- pixel_y = 4
- },
-/obj/item/lighter,
-/obj/item/reagent_containers/pill/patch/aiuri,
-/obj/item/stock_parts/cell/high,
-/obj/effect/turf_decal/trimline/yellow/filled/line{
- dir = 1
- },
-/obj/structure/window/reinforced/spawner/directional/west,
-/obj/item/computer_disk/engineering,
-/obj/item/computer_disk/engineering,
-/obj/item/computer_disk/engineering,
-/turf/open/floor/iron,
-/area/station/command/heads_quarters/ce)
"mki" = (
/obj/machinery/door/airlock/command{
name = "Head of Personnel"
@@ -37951,7 +37962,7 @@
/area/station/commons/fitness/recreation/entertainment)
"myA" = (
/obj/effect/turf_decal/trimline/blue/filled/line,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/bot,
/obj/structure/disposalpipe/segment{
dir = 5
@@ -40604,6 +40615,7 @@
},
/obj/structure/rack,
/obj/item/mod/module/plasma_stabilizer,
+/obj/item/mod/module/signlang_radio,
/obj/item/mod/module/thermal_regulator,
/turf/open/floor/iron,
/area/station/engineering/engine_smes)
@@ -41676,17 +41688,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/secondary/exit)
-"nQv" = (
-/obj/effect/turf_decal/trimline/neutral/warning,
-/obj/structure/table/reinforced,
-/obj/item/table_clock{
- pixel_y = 8
- },
-/obj/structure/window/reinforced/spawner/directional/north,
-/obj/item/storage/backpack/duffelbag/med/surgery,
-/obj/structure/window/reinforced/spawner/directional/west,
-/turf/open/floor/iron/dark,
-/area/station/medical/morgue)
"nQB" = (
/obj/effect/turf_decal/sand,
/obj/effect/turf_decal/trimline/red/filled/line{
@@ -42878,7 +42879,7 @@
/area/station/service/library)
"ols" = (
/obj/effect/turf_decal/trimline/blue/filled/line,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/camera/directional/south{
c_tag = "Medical - Lobby";
network = list("ss13","medbay")
@@ -42951,6 +42952,11 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 1
},
+/obj/machinery/status_display/door_timer{
+ id = "Isolation_D";
+ name = "Isolation Cell D";
+ pixel_y = -32
+ },
/turf/open/floor/iron,
/area/station/security/execution/transfer)
"onc" = (
@@ -45795,8 +45801,8 @@
/obj/effect/turf_decal/trimline/green/filled/line{
dir = 4
},
-/obj/structure/bed{
- dir = 4
+/obj/structure/bed/medical/anchored{
+ dir = 8
},
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/turf/open/floor/iron,
@@ -48622,6 +48628,17 @@
/obj/item/soap/syndie,
/turf/open/floor/iron/showroomfloor,
/area/station/commons/vacant_room)
+"qtQ" = (
+/obj/effect/turf_decal/trimline/neutral/warning,
+/obj/structure/table/reinforced,
+/obj/item/table_clock{
+ pixel_y = 8
+ },
+/obj/structure/window/reinforced/spawner/directional/north,
+/obj/item/surgery_tray/full/morgue,
+/obj/structure/window/reinforced/spawner/directional/west,
+/turf/open/floor/iron/dark,
+/area/station/medical/morgue)
"qtS" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/disposalpipe/segment{
@@ -48741,6 +48758,15 @@
/obj/item/storage/bag/money,
/turf/open/floor/iron/dark,
/area/station/cargo/miningdock/oresilo)
+"qwV" = (
+/obj/effect/turf_decal/trimline/red/filled/line,
+/obj/machinery/status_display/door_timer{
+ id = "Isolation_B";
+ name = "Isolation Cell B";
+ pixel_y = -32
+ },
+/turf/open/floor/iron,
+/area/station/security/execution/transfer)
"qwX" = (
/obj/structure/flora/bush/grassy/style_random,
/turf/open/floor/grass,
@@ -49875,6 +49901,17 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/wood,
/area/station/commons/dorms)
+"qTt" = (
+/obj/effect/turf_decal/trimline/red/filled/line{
+ dir = 1
+ },
+/obj/machinery/status_display/door_timer{
+ id = "Isolation_A";
+ name = "Isolation Cell A";
+ pixel_y = 32
+ },
+/turf/open/floor/iron,
+/area/station/security/execution/transfer)
"qTv" = (
/obj/effect/turf_decal/trimline/neutral/filled/line{
dir = 4
@@ -55471,7 +55508,7 @@
/obj/effect/turf_decal/trimline/purple/filled/line{
dir = 1
},
-/obj/machinery/lapvend,
+/obj/machinery/vending/robotics,
/turf/open/floor/iron/white,
/area/station/science/lobby)
"sSH" = (
@@ -59937,7 +59974,7 @@
/turf/open/floor/iron/cafeteria,
/area/station/commons/dorms/laundry)
"urO" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/machinery/power/apc/auto_name/directional/east,
/obj/structure/cable,
@@ -60926,7 +60963,7 @@
/turf/open/floor/iron/dark,
/area/station/science/xenobiology)
"uGL" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/bot,
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 4
@@ -61822,7 +61859,7 @@
/obj/structure/table/glass,
/obj/effect/turf_decal/trimline/blue/filled/line,
/obj/item/radio/intercom/directional/south,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/turf/open/floor/iron/white,
/area/station/medical/surgery/fore)
"uWn" = (
@@ -63196,7 +63233,7 @@
/turf/open/floor/iron/cafeteria,
/area/station/service/kitchen)
"vuO" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/turf/open/floor/iron/white,
/area/station/security/execution/education)
"vuT" = (
@@ -67670,6 +67707,7 @@
"xfW" = (
/obj/structure/table,
/obj/item/mod/module/plasma_stabilizer,
+/obj/item/mod/module/signlang_radio,
/obj/item/mod/module/thermal_regulator,
/turf/open/floor/iron,
/area/station/security/office)
@@ -69509,7 +69547,9 @@
/turf/open/floor/iron/dark,
/area/station/hallway/secondary/exit)
"xRJ" = (
-/obj/structure/bed,
+/obj/structure/bed/medical/emergency{
+ dir = 4
+ },
/obj/effect/turf_decal/trimline/red/filled/line,
/obj/machinery/light/cold/directional/south,
/turf/open/floor/iron/white,
@@ -83568,7 +83608,7 @@ jWs
cuM
uUD
cWF
-rnm
+frL
ajM
ona
cWF
@@ -84339,9 +84379,9 @@ jWs
cuM
uUD
cWF
-fIH
+qTt
eTl
-kwG
+qwV
cWF
udO
lrq
@@ -102910,7 +102950,7 @@ dor
fSp
vKv
roB
-mjX
+axh
iHK
bAK
jsW
@@ -172545,7 +172585,7 @@ hiZ
wTP
sFA
uKP
-nQv
+qtQ
qfS
gNN
whz
diff --git a/_maps/shuttles/emergency_asteroid.dmm b/_maps/shuttles/emergency_asteroid.dmm
index 997d1d1330e..9bfcf599bb2 100644
--- a/_maps/shuttles/emergency_asteroid.dmm
+++ b/_maps/shuttles/emergency_asteroid.dmm
@@ -106,7 +106,7 @@
/turf/open/floor/mineral/titanium/blue,
/area/shuttle/escape)
"aN" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/turf/open/floor/mineral/titanium/blue,
/area/shuttle/escape)
"aR" = (
diff --git a/_maps/shuttles/emergency_birdshot.dmm b/_maps/shuttles/emergency_birdshot.dmm
index ca46d531d81..20ffeb679d7 100644
--- a/_maps/shuttles/emergency_birdshot.dmm
+++ b/_maps/shuttles/emergency_birdshot.dmm
@@ -440,7 +440,7 @@
/area/shuttle/escape/brig)
"tH" = (
/obj/item/trash/pistachios,
-/obj/item/roller{
+/obj/item/emergency_bed{
pixel_x = -5
},
/turf/open/floor/mineral/titanium/white,
@@ -751,7 +751,7 @@
/area/shuttle/escape)
"Ko" = (
/obj/structure/table/optable,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/item/clothing/mask/surgical,
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/mineral/titanium/white,
diff --git a/_maps/shuttles/emergency_delta.dmm b/_maps/shuttles/emergency_delta.dmm
index 14a6c123b85..f2102147313 100644
--- a/_maps/shuttles/emergency_delta.dmm
+++ b/_maps/shuttles/emergency_delta.dmm
@@ -309,7 +309,7 @@
/turf/open/floor/iron/white,
/area/shuttle/escape)
"aL" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/effect/turf_decal/tile/blue/half/contrasted,
/turf/open/floor/iron/white,
@@ -319,7 +319,7 @@
/turf/open/floor/iron/white,
/area/shuttle/escape)
"aN" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/structure/extinguisher_cabinet/directional/east,
/obj/machinery/light/small/directional/east,
diff --git a/_maps/shuttles/emergency_donut.dmm b/_maps/shuttles/emergency_donut.dmm
index 664a70f1e1c..67dc9f62da7 100644
--- a/_maps/shuttles/emergency_donut.dmm
+++ b/_maps/shuttles/emergency_donut.dmm
@@ -317,7 +317,7 @@
/turf/open/floor/plating/airless,
/area/shuttle/escape)
"ed" = (
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/item/clothing/suit/apron/surgical,
/obj/item/clothing/mask/surgical,
/obj/structure/table/optable,
diff --git a/_maps/shuttles/emergency_fish.dmm b/_maps/shuttles/emergency_fish.dmm
index 9d337de48c6..99e9848a0b0 100644
--- a/_maps/shuttles/emergency_fish.dmm
+++ b/_maps/shuttles/emergency_fish.dmm
@@ -849,7 +849,7 @@
/area/shuttle/escape)
"VD" = (
/obj/structure/table/glass,
-/obj/item/storage/backpack/duffelbag/med/surgery{
+/obj/item/surgery_tray/full{
pixel_y = 6
},
/obj/effect/turf_decal/tile/blue/anticorner/contrasted{
diff --git a/_maps/shuttles/emergency_humpback.dmm b/_maps/shuttles/emergency_humpback.dmm
new file mode 100644
index 00000000000..f4c50bf6b84
--- /dev/null
+++ b/_maps/shuttles/emergency_humpback.dmm
@@ -0,0 +1,1308 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"ao" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/visible,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape/brig)
+"at" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on{
+ dir = 1
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"bL" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape/brig)
+"bS" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/obj/structure/chair/comfy/shuttle,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"bT" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"cK" = (
+/turf/open/floor/iron/smooth_half/airless,
+/area/shuttle/escape)
+"df" = (
+/obj/machinery/door/airlock/external,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/obj/effect/turf_decal/siding/blue,
+/obj/effect/mapping_helpers/airlock/access/all/command/general,
+/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
+ cycle_id = "evac3"
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"dl" = (
+/obj/structure/chair/sofa/right{
+ dir = 4
+ },
+/turf/open/floor/iron/smooth,
+/area/shuttle/escape)
+"dF" = (
+/obj/machinery/power/shuttle_engine/propulsion{
+ dir = 1
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/turf/open/floor/plating/airless,
+/area/shuttle/escape/brig)
+"dP" = (
+/obj/structure/table/reinforced/plastitaniumglass,
+/obj/effect/spawner/random/food_or_drink/booze,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"ed" = (
+/obj/structure/table,
+/obj/item/storage/medkit/regular,
+/obj/item/storage/medkit/toxin{
+ pixel_x = 4;
+ pixel_y = 4
+ },
+/turf/open/floor/wood/large,
+/area/shuttle/escape)
+"ez" = (
+/obj/machinery/door/airlock/public/glass{
+ name = "Cyborg Bay"
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"eK" = (
+/obj/structure/window/reinforced/spawner/directional/south,
+/obj/machinery/power/shuttle_engine/heater{
+ dir = 1
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/turf/open/floor/plating/airless,
+/area/shuttle/escape)
+"eU" = (
+/obj/machinery/door/airlock/external/glass,
+/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
+ cycle_id = "evac3"
+ },
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"eW" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/obj/machinery/status_display/evac/directional/east,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"fu" = (
+/obj/machinery/computer/emergency_shuttle{
+ dir = 1
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"gL" = (
+/obj/machinery/door/airlock/security/glass{
+ name = "Escape Shuttle Brig"
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/obj/effect/mapping_helpers/airlock/access/all/security/general,
+/obj/effect/mapping_helpers/airlock/cyclelink_helper,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape/brig)
+"gW" = (
+/obj/structure/window/reinforced/plasma/spawner/directional/east,
+/obj/machinery/vending/boozeomat/all_access,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"hd" = (
+/obj/machinery/atmospherics/components/binary/pump/on/supply{
+ dir = 4
+ },
+/obj/structure/extinguisher_cabinet/directional/south,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape/brig)
+"he" = (
+/obj/machinery/vending/wallmed/directional/east,
+/turf/open/floor/wood/large,
+/area/shuttle/escape)
+"hk" = (
+/obj/machinery/light/directional/north,
+/obj/structure/table,
+/obj/machinery/recharger,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape/brig)
+"hp" = (
+/obj/structure/lattice/catwalk,
+/turf/template_noop,
+/area/shuttle/escape)
+"hs" = (
+/obj/effect/turf_decal/siding/wood,
+/turf/open/floor/iron/showroomfloor,
+/area/shuttle/escape)
+"hA" = (
+/turf/open/floor/iron/smooth_half/airless{
+ dir = 1
+ },
+/area/shuttle/escape)
+"ig" = (
+/obj/structure/chair/comfy/shuttle{
+ dir = 8
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"iW" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/obj/structure/chair/comfy/shuttle,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"ji" = (
+/obj/machinery/door/airlock/external,
+/obj/effect/turf_decal/siding/blue,
+/obj/effect/mapping_helpers/airlock/access/all/command/general,
+/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
+ cycle_id = "evac3"
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"jJ" = (
+/obj/machinery/computer/arcade/orion_trail{
+ dir = 1
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"kB" = (
+/obj/machinery/door/airlock/external,
+/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
+ cycle_id = "evac3"
+ },
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"kZ" = (
+/obj/structure/table,
+/obj/item/storage/medkit/fire,
+/obj/item/storage/medkit/brute{
+ pixel_x = 4;
+ pixel_y = 4
+ },
+/turf/open/floor/wood/large,
+/area/shuttle/escape)
+"my" = (
+/obj/machinery/computer/security{
+ dir = 4
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"mF" = (
+/obj/effect/spawner/structure/window/reinforced/plasma/plastitanium,
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"mI" = (
+/obj/structure/lattice/catwalk,
+/obj/structure/railing{
+ dir = 8
+ },
+/obj/structure/chair/plastic{
+ dir = 8
+ },
+/turf/template_noop,
+/area/shuttle/escape)
+"mO" = (
+/obj/structure/lattice/catwalk,
+/obj/machinery/light/small/dim/directional/east,
+/turf/template_noop,
+/area/shuttle/escape)
+"nm" = (
+/obj/structure/chair/stool/directional/south,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"ns" = (
+/obj/structure/table/reinforced/plastitaniumglass,
+/obj/machinery/cell_charger,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"nG" = (
+/turf/open/floor/wood/large,
+/area/shuttle/escape)
+"nQ" = (
+/turf/closed/wall/mineral/plastitanium/nodiagonal,
+/area/shuttle/escape/brig)
+"oj" = (
+/obj/structure/table/reinforced/plastitaniumglass,
+/obj/item/storage/fancy/donut_box,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"oO" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/turf/open/floor/iron/smooth,
+/area/shuttle/escape)
+"oP" = (
+/obj/structure/window/reinforced/plasma/spawner/directional/west,
+/obj/structure/table/reinforced/plastitaniumglass,
+/obj/machinery/chem_dispenser/drinks{
+ dir = 4
+ },
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"po" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/turf/open/floor/iron/smooth_corner/airless,
+/area/shuttle/escape)
+"pE" = (
+/obj/machinery/door/window/brigdoor/left/directional/east,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"qp" = (
+/obj/machinery/recharge_station,
+/obj/machinery/light/small/directional/south,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"qP" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/obj/machinery/light/small/dim/directional/west,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"rr" = (
+/obj/structure/chair/comfy/shuttle{
+ dir = 4
+ },
+/obj/machinery/status_display/evac/directional/west,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"rt" = (
+/obj/machinery/power/shuttle_engine/propulsion{
+ dir = 1
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/turf/open/floor/plating/airless,
+/area/shuttle/escape)
+"rw" = (
+/obj/machinery/computer/crew{
+ dir = 1
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"ry" = (
+/obj/structure/table,
+/obj/item/trash/chips,
+/turf/open/floor/iron/smooth,
+/area/shuttle/escape)
+"rA" = (
+/obj/structure/chair/comfy/shuttle{
+ dir = 4
+ },
+/obj/machinery/vending/wallmed/directional/west,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"rL" = (
+/obj/structure/lattice/catwalk,
+/obj/structure/marker_beacon/jade,
+/turf/template_noop,
+/area/shuttle/escape)
+"sQ" = (
+/obj/structure/window/reinforced/plasma/spawner/directional/south,
+/obj/structure/window/reinforced/plasma/spawner/directional/east,
+/obj/structure/window/reinforced/plasma/spawner/directional/west,
+/obj/structure/window/reinforced/plasma/spawner/directional/north,
+/obj/structure/bonfire/prelit,
+/obj/machinery/atmospherics/components/unary/vent_pump/on{
+ dir = 8
+ },
+/turf/open/floor/iron/smooth_corner/airless{
+ dir = 1
+ },
+/area/shuttle/escape)
+"tY" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/obj/machinery/button/flasher{
+ pixel_y = 26;
+ pixel_x = 26;
+ id = "evacflash"
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"uw" = (
+/obj/machinery/computer/atmos_control/air_tank{
+ atmos_chambers = list("evacair" = "Mixed Air Supply")
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape/brig)
+"uW" = (
+/obj/machinery/recharge_station,
+/obj/structure/extinguisher_cabinet/directional/south,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"vk" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/turf/open/floor/iron/smooth_half/airless,
+/area/shuttle/escape)
+"vn" = (
+/obj/structure/window/reinforced/spawner/directional/south,
+/obj/machinery/power/shuttle_engine/heater{
+ dir = 1
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/turf/open/floor/plating/airless,
+/area/shuttle/escape/brig)
+"vw" = (
+/turf/template_noop,
+/area/template_noop)
+"vF" = (
+/obj/structure/chair/stool/bar/directional/south{
+ can_buckle = 1
+ },
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"vO" = (
+/obj/structure/closet,
+/obj/item/multitool,
+/obj/effect/spawner/random/engineering/toolbox,
+/obj/machinery/light/small/directional/north,
+/obj/effect/spawner/random/contraband/narcotics,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"vR" = (
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"wf" = (
+/obj/machinery/door/airlock/mining/glass{
+ name = "Emergency Shuttle Cargo Hold"
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"xb" = (
+/obj/structure/sign/departments/medbay/alt,
+/turf/closed/wall/mineral/plastitanium/nodiagonal,
+/area/shuttle/escape/brig)
+"xy" = (
+/obj/machinery/suit_storage_unit/standard_unit,
+/obj/machinery/light/small/dim/directional/east,
+/obj/effect/turf_decal/stripes/line,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"yc" = (
+/obj/structure/statue/gold/hos,
+/obj/machinery/light/floor,
+/turf/open/floor/mineral/diamond,
+/area/shuttle/escape)
+"yh" = (
+/obj/structure/lattice/catwalk,
+/obj/structure/railing{
+ dir = 8
+ },
+/obj/structure/table,
+/obj/item/binoculars,
+/turf/template_noop,
+/area/shuttle/escape)
+"yH" = (
+/obj/structure/chair/sofa/middle{
+ dir = 4
+ },
+/obj/machinery/light/directional/west,
+/turf/open/floor/iron/smooth,
+/area/shuttle/escape)
+"yN" = (
+/obj/machinery/door/airlock/grunge{
+ name = "Emergency Shuttle Airlock"
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"zn" = (
+/obj/structure/table,
+/obj/item/surgery_tray/full,
+/turf/open/floor/iron/showroomfloor,
+/area/shuttle/escape)
+"zr" = (
+/obj/structure/railing{
+ dir = 4
+ },
+/turf/open/floor/iron/smooth_half/airless{
+ dir = 1
+ },
+/area/shuttle/escape)
+"zG" = (
+/obj/machinery/chem_master,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"zH" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"zZ" = (
+/obj/structure/table/reinforced/plastitaniumglass,
+/obj/machinery/recharger,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"Af" = (
+/obj/structure/chair/comfy/shuttle{
+ dir = 4
+ },
+/obj/machinery/light/dim/directional/west,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"Ax" = (
+/obj/structure/railing/corner,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/turf/open/floor/iron/smooth_half/airless{
+ dir = 4
+ },
+/area/shuttle/escape)
+"AA" = (
+/obj/machinery/suit_storage_unit/standard_unit,
+/obj/effect/turf_decal/stripes/line,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"Bu" = (
+/obj/structure/chair/comfy/shuttle{
+ dir = 8
+ },
+/obj/structure/extinguisher_cabinet/directional/east,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"Ch" = (
+/obj/structure/chair/sofa/left{
+ dir = 4
+ },
+/turf/open/floor/iron/smooth,
+/area/shuttle/escape)
+"Cl" = (
+/obj/machinery/door/airlock/medical/glass{
+ name = "Medbay"
+ },
+/obj/effect/turf_decal/siding/wood,
+/turf/open/floor/wood/large,
+/area/shuttle/escape)
+"CA" = (
+/obj/effect/spawner/random/structure/crate_loot,
+/obj/effect/spawner/random/maintenance/seven,
+/obj/item/reagent_containers/pill/maintenance,
+/obj/item/reagent_containers/pill/maintenance,
+/obj/item/reagent_containers/pill/maintenance,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"CH" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on{
+ dir = 8
+ },
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"CW" = (
+/obj/structure/railing{
+ dir = 4
+ },
+/obj/structure/table,
+/obj/item/binoculars,
+/turf/open/floor/iron/smooth_corner/airless{
+ dir = 1
+ },
+/area/shuttle/escape)
+"Df" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on{
+ dir = 1
+ },
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"Dj" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon/monitored/air_output{
+ dir = 1;
+ chamber_id = "evacair"
+ },
+/obj/machinery/light/small/directional/east,
+/turf/open/floor/engine/air,
+/area/shuttle/escape/brig)
+"Ef" = (
+/obj/machinery/smartfridge/chemistry/preloaded,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"EJ" = (
+/obj/effect/turf_decal/siding/wood,
+/obj/structure/extinguisher_cabinet/directional/west,
+/turf/open/floor/iron/showroomfloor,
+/area/shuttle/escape)
+"EO" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"Fw" = (
+/obj/machinery/door/airlock/external/glass,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
+ cycle_id = "evac3"
+ },
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"FG" = (
+/obj/machinery/door/airlock/security/glass{
+ name = "Escape Shuttle Brig"
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/obj/effect/mapping_helpers/airlock/access/all/security/general,
+/obj/effect/turf_decal/stripes/line,
+/obj/effect/mapping_helpers/airlock/cyclelink_helper{
+ dir = 1
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape/brig)
+"FZ" = (
+/obj/structure/railing/corner,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/turf/open/floor/iron/smooth_half/airless{
+ dir = 1
+ },
+/area/shuttle/escape)
+"GR" = (
+/turf/open/floor/iron/smooth,
+/area/shuttle/escape)
+"IB" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/turf/open/floor/mineral/diamond,
+/area/shuttle/escape)
+"JB" = (
+/obj/machinery/suit_storage_unit/standard_unit,
+/obj/effect/turf_decal/stripes/line{
+ dir = 4
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"JW" = (
+/obj/machinery/light/directional/north,
+/obj/machinery/computer/operating,
+/turf/open/floor/iron/showroomfloor,
+/area/shuttle/escape)
+"Kf" = (
+/obj/structure/table/reinforced/plastitaniumglass,
+/obj/item/storage/box/drinkingglasses,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"Ko" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/obj/machinery/airalarm/directional/east,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"Kv" = (
+/obj/structure/tank_dispenser/oxygen,
+/obj/machinery/light/small/directional/west,
+/obj/effect/turf_decal/stripes/line{
+ dir = 4
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"KP" = (
+/obj/structure/window/reinforced/plasma/spawner/directional/west,
+/obj/structure/table/reinforced/plastitaniumglass,
+/obj/machinery/reagentgrinder,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"KX" = (
+/obj/effect/spawner/structure/window/reinforced/plasma/plastitanium,
+/turf/open/floor/plating,
+/area/shuttle/escape/brig)
+"Lk" = (
+/obj/structure/statue/diamond/ai2,
+/obj/machinery/light/floor,
+/turf/open/floor/mineral/diamond,
+/area/shuttle/escape)
+"Lp" = (
+/obj/structure/closet/crate/secure/loot,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"LB" = (
+/obj/machinery/door/airlock/command{
+ name = "Cockpit"
+ },
+/obj/effect/mapping_helpers/airlock/access/all/command/general,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/obj/effect/turf_decal/siding/dark{
+ dir = 1
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"LC" = (
+/obj/structure/chair/comfy/shuttle{
+ dir = 1
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"LN" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"LY" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/obj/machinery/flasher/directional/east{
+ id = "evacflash"
+ },
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"MP" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/obj/machinery/status_display/evac/directional/west,
+/turf/open/floor/wood/large,
+/area/shuttle/escape)
+"MU" = (
+/obj/machinery/door/airlock/external,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
+ cycle_id = "evac3"
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"MY" = (
+/obj/structure/railing/corner/end/flip,
+/obj/structure/railing/corner/end{
+ dir = 1
+ },
+/turf/open/floor/iron/smooth_half/airless{
+ dir = 1
+ },
+/area/shuttle/escape)
+"NR" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on{
+ dir = 4
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape/brig)
+"Oj" = (
+/turf/closed/wall/mineral/plastitanium,
+/area/shuttle/escape)
+"Oo" = (
+/obj/structure/chair/comfy/shuttle{
+ dir = 8
+ },
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"Oq" = (
+/obj/effect/spawner/structure/window/reinforced/plasma/plastitanium,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/visible,
+/turf/open/floor/plating,
+/area/shuttle/escape/brig)
+"Ot" = (
+/obj/machinery/door/airlock/external,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
+ cycle_id = "evac3"
+ },
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"OO" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/turf/open/floor/wood/large,
+/area/shuttle/escape)
+"Pt" = (
+/obj/machinery/stasis,
+/turf/open/floor/iron/showroomfloor,
+/area/shuttle/escape)
+"PS" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on{
+ dir = 8
+ },
+/turf/open/floor/wood/large,
+/area/shuttle/escape)
+"PX" = (
+/obj/structure/chair/comfy/shuttle,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"Qe" = (
+/obj/machinery/light/directional/north,
+/obj/machinery/atmospherics/components/unary/vent_pump/on,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"Sl" = (
+/turf/closed/wall/mineral/plastitanium/nodiagonal,
+/area/shuttle/escape)
+"Sx" = (
+/obj/structure/table/optable,
+/turf/open/floor/iron/showroomfloor,
+/area/shuttle/escape)
+"SC" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/obj/structure/extinguisher_cabinet/directional/west,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"SJ" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/obj/machinery/light/directional/west,
+/obj/machinery/vending/cigarette,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"Ta" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on{
+ dir = 4
+ },
+/turf/open/floor/mineral/diamond,
+/area/shuttle/escape)
+"Te" = (
+/turf/closed/wall/mineral/plastitanium,
+/area/shuttle/escape/brig)
+"Ty" = (
+/obj/machinery/door/airlock/grunge{
+ name = "Emergency Shuttle Airlock"
+ },
+/obj/docking_port/mobile/emergency,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"UR" = (
+/obj/machinery/status_display/evac/directional/north,
+/turf/open/floor/iron/smooth,
+/area/shuttle/escape)
+"VH" = (
+/obj/structure/railing,
+/turf/open/floor/iron/smooth_corner/airless{
+ dir = 1
+ },
+/area/shuttle/escape)
+"VL" = (
+/obj/machinery/door/airlock/external,
+/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
+ cycle_id = "evac3"
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"WG" = (
+/obj/structure/chair/comfy/shuttle,
+/obj/item/restraints/handcuffs,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape/brig)
+"Xh" = (
+/obj/structure/window/reinforced/plasma/spawner/directional/west,
+/obj/structure/table/reinforced/plastitaniumglass,
+/obj/machinery/chem_dispenser/drinks/beer{
+ dir = 4
+ },
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"Xi" = (
+/obj/structure/window/reinforced/plasma/spawner/directional/east,
+/obj/machinery/light/directional/south,
+/obj/structure/closet/cabinet,
+/obj/item/reagent_containers/cup/glass/shaker,
+/obj/item/storage/fancy/cigarettes/cigars/havana,
+/obj/item/instrument/guitar,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/escape)
+"Xv" = (
+/obj/machinery/door/airlock/external/glass,
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"XQ" = (
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"Ys" = (
+/obj/machinery/computer/communications{
+ dir = 1
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"YF" = (
+/obj/machinery/air_sensor/air_tank{
+ chamber_id = "evacair"
+ },
+/turf/open/floor/engine/air,
+/area/shuttle/escape/brig)
+"Zs" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
+/obj/structure/extinguisher_cabinet/directional/east,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"ZG" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 4
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+"ZR" = (
+/obj/machinery/light/directional/west,
+/obj/structure/chair/comfy/shuttle{
+ dir = 4
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/escape)
+
+(1,1,1) = {"
+vw
+Te
+Te
+Te
+Te
+KX
+nQ
+yN
+Sl
+Ty
+Sl
+mI
+yh
+Sl
+Oj
+yN
+Sl
+yN
+Sl
+Sl
+Oj
+vw
+vw
+vw
+vw
+vw
+"}
+(2,1,1) = {"
+dF
+vn
+WG
+NR
+KX
+YF
+KX
+XQ
+Oj
+XQ
+mF
+hp
+hp
+mF
+SJ
+LN
+ez
+LN
+at
+qp
+Sl
+vw
+vw
+vw
+vw
+vw
+"}
+(3,1,1) = {"
+dF
+vn
+WG
+ao
+Oq
+Dj
+KX
+XQ
+ZR
+XQ
+mF
+hp
+mO
+mF
+iW
+XQ
+Sl
+ns
+XQ
+uW
+Sl
+vw
+vw
+vw
+vw
+vw
+"}
+(4,1,1) = {"
+Te
+nQ
+hk
+hd
+Te
+Te
+nQ
+ZG
+ZG
+ZG
+Sl
+Xv
+Oj
+Sl
+bS
+ZG
+Sl
+Xh
+oP
+KP
+Sl
+Sl
+mF
+mF
+mF
+vw
+"}
+(5,1,1) = {"
+dF
+vn
+uw
+ao
+gL
+bL
+FG
+EO
+vR
+vR
+rr
+vR
+Af
+rA
+EO
+vF
+dP
+vR
+vR
+Kf
+mF
+oj
+my
+zZ
+mF
+mF
+"}
+(6,1,1) = {"
+dF
+vn
+nQ
+Te
+Te
+Te
+xb
+EO
+EO
+EO
+EO
+EO
+EO
+vR
+EO
+vF
+dP
+zH
+EO
+zG
+mF
+XQ
+ig
+XQ
+rw
+mF
+"}
+(7,1,1) = {"
+rt
+eK
+Pt
+EJ
+MP
+OO
+Cl
+EO
+CH
+vR
+vR
+vR
+EO
+EO
+EO
+Df
+Sl
+gW
+pE
+Xi
+Sl
+Qe
+LN
+PX
+fu
+mF
+"}
+(8,1,1) = {"
+rt
+eK
+Pt
+hs
+OO
+nG
+mF
+vR
+vR
+Oo
+Bu
+Oo
+EO
+Oo
+Ko
+EO
+EO
+eW
+EO
+LY
+LB
+tY
+Zs
+XQ
+Ys
+mF
+"}
+(9,1,1) = {"
+Oj
+Sl
+JW
+hs
+PS
+nG
+Ef
+bT
+LC
+Sl
+Sl
+Sl
+wf
+Sl
+Sl
+Oj
+Oj
+Oj
+Oj
+Oj
+Sl
+mF
+Sl
+mF
+mF
+mF
+"}
+(10,1,1) = {"
+rt
+eK
+Sx
+hs
+nG
+ed
+Sl
+nm
+jJ
+Sl
+CA
+SC
+EO
+Sl
+ry
+Ch
+yH
+dl
+GR
+cK
+VL
+XQ
+ji
+Ta
+Lk
+mF
+"}
+(11,1,1) = {"
+rt
+eK
+zn
+hs
+he
+kZ
+Oj
+Sl
+Sl
+Oj
+vO
+EO
+Lp
+Oj
+UR
+GR
+oO
+oO
+oO
+vk
+MU
+LN
+df
+IB
+yc
+mF
+"}
+(12,1,1) = {"
+vw
+Oj
+Oj
+Oj
+Oj
+Oj
+Oj
+JB
+Kv
+Oj
+Oj
+wf
+Oj
+Sl
+GR
+po
+FZ
+zr
+MY
+CW
+Sl
+mF
+Sl
+mF
+mF
+mF
+"}
+(13,1,1) = {"
+vw
+vw
+vw
+vw
+rt
+eK
+AA
+zH
+EO
+Fw
+qP
+EO
+qP
+Ot
+oO
+Ax
+sQ
+vw
+rL
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+"}
+(14,1,1) = {"
+vw
+vw
+vw
+vw
+rt
+eK
+xy
+vR
+vR
+eU
+vR
+CH
+vR
+kB
+hA
+VH
+vw
+vw
+hp
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+"}
+(15,1,1) = {"
+vw
+vw
+vw
+vw
+vw
+Oj
+Sl
+kB
+kB
+Sl
+mF
+mF
+mF
+Sl
+Oj
+mF
+vw
+vw
+rL
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+"}
+(16,1,1) = {"
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+hp
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+"}
+(17,1,1) = {"
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+rL
+vw
+vw
+vw
+vw
+vw
+vw
+vw
+"}
diff --git a/_maps/shuttles/emergency_lance.dmm b/_maps/shuttles/emergency_lance.dmm
index ff0dc795797..c6c0d9d9c18 100644
--- a/_maps/shuttles/emergency_lance.dmm
+++ b/_maps/shuttles/emergency_lance.dmm
@@ -370,7 +370,7 @@
/area/shuttle/escape)
"kx" = (
/obj/machinery/iv_drip,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/tile/dark_blue/half/contrasted,
/obj/machinery/light/directional/north,
/turf/open/floor/iron/dark/side{
@@ -387,7 +387,7 @@
},
/area/shuttle/escape/brig)
"kN" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/structure/extinguisher_cabinet/directional/west,
/obj/effect/mapping_helpers/broken_floor,
@@ -967,8 +967,8 @@
/obj/item/book/manual/wiki/surgery{
pixel_x = -15
},
-/obj/item/storage/backpack/duffelbag/med/surgery,
-/obj/item/storage/backpack/duffelbag/med/surgery{
+/obj/item/surgery_tray/full,
+/obj/item/surgery_tray/full{
pixel_x = 5
},
/obj/effect/turf_decal/tile/dark_blue/half/contrasted{
@@ -1250,7 +1250,7 @@
"MC" = (
/obj/structure/extinguisher_cabinet/directional/north,
/obj/machinery/iv_drip,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/tile/dark_blue/half/contrasted,
/turf/open/floor/iron/dark/side{
dir = 1
@@ -1577,7 +1577,7 @@
/turf/open/floor/iron/dark/textured,
/area/shuttle/escape)
"Xz" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/turf/open/floor/iron/dark/textured,
/area/shuttle/escape)
diff --git a/_maps/shuttles/emergency_lima.dmm b/_maps/shuttles/emergency_lima.dmm
index ee19a4a22dc..a5e265684e1 100644
--- a/_maps/shuttles/emergency_lima.dmm
+++ b/_maps/shuttles/emergency_lima.dmm
@@ -68,7 +68,7 @@
/turf/open/floor/mineral/titanium/white,
/area/shuttle/escape)
"gN" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/structure/extinguisher_cabinet{
pixel_y = -30
},
diff --git a/_maps/shuttles/emergency_medisim.dmm b/_maps/shuttles/emergency_medisim.dmm
index 04779fedacb..7689bed7306 100644
--- a/_maps/shuttles/emergency_medisim.dmm
+++ b/_maps/shuttles/emergency_medisim.dmm
@@ -519,14 +519,13 @@
/turf/template_noop,
/area/shuttle/escape)
"un" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/turf/open/floor/mineral/titanium/tiled/blue,
/area/shuttle/escape)
"uG" = (
-/obj/structure/bed/pod{
- desc = "An old medical bed, just waiting for replacement with something up to date.";
- name = "medical bed"
+/obj/structure/bed/medical{
+ dir = 4
},
/obj/structure/curtain,
/turf/open/floor/mineral/titanium/tiled/blue,
diff --git a/_maps/shuttles/emergency_mini.dmm b/_maps/shuttles/emergency_mini.dmm
index 5bad5050e77..73c5f42b38f 100644
--- a/_maps/shuttles/emergency_mini.dmm
+++ b/_maps/shuttles/emergency_mini.dmm
@@ -227,7 +227,7 @@
"W" = (
/obj/structure/table,
/obj/item/clothing/suit/apron/surgical,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/turf/open/floor/mineral/titanium/white,
/area/shuttle/escape)
"X" = (
diff --git a/_maps/shuttles/emergency_nature.dmm b/_maps/shuttles/emergency_nature.dmm
index c5256bdf6bf..95eada06cfb 100644
--- a/_maps/shuttles/emergency_nature.dmm
+++ b/_maps/shuttles/emergency_nature.dmm
@@ -498,7 +498,7 @@
/area/shuttle/escape)
"sF" = (
/obj/effect/turf_decal/trimline/blue/filled/line,
-/obj/item/storage/backpack/duffelbag/med/surgery{
+/obj/item/surgery_tray/full{
pixel_y = 5
},
/obj/structure/rack,
diff --git a/_maps/shuttles/emergency_northstar.dmm b/_maps/shuttles/emergency_northstar.dmm
index 25616f70dde..20795c72317 100644
--- a/_maps/shuttles/emergency_northstar.dmm
+++ b/_maps/shuttles/emergency_northstar.dmm
@@ -127,7 +127,7 @@
"nC" = (
/obj/structure/table/reinforced/rglass,
/obj/item/defibrillator/loaded,
-/obj/item/storage/backpack/duffelbag/med/surgery{
+/obj/item/surgery_tray/full{
pixel_y = 13
},
/obj/effect/turf_decal/tile/blue/anticorner{
diff --git a/_maps/shuttles/emergency_raven.dmm b/_maps/shuttles/emergency_raven.dmm
index 4345319c2e3..4b12d66baed 100644
--- a/_maps/shuttles/emergency_raven.dmm
+++ b/_maps/shuttles/emergency_raven.dmm
@@ -511,7 +511,7 @@
/area/shuttle/escape)
"by" = (
/obj/machinery/iv_drip,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/turf/open/floor/iron/white/side{
dir = 10
},
diff --git a/_maps/shuttles/emergency_russiafightpit.dmm b/_maps/shuttles/emergency_russiafightpit.dmm
index 020b44e6e14..6d8a0e5e8fb 100644
--- a/_maps/shuttles/emergency_russiafightpit.dmm
+++ b/_maps/shuttles/emergency_russiafightpit.dmm
@@ -438,7 +438,7 @@
"iJ" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/table,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/item/clothing/gloves/fingerless,
/turf/open/floor/iron,
/area/shuttle/escape)
diff --git a/_maps/shuttles/emergency_shadow.dmm b/_maps/shuttles/emergency_shadow.dmm
index 704ec17a369..15593e7e956 100644
--- a/_maps/shuttles/emergency_shadow.dmm
+++ b/_maps/shuttles/emergency_shadow.dmm
@@ -1000,7 +1000,7 @@
"Sb" = (
/obj/structure/table,
/obj/structure/window/reinforced/spawner/directional/west,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/item/clothing/suit/apron/surgical,
/obj/item/clothing/mask/surgical,
/obj/item/clothing/gloves/latex/nitrile{
diff --git a/_maps/shuttles/emergency_tram.dmm b/_maps/shuttles/emergency_tram.dmm
index e827adeb3b9..5ec40d242d6 100644
--- a/_maps/shuttles/emergency_tram.dmm
+++ b/_maps/shuttles/emergency_tram.dmm
@@ -203,7 +203,7 @@
/area/shuttle/escape)
"aX" = (
/obj/structure/table/optable,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/item/clothing/mask/surgical,
/turf/open/floor/mineral/titanium/blue,
/area/shuttle/escape)
diff --git a/_maps/shuttles/emergency_tranquility.dmm b/_maps/shuttles/emergency_tranquility.dmm
index ce1262d35c6..a8a933b5b70 100644
--- a/_maps/shuttles/emergency_tranquility.dmm
+++ b/_maps/shuttles/emergency_tranquility.dmm
@@ -2562,7 +2562,7 @@
/obj/effect/turf_decal/tile/blue/opposingcorners,
/obj/structure/table,
/obj/item/lazarus_injector,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/obj/item/clothing/gloves/latex/nitrile{
pixel_y = 4
},
diff --git a/_maps/shuttles/emergency_venture.dmm b/_maps/shuttles/emergency_venture.dmm
index e57cd3a6eee..6b72f22dc29 100644
--- a/_maps/shuttles/emergency_venture.dmm
+++ b/_maps/shuttles/emergency_venture.dmm
@@ -360,7 +360,7 @@
/turf/open/floor/iron,
/area/shuttle/escape)
"tE" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/tile/blue/anticorner/contrasted{
dir = 1
},
diff --git a/_maps/shuttles/infiltrator_basic.dmm b/_maps/shuttles/infiltrator_basic.dmm
index 68b28c95777..ca3da37f63b 100644
--- a/_maps/shuttles/infiltrator_basic.dmm
+++ b/_maps/shuttles/infiltrator_basic.dmm
@@ -266,7 +266,7 @@
/area/shuttle/syndicate/medical)
"bs" = (
/obj/machinery/light/directional/north,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/effect/turf_decal/siding/thinplating_new{
dir = 4
diff --git a/_maps/shuttles/pirate_Interdyne.dmm b/_maps/shuttles/pirate_ex_interdyne.dmm
similarity index 100%
rename from _maps/shuttles/pirate_Interdyne.dmm
rename to _maps/shuttles/pirate_ex_interdyne.dmm
diff --git a/_maps/shuttles/pirate_irs.dmm b/_maps/shuttles/pirate_irs.dmm
index 23e28743c0d..38067cecaae 100644
--- a/_maps/shuttles/pirate_irs.dmm
+++ b/_maps/shuttles/pirate_irs.dmm
@@ -796,7 +796,7 @@
/obj/effect/turf_decal/trimline/dark_blue/filled/line{
dir = 5
},
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/structure/curtain,
/turf/open/floor/iron/dark,
/area/shuttle/pirate)
@@ -1017,7 +1017,7 @@
/obj/effect/turf_decal/trimline/dark_blue/filled/line{
dir = 4
},
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/structure/curtain,
/turf/open/floor/iron/dark,
/area/shuttle/pirate)
diff --git a/_maps/shuttles/ruin_cyborg_mothership.dmm b/_maps/shuttles/ruin_cyborg_mothership.dmm
index 30fae567714..ac61c9b98df 100644
--- a/_maps/shuttles/ruin_cyborg_mothership.dmm
+++ b/_maps/shuttles/ruin_cyborg_mothership.dmm
@@ -1,13 +1,4 @@
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
-"am" = (
-/obj/structure/lattice/catwalk,
-/obj/structure/spacevine,
-/obj/machinery/shieldgen{
- anchored = 1;
- req_access = null
- },
-/turf/template_noop,
-/area/shuttle/ruin/cyborg_mothership)
"aB" = (
/obj/machinery/conveyor{
dir = 8;
@@ -21,8 +12,7 @@
id = "mothership_main"
},
/obj/machinery/recycler{
- dir = 1;
- eat_dir = 4
+ dir = 8
},
/turf/open/floor/plating/airless,
/area/shuttle/ruin/cyborg_mothership)
@@ -58,6 +48,10 @@
},
/turf/template_noop,
/area/shuttle/ruin/cyborg_mothership)
+"dO" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/circuit/airless,
+/area/shuttle/ruin/cyborg_mothership)
"ey" = (
/obj/structure/table,
/obj/item/toy/talking/ai{
@@ -77,13 +71,6 @@
},
/turf/open/floor/plating/airless,
/area/shuttle/ruin/cyborg_mothership)
-"eQ" = (
-/obj/effect/turf_decal/stripes/asteroid/line{
- dir = 1
- },
-/obj/machinery/light/floor,
-/turf/open/floor/iron/showroomfloor,
-/area/shuttle/ruin/cyborg_mothership)
"fB" = (
/obj/structure/sign/warning/vacuum/external/directional/west,
/obj/structure/closet/emcloset/anchored,
@@ -130,17 +117,24 @@
},
/turf/open/floor/plating/airless,
/area/shuttle/ruin/cyborg_mothership)
+"ir" = (
+/obj/structure/table/optable,
+/obj/effect/turf_decal/bot,
+/turf/open/floor/iron/dark,
+/area/shuttle/ruin/cyborg_mothership)
"iv" = (
/obj/structure/lattice,
/obj/structure/spacevine,
/turf/template_noop,
/area/shuttle/ruin/cyborg_mothership)
-"iD" = (
-/obj/effect/turf_decal/stripes/asteroid/line{
- dir = 1
- },
-/obj/machinery/light/floor/broken,
-/turf/open/floor/iron/showroomfloor,
+"iN" = (
+/obj/structure/table,
+/obj/effect/turf_decal/bot,
+/obj/item/clothing/gloves/latex,
+/obj/item/clothing/mask/surgical,
+/obj/item/razor,
+/obj/structure/mirror/directional/west,
+/turf/open/floor/iron/dark,
/area/shuttle/ruin/cyborg_mothership)
"iO" = (
/obj/machinery/rnd/production/protolathe/offstation,
@@ -150,13 +144,6 @@
},
/turf/open/floor/circuit/airless,
/area/shuttle/ruin/cyborg_mothership)
-"jl" = (
-/obj/item/stack/rods,
-/obj/machinery/button/door/directional/east{
- id = "mothership_right"
- },
-/turf/open/floor/circuit/airless,
-/area/shuttle/ruin/cyborg_mothership)
"jx" = (
/obj/effect/mapping_helpers/burnt_floor,
/obj/effect/turf_decal/stripes/asteroid/line{
@@ -214,6 +201,13 @@
/obj/structure/plasticflaps,
/turf/open/floor/plating/airless,
/area/shuttle/ruin/cyborg_mothership)
+"ms" = (
+/obj/item/stack/rods,
+/obj/machinery/button/door/directional/east{
+ id = "mothership_right"
+ },
+/turf/open/floor/circuit/airless,
+/area/shuttle/ruin/cyborg_mothership)
"mC" = (
/obj/machinery/mineral/ore_redemption/offstation{
input_dir = 4
@@ -221,6 +215,17 @@
/obj/structure/lattice/catwalk,
/turf/open/space/basic,
/area/shuttle/ruin/cyborg_mothership)
+"mG" = (
+/obj/structure/table,
+/obj/item/surgery_tray/full,
+/obj/effect/turf_decal/bot,
+/obj/structure/sink/directional/east,
+/obj/item/toy/figure/borg{
+ pixel_x = 7;
+ pixel_y = 12
+ },
+/turf/open/floor/iron/dark,
+/area/shuttle/ruin/cyborg_mothership)
"mN" = (
/obj/machinery/conveyor{
dir = 4;
@@ -286,17 +291,6 @@
/obj/structure/cable,
/turf/open/floor/plating/airless,
/area/shuttle/ruin/cyborg_mothership)
-"oU" = (
-/mob/living/basic/hivebot/range,
-/turf/open/floor/circuit/airless,
-/area/shuttle/ruin/cyborg_mothership)
-"pe" = (
-/obj/machinery/button/door/directional/west{
- id = "mothership_left"
- },
-/obj/structure/cable,
-/turf/open/floor/circuit/airless,
-/area/shuttle/ruin/cyborg_mothership)
"po" = (
/obj/machinery/door/airlock/hatch,
/obj/structure/cable,
@@ -322,18 +316,6 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/shuttle/ruin/cyborg_mothership)
-"pR" = (
-/obj/machinery/camera/directional/south,
-/obj/structure/cable,
-/obj/machinery/power/apc/auto_name/directional/south{
- environ = 0;
- equipment = 0;
- lighting = 0
- },
-/obj/effect/mapping_helpers/apc/unlocked,
-/obj/machinery/light/cold/no_nightlight/directional/south,
-/turf/open/floor/circuit/airless,
-/area/shuttle/ruin/cyborg_mothership)
"pY" = (
/obj/machinery/recharge_station,
/obj/structure/sign/warning/vacuum/external/directional/east,
@@ -355,6 +337,18 @@
/obj/structure/cable,
/turf/open/floor/plating/airless,
/area/shuttle/ruin/cyborg_mothership)
+"qz" = (
+/obj/machinery/camera/directional/south,
+/obj/structure/cable,
+/obj/machinery/power/apc/auto_name/directional/south{
+ environ = 0;
+ equipment = 0;
+ lighting = 0
+ },
+/obj/effect/mapping_helpers/apc/unlocked,
+/obj/machinery/light/cold/no_nightlight/directional/south,
+/turf/open/floor/circuit/airless,
+/area/shuttle/ruin/cyborg_mothership)
"qV" = (
/obj/structure/spacevine,
/obj/machinery/conveyor{
@@ -375,6 +369,15 @@
},
/turf/open/floor/circuit/airless,
/area/shuttle/ruin/cyborg_mothership)
+"rJ" = (
+/mob/living/basic/hivebot,
+/obj/structure/spacevine,
+/obj/machinery/conveyor{
+ id = "mothership_main"
+ },
+/obj/structure/cable,
+/turf/open/floor/plating/airless,
+/area/shuttle/ruin/cyborg_mothership)
"so" = (
/obj/structure/lattice,
/turf/template_noop,
@@ -454,26 +457,6 @@
/obj/structure/cable,
/turf/open/floor/plating/airless,
/area/shuttle/ruin/cyborg_mothership)
-"xs" = (
-/mob/living/basic/hivebot,
-/obj/structure/spacevine,
-/obj/machinery/conveyor{
- id = "mothership_main"
- },
-/obj/structure/cable,
-/turf/open/floor/plating/airless,
-/area/shuttle/ruin/cyborg_mothership)
-"xz" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/structure/window/reinforced/spawner/directional/north{
- layer = 2.9
- },
-/obj/effect/turf_decal/stripes/asteroid/line{
- dir = 4
- },
-/obj/machinery/power/port_gen/pacman,
-/turf/open/floor/plating/airless,
-/area/shuttle/ruin/cyborg_mothership)
"yd" = (
/obj/effect/mapping_helpers/burnt_floor,
/obj/effect/turf_decal/stripes/asteroid/line{
@@ -488,6 +471,13 @@
},
/turf/open/floor/circuit/airless,
/area/shuttle/ruin/cyborg_mothership)
+"yw" = (
+/obj/effect/turf_decal/stripes/asteroid/line{
+ dir = 1
+ },
+/obj/machinery/light/floor/broken,
+/turf/open/floor/iron/showroomfloor,
+/area/shuttle/ruin/cyborg_mothership)
"yA" = (
/obj/structure/spacevine,
/obj/machinery/conveyor{
@@ -500,14 +490,9 @@
/obj/machinery/status_display/ai,
/turf/closed/wall/mineral/titanium/nodiagonal,
/area/shuttle/ruin/cyborg_mothership)
-"yI" = (
-/obj/structure/table,
-/obj/effect/turf_decal/bot,
-/obj/item/clothing/gloves/latex,
-/obj/item/clothing/mask/surgical,
-/obj/item/razor,
-/obj/structure/mirror/directional/west,
-/turf/open/floor/iron/dark,
+"yG" = (
+/mob/living/basic/hivebot/range,
+/turf/open/floor/circuit/airless,
/area/shuttle/ruin/cyborg_mothership)
"yQ" = (
/obj/item/organ/internal/brain,
@@ -546,12 +531,6 @@
/obj/structure/cable,
/turf/open/floor/plating/airless,
/area/shuttle/ruin/cyborg_mothership)
-"Ba" = (
-/mob/living/basic/hivebot,
-/obj/item/circuitboard/aicore,
-/obj/structure/cable,
-/turf/open/floor/circuit/green/airless,
-/area/shuttle/ruin/cyborg_mothership)
"BD" = (
/obj/structure/cable,
/obj/machinery/power/solar,
@@ -610,6 +589,11 @@
/obj/machinery/camera/directional/south,
/turf/open/floor/iron/showroomfloor,
/area/shuttle/ruin/cyborg_mothership)
+"FQ" = (
+/obj/structure/lattice,
+/mob/living/basic/hivebot/range,
+/turf/template_noop,
+/area/shuttle/ruin/cyborg_mothership)
"Ge" = (
/obj/structure/spacevine,
/obj/machinery/conveyor{
@@ -619,6 +603,15 @@
/obj/structure/cable,
/turf/open/floor/plating/airless,
/area/shuttle/ruin/cyborg_mothership)
+"GF" = (
+/obj/structure/lattice/catwalk,
+/obj/structure/spacevine,
+/obj/machinery/shieldgen{
+ anchored = 1;
+ req_access = null
+ },
+/turf/template_noop,
+/area/shuttle/ruin/cyborg_mothership)
"Hg" = (
/obj/machinery/conveyor{
id = "Recycler"
@@ -626,6 +619,12 @@
/obj/structure/cable,
/turf/open/floor/plating/airless,
/area/shuttle/ruin/cyborg_mothership)
+"HK" = (
+/mob/living/basic/hivebot,
+/obj/item/circuitboard/aicore,
+/obj/structure/cable,
+/turf/open/floor/circuit/green/airless,
+/area/shuttle/ruin/cyborg_mothership)
"HM" = (
/obj/machinery/space_heater{
anchored = 1
@@ -637,11 +636,6 @@
/obj/item/wrench,
/turf/open/floor/plating,
/area/shuttle/ruin/cyborg_mothership)
-"HQ" = (
-/obj/structure/lattice,
-/mob/living/basic/hivebot/range,
-/turf/template_noop,
-/area/shuttle/ruin/cyborg_mothership)
"IS" = (
/obj/structure/lattice,
/obj/machinery/camera/directional/west,
@@ -655,6 +649,11 @@
/obj/structure/cable,
/turf/open/floor/plating/airless,
/area/shuttle/ruin/cyborg_mothership)
+"JJ" = (
+/obj/structure/lattice,
+/mob/living/basic/hivebot/mechanic,
+/turf/template_noop,
+/area/shuttle/ruin/cyborg_mothership)
"Ks" = (
/obj/structure/cable,
/obj/machinery/conveyor/inverted{
@@ -686,11 +685,6 @@
},
/turf/open/floor/circuit/airless,
/area/shuttle/ruin/cyborg_mothership)
-"LT" = (
-/obj/structure/table/optable,
-/obj/effect/turf_decal/bot,
-/turf/open/floor/iron/dark,
-/area/shuttle/ruin/cyborg_mothership)
"MB" = (
/obj/machinery/computer/shuttle/cyborg_mothership{
dir = 1
@@ -721,21 +715,12 @@
/obj/structure/plasticflaps,
/turf/open/floor/iron/showroomfloor,
/area/shuttle/ruin/cyborg_mothership)
-"On" = (
-/obj/structure/lattice,
-/mob/living/basic/hivebot/mechanic,
-/turf/template_noop,
-/area/shuttle/ruin/cyborg_mothership)
-"Oq" = (
-/obj/structure/table,
-/obj/item/storage/backpack/duffelbag/med/surgery,
-/obj/effect/turf_decal/bot,
-/obj/structure/sink/directional/east,
-/obj/item/toy/figure/borg{
- pixel_x = 7;
- pixel_y = 12
+"Nz" = (
+/obj/machinery/button/door/directional/west{
+ id = "mothership_left"
},
-/turf/open/floor/iron/dark,
+/obj/structure/cable,
+/turf/open/floor/circuit/airless,
/area/shuttle/ruin/cyborg_mothership)
"Ou" = (
/obj/machinery/camera/directional/west,
@@ -746,14 +731,6 @@
},
/turf/open/floor/plating/airless,
/area/shuttle/ruin/cyborg_mothership)
-"OA" = (
-/obj/structure/lattice/catwalk,
-/obj/machinery/shieldgen{
- anchored = 1;
- req_access = null
- },
-/turf/template_noop,
-/area/shuttle/ruin/cyborg_mothership)
"OY" = (
/obj/machinery/power/shuttle_engine/heater,
/obj/structure/window/reinforced/spawner/directional/north{
@@ -779,10 +756,6 @@
/obj/machinery/camera/directional/east,
/turf/template_noop,
/area/shuttle/ruin/cyborg_mothership)
-"QO" = (
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/circuit/airless,
-/area/shuttle/ruin/cyborg_mothership)
"Rv" = (
/obj/structure/window/reinforced/spawner/directional/south,
/obj/structure/ore_box,
@@ -814,6 +787,13 @@
},
/turf/open/floor/plating/airless,
/area/shuttle/ruin/cyborg_mothership)
+"Sd" = (
+/obj/effect/turf_decal/stripes/asteroid/line{
+ dir = 1
+ },
+/obj/machinery/light/floor,
+/turf/open/floor/iron/showroomfloor,
+/area/shuttle/ruin/cyborg_mothership)
"SV" = (
/obj/machinery/power/shuttle_engine/heater,
/obj/structure/window/reinforced/spawner/directional/north{
@@ -827,6 +807,17 @@
/obj/item/stack/sheet/mineral/titanium,
/turf/template_noop,
/area/shuttle/ruin/cyborg_mothership)
+"TH" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/window/reinforced/spawner/directional/north{
+ layer = 2.9
+ },
+/obj/effect/turf_decal/stripes/asteroid/line{
+ dir = 4
+ },
+/obj/machinery/power/port_gen/pacman,
+/turf/open/floor/plating/airless,
+/area/shuttle/ruin/cyborg_mothership)
"TZ" = (
/obj/item/radio/intercom/directional/south,
/obj/structure/ai_core,
@@ -930,6 +921,14 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/shuttle/ruin/cyborg_mothership)
+"ZO" = (
+/obj/structure/lattice/catwalk,
+/obj/machinery/shieldgen{
+ anchored = 1;
+ req_access = null
+ },
+/turf/template_noop,
+/area/shuttle/ruin/cyborg_mothership)
(1,1,1) = {"
hR
@@ -991,7 +990,7 @@ hR
hR
hR
hR
-xz
+TH
RD
wA
jx
@@ -1011,7 +1010,7 @@ hR
hR
hR
hR
-am
+GF
oe
oe
oe
@@ -1050,7 +1049,7 @@ of
oe
BD
oe
-OA
+ZO
hR
hR
hR
@@ -1115,7 +1114,7 @@ oR
eO
hR
so
-On
+JJ
so
kz
mp
@@ -1161,13 +1160,13 @@ kz
zZ
zZ
mN
-yI
-Oq
+iN
+mG
zZ
kz
kz
zZ
-pe
+Nz
ww
UL
Uq
@@ -1186,13 +1185,13 @@ yF
fB
zZ
Ey
-eQ
+Sd
Fe
yF
HM
yF
yg
-Ba
+HK
vy
Dv
Ln
@@ -1221,7 +1220,7 @@ ks
TZ
zZ
uK
-pR
+qz
zZ
VU
tr
@@ -1236,7 +1235,7 @@ yF
pY
zZ
Ey
-iD
+yw
bE
yF
hB
@@ -1245,7 +1244,7 @@ dA
Ng
MB
ey
-oU
+yG
Uq
yF
so
@@ -1261,16 +1260,16 @@ kz
zZ
zZ
mN
-LT
+ir
hs
zZ
kz
Em
no
-jl
+ms
pz
Uq
-QO
+dO
zZ
kz
hR
@@ -1338,7 +1337,7 @@ hR
hR
oe
qV
-HQ
+FQ
so
so
hR
@@ -1400,7 +1399,7 @@ MZ
BD
oe
oe
-am
+GF
hR
hR
hR
@@ -1411,14 +1410,14 @@ hR
hR
hR
hR
-OA
+ZO
oe
oe
oe
RV
tW
tW
-xs
+rJ
Jj
tW
Sc
diff --git a/_maps/shuttles/skyrat/emergency_outpost.dmm b/_maps/shuttles/skyrat/emergency_outpost.dmm
index 967a2e09c53..7c210566e08 100644
--- a/_maps/shuttles/skyrat/emergency_outpost.dmm
+++ b/_maps/shuttles/skyrat/emergency_outpost.dmm
@@ -228,7 +228,7 @@
/area/shuttle/escape)
"vD" = (
/obj/structure/table/glass,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/surgery_tray/full,
/turf/open/floor/mineral/titanium/white,
/area/shuttle/escape)
"vI" = (
diff --git a/_maps/shuttles/skyrat/emergency_skyrat.dmm b/_maps/shuttles/skyrat/emergency_skyrat.dmm
index a6eacf1dd4b..fee55c936e9 100644
--- a/_maps/shuttles/skyrat/emergency_skyrat.dmm
+++ b/_maps/shuttles/skyrat/emergency_skyrat.dmm
@@ -96,7 +96,7 @@
/area/shuttle/escape)
"gI" = (
/obj/structure/table/reinforced/rglass,
-/obj/item/storage/backpack/duffelbag/med/surgery{
+/obj/item/surgery_tray/full{
pixel_y = 8
},
/turf/open/floor/iron/dark/textured_large,
diff --git a/_maps/shuttles/whiteship_birdshot.dmm b/_maps/shuttles/whiteship_birdshot.dmm
index 65c3fbc5502..25dc64ed0fc 100644
--- a/_maps/shuttles/whiteship_birdshot.dmm
+++ b/_maps/shuttles/whiteship_birdshot.dmm
@@ -149,7 +149,7 @@
pixel_y = 3
},
/obj/item/reagent_containers/blood,
-/obj/item/storage/backpack/duffelbag/med/surgery{
+/obj/item/surgery_tray/full{
pixel_x = 2;
pixel_y = 9
},
diff --git a/_maps/shuttles/whiteship_box.dmm b/_maps/shuttles/whiteship_box.dmm
index 1fcda0639e1..48d47820df2 100644
--- a/_maps/shuttles/whiteship_box.dmm
+++ b/_maps/shuttles/whiteship_box.dmm
@@ -104,7 +104,7 @@
},
/obj/machinery/airalarm/directional/north,
/obj/effect/mapping_helpers/airalarm/all_access,
-/obj/item/storage/backpack/duffelbag/med/surgery{
+/obj/item/surgery_tray/full{
pixel_y = 4
},
/obj/item/clothing/suit/apron/surgical,
@@ -1212,7 +1212,7 @@
/area/shuttle/abandoned/medbay)
"cF" = (
/obj/effect/decal/cleanable/dirt,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/obj/machinery/light/small/built/directional/north,
/obj/effect/decal/cleanable/blood/old,
@@ -1247,7 +1247,7 @@
"cH" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/dirt,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/turf/open/floor/iron/white/side{
dir = 1
@@ -1555,7 +1555,7 @@
"dk" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/dirt,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/turf/open/floor/iron/white/side{
dir = 10
@@ -1624,7 +1624,7 @@
"dr" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/dirt,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
/turf/open/floor/iron/white/side{
dir = 6
diff --git a/_maps/shuttles/whiteship_delta.dmm b/_maps/shuttles/whiteship_delta.dmm
index c64f0236fa9..2ee3a6e691e 100644
--- a/_maps/shuttles/whiteship_delta.dmm
+++ b/_maps/shuttles/whiteship_delta.dmm
@@ -1623,7 +1623,7 @@
/area/shuttle/abandoned/medbay)
"dO" = (
/obj/structure/table,
-/obj/item/storage/backpack/duffelbag/med/surgery{
+/obj/item/surgery_tray/full{
pixel_y = 4
},
/obj/effect/decal/cleanable/dirt,
@@ -1804,7 +1804,7 @@
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/box/white/corners,
/obj/structure/closet/crate/medical,
-/obj/item/roller{
+/obj/item/emergency_bed{
pixel_y = 4
},
/obj/item/healthanalyzer,
diff --git a/_maps/shuttles/whiteship_obelisk.dmm b/_maps/shuttles/whiteship_obelisk.dmm
index edf3e2a1adb..ec9697103d9 100644
--- a/_maps/shuttles/whiteship_obelisk.dmm
+++ b/_maps/shuttles/whiteship_obelisk.dmm
@@ -704,7 +704,7 @@
/turf/open/floor/mineral/titanium/white,
/area/shuttle/abandoned/medbay)
"Ow" = (
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/turf/open/floor/mineral/titanium/white,
/area/shuttle/abandoned/medbay)
"Ph" = (
diff --git a/_maps/shuttles/zubbers/emergency_burgerstation.dmm b/_maps/shuttles/zubbers/emergency_burgerstation.dmm
index 376d8f3ddf6..ecd8942509d 100644
--- a/_maps/shuttles/zubbers/emergency_burgerstation.dmm
+++ b/_maps/shuttles/zubbers/emergency_burgerstation.dmm
@@ -290,7 +290,7 @@
/area/shuttle/escape)
"kE" = (
/obj/machinery/door/window/right/directional/south,
-/mob/living/simple_animal/hostile/retaliate/clown/longface{
+/mob/living/basic/clown/longface{
name = "In-Flight Entertainment";
pixel_y = 4;
unique_name = 1
@@ -437,7 +437,7 @@
/area/shuttle/escape)
"nO" = (
/obj/structure/table/glass,
-/obj/item/storage/backpack/duffelbag/med/surgery{
+/obj/item/surgery_tray/full{
pixel_y = 6
},
/turf/open/floor/mineral/titanium/tiled/blue,
diff --git a/_maps/skyrat/automapper/automapper_config.toml b/_maps/skyrat/automapper/automapper_config.toml
index dcd437425ae..087b6d224e6 100644
--- a/_maps/skyrat/automapper/automapper_config.toml
+++ b/_maps/skyrat/automapper/automapper_config.toml
@@ -114,7 +114,7 @@ trait_name = "Station"
map_files = ["icebox_arrivals.dmm"]
directory = "_maps/skyrat/automapper/templates/icebox/"
required_map = "IceBoxStation.dmm"
-coordinates = [10, 116, 3]
+coordinates = [8, 115, 3]
trait_name = "Station"
# Icebox Cryo
@@ -334,5 +334,5 @@ trait_name = "Station"
map_files = ["northstar_supermatter.dmm"]
directory = "_maps/skyrat/automapper/templates/northstar/"
required_map = "north_star.dmm"
-coordinates = [174, 129, 1]
+coordinates = [171, 129, 1]
trait_name = "Station"
diff --git a/_maps/skyrat/automapper/templates/birdshot/birdshot_ntrep_office.dmm b/_maps/skyrat/automapper/templates/birdshot/birdshot_ntrep_office.dmm
index b815c467669..41608333fd3 100644
--- a/_maps/skyrat/automapper/templates/birdshot/birdshot_ntrep_office.dmm
+++ b/_maps/skyrat/automapper/templates/birdshot/birdshot_ntrep_office.dmm
@@ -10,29 +10,29 @@
name = "Nanotrasen Consultant's Fax Machine"
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"aU" = (
/obj/machinery/light/directional/west,
/obj/machinery/light_switch/directional/west,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"bD" = (
/obj/structure/closet/secure_closet/nanotrasen_consultant/station,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"ca" = (
/obj/structure/chair/comfy/black{
dir = 4
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"cP" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/structure/cable,
/obj/machinery/light/directional/south,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"eD" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -65,7 +65,7 @@
/obj/structure/cable,
/obj/machinery/light_switch/directional/south,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"iC" = (
/obj/effect/mapping_helpers/broken_floor,
/obj/structure/cable,
@@ -96,7 +96,7 @@
dir = 8
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"lJ" = (
/obj/machinery/power/apc/auto_name/directional/north,
/obj/structure/cable,
@@ -112,7 +112,7 @@
},
/obj/structure/sign/calendar/directional/west,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"nw" = (
/turf/template_noop,
/area/template_noop)
@@ -128,18 +128,18 @@
dir = 1
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"rA" = (
/obj/machinery/modular_computer/preset/command,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"sZ" = (
/turf/closed/wall/r_wall,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"ti" = (
/obj/structure/filingcabinet/chestdrawer,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"vK" = (
/obj/structure/extinguisher_cabinet/directional/east,
/obj/machinery/camera/autoname/directional/east,
@@ -148,7 +148,7 @@
},
/obj/effect/landmark/start/nanotrasen_consultant,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"wx" = (
/obj/structure/cable,
/turf/open/floor/plating,
@@ -176,7 +176,7 @@
},
/obj/item/radio/intercom/directional/north,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"xL" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/structure/cable,
@@ -184,10 +184,10 @@
dir = 8
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"yC" = (
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Ab" = (
/turf/closed/wall,
/area/station/maintenance/hallway/abandoned_command)
@@ -234,7 +234,7 @@
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/obj/machinery/newscaster/directional/north,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"FF" = (
/obj/structure/cable,
/turf/template_noop,
@@ -273,18 +273,18 @@
pixel_y = 7
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Ll" = (
/obj/machinery/firealarm/directional/north,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Nt" = (
/turf/open/floor/iron,
/area/station/maintenance/hallway/abandoned_command)
"OS" = (
/obj/structure/filingcabinet/employment,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Pd" = (
/obj/structure/disposalpipe/segment{
dir = 5
@@ -308,14 +308,14 @@
dir = 8
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Rk" = (
/turf/closed/wall,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"TT" = (
/obj/machinery/photocopier,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"VM" = (
/obj/structure/table/wood,
/obj/item/stamp/centcom{
@@ -323,7 +323,7 @@
pixel_x = -7
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Yp" = (
/turf/closed/wall/r_wall,
/area/station/maintenance/fore/lesser)
diff --git a/_maps/skyrat/automapper/templates/birdshot/birdshot_supermatter.dmm b/_maps/skyrat/automapper/templates/birdshot/birdshot_supermatter.dmm
index 33005aba421..fc0d26771fb 100644
--- a/_maps/skyrat/automapper/templates/birdshot/birdshot_supermatter.dmm
+++ b/_maps/skyrat/automapper/templates/birdshot/birdshot_supermatter.dmm
@@ -14,7 +14,7 @@
/turf/template_noop,
/area/template_noop)
"v" = (
-/obj/item/folder/biscuit/confidential/delam,
+/obj/structure/sign/delam_procedure,
/turf/template_noop,
/area/template_noop)
"B" = (
diff --git a/_maps/skyrat/automapper/templates/deltastation/deltastation_ntrep_office.dmm b/_maps/skyrat/automapper/templates/deltastation/deltastation_ntrep_office.dmm
index 65763878a52..2ce018e9314 100644
--- a/_maps/skyrat/automapper/templates/deltastation/deltastation_ntrep_office.dmm
+++ b/_maps/skyrat/automapper/templates/deltastation/deltastation_ntrep_office.dmm
@@ -1,7 +1,7 @@
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
"a" = (
/turf/closed/wall/r_wall,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"b" = (
/obj/structure/table/wood,
/obj/item/stamp{
@@ -14,7 +14,7 @@
pixel_y = 8
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"c" = (
/obj/structure/sign/directions/engineering,
/obj/structure/sign/directions/evac{
@@ -24,7 +24,7 @@
pixel_y = 8
},
/turf/closed/wall/r_wall,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"f" = (
/obj/structure/table/wood,
/obj/item/camera_film{
@@ -40,7 +40,7 @@
},
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"i" = (
/turf/template_noop,
/area/template_noop)
@@ -48,24 +48,24 @@
/obj/machinery/light/directional/east,
/obj/machinery/photocopier,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"k" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
},
/obj/effect/landmark/start/nanotrasen_consultant,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"m" = (
/obj/structure/extinguisher_cabinet/directional/north,
/obj/effect/turf_decal/siding/wood,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"n" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"o" = (
/obj/machinery/button/door/directional/south{
id = "nt_rep_priv";
@@ -77,13 +77,13 @@
dir = 4
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"q" = (
/obj/structure/chair/office{
dir = 8
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"s" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/door/airlock/maintenance_hatch{
@@ -103,13 +103,13 @@
/obj/structure/sign/poster/official/random/directional/north,
/obj/item/radio/intercom/directional/west,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"u" = (
/obj/structure/cable,
/obj/structure/filingcabinet/chestdrawer,
/obj/machinery/power/apc/auto_name/directional/west,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"v" = (
/obj/machinery/newscaster/directional/west,
/obj/structure/chair/office{
@@ -117,7 +117,7 @@
},
/obj/effect/landmark/start/nanotrasen_consultant,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"w" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/door/poddoor/preopen{
@@ -125,7 +125,7 @@
name = "Privacy Shutter"
},
/turf/open/floor/plating,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"x" = (
/obj/structure/sign/poster/official/random/directional/south,
/obj/structure/disposalpipe/segment{
@@ -143,13 +143,13 @@
pixel_x = -8
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"y" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/cable,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"z" = (
/obj/structure/cable,
/obj/effect/turf_decal/siding/wood{
@@ -158,10 +158,10 @@
/obj/effect/landmark/start/nanotrasen_consultant,
/obj/machinery/airalarm/directional/north,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"B" = (
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"C" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/turf_decal/siding/wood{
@@ -169,18 +169,18 @@
},
/obj/structure/cable,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"D" = (
/obj/structure/closet/secure_closet/nanotrasen_consultant/station,
/obj/item/storage/briefcase,
/obj/item/assembly/flash/handheld,
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"E" = (
/obj/structure/filingcabinet/employment,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"F" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/turf_decal/siding/wood/corner{
@@ -189,7 +189,7 @@
/obj/structure/cable,
/obj/machinery/holopad,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"I" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -199,7 +199,7 @@
},
/obj/effect/landmark/start/nanotrasen_consultant,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"J" = (
/obj/structure/table/wood,
/obj/item/paper_bin{
@@ -207,7 +207,7 @@
},
/obj/item/pen/fountain,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"K" = (
/obj/machinery/light_switch/directional/north,
/obj/structure/disposalpipe/segment{
@@ -217,7 +217,7 @@
dir = 4
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"L" = (
/obj/machinery/door/airlock/corporate{
name = "NT Consultant's Office"
@@ -228,14 +228,14 @@
/obj/effect/mapping_helpers/airlock/access/all/cent_com/rep_door,
/obj/machinery/door/firedoor,
/turf/open/floor/iron,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"M" = (
/obj/machinery/status_display/ai/directional/south,
/obj/machinery/modular_computer/preset/command{
dir = 1
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"P" = (
/obj/machinery/airalarm/directional/south,
/obj/effect/turf_decal/siding/wood{
@@ -247,7 +247,7 @@
},
/obj/structure/cable,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Q" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -258,7 +258,7 @@
name = "Nanotrasen Consultant's Fax Machine"
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"S" = (
/obj/machinery/disposal/bin,
/obj/structure/disposalpipe/trunk{
@@ -266,12 +266,12 @@
},
/obj/machinery/firealarm/directional/south,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"U" = (
/obj/structure/fireplace,
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"V" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/obj/effect/turf_decal/siding/wood/corner{
@@ -280,17 +280,17 @@
/obj/structure/cable,
/obj/effect/landmark/start/nanotrasen_consultant,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"W" = (
/obj/structure/disposalpipe/segment{
dir = 6
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Y" = (
/obj/effect/turf_decal/siding/wood,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
(1,1,1) = {"
i
diff --git a/_maps/skyrat/automapper/templates/deltastation/deltastation_supermatter.dmm b/_maps/skyrat/automapper/templates/deltastation/deltastation_supermatter.dmm
index 3ede0c69f00..3a91788fd6a 100644
--- a/_maps/skyrat/automapper/templates/deltastation/deltastation_supermatter.dmm
+++ b/_maps/skyrat/automapper/templates/deltastation/deltastation_supermatter.dmm
@@ -7,7 +7,7 @@
/turf/template_noop,
/area/template_noop)
"j" = (
-/obj/item/folder/biscuit/confidential/delam,
+/obj/structure/sign/delam_procedure,
/turf/template_noop,
/area/template_noop)
"l" = (
@@ -69,7 +69,7 @@ a
a
a
M
-a
+j
a
"}
(6,1,1) = {"
@@ -87,6 +87,6 @@ a
a
a
a
-j
+a
a
"}
diff --git a/_maps/skyrat/automapper/templates/icebox/icebox_arrivals.dmm b/_maps/skyrat/automapper/templates/icebox/icebox_arrivals.dmm
index 6fa682ec4d4..4cda5d6b97d 100644
--- a/_maps/skyrat/automapper/templates/icebox/icebox_arrivals.dmm
+++ b/_maps/skyrat/automapper/templates/icebox/icebox_arrivals.dmm
@@ -1,12 +1,19 @@
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
"al" = (
-/obj/effect/turf_decal/stripes/corner{
- dir = 4
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
},
+/obj/machinery/status_display/shuttle{
+ pixel_x = -32;
+ shuttle_id = "arrivals_shuttle"
+ },
+/obj/machinery/light/directional/west,
/obj/effect/turf_decal/stripes/corner{
dir = 1
},
-/turf/open/floor/iron,
+/turf/open/floor/iron/white/corner{
+ dir = 1
+ },
/area/station/hallway/secondary/entry)
"as" = (
/obj/effect/turf_decal/stripes/line{
@@ -15,9 +22,21 @@
/turf/open/floor/plating,
/area/station/hallway/secondary/entry)
"aD" = (
+/obj/machinery/door/firedoor,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/cable,
-/turf/open/floor/iron,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 8
+ },
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 4
+ },
+/turf/open/floor/iron/dark/textured,
+/area/station/hallway/secondary/entry)
+"aK" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
+/turf/open/floor/iron/large,
/area/station/hallway/secondary/entry)
"aT" = (
/obj/effect/turf_decal/weather/snow/corner{
@@ -27,22 +46,35 @@
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
"bE" = (
-/obj/structure/sign/warning/docking/directional/north,
+/obj/structure/sign/nanotrasen{
+ pixel_x = 32
+ },
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors/nospawn)
"bI" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron,
+/obj/item/kirbyplants/random,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/firealarm/directional/east,
+/obj/machinery/status_display/ai/directional/north,
+/obj/effect/turf_decal/siding/white,
+/turf/open/floor/iron/dark,
/area/station/hallway/secondary/entry)
"ca" = (
-/obj/effect/turf_decal/stripes/corner{
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 1
},
-/obj/effect/turf_decal/stripes/corner{
+/turf/open/floor/iron/large,
+/area/station/hallway/secondary/entry)
+"ce" = (
+/obj/effect/turf_decal/siding/thinplating_new/corner{
dir = 4
},
-/turf/open/floor/iron,
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/turf/open/floor/iron/white/side{
+ dir = 8
+ },
/area/station/hallway/secondary/entry)
"co" = (
/turf/open/floor/plating,
@@ -76,25 +108,17 @@
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
"dr" = (
-/obj/docking_port/stationary{
- dir = 8;
- dwidth = 1;
- height = 13;
- shuttle_id = "arrivals_stationary";
- name = "arrivals";
- width = 5
- },
-/turf/open/misc/asteroid/snow/icemoon,
-/area/icemoon/surface/outdoors/nospawn)
-"dt" = (
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
- dir = 1
- },
-/obj/machinery/door/airlock/external{
- name = "Port Docking Bay 3"
- },
-/turf/open/floor/plating,
+/obj/machinery/holopad,
+/obj/effect/turf_decal/bot,
+/turf/open/floor/iron/large,
/area/station/hallway/secondary/entry)
+"dt" = (
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 5
+ },
+/obj/effect/turf_decal/weather/snow/corner,
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"dG" = (
/obj/effect/mapping_helpers/airlock/cyclelink_helper{
dir = 1
@@ -107,6 +131,18 @@
"ej" = (
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors/nospawn)
+"en" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/machinery/computer/shuttle/arrivals/recall,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
"ep" = (
/obj/effect/turf_decal/stripes{
dir = 6
@@ -142,14 +178,20 @@
"eR" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron/white/corner{
+/obj/effect/turf_decal/tile/blue{
dir = 1
},
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
/area/station/hallway/secondary/entry)
"fc" = (
-/obj/effect/turf_decal/stripes/line,
-/obj/structure/sign/warning/gas_mask/directional/south,
-/turf/open/floor/iron,
+/obj/item/kirbyplants/random,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/siding/white{
+ dir = 1
+ },
+/turf/open/floor/iron/dark,
/area/station/hallway/secondary/entry)
"fV" = (
/obj/structure/table/wood,
@@ -165,56 +207,57 @@
/turf/open/floor/iron/grimy,
/area/station/hallway/secondary/entry)
"fW" = (
-/obj/machinery/light/directional/north,
-/obj/effect/turf_decal/tile/blue{
- dir = 4
- },
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron/white/corner{
+/obj/effect/turf_decal/tile/blue{
dir = 1
},
+/obj/machinery/newscaster/directional/north,
+/obj/machinery/light/directional/north,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
/area/station/hallway/secondary/entry)
"gd" = (
/obj/item/radio/intercom/directional/south,
/turf/open/floor/plating,
/area/station/hallway/secondary/entry)
"gT" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
+/obj/effect/turf_decal/siding/thinplating_new/corner,
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/turf/open/floor/iron/white/side{
+ dir = 8
+ },
/area/station/hallway/secondary/entry)
"hE" = (
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
- dir = 1
- },
-/obj/machinery/door/airlock/external{
- name = "Port Docking Bay 4"
- },
-/turf/open/floor/plating,
-/area/station/hallway/secondary/entry)
+/obj/structure/flora/tree/pine/style_random,
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"hS" = (
/obj/structure/statue/snow/snowman,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors/nospawn)
"iv" = (
-/obj/structure/chair{
+/obj/structure/chair/sofa/bench{
dir = 1
},
/obj/effect/turf_decal/stripes/line,
-/obj/structure/sign/warning/docking/directional/south,
-/turf/open/floor/iron,
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/turf/open/floor/iron/white/corner,
/area/station/hallway/secondary/entry)
"iy" = (
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
"iO" = (
-/obj/item/beacon,
-/obj/effect/turf_decal/stripes/line{
- dir = 1
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 9
},
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"iP" = (
/obj/structure/fence,
/obj/effect/turf_decal/weather/snow/corner{
@@ -226,7 +269,7 @@
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
},
-/turf/open/floor/iron,
+/turf/open/floor/iron/large,
/area/station/hallway/secondary/entry)
"jn" = (
/obj/effect/turf_decal/stripes/line{
@@ -239,13 +282,10 @@
/turf/open/floor/iron/grimy,
/area/station/hallway/secondary/entry)
"ks" = (
-/obj/effect/turf_decal/tile/blue{
- dir = 8
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron/white/corner,
-/area/station/hallway/secondary/entry)
+/obj/structure/sign/warning/docking/directional/north,
+/obj/structure/flora/grass/green/style_random,
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"kz" = (
/obj/item/toy/snowball{
pixel_x = -10;
@@ -282,15 +322,13 @@
},
/area/station/hallway/secondary/entry)
"lY" = (
-/obj/effect/turf_decal/tile/blue{
- dir = 4
- },
-/obj/machinery/light/directional/north,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron/white/corner{
+/obj/effect/turf_decal/tile/blue{
dir = 1
},
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
/area/station/hallway/secondary/entry)
"mk" = (
/obj/structure/fence/corner,
@@ -300,10 +338,21 @@
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
"mt" = (
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+/obj/machinery/door/firedoor,
+/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,
+/obj/effect/turf_decal/stripes/white/line{
dir = 8
},
-/turf/open/floor/iron,
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 4
+ },
+/obj/machinery/door/airlock/multi_tile/public/glass{
+ name = "Arrivals Dock";
+ dir = 4
+ },
+/turf/open/floor/iron/dark/textured,
/area/station/hallway/secondary/entry)
"mM" = (
/obj/effect/turf_decal/weather/snow/corner{
@@ -313,11 +362,17 @@
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
"nc" = (
-/obj/effect/turf_decal/stripes/corner{
+/obj/structure/chair/sofa/bench/left,
+/obj/effect/turf_decal/stripes/line{
+ dir = 5
+ },
+/obj/effect/turf_decal/tile/blue,
+/obj/effect/turf_decal/tile/blue{
dir = 1
},
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
-/turf/open/floor/iron,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
/area/station/hallway/secondary/entry)
"nH" = (
/obj/effect/turf_decal/stripes{
@@ -328,39 +383,65 @@
"nJ" = (
/turf/open/floor/iron/grimy,
/area/station/hallway/secondary/entry)
+"nL" = (
+/obj/docking_port/stationary/random/icemoon{
+ dir = 8;
+ name = "lavaland";
+ shuttle_id = "pod_lavaland"
+ },
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"nR" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
},
-/obj/machinery/computer/shuttle/arrivals/recall,
+/obj/structure/chair/sofa/bench/right,
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
+"oZ" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
/turf/open/floor/iron,
/area/station/hallway/secondary/entry)
"pd" = (
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
- dir = 1
- },
-/obj/machinery/door/airlock/external{
- name = "Port Docking Bay 1"
- },
-/obj/effect/landmark/navigate_destination{
- location = "Arrival Shuttle"
- },
-/turf/open/floor/plating,
-/area/station/hallway/secondary/entry)
+/obj/structure/marker_beacon/burgundy,
+/turf/open/floor/plating/snowed/smoothed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"pq" = (
/obj/effect/turf_decal/tile/blue{
dir = 8
},
/turf/open/floor/iron/white/corner,
/area/station/hallway/secondary/entry)
+"pY" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/status_display/evac/directional/south,
+/obj/effect/turf_decal/siding/white{
+ dir = 1
+ },
+/obj/structure/closet/firecloset,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
"qb" = (
/obj/effect/landmark/carpspawn,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors/nospawn)
"qB" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/door/firedoor,
-/turf/open/floor/iron,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 8
+ },
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 4
+ },
+/turf/open/floor/iron/dark/textured,
/area/station/hallway/secondary/entry)
"qD" = (
/obj/structure/closet/emcloset,
@@ -391,11 +472,11 @@
/turf/open/floor/iron/grimy,
/area/station/hallway/secondary/entry)
"tv" = (
-/obj/structure/closet/emcloset,
-/obj/effect/turf_decal/stripes/line{
- dir = 9
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
},
-/turf/open/floor/iron,
+/turf/open/floor/iron/white/corner,
/area/station/hallway/secondary/entry)
"tB" = (
/obj/effect/turf_decal/tile/blue{
@@ -421,22 +502,23 @@
/turf/open/floor/plating,
/area/station/hallway/secondary/entry)
"uG" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/turf_decal/stripes/line{
- dir = 8
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/turf/open/floor/iron/white/corner{
+ dir = 4
},
-/turf/open/floor/iron,
/area/station/hallway/secondary/entry)
"uR" = (
/obj/effect/spawner/random/vending/snackvend,
/turf/open/floor/iron/grimy,
/area/station/hallway/secondary/entry)
"vG" = (
-/obj/structure/closet/emcloset,
-/obj/effect/turf_decal/stripes/line{
- dir = 10
- },
-/turf/open/floor/iron,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/siding/white,
+/obj/structure/closet/firecloset,
+/obj/machinery/mining_weather_monitor/directional/north,
+/turf/open/floor/iron/dark,
/area/station/hallway/secondary/entry)
"wj" = (
/obj/structure/chair/comfy/brown,
@@ -453,20 +535,16 @@
},
/area/station/hallway/secondary/entry)
"xd" = (
-/obj/effect/turf_decal/tile/blue{
- dir = 8
- },
-/obj/machinery/camera/directional/south,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron/white/corner,
-/area/station/hallway/secondary/entry)
+/obj/structure/sign/warning/docking/directional/south,
+/turf/open/floor/plating/snowed/smoothed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"xf" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/turf_decal/stripes/corner{
- dir = 8
- },
-/turf/open/floor/iron,
+/obj/structure/closet/emcloset,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/status_display/evac/directional/north,
+/obj/effect/turf_decal/siding/white,
+/obj/effect/landmark/start/hangover/closet,
+/turf/open/floor/iron/dark,
/area/station/hallway/secondary/entry)
"xr" = (
/obj/structure/closet/emcloset/anchored,
@@ -483,11 +561,19 @@
/turf/open/floor/plating,
/area/station/hallway/secondary/entry)
"xD" = (
-/obj/structure/chair{
- dir = 1
+/obj/machinery/door/firedoor,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 8
},
-/obj/effect/turf_decal/stripes/line,
-/turf/open/floor/iron,
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 4
+ },
+/obj/machinery/door/airlock/multi_tile/public/glass{
+ name = "Auxiliary Dock";
+ dir = 4
+ },
+/turf/open/floor/iron/dark/textured,
/area/station/hallway/secondary/entry)
"xI" = (
/obj/structure/table/wood,
@@ -514,10 +600,13 @@
/turf/closed/wall,
/area/station/hallway/secondary/entry)
"zA" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 9
+/obj/structure/closet/emcloset,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/siding/white{
+ dir = 1
},
-/turf/open/floor/iron,
+/obj/machinery/mining_weather_monitor/directional/south,
+/turf/open/floor/iron/dark,
/area/station/hallway/secondary/entry)
"zX" = (
/obj/structure/chair/comfy/brown{
@@ -530,74 +619,98 @@
/turf/open/floor/iron/grimy,
/area/station/hallway/secondary/entry)
"Ar" = (
-/obj/machinery/vending/cigarette,
-/obj/effect/turf_decal/stripes/line{
- dir = 6
- },
-/turf/open/floor/iron,
+/obj/structure/rack,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/effect/turf_decal/siding/white,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/entry)
+"AF" = (
+/turf/open/floor/iron/white/corner,
/area/station/hallway/secondary/entry)
"AH" = (
-/obj/effect/mapping_helpers/airlock/cyclelink_helper,
-/obj/machinery/door/airlock/external{
- name = "Port Docking Bay 3"
+/obj/structure/marker_beacon/burgundy,
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 10
},
-/turf/open/floor/plating,
-/area/station/hallway/secondary/entry)
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"Be" = (
/obj/effect/turf_decal/stripes/corner,
-/turf/open/floor/iron,
+/obj/effect/turf_decal/tile/blue{
+ dir = 4
+ },
+/turf/open/floor/iron/white/corner,
/area/station/hallway/secondary/entry)
"Bo" = (
/obj/effect/turf_decal/stripes/corner{
dir = 8
},
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
-"Ci" = (
-/obj/item/radio/intercom/directional/south,
-/obj/structure/chair{
- dir = 1
- },
-/obj/effect/turf_decal/stripes/line,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
-"Ck" = (
-/obj/effect/turf_decal/stripes/line,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
-"Dr" = (
-/obj/machinery/light/directional/west,
-/obj/effect/turf_decal/stripes/line{
- dir = 8
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
-"DW" = (
-/obj/machinery/light/directional/south,
/obj/effect/turf_decal/tile/blue{
dir = 8
},
-/obj/machinery/camera/directional/south,
-/obj/machinery/status_display/shuttle/directional/south{
- shuttle_id = "arrivals_shuttle"
+/turf/open/floor/iron/white/corner{
+ dir = 1
},
+/area/station/hallway/secondary/entry)
+"Ci" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/machinery/light/directional/north,
+/obj/item/radio/intercom/directional/north,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/item/kirbyplants/random,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
+/area/station/hallway/secondary/entry)
+"Ck" = (
+/obj/structure/sign/nanotrasen{
+ pixel_x = 32
+ },
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 10
+ },
+/obj/structure/marker_beacon/burgundy,
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
+"Dr" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
+/turf/open/floor/iron/large,
+/area/station/hallway/secondary/entry)
+"DD" = (
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 5
+ },
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
+"DW" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/obj/machinery/camera/directional/south{
+ c_tag = "Arrivals Dock South"
+ },
+/obj/item/radio/intercom/directional/south,
/turf/open/floor/iron/white/corner,
/area/station/hallway/secondary/entry)
"EN" = (
-/obj/effect/turf_decal/stripes/line{
+/obj/effect/turf_decal/weather/snow/corner{
dir = 10
},
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"Fd" = (
-/obj/machinery/camera/directional/south{
- c_tag = "Arrivals Bay 3 & 4"
+/obj/effect/turf_decal/stripes/corner{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/blue,
+/turf/open/floor/iron/white/corner{
+ dir = 4
},
-/obj/effect/turf_decal/stripes/line,
-/obj/effect/spawner/random/vending/snackvend,
-/turf/open/floor/iron,
/area/station/hallway/secondary/entry)
"FC" = (
/obj/effect/turf_decal/stripes{
@@ -605,13 +718,6 @@
},
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
-"FG" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 1
- },
-/obj/structure/sign/warning/cold_temp/directional/north,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
"FL" = (
/obj/structure/fence/corner{
dir = 4
@@ -622,10 +728,13 @@
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
"FR" = (
+/obj/structure/chair/sofa/bench/right{
+ dir = 1
+ },
+/obj/effect/turf_decal/stripes/line,
/obj/effect/turf_decal/tile/blue{
dir = 8
},
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/white/corner,
/area/station/hallway/secondary/entry)
"Gc" = (
@@ -639,12 +748,12 @@
/turf/open/floor/plating,
/area/station/hallway/secondary/entry)
"Gw" = (
-/obj/effect/turf_decal/stripes/corner{
- dir = 4
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 6
},
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
+/obj/structure/marker_beacon/burgundy,
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"Gy" = (
/obj/effect/turf_decal/bot,
/obj/structure/marker_beacon/burgundy{
@@ -655,13 +764,13 @@
"Hm" = (
/obj/docking_port/stationary{
dir = 2;
- dwidth = 11;
- height = 22;
- shuttle_id = "whiteship_home";
- name = "SS13: Auxiliary Dock, Station-Port";
- width = 35
+ dwidth = 2;
+ height = 13;
+ name = "port bay 2";
+ shuttle_id = "ferry_home";
+ width = 5
},
-/turf/open/floor/plating/snowed/icemoon,
+/turf/open/floor/plating/snowed/smoothed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
"HQ" = (
/obj/docking_port/stationary/random/icemoon{
@@ -672,13 +781,11 @@
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors/nospawn)
"HX" = (
-/obj/effect/turf_decal/stripes/corner{
+/obj/effect/turf_decal/weather/snow/corner{
dir = 1
},
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"IC" = (
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
@@ -692,6 +799,20 @@
},
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
+"IS" = (
+/obj/structure/chair/sofa/bench/left{
+ dir = 1
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 10
+ },
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/turf/open/floor/iron/cafeteria{
+ dir = 5
+ },
+/area/station/hallway/secondary/entry)
"Jj" = (
/obj/effect/turf_decal/siding/thinplating_new{
dir = 1
@@ -699,13 +820,22 @@
/turf/open/floor/iron/grimy,
/area/station/hallway/secondary/entry)
"Jy" = (
-/obj/structure/closet/emcloset,
-/obj/effect/turf_decal/stripes/line,
-/turf/open/floor/iron,
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/machinery/airalarm/directional/north,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
/area/station/hallway/secondary/entry)
"JC" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/obj/item/kirbyplants/random,
+/turf/open/floor/iron/cafeteria{
+ dir = 5
+ },
/area/station/hallway/secondary/entry)
"JP" = (
/obj/structure/marker_beacon/burgundy{
@@ -721,12 +851,11 @@
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
"JR" = (
-/obj/effect/mapping_helpers/airlock/cyclelink_helper,
-/obj/machinery/door/airlock/external{
- name = "Port Docking Bay 4"
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 4
},
-/turf/open/floor/plating,
-/area/station/hallway/secondary/entry)
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"Kr" = (
/obj/effect/turf_decal/weather/snow/corner,
/obj/structure/fence/door,
@@ -741,16 +870,33 @@
/turf/open/floor/iron,
/area/station/hallway/secondary/entry)
"LM" = (
-/obj/structure/extinguisher_cabinet/directional/east,
-/obj/machinery/light/directional/east,
-/obj/structure/cable,
-/turf/open/floor/iron,
+/obj/effect/turf_decal/weather/snow/corner,
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
+"LN" = (
+/obj/machinery/light/directional/south,
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/obj/machinery/camera/directional/south,
+/obj/machinery/status_display/shuttle/directional/south{
+ shuttle_id = "arrivals_shuttle"
+ },
+/obj/item/kirbyplants/random,
+/turf/open/floor/iron/white/corner,
/area/station/hallway/secondary/entry)
"Mh" = (
/obj/effect/turf_decal/stripes/line{
+ dir = 6
+ },
+/obj/effect/turf_decal/tile/blue{
dir = 4
},
-/turf/open/floor/iron,
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/obj/item/kirbyplants/random,
+/turf/open/floor/iron/white/corner,
/area/station/hallway/secondary/entry)
"Nt" = (
/obj/docking_port/stationary/escape_pod{
@@ -765,12 +911,11 @@
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
"Nz" = (
-/obj/structure/closet/emcloset,
-/obj/effect/turf_decal/stripes/line{
- dir = 1
+/obj/structure/sign/nanotrasen{
+ pixel_y = 32
},
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"Ot" = (
/obj/structure/fence{
dir = 4
@@ -779,13 +924,8 @@
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
"OJ" = (
-/obj/effect/turf_decal/tile/blue{
- dir = 8
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
+/turf/open/floor/plating/snowed/smoothed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"OL" = (
/obj/effect/turf_decal/tile/blue{
dir = 4
@@ -801,27 +941,38 @@
/turf/closed/wall/r_wall,
/area/station/hallway/secondary/entry)
"OZ" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 8
+/obj/structure/rack,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/firealarm/directional/east,
+/obj/machinery/status_display/ai/directional/south,
+/obj/effect/turf_decal/siding/white{
+ dir = 1
},
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
+/turf/open/floor/iron/dark,
/area/station/hallway/secondary/entry)
"Pb" = (
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
+/obj/effect/turf_decal/tile/blue{
dir = 8
},
-/obj/machinery/door/airlock/external,
-/turf/open/floor/plating,
+/obj/machinery/airalarm/directional/south,
+/turf/open/floor/iron/white/corner,
/area/station/hallway/secondary/entry)
"Pn" = (
/turf/open/genturf,
/area/icemoon/surface/outdoors/unexplored/rivers/no_monsters)
"PC" = (
-/obj/effect/turf_decal/stripes/line,
-/obj/structure/sign/warning/cold_temp/directional/south,
-/turf/open/floor/iron,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/machinery/camera/directional/north{
+ c_tag = "Arrivals Aux Dock"
+ },
+/obj/item/radio/intercom/directional/north,
+/turf/open/floor/iron/white/corner{
+ dir = 4
+ },
/area/station/hallway/secondary/entry)
"PY" = (
/obj/structure/fence/corner{
@@ -835,6 +986,12 @@
},
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
+"QL" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/turf/open/floor/iron,
+/area/station/hallway/secondary/entry)
"QV" = (
/obj/effect/turf_decal/stripes/line{
dir = 8
@@ -852,10 +1009,14 @@
/turf/open/floor/plating,
/area/station/hallway/secondary/entry)
"QW" = (
-/obj/machinery/door/firedoor,
-/obj/machinery/status_display/evac/directional/east,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 10
+ },
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 1
+ },
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"Rx" = (
/obj/effect/turf_decal/weather/snow/corner{
dir = 10
@@ -882,11 +1043,20 @@
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
"Se" = (
-/obj/machinery/status_display/evac/directional/east,
/obj/effect/turf_decal/tile/blue{
- dir = 4
+ dir = 1
+ },
+/obj/machinery/status_display/shuttle{
+ pixel_x = -32;
+ shuttle_id = "arrivals_shuttle"
+ },
+/obj/machinery/light/directional/west,
+/obj/effect/turf_decal/stripes/corner{
+ dir = 8
+ },
+/turf/open/floor/iron/white/corner{
+ dir = 8
},
-/turf/open/floor/iron,
/area/station/hallway/secondary/entry)
"Sw" = (
/obj/machinery/door/airlock/external{
@@ -898,11 +1068,15 @@
/turf/open/floor/plating,
/area/station/hallway/secondary/entry)
"SQ" = (
-/obj/effect/turf_decal/stripes/corner{
- dir = 1
+/obj/structure/sign/nanotrasen{
+ pixel_x = -32
},
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 6
+ },
+/obj/structure/marker_beacon/burgundy,
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"SS" = (
/obj/effect/turf_decal/siding/thinplating_new{
dir = 5
@@ -910,15 +1084,24 @@
/turf/open/floor/iron/grimy,
/area/station/hallway/secondary/entry)
"Th" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/turf_decal/stripes/corner{
- dir = 1
- },
-/obj/effect/turf_decal/stripes/corner{
+/obj/effect/turf_decal/tile/blue{
dir = 8
},
-/turf/open/floor/iron,
+/turf/open/floor/iron/white/corner,
/area/station/hallway/secondary/entry)
+"Tq" = (
+/obj/docking_port/stationary{
+ dir = 8;
+ dwidth = 1;
+ height = 13;
+ shuttle_id = "arrivals_stationary";
+ name = "arrivals";
+ width = 5
+ },
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"Tt" = (
/obj/effect/turf_decal/stripes{
dir = 9
@@ -926,30 +1109,31 @@
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
"TC" = (
-/obj/effect/turf_decal/stripes/corner{
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
},
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron,
+/obj/effect/landmark/navigate_destination/dockaux,
+/turf/open/floor/iron/large,
/area/station/hallway/secondary/entry)
"Uh" = (
/obj/item/kirbyplants/random,
/turf/open/floor/iron/grimy,
/area/station/hallway/secondary/entry)
"Uj" = (
-/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,
+/obj/effect/turf_decal/stripes/corner{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/turf/open/floor/iron/white/corner{
+ dir = 8
+ },
/area/station/hallway/secondary/entry)
"UH" = (
-/obj/structure/closet/emcloset,
-/obj/effect/turf_decal/stripes/line{
- dir = 5
- },
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
+/obj/structure/sign/warning/docking/directional/south,
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"UO" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 1
@@ -957,20 +1141,31 @@
/turf/open/floor/iron,
/area/station/hallway/secondary/entry)
"Vp" = (
-/obj/machinery/holopad,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
-"VD" = (
-/obj/machinery/light/directional/south,
-/obj/effect/turf_decal/tile/blue{
+/obj/effect/turf_decal/siding/thinplating_new{
+ dir = 4
+ },
+/obj/effect/turf_decal/stripes/line{
dir = 8
},
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/status_display/shuttle/directional/south{
- shuttle_id = "arrivals_shuttle"
+/turf/open/floor/iron/white/side{
+ dir = 8
+ },
+/area/station/hallway/secondary/entry)
+"VD" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/structure/table,
+/obj/item/storage/medkit/emergency{
+ pixel_y = 5
+ },
+/obj/item/radio/off,
+/turf/open/floor/iron/white/corner{
+ dir = 4
},
-/turf/open/floor/iron/white/corner,
/area/station/hallway/secondary/entry)
"Wb" = (
/obj/effect/turf_decal/weather/snow/corner{
@@ -982,24 +1177,26 @@
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
"WC" = (
-/obj/machinery/firealarm/directional/west,
-/obj/effect/turf_decal/stripes/line{
- dir = 8
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
+/obj/structure/flora/grass/brown/style_random,
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"Xd" = (
-/obj/item/radio/intercom/directional/north,
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 6
+ },
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
+"Xj" = (
/obj/effect/turf_decal/stripes/line{
+ dir = 9
+ },
+/obj/effect/turf_decal/tile/blue{
dir = 1
},
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
-"Xj" = (
-/obj/structure/cable,
-/turf/open/floor/iron,
+/obj/item/kirbyplants/random,
+/turf/open/floor/iron/cafeteria{
+ dir = 8
+ },
/area/station/hallway/secondary/entry)
"Xp" = (
/obj/machinery/door/airlock/external{
@@ -1011,19 +1208,20 @@
/turf/open/floor/plating,
/area/station/hallway/secondary/entry)
"XM" = (
-/obj/machinery/camera/directional/east{
- c_tag = "Arrivals Bay 2"
+/obj/effect/turf_decal/weather/snow/corner{
+ dir = 8
},
-/turf/open/floor/iron,
-/area/station/hallway/secondary/entry)
+/turf/open/floor/plating/snowed/icemoon,
+/area/icemoon/surface/outdoors/nospawn)
"Ya" = (
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
- dir = 4
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
},
-/obj/machinery/door/airlock/external{
- space_dir = 8
- },
-/turf/open/floor/plating,
+/obj/machinery/newscaster/directional/south,
+/obj/machinery/light/directional/south,
+/turf/open/floor/iron/white/corner,
/area/station/hallway/secondary/entry)
"Zb" = (
/obj/machinery/door/airlock/external{
@@ -1043,11 +1241,9 @@
/turf/open/floor/plating/snowed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
"ZN" = (
-/obj/effect/spawner/random/vending/snackvend,
-/obj/effect/turf_decal/stripes/line{
- dir = 9
+/turf/open/floor/iron/white/corner{
+ dir = 4
},
-/turf/open/floor/iron,
/area/station/hallway/secondary/entry)
(1,1,1) = {"
@@ -1638,8 +1834,8 @@ HQ
ej
ej
ej
-ej
-ej
+OJ
+OJ
ej
ej
IC
@@ -1668,11 +1864,11 @@ ej
ej
ej
ej
+pd
+OJ
+nL
ej
-ej
-ej
-ej
-ej
+pd
ej
IC
wQ
@@ -1691,20 +1887,20 @@ ej
ej
"}
(21,1,1) = {"
-Pn
-Pn
-ej
-ej
-ej
-ej
-ej
-ej
+OJ
ej
ej
ej
ej
ej
+OJ
ej
+OJ
+OJ
+iy
+iy
+iy
+OJ
ej
IC
wQ
@@ -1723,20 +1919,20 @@ ej
ej
"}
(22,1,1) = {"
-Pn
-Pn
-ej
-ej
-ej
-ej
-ej
-ej
-ej
-ej
-ej
+ej
+ej
+iO
+XM
+EN
+OJ
ej
ej
ej
+cp
+iy
+iy
+iy
+cp
ej
IC
yO
@@ -1755,20 +1951,20 @@ ej
ej
"}
(23,1,1) = {"
-Pn
-Pn
-ej
-ej
ej
+iO
+iy
+iy
+iy
+EN
ej
+pd
+OJ
+cp
iy
Nt
iy
-ej
-ej
-ej
-ej
-ej
+cp
ej
rR
OL
@@ -1787,9 +1983,13 @@ ej
ej
"}
(24,1,1) = {"
-ej
-ej
-ej
+iO
+iy
+iy
+iy
+iy
+iy
+EN
ej
ej
rR
@@ -1797,11 +1997,7 @@ cp
Gc
cp
rR
-ej
-ej
-ej
-ej
-ej
+OJ
IC
wQ
LL
@@ -1819,21 +2015,21 @@ ej
ej
"}
(25,1,1) = {"
-ej
-ej
-ej
-ej
-ej
+HX
+iy
+iy
+iy
+iy
+iy
+LM
+OJ
+UH
OQ
qD
co
tV
rR
ej
-ej
-ej
-ej
-ej
IC
wQ
LL
@@ -1851,21 +2047,21 @@ ej
ej
"}
(26,1,1) = {"
-ej
-ej
-ej
-ej
-ej
+iy
+iy
+iy
+iy
+iy
+iy
+LM
+Ck
+OJ
rR
cp
Xp
yV
rR
-ej
-ej
-ej
-ej
-ej
+ks
IC
lA
jm
@@ -1874,7 +2070,7 @@ fV
rR
ej
ej
-ej
+pd
ej
ej
ej
@@ -1883,21 +2079,21 @@ ej
ej
"}
(27,1,1) = {"
-ej
-ej
-ej
+iy
+iy
+iy
+iy
+iy
+iy
iy
IC
IC
IC
+IC
sm
-DW
+LN
rR
ej
-ej
-ej
-ej
-ej
IC
lA
LL
@@ -1907,419 +2103,419 @@ OQ
ej
ej
ej
+OJ
ej
ej
ej
-ej
-ej
-ej
+OJ
+pd
"}
(28,1,1) = {"
-ej
-ej
-ej
+iy
+iy
+iy
+iy
+iy
+iy
iy
Zb
co
+co
dG
-ca
-pq
+Dr
+tv
IC
-ej
-ej
-ej
-ej
-ej
-IC
-lA
+OJ
+cp
+Ci
LL
-fc
+LB
IC
IC
IC
-iy
-ej
-ej
+Nz
+OJ
ej
ej
+OJ
ej
ej
ej
"}
(29,1,1) = {"
-ej
-ej
-ej
+iy
+iy
+iy
+iy
+iy
+iy
iy
IC
IC
IC
-FG
-pq
+xC
+uG
+tv
+IC
+OJ
IC
-ej
-ej
-ej
-ej
-ej
-rR
lY
LL
-Ck
-JR
+Zb
co
-hE
-Hm
-ej
-ej
-ej
-ej
-ej
+co
+dG
+OJ
+OJ
+OJ
+ej
+OJ
ej
ej
+OJ
"}
(30,1,1) = {"
-ej
-ej
-ej
-ej
-IC
-ZN
-jn
-nc
-FR
-IC
-ej
-ej
-ej
-ej
-ej
-IC
-lA
-LL
-PC
-IC
-IC
-IC
iy
+iy
+iy
+iy
+iy
+iy
+iy
+AH
+IC
+Xj
+Uj
+oZ
+tv
+IC
+OJ
+IC
+lY
+pq
+xC
+IC
+IC
+IC
+OJ
+OJ
+OJ
+OJ
ej
-ej
-ej
-ej
-ej
+OJ
ej
ej
"}
(31,1,1) = {"
-ej
-ej
-ej
-ej
+iy
+iy
+iy
+iy
+iy
+iy
+iy
+iy
IC
-nR
+en
LL
-LL
-FR
+aK
+Th
IC
-ej
-ej
-ej
-ej
-ej
+OJ
IC
-lA
-LL
+lY
+QL
Bo
-jn
-vG
+IS
IC
+QW
+ej
+OJ
ej
ej
ej
-ej
-ej
-ej
+OJ
ej
ej
"}
(32,1,1) = {"
-ej
-ej
-ej
-ej
+iy
+iy
+iy
+iy
+iy
+iy
+iy
+LM
IC
-iO
+VD
LL
LL
-FR
+Th
IC
-ej
-ej
-ej
-ej
-ej
+OJ
IC
-lA
+lY
+dr
LL
-LL
-LL
-Jy
+iv
IC
+LM
ej
ej
+OJ
ej
+OJ
ej
-ej
-ej
-ej
+OJ
ej
"}
(33,1,1) = {"
-ej
-ej
-ej
-ej
+iy
+iy
+iy
+iy
+iy
+iy
+iy
+LM
IC
-Nz
+nR
LL
+dr
+Th
+IC
+OJ
+IC
+eR
+ca
LL
FR
IC
+LM
+ej
+OJ
+ej
+OJ
ej
ej
-ej
-ej
-ej
-IC
-lA
-LL
-LL
-LL
-Fd
-IC
-ej
-ej
-ej
-ej
-ej
-ej
-ej
+OJ
ej
"}
(34,1,1) = {"
-ej
-ej
-ej
-ej
-IC
-UH
-Mh
+iy
+iy
+iy
+iy
+iy
+iy
+iy
Gw
-ks
IC
-ej
-ej
-ej
-ej
-ej
+nc
+Fd
+ZN
+Th
IC
-lA
-LL
+OJ
+IC
+eR
+AF
Be
Mh
-Ar
IC
+dt
+ej
+OJ
ej
ej
-ej
-ej
-ej
-ej
+OJ
+OJ
ej
ej
"}
(35,1,1) = {"
-ej
-ej
-ej
+iy
+iy
+iy
+iy
+iy
+iy
iy
IC
IC
IC
-FG
-ks
+xC
+uG
+Th
IC
-ej
-ej
-ej
-ej
-ej
+OJ
IC
-lA
-LL
-PC
+eR
+pq
+xC
IC
IC
IC
-iy
-ej
-ej
-ej
+ej
+OJ
+OJ
ej
ej
ej
+OJ
ej
"}
(36,1,1) = {"
-ej
-ej
-ej
+iy
+iy
+iy
+iy
+iy
+iy
iy
ub
co
-pd
-al
-ks
-IC
-ej
-iy
-iy
-iy
-ej
-IC
-lA
-LL
-Ck
-AH
co
-dt
-iy
-ej
-ej
-ej
+dG
+Dr
+Th
+IC
+OJ
+IC
+eR
+TC
+ub
+co
+co
+dG
+Hm
+OJ
+OJ
ej
+qb
ej
ej
ej
"}
(37,1,1) = {"
-ej
-ej
-ej
+iy
+iy
+iy
+iy
+iy
+iy
iy
IC
IC
IC
-sm
-VD
-rR
-ej
-IC
+LB
+uG
Ya
-IC
-ej
-rR
+cp
+OJ
+cp
fW
-LL
-fc
+pq
+LB
IC
IC
IC
-iy
+Nz
+OJ
+OJ
+OJ
ej
-ej
-ej
-ej
-qb
+OJ
ej
ej
"}
(38,1,1) = {"
-ej
-ej
-dr
-ej
-ej
-IC
-zA
+iy
+iy
+iy
+iy
+iy
+Tq
+iy
SQ
xd
-rR
-IC
-IC
-co
-IC
-IC
-rR
-lA
-LL
-Bo
-EN
-IC
-ej
-ej
+cp
+cp
+Jy
+DW
+cp
+cp
+cp
+PC
+Pb
+cp
+cp
+ks
ej
ej
+OJ
ej
ej
+OJ
ej
ej
ej
"}
(39,1,1) = {"
-IC
-IC
-IC
-rR
-rR
-rR
+DD
+JR
+iy
+iy
+iy
+JR
Xd
-LL
+OJ
OJ
cp
vG
-xC
-Pb
-LB
-tv
+uG
+Th
+fc
cp
+Ar
eR
-LL
-LL
-Ci
-rR
-ej
-ej
-ej
-ej
-ej
+pq
+zA
+cp
+ej
+hE
+ej
+pd
+OJ
ej
ej
ej
+OJ
ej
"}
(40,1,1) = {"
-OZ
-OZ
-OZ
-WC
-Dr
-OZ
-HX
-gT
-gT
-qB
+cp
+IC
+IC
+IC
+IC
+IC
+cp
+cp
+cp
+cp
xf
uG
Th
OZ
-TC
+cp
bI
-bI
-UO
-LL
-xD
-rR
+eR
+pq
+pY
+cp
+ej
bE
ej
ej
@@ -2333,27 +2529,27 @@ ej
(41,1,1) = {"
Se
gT
-LL
-LL
Vp
-LL
-LL
+Vp
+Vp
+ce
+al
JC
-LL
-QW
-XM
-LL
-mt
-Uj
-LM
-Xj
-aD
-LL
-LL
-iv
cp
-ej
-ej
+cp
+cp
+qB
+mt
+cp
+cp
+cp
+aD
+xD
+cp
+cp
+cp
+cp
+WC
ej
ej
ej
diff --git a/_maps/skyrat/automapper/templates/icebox/icebox_ntrep_office.dmm b/_maps/skyrat/automapper/templates/icebox/icebox_ntrep_office.dmm
index 3bcb075cc9d..cbfaddfb20c 100644
--- a/_maps/skyrat/automapper/templates/icebox/icebox_ntrep_office.dmm
+++ b/_maps/skyrat/automapper/templates/icebox/icebox_ntrep_office.dmm
@@ -13,10 +13,10 @@
pixel_x = -6
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"an" = (
/turf/closed/wall/r_wall,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"aB" = (
/obj/structure/chair/sofa/bench/left{
dir = 1
@@ -45,7 +45,7 @@
/obj/effect/turf_decal/siding/wood,
/obj/structure/filingcabinet/chestdrawer,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"cn" = (
/turf/closed/mineral/random/snow,
/area/icemoon/underground/explored)
@@ -61,7 +61,7 @@
dir = 4
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"dX" = (
/obj/machinery/door/airlock/maintenance,
/obj/structure/cable,
@@ -134,7 +134,7 @@
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"hX" = (
/obj/structure/flora/rock/icy/style_random,
/turf/open/misc/asteroid/snow/icemoon,
@@ -148,7 +148,7 @@
dir = 8
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"kL" = (
/turf/open/floor/iron/dark,
/area/mine/storage)
@@ -164,7 +164,7 @@
"lJ" = (
/obj/structure/fireplace,
/turf/open/floor/iron/dark,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"lX" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/mapping_helpers/broken_floor,
@@ -193,7 +193,7 @@
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"oP" = (
/obj/machinery/light/directional/east,
/turf/open/misc/asteroid/snow/icemoon,
@@ -226,7 +226,7 @@
/obj/machinery/light/directional/north,
/obj/machinery/status_display/ai/directional/north,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"qr" = (
/obj/structure/flora/grass/green/style_random,
/turf/open/misc/asteroid/snow/icemoon,
@@ -240,17 +240,17 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"sV" = (
/obj/structure/chair/office{
dir = 8
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"tw" = (
/obj/structure/filingcabinet/employment,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"tD" = (
/obj/machinery/modular_computer/preset/command{
dir = 4
@@ -266,7 +266,7 @@
pixel_y = -8
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"uu" = (
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
@@ -305,7 +305,7 @@
},
/obj/item/pen/fountain,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"vS" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 4
@@ -323,7 +323,7 @@
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"yt" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/item/radio/intercom/directional/south,
@@ -338,7 +338,7 @@
/obj/machinery/light/directional/west,
/obj/item/radio/intercom/directional/west,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"zD" = (
/obj/structure/table/wood,
/obj/item/folder/yellow,
@@ -353,11 +353,11 @@
},
/obj/machinery/airalarm/directional/east,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"zQ" = (
/obj/effect/landmark/start/nanotrasen_consultant,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Ag" = (
/obj/effect/spawner/random/trash/hobo_squat,
/obj/effect/mapping_helpers/broken_floor,
@@ -379,7 +379,7 @@
dir = 4
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Ct" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 4
@@ -413,7 +413,7 @@
},
/obj/effect/landmark/start/nanotrasen_consultant,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Fk" = (
/turf/open/genturf/blue,
/area/icemoon/underground/unexplored/rivers/deep/shoreline)
@@ -422,7 +422,7 @@
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Hy" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/door/poddoor/preopen{
@@ -430,7 +430,7 @@
name = "Privacy Shutter"
},
/turf/open/floor/plating,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"HF" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -477,7 +477,7 @@
name = "Nanotrasen Consultant's Fax Machine"
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Kq" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -489,7 +489,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/landmark/start/nanotrasen_consultant,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Lj" = (
/turf/closed/wall/r_wall,
/area/mine/storage)
@@ -512,7 +512,7 @@
/obj/machinery/light/directional/east,
/obj/machinery/light_switch/directional/south,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Nb" = (
/obj/effect/spawner/random/engineering/atmospherics_portable,
/turf/open/floor/plating,
@@ -564,7 +564,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Qm" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/obj/machinery/light/directional/east,
@@ -580,7 +580,7 @@
},
/obj/item/radio/intercom/directional/east,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Rd" = (
/obj/machinery/door/airlock/external{
glass = 1;
@@ -611,14 +611,14 @@
"RH" = (
/obj/item/kirbyplants/random,
/turf/open/floor/iron/dark,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"RJ" = (
/obj/effect/landmark/start/assistant,
/turf/open/floor/iron,
/area/station/hallway/primary/central)
"RS" = (
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"ST" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/mapping_helpers/burnt_floor,
@@ -628,7 +628,7 @@
/obj/machinery/power/apc/auto_name/directional/north,
/obj/structure/cable,
/turf/open/floor/iron/dark,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Uj" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/door/poddoor/preopen{
@@ -636,7 +636,7 @@
name = "Wildlife Observation Shutters"
},
/turf/open/floor/plating,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Xo" = (
/obj/structure/sign/warning/directional/north,
/turf/open/misc/asteroid/snow/icemoon,
@@ -679,7 +679,7 @@
"YS" = (
/obj/machinery/photocopier,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
(1,1,1) = {"
qr
diff --git a/_maps/skyrat/automapper/templates/icebox/icebox_supermatter.dmm b/_maps/skyrat/automapper/templates/icebox/icebox_supermatter.dmm
index 8c6304ec809..07732061300 100644
--- a/_maps/skyrat/automapper/templates/icebox/icebox_supermatter.dmm
+++ b/_maps/skyrat/automapper/templates/icebox/icebox_supermatter.dmm
@@ -2,22 +2,41 @@
"a" = (
/turf/template_noop,
/area/template_noop)
-"t" = (
+"c" = (
/obj/machinery/button/delam_scram,
/turf/template_noop,
/area/template_noop)
-"x" = (
-/obj/item/folder/biscuit/confidential/delam,
-/turf/template_noop,
-/area/template_noop)
-"H" = (
+"i" = (
/obj/effect/turf_decal/stripes/red/box,
/turf/template_noop,
/area/template_noop)
-"J" = (
+"n" = (
+/obj/effect/spawner/structure/window/reinforced/plasma,
+/turf/template_noop,
+/area/station/engineering/supermatter/room)
+"p" = (
/obj/machinery/atmospherics/components/unary/delam_scram/directional/east,
/turf/template_noop,
/area/template_noop)
+"s" = (
+/obj/structure/sign/delam_procedure,
+/turf/closed/wall/r_wall,
+/area/station/engineering/supermatter/room)
+"y" = (
+/obj/effect/turf_decal/stripes/red/box,
+/turf/open/floor/engine,
+/area/station/engineering/supermatter/room)
+"H" = (
+/obj/structure/table/reinforced,
+/obj/item/clothing/suit/utility/radiation,
+/obj/item/clothing/head/utility/radiation,
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/item/geiger_counter,
+/obj/item/clothing/glasses/meson,
+/turf/open/floor/engine,
+/area/station/engineering/supermatter/room)
(1,1,1) = {"
a
@@ -30,7 +49,7 @@ a
a
a
a
-J
+p
"}
(2,1,1) = {"
a
@@ -46,9 +65,9 @@ a
a
"}
(3,1,1) = {"
-H
-t
-H
+i
+c
+y
a
a
a
@@ -60,7 +79,33 @@ a
"}
(4,1,1) = {"
a
-x
+s
+H
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(5,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(6,1,1) = {"
+a
+n
a
a
a
diff --git a/_maps/skyrat/automapper/templates/kilostation/kilostation_ert_bay.dmm b/_maps/skyrat/automapper/templates/kilostation/kilostation_ert_bay.dmm
index 7e94976b7cc..34e0fbcad74 100644
--- a/_maps/skyrat/automapper/templates/kilostation/kilostation_ert_bay.dmm
+++ b/_maps/skyrat/automapper/templates/kilostation/kilostation_ert_bay.dmm
@@ -13,7 +13,7 @@
/obj/machinery/newscaster/directional/east,
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"bb" = (
/obj/machinery/door/airlock/maintenance/external{
name = "Transit Intersection"
@@ -67,7 +67,7 @@
/obj/machinery/airalarm/directional/north,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"cc" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 4
@@ -82,7 +82,7 @@
"cm" = (
/obj/structure/filingcabinet/employment,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"cW" = (
/obj/structure/fans/tiny/forcefield{
dir = 1
@@ -98,7 +98,7 @@
/obj/item/assembly/flash/handheld,
/obj/machinery/status_display/ai/directional/north,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"df" = (
/obj/machinery/disposal/bin,
/obj/structure/disposalpipe/trunk{
@@ -241,7 +241,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"fA" = (
/obj/structure/disposalpipe/segment,
/obj/structure/window/reinforced/spawner/directional/north,
@@ -344,7 +344,7 @@
},
/obj/machinery/holopad,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"ha" = (
/obj/structure/sign/departments/holy{
pixel_y = 30
@@ -492,7 +492,7 @@
id = "nt_rep_priv_2"
},
/turf/open/floor/plating,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"kE" = (
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
@@ -568,7 +568,7 @@
/area/station/hallway/primary/fore)
"mZ" = (
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"nc" = (
/obj/effect/turf_decal/sand/plating,
/obj/structure/disposalpipe/segment,
@@ -657,11 +657,11 @@
id = "nt_rep_priv"
},
/turf/open/floor/plating,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"oZ" = (
/obj/effect/decal/cleanable/dirt,
/turf/closed/wall/r_wall/rust,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"pf" = (
/turf/closed/wall,
/area/station/maintenance/fore)
@@ -712,7 +712,7 @@
pixel_x = -2
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"qS" = (
/obj/effect/turf_decal/tile/neutral{
dir = 4
@@ -770,7 +770,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"rT" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
@@ -821,7 +821,7 @@
/obj/effect/landmark/start/nanotrasen_consultant,
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"uj" = (
/obj/structure/lattice,
/obj/structure/grille/broken,
@@ -909,7 +909,7 @@
},
/obj/item/camera_film,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"vV" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/stripes/line,
@@ -961,10 +961,10 @@
},
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"xV" = (
/turf/closed/wall/r_wall/rust,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"yd" = (
/obj/structure/chair/sofa/bench/left{
dir = 1
@@ -984,7 +984,7 @@
/area/space/nearstation)
"zb" = (
/turf/closed/wall/r_wall,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"ze" = (
/obj/machinery/light/directional/south,
/obj/effect/turf_decal/stripes/corner{
@@ -1001,7 +1001,7 @@
/obj/machinery/light/directional/east,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"zF" = (
/obj/structure/table/wood,
/obj/item/paper_bin{
@@ -1009,7 +1009,7 @@
},
/obj/item/pen/fountain,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"zR" = (
/obj/effect/spawner/structure/window,
/obj/structure/curtain/cloth/fancy/mechanical{
@@ -1052,7 +1052,7 @@
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Bx" = (
/obj/structure/disposalpipe/segment{
dir = 6
@@ -1091,7 +1091,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/firealarm/directional/south,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Cm" = (
/obj/structure/flora/rock/style_random,
/turf/open/misc/asteroid/airless,
@@ -1133,7 +1133,7 @@
/area/station/hallway/primary/fore)
"DJ" = (
/turf/closed/wall/rust,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Ef" = (
/obj/machinery/light/directional/north,
/obj/effect/turf_decal/stripes/line{
@@ -1178,7 +1178,7 @@
/obj/effect/landmark/start/nanotrasen_consultant,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"EG" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -1188,7 +1188,7 @@
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"EI" = (
/obj/effect/turf_decal/tile/purple/opposingcorners{
dir = 8
@@ -1227,7 +1227,7 @@
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Fg" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -1391,7 +1391,7 @@
pixel_x = -4
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Ja" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -1414,7 +1414,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Jn" = (
/obj/structure/chair/sofa/bench{
dir = 8
@@ -1446,7 +1446,7 @@
name = "Privacy Shutters Control"
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"KE" = (
/obj/effect/turf_decal/stripes/line{
dir = 8
@@ -1522,7 +1522,7 @@
},
/obj/structure/filingcabinet/chestdrawer,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Nu" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
@@ -1592,7 +1592,7 @@
dir = 4
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"OY" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -1728,7 +1728,7 @@
dir = 1
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Th" = (
/obj/effect/decal/cleanable/dirt,
/obj/item/radio/intercom/directional/east,
@@ -1831,7 +1831,7 @@
/turf/open/floor/iron/dark/corner{
dir = 4
},
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"WY" = (
/obj/effect/turf_decal/tile/blue{
dir = 4
@@ -1900,7 +1900,7 @@
"YD" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"YS" = (
/obj/effect/turf_decal/sand/plating,
/obj/structure/disposalpipe/segment{
@@ -1912,7 +1912,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Ze" = (
/obj/structure/transit_tube/crossing,
/obj/effect/turf_decal/sand/plating,
@@ -1927,7 +1927,7 @@
"ZN" = (
/obj/structure/table/wood,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
(1,1,1) = {"
Gh
diff --git a/_maps/skyrat/automapper/templates/metastation/metastation_ntrep_office.dmm b/_maps/skyrat/automapper/templates/metastation/metastation_ntrep_office.dmm
index 11fb07a577f..c18d33363e6 100644
--- a/_maps/skyrat/automapper/templates/metastation/metastation_ntrep_office.dmm
+++ b/_maps/skyrat/automapper/templates/metastation/metastation_ntrep_office.dmm
@@ -6,7 +6,7 @@
name = "Privacy Shutter"
},
/turf/open/floor/plating,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"b" = (
/obj/structure/table/wood,
/obj/item/camera_film{
@@ -17,7 +17,7 @@
pixel_y = 4
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"d" = (
/turf/closed/wall/r_wall,
/area/station/maintenance/port)
@@ -27,7 +27,7 @@
},
/obj/machinery/holopad,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"f" = (
/obj/machinery/button/door/directional/west{
id = "nt_rep_priv";
@@ -52,14 +52,14 @@
pixel_y = 6
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"g" = (
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"i" = (
/obj/item/kirbyplants/random,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"j" = (
/obj/structure/sign/poster/official/random/directional/south,
/obj/structure/chair/office{
@@ -67,16 +67,16 @@
},
/obj/effect/landmark/start/nanotrasen_consultant,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"k" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"l" = (
/obj/structure/cable,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"p" = (
/obj/effect/turf_decal/tile/neutral{
dir = 8
@@ -85,43 +85,43 @@
/area/station/hallway/primary/port)
"q" = (
/turf/closed/wall,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"s" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 4
},
/obj/machinery/status_display/ai/directional/west,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"u" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"v" = (
/obj/machinery/camera/directional/west{
c_tag = "NT Consultant's Office";
name = "command camera"
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"w" = (
/obj/structure/table/wood,
/obj/item/stamp/centcom{
pixel_x = 8
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"x" = (
/obj/machinery/light/directional/west,
/obj/machinery/modular_computer/preset/command{
dir = 4
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"y" = (
/obj/machinery/firealarm/directional/east,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"z" = (
/obj/structure/table/wood,
/obj/item/paper_bin{
@@ -129,18 +129,18 @@
},
/obj/item/pen/fountain,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"A" = (
/obj/machinery/airalarm/directional/east,
/obj/machinery/light/directional/east,
/obj/structure/closet/secure_closet/nanotrasen_consultant/station,
/obj/item/assembly/flash/handheld,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"B" = (
/obj/structure/filingcabinet/employment,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"C" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -148,7 +148,7 @@
dir = 4
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"D" = (
/turf/template_noop,
/area/template_noop)
@@ -156,14 +156,14 @@
/obj/item/kirbyplants/random,
/obj/machinery/airalarm/directional/south,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"F" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/light_switch/directional/east,
/obj/effect/turf_decal/siding/wood/corner,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"I" = (
/obj/structure/table/wood,
/obj/machinery/fax{
@@ -171,18 +171,18 @@
name = "Nanotrasen Consultant's Fax Machine"
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"L" = (
/obj/structure/chair/office{
dir = 8
},
/obj/effect/landmark/start/nanotrasen_consultant,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"M" = (
/obj/machinery/status_display/ai/directional/east,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"N" = (
/obj/structure/chair/office{
dir = 4
@@ -191,14 +191,14 @@
dir = 4
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"O" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 4
},
/obj/item/radio/intercom/directional/south,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"P" = (
/obj/structure/table/wood,
/obj/item/stamp/denied{
@@ -210,7 +210,7 @@
pixel_y = 6
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Q" = (
/obj/machinery/door/airlock/corporate{
name = "NT Consultant's Office"
@@ -220,18 +220,18 @@
/obj/effect/mapping_helpers/airlock/access/all/cent_com/rep_door,
/obj/machinery/door/firedoor,
/turf/open/floor/iron,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"S" = (
/obj/machinery/newscaster/directional/north,
/obj/structure/filingcabinet/chestdrawer,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"T" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"V" = (
/obj/machinery/door/airlock/maintenance,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -240,13 +240,13 @@
/area/station/maintenance/port)
"Y" = (
/turf/closed/wall/r_wall,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Z" = (
/obj/structure/cable,
/obj/machinery/power/apc/auto_name/directional/west,
/obj/machinery/photocopier,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
(1,1,1) = {"
D
diff --git a/_maps/skyrat/automapper/templates/metastation/metastation_supermatter.dmm b/_maps/skyrat/automapper/templates/metastation/metastation_supermatter.dmm
index dae4b01581d..280a852105d 100644
--- a/_maps/skyrat/automapper/templates/metastation/metastation_supermatter.dmm
+++ b/_maps/skyrat/automapper/templates/metastation/metastation_supermatter.dmm
@@ -21,9 +21,9 @@
/turf/open/floor/engine,
/area/station/engineering/supermatter/room)
"R" = (
-/obj/item/folder/biscuit/confidential/delam,
-/turf/template_noop,
-/area/template_noop)
+/obj/structure/sign/delam_procedure,
+/turf/closed/wall/r_wall,
+/area/station/engineering/supermatter/room)
"V" = (
/obj/machinery/atmospherics/components/unary/delam_scram/directional/west,
/turf/template_noop,
diff --git a/_maps/skyrat/automapper/templates/northstar/northstar_ntrep_office.dmm b/_maps/skyrat/automapper/templates/northstar/northstar_ntrep_office.dmm
index abbfb683347..f797c7905a7 100644
--- a/_maps/skyrat/automapper/templates/northstar/northstar_ntrep_office.dmm
+++ b/_maps/skyrat/automapper/templates/northstar/northstar_ntrep_office.dmm
@@ -2,13 +2,13 @@
"a" = (
/obj/structure/filingcabinet/employment,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"b" = (
/obj/machinery/light/warm/directional/south,
/obj/machinery/newscaster/directional/south,
/obj/effect/landmark/start/nanotrasen_consultant,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"c" = (
/obj/machinery/door/airlock/corporate{
name = "NT Consultant's Office";
@@ -20,7 +20,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/door/firedoor,
/turf/open/floor/plating,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"e" = (
/obj/structure/table/wood,
/obj/machinery/fax{
@@ -28,12 +28,12 @@
name = "Nanotrasen Consultant's Fax Machine"
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"g" = (
/obj/effect/turf_decal/siding/wood,
/obj/structure/chair/comfy/black,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"h" = (
/obj/effect/turf_decal/siding/wood{
dir = 4
@@ -43,17 +43,17 @@
/obj/structure/cable,
/obj/machinery/light/warm/directional/north,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"i" = (
/obj/effect/turf_decal/siding/wood,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"j" = (
/obj/structure/chair/comfy/black{
dir = 1
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"k" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -72,7 +72,7 @@
pixel_x = -4
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"q" = (
/obj/structure/table/wood,
/obj/item/paper_bin/carbon{
@@ -102,7 +102,7 @@
pixel_x = -37
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"r" = (
/obj/structure/table/wood,
/obj/item/stamp/centcom{
@@ -111,7 +111,7 @@
},
/obj/item/folder/blue,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"s" = (
/obj/effect/turf_decal/siding/wood/corner{
dir = 4
@@ -119,7 +119,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/cable,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"t" = (
/obj/machinery/light_switch/directional/north,
/obj/machinery/disposal/bin,
@@ -127,7 +127,7 @@
dir = 4
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"u" = (
/obj/effect/turf_decal/siding/wood{
dir = 8
@@ -136,21 +136,21 @@
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"v" = (
/obj/structure/closet/secure_closet/nanotrasen_consultant/station,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"w" = (
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"y" = (
/turf/closed/wall/r_wall,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"z" = (
/obj/structure/filingcabinet/chestdrawer,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"A" = (
/obj/effect/turf_decal/siding/wood/corner{
dir = 8
@@ -160,13 +160,13 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/cable,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"B" = (
/obj/effect/turf_decal/siding/wood,
/obj/structure/chair/comfy/black,
/obj/machinery/airalarm/directional/west,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"D" = (
/turf/template_noop,
/area/template_noop)
@@ -179,14 +179,14 @@
/obj/machinery/door/firedoor,
/obj/effect/mapping_helpers/airlock/access/all/cent_com/rep_door,
/turf/open/floor/iron,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"F" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"H" = (
/obj/machinery/camera/autoname/directional/east,
/obj/item/radio/intercom/directional/east{
@@ -196,11 +196,11 @@
dir = 8
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"I" = (
/obj/structure/extinguisher_cabinet/directional/east,
/turf/open/floor/iron/textured_edge,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"J" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -209,15 +209,15 @@
dir = 1
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"L" = (
/obj/machinery/firealarm/directional/west,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"O" = (
/obj/structure/fireplace,
/turf/open/floor/iron/textured_edge,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Q" = (
/obj/structure/table/wood,
/obj/item/camera{
@@ -233,7 +233,7 @@
pixel_y = 7
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"R" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/door/poddoor/preopen{
@@ -241,33 +241,33 @@
name = "Privacy Shutter"
},
/turf/open/floor/plating,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"V" = (
/obj/structure/sign/flag/nanotrasen/directional/north,
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/turf/open/floor/iron/textured_edge,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"W" = (
/obj/item/kirbyplants/monkey,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"X" = (
/obj/structure/disposalpipe/segment{
dir = 9
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Y" = (
/obj/machinery/modular_computer/preset/command{
dir = 4
},
/obj/structure/sign/calendar/directional/west,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Z" = (
/obj/machinery/light_switch/directional/south,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
(1,1,1) = {"
y
diff --git a/_maps/skyrat/automapper/templates/northstar/northstar_supermatter.dmm b/_maps/skyrat/automapper/templates/northstar/northstar_supermatter.dmm
index 2c83fd47def..a02542f376a 100644
--- a/_maps/skyrat/automapper/templates/northstar/northstar_supermatter.dmm
+++ b/_maps/skyrat/automapper/templates/northstar/northstar_supermatter.dmm
@@ -1,84 +1,170 @@
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
"a" = (
+/turf/template_noop,
+/area/template_noop)
+"b" = (
/obj/machinery/atmospherics/components/unary/delam_scram/directional/west,
/turf/template_noop,
/area/template_noop)
+"c" = (
+/obj/effect/spawner/structure/window/reinforced/plasma,
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/station/engineering/supermatter/room)
+"e" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/incident_display/delam/directional/north,
+/turf/open/floor/iron,
+/area/station/engineering/lobby)
+"n" = (
+/obj/machinery/button/door/directional/north{
+ id = "Secure Storage";
+ req_access = list("engineering")
+ },
+/turf/template_noop,
+/area/template_noop)
+"o" = (
+/obj/structure/sign/delam_procedure/directional/west,
+/turf/template_noop,
+/area/template_noop)
"q" = (
/obj/effect/turf_decal/stripes/red/box,
/turf/template_noop,
/area/template_noop)
-"s" = (
+"v" = (
/obj/structure/cable,
-/obj/machinery/incident_display/delam/directional/north,
/turf/open/floor/iron/half{
dir = 1
},
/area/station/engineering/lobby)
-"x" = (
-/turf/template_noop,
-/area/template_noop)
-"I" = (
-/obj/effect/spawner/structure/window/reinforced/plasma,
+"y" = (
+/obj/effect/turf_decal/tile/red{
+ dir = 8
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/cable,
-/obj/item/folder/biscuit/confidential/delam,
-/turf/open/floor/plating,
-/area/station/engineering/supermatter/room)
-"O" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/engineering/lobby)
+"A" = (
/obj/machinery/button/delam_scram,
/turf/closed/wall/r_wall,
/area/station/engineering/supermatter/room)
-"S" = (
+"C" = (
/obj/effect/turf_decal/stripes/red/box,
/turf/open/floor/iron/half{
dir = 1
},
/area/station/engineering/lobby)
+"P" = (
+/obj/structure/sign/delam_procedure,
+/turf/template_noop,
+/area/template_noop)
(1,1,1) = {"
-s
-S
-x
-x
-"}
-(2,1,1) = {"
-I
-O
-x
-x
-"}
-(3,1,1) = {"
-x
-q
-x
-x
-"}
-(4,1,1) = {"
-x
-x
-x
-x
-"}
-(5,1,1) = {"
-x
-x
-x
-x
-"}
-(6,1,1) = {"
-x
-x
-x
-x
-"}
-(7,1,1) = {"
-x
-x
-x
-x
-"}
-(8,1,1) = {"
-x
-x
-x
+n
+a
+a
+a
+a
+a
a
"}
+(2,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+"}
+(3,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+"}
+(4,1,1) = {"
+e
+a
+P
+v
+C
+a
+a
+"}
+(5,1,1) = {"
+y
+a
+a
+c
+A
+a
+a
+"}
+(6,1,1) = {"
+a
+a
+a
+a
+q
+o
+a
+"}
+(7,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+"}
+(8,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+"}
+(9,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+"}
+(10,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+"}
+(11,1,1) = {"
+a
+a
+a
+a
+a
+a
+b
+"}
diff --git a/_maps/skyrat/automapper/templates/tramstation/tramstation_ntrep_office.dmm b/_maps/skyrat/automapper/templates/tramstation/tramstation_ntrep_office.dmm
index 9cc955b7652..bd1e3e8870c 100644
--- a/_maps/skyrat/automapper/templates/tramstation/tramstation_ntrep_office.dmm
+++ b/_maps/skyrat/automapper/templates/tramstation/tramstation_ntrep_office.dmm
@@ -1,13 +1,13 @@
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
"a" = (
/turf/closed/wall,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"b" = (
/obj/machinery/modular_computer/preset/command{
dir = 1
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"c" = (
/obj/structure/table/wood,
/obj/item/paper_bin/carbon{
@@ -28,11 +28,11 @@
/obj/machinery/newscaster/directional/south,
/obj/item/radio/intercom/directional/west,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"e" = (
/obj/structure/closet/secure_closet/nanotrasen_consultant/station,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"f" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/door/poddoor/preopen{
@@ -41,21 +41,21 @@
},
/obj/structure/cable,
/turf/open/floor/plating,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"g" = (
/obj/effect/turf_decal/siding/wood{
dir = 4
},
/obj/machinery/firealarm/directional/north,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"h" = (
/obj/effect/turf_decal/siding/wood,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 4
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"i" = (
/obj/structure/cable,
/obj/machinery/power/apc/auto_name/directional/north,
@@ -64,20 +64,20 @@
dir = 8
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"j" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"k" = (
/obj/effect/turf_decal/siding/wood{
dir = 8
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"l" = (
/obj/structure/cable,
/obj/structure/chair/comfy/black{
@@ -87,12 +87,12 @@
dir = 1
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"m" = (
/obj/effect/turf_decal/siding/wood,
/obj/structure/sign/flag/nanotrasen/directional/north,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"n" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -101,7 +101,7 @@
dir = 4
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"o" = (
/obj/structure/cable,
/obj/structure/table/wood,
@@ -109,16 +109,16 @@
dir = 8
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"p" = (
/obj/structure/filingcabinet/employment,
/obj/effect/turf_decal/siding/wood,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"q" = (
/obj/structure/table/wood,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"r" = (
/obj/structure/cable,
/obj/machinery/door/airlock/corporate{
@@ -128,10 +128,10 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/door/firedoor,
/turf/open/floor/iron/dark/textured_large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"s" = (
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"t" = (
/obj/structure/table/wood,
/obj/item/stamp/centcom{
@@ -139,23 +139,23 @@
pixel_x = -7
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"u" = (
/obj/machinery/button/door/directional/west{
id = "nt_rep_priv";
name = "Privacy Shutters Control"
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"v" = (
/obj/item/kirbyplants/random,
/obj/machinery/airalarm/directional/north,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"w" = (
/obj/item/radio/intercom/directional/east,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"x" = (
/obj/effect/turf_decal/siding/wood/corner{
dir = 4
@@ -165,12 +165,12 @@
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"y" = (
/obj/effect/turf_decal/siding/wood,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"A" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -179,10 +179,10 @@
dir = 8
},
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"B" = (
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"C" = (
/obj/structure/table/wood,
/obj/item/camera{
@@ -198,7 +198,7 @@
pixel_y = 7
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"E" = (
/obj/structure/table/wood,
/obj/machinery/fax{
@@ -206,13 +206,13 @@
name = "Nanotrasen Consultant's Fax Machine"
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"F" = (
/obj/item/kirbyplants/random,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/light_switch/directional/south,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"G" = (
/obj/effect/turf_decal/siding/wood{
dir = 4
@@ -222,27 +222,27 @@
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"H" = (
/obj/machinery/light/warm/directional/west,
/obj/structure/sign/calendar/directional/west,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"J" = (
/obj/machinery/status_display/evac/directional/north,
/obj/machinery/light/warm/directional/north,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"K" = (
/obj/machinery/photocopier,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"M" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"N" = (
/obj/effect/turf_decal/siding/wood{
dir = 4
@@ -252,12 +252,12 @@
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"O" = (
/obj/structure/chair/office,
/obj/effect/landmark/start/nanotrasen_consultant,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Q" = (
/obj/structure/cable,
/obj/effect/turf_decal/siding/wood{
@@ -266,18 +266,18 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"T" = (
/obj/structure/sign/clock/directional/east,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"U" = (
/obj/machinery/status_display/ai/directional/east,
/obj/structure/chair/comfy/black{
dir = 8
},
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"V" = (
/obj/structure/filingcabinet/chestdrawer,
/obj/effect/turf_decal/siding/wood{
@@ -286,18 +286,18 @@
/obj/machinery/light/warm/directional/east,
/obj/structure/extinguisher_cabinet/directional/east,
/turf/open/floor/wood,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"W" = (
/obj/structure/chair/comfy/black,
/obj/machinery/newscaster/directional/north,
/obj/machinery/light/warm/directional/north,
/turf/open/floor/carpet/executive,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
"Z" = (
/obj/machinery/holopad,
/obj/effect/turf_decal/bot,
/turf/open/floor/iron/dark/textured_large,
-/area/command/heads_quarters/captain/private/nt_rep)
+/area/station/command/heads_quarters/nt_rep)
(1,1,1) = {"
a
diff --git a/_maps/skyrat/automapper/templates/tramstation/tramstation_supermatter.dmm b/_maps/skyrat/automapper/templates/tramstation/tramstation_supermatter.dmm
index a8b22dcfaa5..ca7e23d65df 100644
--- a/_maps/skyrat/automapper/templates/tramstation/tramstation_supermatter.dmm
+++ b/_maps/skyrat/automapper/templates/tramstation/tramstation_supermatter.dmm
@@ -3,9 +3,10 @@
/turf/template_noop,
/area/template_noop)
"k" = (
-/obj/item/folder/biscuit/confidential/delam,
-/turf/template_noop,
-/area/template_noop)
+/obj/effect/turf_decal/stripes/red/box,
+/obj/structure/sign/delam_procedure,
+/turf/closed/wall/r_wall,
+/area/station/engineering/supermatter/room)
"l" = (
/obj/machinery/power/apc/auto_name/directional/east,
/obj/structure/cable,
diff --git a/_maps/skyrat/lazy_templates/reebe.dmm b/_maps/skyrat/lazy_templates/reebe.dmm
index d918d65d743..e79eefb3cd6 100644
--- a/_maps/skyrat/lazy_templates/reebe.dmm
+++ b/_maps/skyrat/lazy_templates/reebe.dmm
@@ -68,6 +68,10 @@
/obj/structure/fluff/clockwork/blind_eye,
/turf/open/floor/bronze,
/area/ruin/powered/reebe)
+"hU" = (
+/obj/structure/fluff/clockwork/alloy_shards,
+/turf/open/floor/bronze/flat,
+/area/ruin/powered/reebe)
"iJ" = (
/turf/open/floor/bronze,
/area/ruin/powered/reebe)
@@ -101,6 +105,10 @@
},
/turf/open/floor/bronze/filled,
/area/ruin/powered/reebe)
+"mj" = (
+/obj/structure/destructible/clockwork/gear_base/powered/prosperity_prism,
+/turf/open/floor/bronze/flat,
+/area/ruin/powered/reebe)
"mx" = (
/obj/effect/rune/convert,
/turf/open/floor/bronze/flat,
@@ -116,10 +124,6 @@
"mL" = (
/turf/open/indestructible/reebe_void,
/area/ruin/powered/reebe/space)
-"nh" = (
-/obj/structure/destructible/clockwork/gear_base/powered/prosperity_prism,
-/turf/open/floor/bronze/flat,
-/area/ruin/powered/reebe)
"nx" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/table/bronze,
@@ -206,10 +210,6 @@
/obj/effect/landmark/late_cog_portals,
/turf/open/floor/bronze/flat,
/area/ruin/powered/reebe)
-"uT" = (
-/obj/structure/fluff/clockwork/alloy_shards,
-/turf/open/floor/bronze/flat,
-/area/ruin/powered/reebe)
"ve" = (
/obj/effect/spawner/structure/window/bronze,
/turf/open/floor/bronze,
@@ -217,19 +217,25 @@
"vA" = (
/obj/structure/table/bronze,
/obj/item/gun/ballistic/rifle/lionhunter/clockwork,
-/obj/item/ammo_box/strilka310/lionhunter/clock{
+/obj/item/ammo_box/a762/lionhunter/clock{
pixel_x = 12;
pixel_y = 9
},
-/obj/item/ammo_box/strilka310/lionhunter/clock{
+/obj/item/ammo_box/a762/lionhunter/clock{
pixel_x = -12;
pixel_y = 9
},
-/obj/item/ammo_box/strilka310/lionhunter/clock{
+/obj/item/ammo_box/a762/lionhunter/clock{
pixel_y = 9
},
/turf/open/floor/bronze/flat,
/area/ruin/powered/reebe)
+"vV" = (
+/obj/effect/rune/teleport{
+ cultist_name = "Reebe"
+ },
+/turf/open/floor/bronze/flat,
+/area/ruin/powered/reebe)
"wu" = (
/obj/structure/fluff/clockwork/alloy_shards/small{
pixel_x = -4;
@@ -290,6 +296,10 @@
},
/turf/open/floor/bronze,
/area/ruin/powered/reebe)
+"Cj" = (
+/obj/structure/door_assembly/door_assembly_bronze/clock,
+/turf/open/floor/bronze/flat,
+/area/ruin/powered/reebe)
"FD" = (
/obj/effect/portal/permanent/one_way/reebe/leaving,
/turf/open/floor/bronze/filled,
@@ -345,9 +355,13 @@
/obj/structure/fluff/clockwork/blind_eye,
/turf/open/floor/bronze,
/area/ruin/powered/reebe)
-"On" = (
-/obj/effect/rune/teleport,
-/turf/open/floor/bronze/flat,
+"Nh" = (
+/obj/item/ectoplasm,
+/turf/open/indestructible/reebe_void,
+/area/ruin/powered/reebe/space)
+"Nw" = (
+/obj/structure/door_assembly/door_assembly_bronze/clock,
+/turf/open/floor/bronze,
/area/ruin/powered/reebe)
"Os" = (
/obj/item/stack/sheet/mineral/wood,
@@ -379,7 +393,7 @@
/obj/machinery/door/airlock/bronze,
/turf/open/floor/bronze,
/area/ruin/powered/reebe)
-"PD" = (
+"PZ" = (
/obj/structure/destructible/clockwork/gear_base/technologists_lectern,
/turf/open/floor/bronze/flat,
/area/ruin/powered/reebe)
@@ -436,18 +450,10 @@
/obj/item/clockwork/weapon/brass_spear,
/turf/open/floor/bronze/filled,
/area/ruin/powered/reebe)
-"UJ" = (
-/obj/structure/door_assembly/door_assembly_bronze/clock,
-/turf/open/floor/bronze,
-/area/ruin/powered/reebe)
"Vv" = (
/obj/structure/fluff/clockwork/clockgolem_remains,
/turf/open/floor/bronze/flat,
/area/ruin/powered/reebe)
-"Xu" = (
-/obj/structure/door_assembly/door_assembly_bronze/clock,
-/turf/open/floor/bronze/flat,
-/area/ruin/powered/reebe)
"XZ" = (
/obj/effect/mob_spawn/corpse/human/blood_cultist,
/obj/structure/fluff/clockwork/alloy_shards/large{
@@ -1160,7 +1166,7 @@ ve
My
yd
qS
-UJ
+Nw
xd
Pi
xd
@@ -1464,7 +1470,7 @@ QX
QX
ve
yL
-Xu
+Cj
xd
iJ
ve
@@ -1632,7 +1638,7 @@ ny
Bm
Pi
Pi
-PD
+PZ
qS
qS
ve
@@ -1641,7 +1647,7 @@ ve
qS
aj
xd
-UJ
+Nw
aj
qS
qS
@@ -1681,7 +1687,7 @@ Pi
iJ
qS
Pi
-uT
+hU
iJ
xd
Pi
@@ -1787,7 +1793,7 @@ qS
Pi
xd
iJ
-uT
+hU
Pi
sw
oh
@@ -1836,7 +1842,7 @@ ve
ve
qS
qS
-nh
+mj
Pi
Pi
Pi
@@ -1984,7 +1990,7 @@ QX
QX
ve
iJ
-On
+vV
FM
iJ
ve
@@ -2919,7 +2925,7 @@ mL
mL
mL
mL
-mL
+Nh
mL
mL
mL
diff --git a/_maps/templates/holodeck_medicalsim.dmm b/_maps/templates/holodeck_medicalsim.dmm
index 98f5a92da7f..acc38d02c58 100644
--- a/_maps/templates/holodeck_medicalsim.dmm
+++ b/_maps/templates/holodeck_medicalsim.dmm
@@ -244,7 +244,7 @@
/area/template_noop)
"wV" = (
/obj/structure/window/spawner/directional/north,
-/obj/structure/bed/roller,
+/obj/structure/bed/medical/emergency,
/obj/effect/turf_decal/tile/blue/half/contrasted{
dir = 1
},
diff --git a/_maps/templates/lazy_templates/abductor_ships.dmm b/_maps/templates/lazy_templates/abductor_ships.dmm
index 0e33b8d3922..4c7d2e172ff 100644
--- a/_maps/templates/lazy_templates/abductor_ships.dmm
+++ b/_maps/templates/lazy_templates/abductor_ships.dmm
@@ -1,4 +1,10 @@
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"aa" = (
+/turf/open/water,
+/area/awaymission/beach)
+"ab" = (
+/turf/open/lava,
+/area/awaymission/caves)
"bX" = (
/turf/closed/indestructible/abductor{
icon_state = "alien11"
@@ -592,3 +598,515 @@ bX
Zf
Xy
"}
+
+(1,1,2) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(2,1,2) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(3,1,2) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(4,1,2) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(5,1,2) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(6,1,2) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(7,1,2) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(8,1,2) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(9,1,2) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(10,1,2) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(11,1,2) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(12,1,2) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(13,1,2) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(14,1,2) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(15,1,2) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+
+(1,1,3) = {"
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(2,1,3) = {"
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(3,1,3) = {"
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(4,1,3) = {"
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(5,1,3) = {"
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(6,1,3) = {"
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(7,1,3) = {"
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(8,1,3) = {"
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(9,1,3) = {"
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(10,1,3) = {"
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(11,1,3) = {"
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(12,1,3) = {"
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(13,1,3) = {"
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(14,1,3) = {"
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(15,1,3) = {"
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
diff --git a/_maps/templates/heretic_sacrifice_template.dmm b/_maps/templates/lazy_templates/heretic_sacrifice.dmm
similarity index 82%
rename from _maps/templates/heretic_sacrifice_template.dmm
rename to _maps/templates/lazy_templates/heretic_sacrifice.dmm
index d0277a1e712..cbabb4c6485 100644
--- a/_maps/templates/heretic_sacrifice_template.dmm
+++ b/_maps/templates/lazy_templates/heretic_sacrifice.dmm
@@ -40,6 +40,14 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/centcom/heretic_sacrifice/rust)
+"fL" = (
+/obj/effect/decal/cleanable/blood/old,
+/obj/effect/decal/cleanable/dirt/dust,
+/turf/open/indestructible/plating,
+/area/centcom/heretic_sacrifice/knock)
+"fO" = (
+/turf/open/indestructible,
+/area/space)
"gJ" = (
/obj/effect/decal/remains/human,
/turf/open/misc/dirt/jungle/dark{
@@ -47,6 +55,11 @@
slowdown = 0
},
/area/centcom/heretic_sacrifice/ash)
+"hE" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/item/storage/toolbox/mechanical/old,
+/turf/open/indestructible/plating,
+/area/centcom/heretic_sacrifice/knock)
"hZ" = (
/obj/effect/decal/cleanable/blood/old,
/turf/open/indestructible/necropolis/air,
@@ -56,6 +69,9 @@
/obj/structure/cable,
/turf/open/floor/plating/rust,
/area/centcom/heretic_sacrifice/rust)
+"jt" = (
+/turf/closed/indestructible/reinforced,
+/area/centcom/heretic_sacrifice/knock)
"jB" = (
/obj/machinery/light/very_dim/directional/south,
/turf/open/misc/asteroid,
@@ -85,6 +101,11 @@
},
/turf/open/floor/plating,
/area/centcom/heretic_sacrifice/rust)
+"mW" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/item/spear,
+/turf/open/indestructible/plating,
+/area/centcom/heretic_sacrifice/knock)
"mZ" = (
/obj/effect/decal/fakelattice{
density = 0
@@ -150,6 +171,12 @@
/obj/effect/decal/remains/human,
/turf/open/misc/asteroid,
/area/centcom/heretic_sacrifice/void)
+"qo" = (
+/obj/effect/decal/cleanable/blood/old,
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/item/storage/toolbox/mechanical/old,
+/turf/open/indestructible/plating,
+/area/centcom/heretic_sacrifice/knock)
"qu" = (
/obj/effect/turf_decal/weather/dirt,
/turf/open/misc/ashplanet/wateryrock{
@@ -202,6 +229,12 @@
},
/turf/open/floor/plating/rust,
/area/centcom/heretic_sacrifice/rust)
+"uM" = (
+/obj/effect/decal/cleanable/blood/old,
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/item/clothing/under/color/grey/ancient,
+/turf/open/indestructible/plating,
+/area/centcom/heretic_sacrifice/knock)
"uT" = (
/obj/structure/cable,
/turf/open/floor/plating/rust,
@@ -225,6 +258,9 @@
slowdown = 0
},
/area/centcom/heretic_sacrifice/ash)
+"wo" = (
+/turf/closed/indestructible/grille,
+/area/centcom/heretic_sacrifice/knock)
"wt" = (
/obj/structure/stone_tile/block{
dir = 1
@@ -240,6 +276,16 @@
slowdown = 0
},
/area/centcom/heretic_sacrifice/ash)
+"wP" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/item/flashlight/flare{
+ fuel = 1e+031;
+ randomize_fuel = 0;
+ icon_state = "flare-on";
+ on = 1
+ },
+/turf/open/indestructible/plating,
+/area/centcom/heretic_sacrifice/knock)
"wS" = (
/turf/open/misc/dirt/jungle/dark{
planetary_atmos = 0;
@@ -252,6 +298,9 @@
name = "void glass floor"
},
/area/centcom/heretic_sacrifice/void)
+"xc" = (
+/turf/open/indestructible/white,
+/area/space)
"yC" = (
/obj/effect/turf_decal/trimline/brown/line{
dir = 1
@@ -273,6 +322,11 @@
},
/turf/open/floor/plating/rust,
/area/centcom/heretic_sacrifice/rust)
+"Aw" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/item/clothing/mask/gas,
+/turf/open/indestructible/plating,
+/area/centcom/heretic_sacrifice/knock)
"AH" = (
/obj/effect/turf_decal/trimline/brown/corner,
/turf/open/floor/plating/rust,
@@ -287,6 +341,15 @@
"AO" = (
/turf/open/floor/fakespace,
/area/centcom/heretic_sacrifice/void)
+"AW" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/item/clothing/mask/gas/tiki_mask/yalp_elor,
+/turf/open/indestructible/plating,
+/area/centcom/heretic_sacrifice/knock)
+"AY" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/turf/open/indestructible/plating,
+/area/centcom/heretic_sacrifice/knock)
"Bv" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/trimline/brown/line,
@@ -340,6 +403,9 @@
slowdown = 0
},
/area/centcom/heretic_sacrifice/ash)
+"En" = (
+/turf/closed/indestructible/fakedoor/maintenance,
+/area/centcom/heretic_sacrifice/knock)
"ER" = (
/turf/open/misc/ironsand,
/area/centcom/heretic_sacrifice/rust)
@@ -467,6 +533,17 @@
/obj/machinery/light/very_dim/directional/west,
/turf/open/floor/fakespace,
/area/centcom/heretic_sacrifice/void)
+"MZ" = (
+/obj/effect/decal/cleanable/blood/old,
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/item/flashlight/flare{
+ fuel = 1e+031;
+ randomize_fuel = 0;
+ icon_state = "flare-on";
+ on = 1
+ },
+/turf/open/indestructible/plating,
+/area/centcom/heretic_sacrifice/knock)
"Nh" = (
/obj/effect/turf_decal/trimline/brown/line{
dir = 1
@@ -508,6 +585,11 @@
slowdown = 0
},
/area/centcom/heretic_sacrifice/ash)
+"OW" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/item/clothing/under/color/grey/ancient,
+/turf/open/indestructible/plating,
+/area/centcom/heretic_sacrifice/knock)
"Pl" = (
/obj/effect/turf_decal/weather/dirt{
dir = 6
@@ -627,6 +709,12 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/indestructible/necropolis/air,
/area/centcom/heretic_sacrifice/flesh)
+"Zw" = (
+/obj/effect/decal/cleanable/blood/old,
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/landmark/heretic/knock,
+/turf/open/indestructible/plating,
+/area/centcom/heretic_sacrifice/knock)
"ZA" = (
/turf/closed/indestructible/riveted/boss,
/area/centcom/heretic_sacrifice/ash)
@@ -661,9 +749,37 @@ ab
ab
ab
ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
"}
(2,1,1) = {"
ab
+ab
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
Fd
Fd
Fd
@@ -695,6 +811,20 @@ ab
"}
(3,1,1) = {"
ab
+ab
+Fd
+jt
+jt
+wo
+wo
+jt
+En
+En
+jt
+wo
+wo
+jt
+jt
Fd
ZA
ZA
@@ -726,6 +856,20 @@ ab
"}
(4,1,1) = {"
ab
+ab
+Fd
+jt
+AY
+AY
+AY
+AY
+AY
+AY
+AY
+AY
+fL
+AY
+jt
Fd
ZA
Pl
@@ -757,6 +901,20 @@ ab
"}
(5,1,1) = {"
ab
+ab
+Fd
+wo
+AY
+fL
+uM
+AY
+AY
+qo
+fL
+AY
+mW
+MZ
+wo
Fd
ZA
wS
@@ -788,6 +946,20 @@ ab
"}
(6,1,1) = {"
ab
+ab
+Fd
+wo
+AY
+Aw
+fL
+AY
+wP
+fL
+fL
+AY
+qo
+AY
+wo
Fd
ZA
OG
@@ -819,6 +991,20 @@ ab
"}
(7,1,1) = {"
ab
+ab
+Fd
+jt
+AY
+fL
+fL
+AY
+AY
+fL
+AY
+AY
+fL
+Aw
+jt
Fd
ZA
Bw
@@ -850,6 +1036,20 @@ ab
"}
(8,1,1) = {"
ab
+ab
+Fd
+En
+AY
+MZ
+fL
+AY
+Zw
+OW
+AY
+AY
+AY
+fL
+En
Fd
ZA
Bw
@@ -881,6 +1081,20 @@ ab
"}
(9,1,1) = {"
ab
+ab
+Fd
+En
+fL
+AY
+AY
+AY
+fL
+fL
+AY
+AY
+fL
+AY
+En
Fd
ZA
Bw
@@ -912,6 +1126,20 @@ ab
"}
(10,1,1) = {"
ab
+ab
+Fd
+jt
+AY
+AY
+fL
+AY
+fL
+AY
+fL
+AY
+AW
+fL
+jt
Fd
ZA
Bw
@@ -943,6 +1171,20 @@ ab
"}
(11,1,1) = {"
ab
+ab
+Fd
+wo
+fL
+AY
+hE
+MZ
+AY
+AY
+hE
+fL
+wP
+AY
+wo
Fd
ZA
Pl
@@ -974,6 +1216,20 @@ ab
"}
(12,1,1) = {"
ab
+ab
+Fd
+wo
+AY
+fL
+AY
+AY
+AY
+fL
+AY
+OW
+fL
+fL
+wo
Fd
ZA
wS
@@ -1005,6 +1261,20 @@ ab
"}
(13,1,1) = {"
ab
+ab
+Fd
+jt
+AY
+AY
+fL
+fL
+AY
+AY
+AY
+AY
+AY
+AY
+jt
Fd
ZA
OG
@@ -1036,6 +1306,20 @@ ab
"}
(14,1,1) = {"
ab
+ab
+Fd
+jt
+jt
+wo
+wo
+jt
+En
+En
+jt
+wo
+wo
+jt
+jt
Fd
ZA
ZA
@@ -1067,6 +1351,20 @@ ab
"}
(15,1,1) = {"
ab
+ab
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
Fd
Fd
Fd
@@ -1098,6 +1396,20 @@ ab
"}
(16,1,1) = {"
ab
+ab
+Fd
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
Fd
WD
WD
@@ -1129,6 +1441,20 @@ ab
"}
(17,1,1) = {"
ab
+ab
+Fd
+fO
+fO
+fO
+fO
+fO
+fO
+xc
+xc
+xc
+xc
+xc
+fO
Fd
WD
dZ
@@ -1160,6 +1486,20 @@ ab
"}
(18,1,1) = {"
ab
+ab
+Fd
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+xc
+fO
+fO
+fO
Fd
WD
dZ
@@ -1191,6 +1531,20 @@ ab
"}
(19,1,1) = {"
ab
+ab
+Fd
+fO
+fO
+fO
+fO
+fO
+fO
+xc
+xc
+xc
+xc
+xc
+fO
Fd
WD
ER
@@ -1222,6 +1576,20 @@ ab
"}
(20,1,1) = {"
ab
+ab
+Fd
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
Fd
WD
Se
@@ -1253,6 +1621,20 @@ ab
"}
(21,1,1) = {"
ab
+ab
+Fd
+fO
+fO
+fO
+fO
+fO
+fO
+xc
+fO
+xc
+xc
+xc
+fO
Fd
WD
Xr
@@ -1284,6 +1666,20 @@ ab
"}
(22,1,1) = {"
ab
+ab
+Fd
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
Fd
WD
Se
@@ -1315,6 +1711,20 @@ ab
"}
(23,1,1) = {"
ab
+ab
+Fd
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
Fd
WD
Xr
@@ -1346,6 +1756,20 @@ ab
"}
(24,1,1) = {"
ab
+ab
+Fd
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
Fd
WD
ps
@@ -1377,6 +1801,20 @@ ab
"}
(25,1,1) = {"
ab
+ab
+Fd
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
Fd
WD
Je
@@ -1408,6 +1846,20 @@ ab
"}
(26,1,1) = {"
ab
+ab
+Fd
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
Fd
WD
ER
@@ -1439,6 +1891,20 @@ ab
"}
(27,1,1) = {"
ab
+ab
+Fd
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
+fO
Fd
WD
WD
@@ -1470,6 +1936,20 @@ ab
"}
(28,1,1) = {"
ab
+ab
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
+Fd
Fd
Fd
Fd
@@ -1529,4 +2009,18 @@ ab
ab
ab
ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
"}
diff --git a/_maps/templates/lazy_templates/ninja_den.dmm b/_maps/templates/lazy_templates/ninja_den.dmm
index 56ffd856f24..40efeb77e7f 100644
--- a/_maps/templates/lazy_templates/ninja_den.dmm
+++ b/_maps/templates/lazy_templates/ninja_den.dmm
@@ -1,22 +1,52 @@
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"af" = (
+/obj/effect/turf_decal/siding/wood{
+ dir = 4
+ },
+/obj/structure/chair/sofa/corp/left{
+ dir = 4;
+ pixel_x = -4
+ },
+/obj/machinery/light/small/directional/north,
+/turf/open/floor/carpet/black,
+/area/centcom/central_command_areas/holding)
"al" = (
/obj/effect/turf_decal/siding/wood{
dir = 8
},
/turf/open/floor/carpet/black,
/area/centcom/central_command_areas/holding)
-"aq" = (
-/obj/structure/table/wood,
-/obj/item/toy/plush/goatplushie,
-/obj/machinery/light/small/directional/north,
-/turf/open/floor/carpet/black,
-/area/centcom/central_command_areas/holding)
-"aw" = (
-/obj/item/kirbyplants/organic/plant10,
-/obj/machinery/light/small/directional/north,
-/obj/structure/sign/painting/library{
- pixel_y = 32
+"au" = (
+/obj/effect/turf_decal/siding/wood{
+ dir = 1
},
+/obj/structure/rack,
+/obj/item/toy/gun{
+ pixel_y = 2
+ },
+/obj/item/toy/balloon/syndicate{
+ pixel_x = 8;
+ pixel_y = 2
+ },
+/obj/item/toy/balloon/syndicate{
+ pixel_x = 8;
+ pixel_y = 2
+ },
+/obj/item/toy/balloon/syndicate{
+ pixel_x = 8;
+ pixel_y = 2
+ },
+/obj/item/clothing/under/misc/syndicate_souvenir{
+ pixel_y = -5
+ },
+/obj/item/clothing/under/misc/syndicate_souvenir{
+ pixel_y = -5
+ },
+/obj/item/clothing/under/misc/syndicate_souvenir{
+ pixel_y = -5
+ },
+/obj/effect/turf_decal/tile/dark/fourcorners,
+/obj/machinery/light/small/directional/east,
/turf/open/floor/iron/sepia,
/area/centcom/central_command_areas/holding)
"ay" = (
@@ -36,6 +66,12 @@
},
/turf/open/floor/vault/rock,
/area/centcom/central_command_areas/holding)
+"be" = (
+/obj/structure/chair/comfy/black{
+ dir = 4
+ },
+/turf/open/floor/carpet/black,
+/area/centcom/central_command_areas/holding)
"bl" = (
/turf/open/floor/bamboo/tatami/purple,
/area/centcom/central_command_areas/holding)
@@ -43,6 +79,15 @@
/obj/machinery/photocopier,
/turf/open/floor/catwalk_floor,
/area/centcom/central_command_areas/holding)
+"bO" = (
+/obj/structure/flora/rock/pile/jungle/style_random{
+ pixel_x = -12;
+ pixel_y = 15
+ },
+/turf/open/misc/ashplanet/wateryrock{
+ initial_gas_mix = "o2=22;n2=82;TEMP=293.15"
+ },
+/area/centcom/central_command_areas/holding)
"bP" = (
/obj/structure/table/reinforced/plastitaniumglass,
/obj/item/paper_bin,
@@ -83,12 +128,9 @@
},
/turf/open/floor/carpet/black,
/area/centcom/central_command_areas/holding)
-"cv" = (
-/obj/effect/turf_decal/siding/wood,
-/obj/structure/chair/sofa/corp/left{
- pixel_y = 6
- },
-/obj/machinery/light/small/directional/east,
+"cK" = (
+/obj/structure/table/wood,
+/obj/item/flashlight/lamp/green,
/turf/open/floor/carpet/black,
/area/centcom/central_command_areas/holding)
"cQ" = (
@@ -113,25 +155,6 @@
},
/turf/open/floor/iron/sepia,
/area/centcom/central_command_areas/holding)
-"cV" = (
-/obj/structure/closet/secure_closet/freezer/fridge/open,
-/obj/item/food/grown/chili,
-/obj/item/food/grown/chili,
-/obj/item/food/grown/chili,
-/obj/item/food/grown/chili,
-/obj/item/food/grown/chili,
-/obj/item/reagent_containers/condiment/milk,
-/obj/item/reagent_containers/condiment/milk,
-/obj/item/reagent_containers/condiment/soymilk,
-/obj/item/reagent_containers/condiment/soymilk,
-/obj/item/storage/fancy/egg_box,
-/obj/item/food/grown/citrus/lime,
-/obj/item/food/grown/citrus/orange,
-/obj/item/food/grown/citrus/lemon,
-/obj/item/food/grown/watermelon,
-/obj/machinery/light/small/directional/west,
-/turf/open/floor/carpet/black,
-/area/centcom/central_command_areas/holding)
"cW" = (
/obj/effect/turf_decal/siding/wood{
dir = 8
@@ -151,6 +174,11 @@
"dg" = (
/turf/closed/wall/mineral/wood,
/area/centcom/central_command_areas/holding)
+"dv" = (
+/obj/item/kirbyplants/organic/plant10,
+/obj/machinery/light/small/directional/south,
+/turf/open/floor/iron/sepia,
+/area/centcom/central_command_areas/holding)
"dy" = (
/obj/machinery/light/small/directional/west,
/turf/open/floor/wood/tile,
@@ -185,46 +213,11 @@
/obj/effect/turf_decal/siding/wood,
/turf/open/floor/wood/large,
/area/centcom/central_command_areas/holding)
-"eC" = (
-/obj/structure/table/wood,
-/obj/machinery/microwave{
- pixel_y = 6
- },
+"eo" = (
+/obj/item/kirbyplants/organic/plant10,
+/obj/machinery/duct,
/turf/open/floor/carpet/black,
/area/centcom/central_command_areas/holding)
-"eN" = (
-/obj/effect/turf_decal/siding/wood{
- dir = 1
- },
-/obj/structure/rack,
-/obj/item/toy/gun{
- pixel_y = 2
- },
-/obj/item/toy/balloon/syndicate{
- pixel_x = 8;
- pixel_y = 2
- },
-/obj/item/toy/balloon/syndicate{
- pixel_x = 8;
- pixel_y = 2
- },
-/obj/item/toy/balloon/syndicate{
- pixel_x = 8;
- pixel_y = 2
- },
-/obj/item/clothing/under/misc/syndicate_souvenir{
- pixel_y = -5
- },
-/obj/item/clothing/under/misc/syndicate_souvenir{
- pixel_y = -5
- },
-/obj/item/clothing/under/misc/syndicate_souvenir{
- pixel_y = -5
- },
-/obj/effect/turf_decal/tile/dark/fourcorners,
-/obj/machinery/light/small/directional/east,
-/turf/open/floor/iron/sepia,
-/area/centcom/central_command_areas/holding)
"fu" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -234,21 +227,6 @@
},
/turf/open/floor/eighties/red,
/area/centcom/central_command_areas/holding)
-"fx" = (
-/obj/structure/bookcase/random/fiction,
-/obj/machinery/light/small/directional/east,
-/turf/open/floor/carpet/black,
-/area/centcom/central_command_areas/holding)
-"fG" = (
-/obj/item/kirbyplants/organic/plant10,
-/turf/open/floor/wood/parquet,
-/area/centcom/central_command_areas/holding)
-"fV" = (
-/obj/effect/turf_decal/siding/wood,
-/obj/item/kirbyplants/organic/plant10,
-/obj/effect/turf_decal/tile/dark/opposingcorners,
-/turf/open/floor/iron/sepia,
-/area/centcom/central_command_areas/holding)
"ga" = (
/obj/structure/table/reinforced/plastitaniumglass,
/obj/item/toy/mecha/phazon,
@@ -290,6 +268,12 @@
},
/turf/open/floor/iron/sepia,
/area/centcom/central_command_areas/holding)
+"ha" = (
+/obj/machinery/light/directional/north,
+/turf/open/floor/bamboo/tatami/purple{
+ dir = 8
+ },
+/area/centcom/central_command_areas/holding)
"hi" = (
/obj/structure/bed,
/obj/item/bedsheet/syndie,
@@ -297,17 +281,14 @@
dir = 4
},
/area/centcom/central_command_areas/holding)
-"hl" = (
-/obj/effect/turf_decal/siding/wood{
- dir = 1
- },
-/obj/item/kirbyplants/organic/plant10,
-/turf/open/floor/carpet/black,
-/area/centcom/central_command_areas/holding)
"hm" = (
/obj/machinery/vending/clothing,
/turf/open/floor/wood/parquet,
/area/centcom/central_command_areas/holding)
+"hn" = (
+/obj/machinery/light/directional/north,
+/turf/open/floor/wood/large,
+/area/centcom/central_command_areas/holding)
"ho" = (
/obj/structure/chair/pew/left{
dir = 8
@@ -318,11 +299,12 @@
/obj/machinery/duct,
/turf/open/floor/carpet/black,
/area/centcom/central_command_areas/holding)
-"hr" = (
-/obj/machinery/light/directional/north,
-/turf/open/floor/bamboo/tatami/purple{
- dir = 8
+"hs" = (
+/obj/effect/turf_decal/siding/wood{
+ dir = 1
},
+/obj/item/kirbyplants/organic/plant10,
+/turf/open/floor/carpet/black,
/area/centcom/central_command_areas/holding)
"ht" = (
/obj/effect/turf_decal/siding/wood{
@@ -335,16 +317,17 @@
/obj/machinery/computer/libraryconsole/bookmanagement,
/turf/open/floor/carpet/black,
/area/centcom/central_command_areas/holding)
+"hw" = (
+/obj/item/kirbyplants/organic/plant10,
+/obj/structure/sign/painting/library{
+ pixel_y = 32
+ },
+/turf/open/floor/carpet/black,
+/area/centcom/central_command_areas/holding)
"hH" = (
/obj/item/flashlight/lantern,
/turf/open/misc/sandy_dirt,
/area/centcom/central_command_areas/holding)
-"hJ" = (
-/obj/structure/chair/comfy/black{
- dir = 4
- },
-/turf/open/floor/carpet/black,
-/area/centcom/central_command_areas/holding)
"hO" = (
/turf/open/floor/wood/tile,
/area/centcom/central_command_areas/holding)
@@ -378,6 +361,10 @@
/obj/machinery/gibber,
/turf/open/floor/catwalk_floor,
/area/centcom/central_command_areas/holding)
+"iW" = (
+/obj/machinery/light/small/directional/west,
+/turf/open/floor/iron/stairs/medium,
+/area/centcom/central_command_areas/holding)
"jb" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -440,12 +427,6 @@
/obj/item/food/meat/slab/synthmeat,
/turf/open/floor/catwalk_floor,
/area/centcom/central_command_areas/holding)
-"jK" = (
-/obj/machinery/light/small/directional/north,
-/turf/open/floor/bamboo/tatami/black{
- dir = 1
- },
-/area/centcom/central_command_areas/holding)
"jR" = (
/obj/structure/chair/wood{
dir = 4
@@ -532,32 +513,35 @@
"lP" = (
/turf/open/floor/bamboo/tatami/black,
/area/centcom/central_command_areas/holding)
+"lV" = (
+/obj/structure/table/wood/fancy/royalblack,
+/obj/item/book/bible,
+/obj/machinery/light/directional/north,
+/turf/open/floor/wood/large,
+/area/centcom/central_command_areas/holding)
"mj" = (
/obj/effect/turf_decal/siding/wood,
/turf/open/floor/iron/sepia,
/area/centcom/central_command_areas/holding)
+"mr" = (
+/obj/item/kirbyplants/organic/plant10,
+/turf/open/floor/wood/parquet,
+/area/centcom/central_command_areas/holding)
"mw" = (
/turf/open/floor/wood/large,
/area/centcom/central_command_areas/holding)
-"mN" = (
-/obj/structure/chair/comfy/black{
- dir = 8
- },
-/turf/open/floor/carpet/black,
-/area/centcom/central_command_areas/holding)
-"nm" = (
-/obj/machinery/light/directional/south,
+"ni" = (
/obj/structure/rack,
-/obj/item/nullrod/vibro{
- damtype = "stamina";
- force = 30;
- pixel_x = 5;
- pixel_y = -2
- },
-/obj/item/nullrod/claymore/glowing{
+/obj/item/nullrod/claymore/saber/red{
damtype = "stamina";
force = 30
},
+/obj/item/nullrod/claymore/katana{
+ damtype = "stamina";
+ force = 30;
+ pixel_x = -8;
+ pixel_y = -1
+ },
/turf/open/floor/wood/parquet,
/area/centcom/central_command_areas/holding)
"nt" = (
@@ -571,6 +555,41 @@
/obj/structure/sink/kitchen/directional/west,
/turf/open/floor/iron/cafeteria,
/area/centcom/central_command_areas/holding)
+"nR" = (
+/obj/machinery/light/small/directional/east,
+/turf/open/floor/iron/stairs/medium,
+/area/centcom/central_command_areas/holding)
+"nW" = (
+/obj/machinery/light/warm/directional/west,
+/turf/open/water{
+ initial_gas_mix = "o2=22;n2=82;TEMP=293.15"
+ },
+/area/centcom/central_command_areas/holding)
+"od" = (
+/obj/effect/turf_decal/siding/wood{
+ dir = 1
+ },
+/obj/structure/table/reinforced/plastitaniumglass,
+/obj/item/storage/basket,
+/obj/effect/turf_decal/tile/dark/fourcorners,
+/obj/machinery/light/small/directional/west,
+/turf/open/floor/iron/sepia,
+/area/centcom/central_command_areas/holding)
+"oh" = (
+/obj/machinery/light/directional/south,
+/obj/structure/rack,
+/obj/item/nullrod/vibro{
+ damtype = "stamina";
+ force = 30;
+ pixel_x = 5;
+ pixel_y = -2
+ },
+/obj/item/nullrod/claymore/glowing{
+ damtype = "stamina";
+ force = 30
+ },
+/turf/open/floor/wood/parquet,
+/area/centcom/central_command_areas/holding)
"os" = (
/obj/machinery/shower/directional/south,
/obj/item/soap/syndie,
@@ -600,10 +619,6 @@
/obj/machinery/biogenerator,
/turf/open/floor/wood/tile,
/area/centcom/central_command_areas/holding)
-"oP" = (
-/obj/machinery/light/small/directional/south,
-/turf/open/floor/carpet/black,
-/area/centcom/central_command_areas/holding)
"oT" = (
/obj/effect/turf_decal/siding/wood,
/obj/effect/turf_decal/siding/wood{
@@ -649,6 +664,23 @@
},
/turf/open/floor/catwalk_floor,
/area/centcom/central_command_areas/holding)
+"pB" = (
+/obj/structure/rack,
+/obj/item/nullrod/claymore{
+ damtype = "stamina";
+ force = 30;
+ pixel_x = 4;
+ pixel_y = -1
+ },
+/obj/item/nullrod/claymore/darkblade{
+ damtype = "stamina";
+ force = 30;
+ pixel_x = -3;
+ pixel_y = 3
+ },
+/obj/machinery/light/directional/north,
+/turf/open/floor/wood/parquet,
+/area/centcom/central_command_areas/holding)
"pK" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -674,6 +706,35 @@
initial_gas_mix = "TEMP=2.7"
},
/area/centcom/central_command_areas/holding)
+"pU" = (
+/obj/structure/closet,
+/obj/item/surgery_tray/full,
+/obj/machinery/iv_drip,
+/obj/item/emergency_bed,
+/obj/item/storage/medkit/regular,
+/obj/item/reagent_containers/medigel/synthflesh,
+/obj/item/reagent_containers/medigel/synthflesh,
+/obj/item/reagent_containers/medigel/synthflesh,
+/obj/item/organ/internal/heart/cybernetic/tier2,
+/obj/item/organ/internal/heart/cybernetic/tier2,
+/obj/item/defibrillator,
+/turf/open/floor/iron/sepia,
+/area/centcom/central_command_areas/holding)
+"pX" = (
+/obj/machinery/light/small/directional/north,
+/turf/open/floor/bamboo/tatami/black{
+ dir = 1
+ },
+/area/centcom/central_command_areas/holding)
+"qg" = (
+/obj/machinery/light/warm/directional/east,
+/obj/effect/turf_decal/siding/wood{
+ dir = 1
+ },
+/obj/effect/turf_decal/siding/wood,
+/obj/item/kirbyplants/organic/plant10,
+/turf/open/floor/stone,
+/area/centcom/central_command_areas/holding)
"qi" = (
/obj/machinery/hydroponics/constructable,
/turf/open/floor/grass,
@@ -733,15 +794,6 @@
},
/turf/open/floor/catwalk_floor,
/area/centcom/central_command_areas/holding)
-"qW" = (
-/obj/item/kirbyplants/organic/plant10,
-/turf/open/floor/bamboo/tatami/purple,
-/area/centcom/central_command_areas/holding)
-"ri" = (
-/obj/effect/turf_decal/siding/wood,
-/obj/machinery/light/small/directional/south,
-/turf/open/floor/wood/tile,
-/area/centcom/central_command_areas/holding)
"rj" = (
/obj/effect/turf_decal/siding/wood{
dir = 8
@@ -754,6 +806,20 @@
},
/turf/open/floor/iron/sepia,
/area/centcom/central_command_areas/holding)
+"rn" = (
+/obj/structure/table/wood,
+/obj/machinery/chem_dispenser/drinks/beer{
+ dir = 4;
+ pixel_x = -8;
+ pixel_y = 1
+ },
+/obj/item/reagent_containers/cup/beaker{
+ pixel_x = 7;
+ pixel_y = -4
+ },
+/obj/machinery/light/small/directional/west,
+/turf/open/floor/carpet/black,
+/area/centcom/central_command_areas/holding)
"rz" = (
/obj/structure/flora/bush/flowers_yw/style_random,
/obj/structure/flora/bush/flowers_br/style_random,
@@ -776,10 +842,6 @@
dir = 8
},
/area/centcom/central_command_areas/holding)
-"rV" = (
-/obj/item/kirbyplants/organic/plant10,
-/turf/open/floor/carpet/black,
-/area/centcom/central_command_areas/holding)
"sc" = (
/obj/structure/sink/directional/west,
/obj/structure/mirror/directional/east,
@@ -840,10 +902,6 @@
},
/turf/open/floor/wood/tile,
/area/centcom/central_command_areas/holding)
-"uP" = (
-/obj/machinery/light/small/directional/north,
-/turf/open/floor/carpet/black,
-/area/centcom/central_command_areas/holding)
"uQ" = (
/obj/structure/chair/wood{
dir = 8
@@ -852,45 +910,43 @@
dir = 4
},
/area/centcom/central_command_areas/holding)
-"uT" = (
-/obj/structure/flora/rock/pile/jungle/style_random{
- pixel_x = -12;
- pixel_y = 15
- },
-/turf/open/misc/ashplanet/wateryrock{
- initial_gas_mix = "o2=22;n2=82;TEMP=293.15"
- },
-/area/centcom/central_command_areas/holding)
"vr" = (
-/obj/machinery/light/warm/directional/west,
-/turf/open/water{
- initial_gas_mix = "o2=22;n2=82;TEMP=293.15"
+/obj/structure/rack,
+/obj/item/nullrod/claymore/saber{
+ damtype = "stamina";
+ force = 30;
+ pixel_x = 5;
+ pixel_y = -3
},
-/area/centcom/central_command_areas/holding)
-"vv" = (
-/obj/item/kirbyplants/organic/plant10,
-/turf/open/floor/wood/large,
+/obj/item/nullrod/claymore/katana{
+ damtype = "stamina";
+ force = 30
+ },
+/turf/open/floor/wood/parquet,
/area/centcom/central_command_areas/holding)
"vA" = (
/obj/machinery/seed_extractor,
/turf/open/floor/wood/tile,
/area/centcom/central_command_areas/holding)
-"vH" = (
-/obj/item/kirbyplants/organic/plant10,
-/obj/machinery/light/small/directional/south,
-/turf/open/floor/iron/sepia,
-/area/centcom/central_command_areas/holding)
"vS" = (
/obj/structure/table/wood,
/obj/item/paper_bin,
/obj/item/pen/fountain,
/turf/open/floor/carpet/black,
/area/centcom/central_command_areas/holding)
-"wS" = (
-/obj/structure/bookcase/random/reference,
-/obj/machinery/light/small/directional/west,
+"wc" = (
+/obj/effect/turf_decal/siding/wood,
+/obj/structure/chair/sofa/corp/left{
+ pixel_y = 6
+ },
+/obj/machinery/light/small/directional/east,
/turf/open/floor/carpet/black,
/area/centcom/central_command_areas/holding)
+"wq" = (
+/obj/structure/closet/crate/freezer/blood,
+/obj/machinery/light/small/directional/north,
+/turf/open/floor/iron/sepia,
+/area/centcom/central_command_areas/holding)
"wU" = (
/turf/open/floor/wood/parquet,
/area/centcom/central_command_areas/holding)
@@ -965,33 +1021,34 @@
},
/turf/open/floor/iron/sepia,
/area/centcom/central_command_areas/holding)
-"yo" = (
-/obj/structure/table/wood,
-/obj/machinery/chem_dispenser/drinks/beer{
- dir = 4;
- pixel_x = -8;
- pixel_y = 1
- },
-/obj/item/reagent_containers/cup/beaker{
- pixel_x = 7;
- pixel_y = -4
- },
-/obj/machinery/light/small/directional/west,
-/turf/open/floor/carpet/black,
-/area/centcom/central_command_areas/holding)
"yz" = (
/obj/structure/chair/stool/directional/west,
/turf/open/misc/beach/sand,
/area/centcom/central_command_areas/holding)
-"ze" = (
-/obj/effect/turf_decal/siding/wood{
- dir = 4
+"zc" = (
+/obj/structure/table/wood,
+/obj/machinery/microwave{
+ pixel_y = 6
},
-/obj/structure/chair/sofa/corp/left{
- dir = 4;
- pixel_x = -4
- },
-/obj/machinery/light/small/directional/north,
+/turf/open/floor/carpet/black,
+/area/centcom/central_command_areas/holding)
+"zh" = (
+/obj/structure/closet/secure_closet/freezer/fridge/open,
+/obj/item/food/grown/chili,
+/obj/item/food/grown/chili,
+/obj/item/food/grown/chili,
+/obj/item/food/grown/chili,
+/obj/item/food/grown/chili,
+/obj/item/reagent_containers/condiment/milk,
+/obj/item/reagent_containers/condiment/milk,
+/obj/item/reagent_containers/condiment/soymilk,
+/obj/item/reagent_containers/condiment/soymilk,
+/obj/item/storage/fancy/egg_box,
+/obj/item/food/grown/citrus/lime,
+/obj/item/food/grown/citrus/orange,
+/obj/item/food/grown/citrus/lemon,
+/obj/item/food/grown/watermelon,
+/obj/machinery/light/small/directional/west,
/turf/open/floor/carpet/black,
/area/centcom/central_command_areas/holding)
"zB" = (
@@ -1014,15 +1071,11 @@
/obj/structure/window/reinforced/fulltile,
/turf/open/floor/grass,
/area/centcom/central_command_areas/holding)
-"zQ" = (
-/obj/effect/turf_decal/siding/wood{
- dir = 1
- },
-/obj/structure/table/reinforced/plastitaniumglass,
-/obj/item/storage/basket,
-/obj/effect/turf_decal/tile/dark/fourcorners,
-/obj/machinery/light/small/directional/west,
-/turf/open/floor/iron/sepia,
+"zU" = (
+/obj/structure/table/wood,
+/obj/item/toy/plush/goatplushie,
+/obj/machinery/light/small/directional/north,
+/turf/open/floor/carpet/black,
/area/centcom/central_command_areas/holding)
"Af" = (
/obj/effect/turf_decal/siding/wood{
@@ -1072,6 +1125,12 @@
dir = 1
},
/area/centcom/central_command_areas/holding)
+"AP" = (
+/obj/item/kirbyplants/organic/plant10,
+/turf/open/floor/bamboo/tatami/purple{
+ dir = 1
+ },
+/area/centcom/central_command_areas/holding)
"Bn" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -1087,10 +1146,6 @@
/obj/item/food/chawanmushi,
/turf/open/floor/carpet/black,
/area/centcom/central_command_areas/holding)
-"Bt" = (
-/obj/machinery/light/small/directional/east,
-/turf/open/floor/iron/stairs/medium,
-/area/centcom/central_command_areas/holding)
"Bw" = (
/turf/open/misc/beach/sand,
/area/centcom/central_command_areas/holding)
@@ -1161,8 +1216,13 @@
},
/turf/open/floor/grass,
/area/centcom/central_command_areas/holding)
-"Dy" = (
+"DF" = (
/obj/item/kirbyplants/organic/plant10,
+/turf/open/floor/bamboo/tatami/purple,
+/area/centcom/central_command_areas/holding)
+"DG" = (
+/obj/structure/closet/crate/freezer/blood,
+/obj/machinery/light/small/directional/south,
/turf/open/floor/iron/sepia,
/area/centcom/central_command_areas/holding)
"DI" = (
@@ -1213,6 +1273,10 @@
initial_gas_mix = "o2=22;n2=82;TEMP=293.15"
},
/area/centcom/central_command_areas/holding)
+"EC" = (
+/obj/item/kirbyplants/organic/plant10,
+/turf/open/floor/carpet/black,
+/area/centcom/central_command_areas/holding)
"EJ" = (
/obj/item/mop,
/obj/structure/sink/kitchen/directional/west,
@@ -1227,6 +1291,13 @@
dir = 4
},
/area/centcom/central_command_areas/holding)
+"FB" = (
+/obj/machinery/modular_computer/preset/research{
+ dir = 4
+ },
+/obj/machinery/light/directional/west,
+/turf/open/floor/catwalk_floor,
+/area/centcom/central_command_areas/holding)
"FE" = (
/turf/open/floor/catwalk_floor,
/area/centcom/central_command_areas/holding)
@@ -1293,6 +1364,19 @@
},
/turf/open/floor/carpet/black,
/area/centcom/central_command_areas/holding)
+"GN" = (
+/obj/structure/bed/dogbed/cayenne{
+ name = "Paprika's bed"
+ },
+/mob/living/basic/carp/pet/cayenne{
+ desc = "It's Paprika! One of the Spider Clan's lovable Space Carp!";
+ faction = list("neutral");
+ name = "Paprika";
+ real_name = "Paprika"
+ },
+/obj/machinery/light/warm/directional/south,
+/turf/open/floor/carpet/black,
+/area/centcom/central_command_areas/holding)
"GO" = (
/obj/effect/turf_decal/siding/wood{
dir = 8
@@ -1329,11 +1413,6 @@
},
/turf/open/floor/stone,
/area/centcom/central_command_areas/holding)
-"Hf" = (
-/obj/machinery/vending/dinnerware,
-/obj/machinery/light/warm/directional/north,
-/turf/open/floor/iron/sepia,
-/area/centcom/central_command_areas/holding)
"Ho" = (
/obj/effect/turf_decal/siding/wood{
dir = 4
@@ -1353,34 +1432,6 @@
/obj/effect/turf_decal/siding/wood,
/turf/open/floor/carpet/black,
/area/centcom/central_command_areas/holding)
-"Hw" = (
-/obj/structure/rack,
-/obj/item/nullrod/claymore{
- damtype = "stamina";
- force = 30;
- pixel_x = 4;
- pixel_y = -1
- },
-/obj/item/nullrod/claymore/darkblade{
- damtype = "stamina";
- force = 30;
- pixel_x = -3;
- pixel_y = 3
- },
-/obj/machinery/light/directional/north,
-/turf/open/floor/wood/parquet,
-/area/centcom/central_command_areas/holding)
-"HL" = (
-/obj/structure/closet/crate/freezer/blood,
-/obj/machinery/light/small/directional/north,
-/turf/open/floor/iron/sepia,
-/area/centcom/central_command_areas/holding)
-"HP" = (
-/obj/structure/table/wood/fancy/royalblack,
-/obj/item/book/bible,
-/obj/machinery/light/directional/north,
-/turf/open/floor/wood/large,
-/area/centcom/central_command_areas/holding)
"HU" = (
/turf/open/misc/asteroid/basalt/wasteland{
initial_gas_mix = "TEMP=2.7"
@@ -1438,19 +1489,6 @@
/obj/item/paper/guides/jobs/hydroponics,
/turf/open/floor/wood/tile,
/area/centcom/central_command_areas/holding)
-"IY" = (
-/obj/machinery/light/small/directional/south,
-/turf/open/floor/bamboo/tatami/black{
- dir = 4
- },
-/area/centcom/central_command_areas/holding)
-"Je" = (
-/obj/item/kirbyplants/organic/plant10,
-/obj/structure/sign/painting/library{
- pixel_y = 32
- },
-/turf/open/floor/carpet/black,
-/area/centcom/central_command_areas/holding)
"Jf" = (
/obj/structure/table/reinforced/rglass,
/obj/item/wrench{
@@ -1528,6 +1566,11 @@
},
/turf/open/floor/wood/tile,
/area/centcom/central_command_areas/holding)
+"JL" = (
+/obj/effect/turf_decal/siding/wood,
+/obj/machinery/light/small/directional/south,
+/turf/open/floor/wood/tile,
+/area/centcom/central_command_areas/holding)
"JR" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -1587,6 +1630,11 @@
dir = 8
},
/area/centcom/central_command_areas/holding)
+"LE" = (
+/obj/machinery/vending/dinnerware,
+/obj/machinery/light/warm/directional/north,
+/turf/open/floor/iron/sepia,
+/area/centcom/central_command_areas/holding)
"LK" = (
/turf/closed/indestructible/weeb,
/area/centcom/central_command_areas/holding)
@@ -1607,18 +1655,11 @@
},
/turf/open/floor/iron/cafeteria,
/area/centcom/central_command_areas/holding)
-"Mz" = (
-/obj/structure/closet,
-/obj/item/storage/backpack/duffelbag/med/surgery,
-/obj/machinery/iv_drip,
-/obj/item/roller,
-/obj/item/storage/medkit/regular,
-/obj/item/reagent_containers/medigel/synthflesh,
-/obj/item/reagent_containers/medigel/synthflesh,
-/obj/item/reagent_containers/medigel/synthflesh,
-/obj/item/organ/internal/heart/cybernetic/tier2,
-/obj/item/organ/internal/heart/cybernetic/tier2,
-/obj/item/defibrillator,
+"My" = (
+/obj/item/kirbyplants/organic/plant10,
+/obj/structure/sign/painting/library{
+ pixel_y = 32
+ },
/turf/open/floor/iron/sepia,
/area/centcom/central_command_areas/holding)
"ML" = (
@@ -1642,11 +1683,6 @@
/obj/item/food/grown/soybeans,
/turf/open/floor/carpet/black,
/area/centcom/central_command_areas/holding)
-"Nh" = (
-/obj/item/kirbyplants/organic/plant10,
-/obj/machinery/duct,
-/turf/open/floor/carpet/black,
-/area/centcom/central_command_areas/holding)
"Nt" = (
/obj/structure/table/wood,
/obj/machinery/chem_dispenser/drinks{
@@ -1667,6 +1703,10 @@
},
/turf/open/misc/sandy_dirt,
/area/centcom/central_command_areas/holding)
+"ND" = (
+/obj/item/kirbyplants/organic/plant10,
+/turf/open/floor/wood/large,
+/area/centcom/central_command_areas/holding)
"NF" = (
/turf/open/floor/bamboo/tatami/black{
dir = 4
@@ -1678,20 +1718,6 @@
},
/turf/open/floor/carpet/black,
/area/centcom/central_command_areas/holding)
-"NP" = (
-/obj/structure/rack,
-/obj/item/nullrod/claymore/saber/red{
- damtype = "stamina";
- force = 30
- },
-/obj/item/nullrod/claymore/katana{
- damtype = "stamina";
- force = 30;
- pixel_x = -8;
- pixel_y = -1
- },
-/turf/open/floor/wood/parquet,
-/area/centcom/central_command_areas/holding)
"NR" = (
/obj/structure/bookcase/random/fiction,
/turf/open/floor/carpet/black,
@@ -1707,6 +1733,14 @@
dir = 1
},
/area/centcom/central_command_areas/holding)
+"Od" = (
+/obj/item/kirbyplants/organic/plant10,
+/obj/machinery/light/small/directional/north,
+/obj/structure/sign/painting/library{
+ pixel_y = 32
+ },
+/turf/open/floor/iron/sepia,
+/area/centcom/central_command_areas/holding)
"Ok" = (
/obj/effect/turf_decal/siding/wood{
dir = 8
@@ -1716,16 +1750,15 @@
},
/turf/open/floor/stone,
/area/centcom/central_command_areas/holding)
-"Oy" = (
+"Oo" = (
/obj/item/kirbyplants/organic/plant10,
/obj/machinery/light/directional/south,
/turf/open/floor/wood/large,
/area/centcom/central_command_areas/holding)
-"OA" = (
-/obj/item/kirbyplants/organic/plant10,
-/turf/open/floor/bamboo/tatami/purple{
- dir = 1
- },
+"Op" = (
+/obj/structure/bookcase/random/fiction,
+/obj/machinery/light/small/directional/east,
+/turf/open/floor/carpet/black,
/area/centcom/central_command_areas/holding)
"OC" = (
/obj/effect/turf_decal/siding/wood{
@@ -1733,9 +1766,10 @@
},
/turf/open/misc/sandy_dirt,
/area/centcom/central_command_areas/holding)
-"Pf" = (
-/obj/machinery/light/directional/north,
-/turf/open/floor/wood/large,
+"OQ" = (
+/obj/structure/bookcase/random/reference,
+/obj/machinery/light/small/directional/west,
+/turf/open/floor/carpet/black,
/area/centcom/central_command_areas/holding)
"Pl" = (
/obj/structure/flora/bush/flowers_yw/style_random,
@@ -1746,6 +1780,12 @@
/obj/structure/sign/poster/contraband/syndicate_recruitment/directional/south,
/turf/open/floor/wood/large,
/area/centcom/central_command_areas/holding)
+"PH" = (
+/obj/structure/chair/comfy/black{
+ dir = 8
+ },
+/turf/open/floor/carpet/black,
+/area/centcom/central_command_areas/holding)
"PK" = (
/obj/structure/table/reinforced/rglass,
/obj/item/shovel/spade{
@@ -1760,33 +1800,20 @@
/obj/item/instrument/saxophone,
/turf/open/floor/wood/parquet,
/area/centcom/central_command_areas/holding)
-"Qh" = (
-/obj/structure/rack,
-/obj/item/nullrod/claymore/saber{
- damtype = "stamina";
- force = 30;
- pixel_x = 5;
- pixel_y = -3
- },
-/obj/item/nullrod/claymore/katana{
- damtype = "stamina";
- force = 30
- },
-/turf/open/floor/wood/parquet,
+"Qt" = (
+/obj/machinery/light/small/directional/north,
+/turf/open/floor/carpet/black,
/area/centcom/central_command_areas/holding)
"Qu" = (
/obj/machinery/defibrillator_mount/directional/south,
/obj/machinery/stasis,
/turf/open/floor/iron/sepia,
/area/centcom/central_command_areas/holding)
-"QR" = (
-/obj/machinery/light/warm/directional/east,
-/obj/effect/turf_decal/siding/wood{
- dir = 1
- },
+"QJ" = (
/obj/effect/turf_decal/siding/wood,
/obj/item/kirbyplants/organic/plant10,
-/turf/open/floor/stone,
+/obj/effect/turf_decal/tile/dark/opposingcorners,
+/turf/open/floor/iron/sepia,
/area/centcom/central_command_areas/holding)
"QW" = (
/obj/structure/table/wood/fancy/royalblack,
@@ -1858,11 +1885,6 @@
"Sc" = (
/turf/open/floor/stone,
/area/centcom/central_command_areas/holding)
-"Si" = (
-/obj/structure/table/wood,
-/obj/item/flashlight/lamp/green,
-/turf/open/floor/carpet/black,
-/area/centcom/central_command_areas/holding)
"Tc" = (
/obj/effect/turf_decal/siding/wood,
/obj/structure/chair/sofa/corp/right{
@@ -1914,6 +1936,14 @@
/obj/structure/chair/stool/directional/south,
/turf/open/floor/wood/parquet,
/area/centcom/central_command_areas/holding)
+"Uj" = (
+/obj/item/kirbyplants/organic/plant10,
+/turf/open/floor/iron/sepia,
+/area/centcom/central_command_areas/holding)
+"Ul" = (
+/obj/machinery/light/small/directional/south,
+/turf/open/floor/carpet/black,
+/area/centcom/central_command_areas/holding)
"UB" = (
/obj/structure/table/reinforced/plastitaniumglass,
/obj/item/toy/figure/ninja,
@@ -1957,13 +1987,6 @@
/obj/machinery/light/directional/west,
/turf/open/floor/carpet/black,
/area/centcom/central_command_areas/holding)
-"Vg" = (
-/obj/item/kirbyplants/organic/plant10,
-/obj/structure/sign/painting/library{
- pixel_y = 32
- },
-/turf/open/floor/iron/sepia,
-/area/centcom/central_command_areas/holding)
"Vi" = (
/obj/machinery/defibrillator_mount/directional/north,
/obj/machinery/stasis,
@@ -1980,19 +2003,6 @@
},
/turf/open/floor/wood/tile,
/area/centcom/central_command_areas/holding)
-"Vu" = (
-/obj/structure/bed/dogbed/cayenne{
- name = "Paprika's bed"
- },
-/mob/living/basic/carp/pet/cayenne{
- desc = "It's Paprika! One of the Spider Clan's lovable Space Carp!";
- faction = list("neutral");
- name = "Paprika";
- real_name = "Paprika"
- },
-/obj/machinery/light/warm/directional/south,
-/turf/open/floor/carpet/black,
-/area/centcom/central_command_areas/holding)
"VC" = (
/obj/structure/closet/crate/bin,
/obj/item/soap/syndie,
@@ -2036,13 +2046,6 @@
/obj/item/food/grown/redbeet,
/turf/open/floor/catwalk_floor,
/area/centcom/central_command_areas/holding)
-"Wc" = (
-/obj/machinery/modular_computer/preset/research{
- dir = 4
- },
-/obj/machinery/light/directional/west,
-/turf/open/floor/catwalk_floor,
-/area/centcom/central_command_areas/holding)
"We" = (
/obj/machinery/vending/cigarette/syndicate,
/obj/machinery/light/small/directional/south,
@@ -2056,6 +2059,12 @@
},
/turf/open/floor/iron/sepia,
/area/centcom/central_command_areas/holding)
+"WD" = (
+/obj/machinery/light/small/directional/south,
+/turf/open/floor/bamboo/tatami/black{
+ dir = 4
+ },
+/area/centcom/central_command_areas/holding)
"WS" = (
/obj/effect/turf_decal/siding/wood/corner{
dir = 4
@@ -2107,9 +2116,9 @@
initial_gas_mix = "o2=22;n2=82;TEMP=293.15"
},
/area/centcom/central_command_areas/holding)
-"Xj" = (
-/obj/machinery/light/small/directional/west,
-/turf/open/floor/iron/stairs/medium,
+"Xn" = (
+/obj/structure/reagent_dispensers/plumbed,
+/turf/open/floor/carpet/black,
/area/centcom/central_command_areas/holding)
"Xt" = (
/obj/effect/turf_decal/siding/wood,
@@ -2146,11 +2155,6 @@
/obj/item/toy/spinningtoy,
/turf/open/floor/wood/parquet,
/area/centcom/central_command_areas/holding)
-"Yf" = (
-/obj/structure/closet/crate/freezer/blood,
-/obj/machinery/light/small/directional/south,
-/turf/open/floor/iron/sepia,
-/area/centcom/central_command_areas/holding)
"YQ" = (
/turf/open/floor/bamboo/tatami{
dir = 4
@@ -2177,10 +2181,6 @@
},
/turf/open/floor/iron/sepia,
/area/centcom/central_command_areas/holding)
-"Zp" = (
-/obj/structure/reagent_dispensers/plumbed,
-/turf/open/floor/carpet/black,
-/area/centcom/central_command_areas/holding)
"Zq" = (
/obj/structure/bookcase/random/adult,
/turf/open/floor/carpet/black,
@@ -2428,12 +2428,12 @@ gy
wV
Ea
dg
-eC
-yo
+zc
+rn
Nt
JV
-cV
-Zp
+zh
+Xn
dg
ts
FE
@@ -2503,10 +2503,10 @@ rQ
wV
dg
zL
-Nh
+eo
Am
Am
-rV
+EC
VC
dg
dg
@@ -2547,7 +2547,7 @@ MR
dg
dg
oG
-vr
+nW
oG
LK
Ed
@@ -2576,12 +2576,12 @@ CG
CG
Ho
dg
-aq
+zU
AE
Gy
Bo
iF
-Si
+cK
dg
oG
oG
@@ -2722,7 +2722,7 @@ Zj
HU
Zj
CG
-Hf
+LE
zN
hO
hO
@@ -2804,7 +2804,7 @@ pt
pN
hO
hO
-QR
+qg
Bw
yz
Bw
@@ -2873,7 +2873,7 @@ Vj
mw
DL
ht
-ri
+JL
dg
ic
mw
@@ -2941,7 +2941,7 @@ MM
ML
mw
mw
-hl
+hs
dg
dg
iH
@@ -2985,7 +2985,7 @@ mw
mw
ht
kl
-fx
+Op
XP
mw
mw
@@ -3016,7 +3016,7 @@ ML
mw
mw
FU
-Bt
+nR
lI
mw
mw
@@ -3086,15 +3086,15 @@ LK
lh
qx
dg
-fV
+QJ
mw
mw
-zQ
+od
Gw
XP
xw
Am
-mN
+PH
Am
VO
XP
@@ -3130,10 +3130,10 @@ Ey
Dh
XP
xw
-oP
+Ul
dg
-uP
-Vu
+Qt
+GN
dg
iH
mw
@@ -3160,15 +3160,15 @@ LK
os
sc
dg
-fV
+QJ
mw
mw
-eN
+au
GX
XP
xw
Am
-hJ
+be
Am
NU
XP
@@ -3238,7 +3238,7 @@ ML
mw
mw
FU
-Xj
+iW
lI
mw
mw
@@ -3281,7 +3281,7 @@ mw
mw
ZV
kl
-wS
+OQ
XP
mw
mw
@@ -3387,7 +3387,7 @@ pp
pp
cn
XP
-cv
+wc
mw
mw
ht
@@ -3457,8 +3457,8 @@ aB
xq
Zc
ML
-vv
-vv
+ND
+ND
dg
uv
Zk
@@ -3499,7 +3499,7 @@ LK
CG
CG
CG
-Pf
+hn
mw
zN
VD
@@ -3513,7 +3513,7 @@ Zj
CG
bH
qr
-Wc
+FB
bP
Xd
CG
@@ -3577,7 +3577,7 @@ mw
mw
zN
VD
-uT
+bO
zN
mw
mw
@@ -3619,7 +3619,7 @@ dg
iH
GU
dg
-ze
+af
QZ
dg
rj
@@ -3634,7 +3634,7 @@ Ed
(39,1,1) = {"
Ed
CG
-HP
+lV
mw
mw
mw
@@ -3661,7 +3661,7 @@ mw
mw
mw
mw
-Oy
+Oo
dg
lx
Jg
@@ -3749,24 +3749,24 @@ hH
Zb
hH
dg
-OA
+AP
bl
xM
-qW
+DF
dg
-Mz
+pU
DI
-vH
+dv
dg
-Je
+hw
NU
Vf
NU
-rV
+EC
dg
-aw
+Od
Wm
-Mz
+pU
dg
uL
hO
@@ -3786,7 +3786,7 @@ Zb
gp
Zb
dg
-hr
+ha
xM
bl
CL
@@ -3828,9 +3828,9 @@ CL
CL
rR
dg
-HL
+wq
DI
-Dy
+Uj
dg
jR
NU
@@ -3838,9 +3838,9 @@ NU
NU
NU
dg
-Vg
+My
DI
-Yf
+DG
dg
VE
qi
@@ -3904,7 +3904,7 @@ rR
dg
ed
wU
-fG
+mr
oY
Rf
Oa
@@ -3912,7 +3912,7 @@ lP
Oa
lP
oY
-fG
+mr
wU
ed
dg
@@ -3939,7 +3939,7 @@ bl
xM
ee
dg
-Hw
+pB
wU
wU
WX
@@ -3951,7 +3951,7 @@ Rf
oY
Uf
wU
-nm
+oh
dg
qi
ZU
@@ -3976,7 +3976,7 @@ Yd
PV
Tj
dg
-NP
+ni
wU
Uf
oY
@@ -3988,7 +3988,7 @@ NF
oY
Uf
wU
-Qh
+vr
dg
Ez
Ez
@@ -4054,11 +4054,11 @@ LK
LK
LK
CG
-jK
+pX
lP
Oa
lP
-IY
+WD
CG
LK
LK
diff --git a/_maps/templates/lazy_templates/nukie_base.dmm b/_maps/templates/lazy_templates/nukie_base.dmm
index 9815d45806b..68913efe70d 100644
--- a/_maps/templates/lazy_templates/nukie_base.dmm
+++ b/_maps/templates/lazy_templates/nukie_base.dmm
@@ -111,7 +111,7 @@
dir = 5
},
/obj/structure/table/reinforced/plasmarglass,
-/obj/item/storage/backpack/duffelbag/med/surgery{
+/obj/item/surgery_tray/full{
pixel_y = -11
},
/obj/item/storage/belt/medical,
diff --git a/_maps/templates/lazy_templates/wizard_den.dmm b/_maps/templates/lazy_templates/wizard_den.dmm
index 7695dab4abf..c6150df4018 100644
--- a/_maps/templates/lazy_templates/wizard_den.dmm
+++ b/_maps/templates/lazy_templates/wizard_den.dmm
@@ -430,7 +430,7 @@
/turf/open/floor/wood,
/area/centcom/wizard_station)
"SD" = (
-/obj/structure/bookcase/random/reference,
+/obj/structure/bookcase/random/reference/wizard,
/turf/open/floor/engine/cult,
/area/centcom/wizard_station)
"Tl" = (
diff --git a/code/__DEFINES/achievements.dm b/code/__DEFINES/achievements.dm
index 45390b5ff3c..4a0299d835a 100644
--- a/code/__DEFINES/achievements.dm
+++ b/code/__DEFINES/achievements.dm
@@ -11,6 +11,12 @@
///the priority of the achievements score. NO achievement should have a priority equal or lower than this.
#define AWARD_PRIORITY_LAST 0
+/// preferences for the sound played when unlocking an achievement
+#define CHEEVO_SOUND_TADA "Tada Fanfare"
+#define CHEEVO_SOUND_JINGLE "Beeps Jingle"
+#define CHEEVO_SOUND_PING "Success Ping"
+#define CHEEVO_SOUND_OFF "Disabled"
+
//Misc Medal hub IDs
#define MEDAL_METEOR "Your Life Before Your Eyes"
#define MEDAL_PULSE "Jackpot"
@@ -40,6 +46,7 @@
#define MEDAL_VOID_ASCENSION "Void"
#define MEDAL_BLADE_ASCENSION "Blade"
#define MEDAL_COSMOS_ASCENSION "Cosmos"
+#define MEDAL_KNOCK_ASCENSION "Knock"
#define MEDAL_TOOLBOX_SOUL "Toolsoul"
#define MEDAL_CHEM_TUT "Beginner Chemist"
#define MEDAL_HOT_DAMN "Hot Damn!"
@@ -95,7 +102,6 @@
#define BOSS_MEDAL_HIEROPHANT "Hierophant Killer"
#define BOSS_MEDAL_LEGION "Legion Killer"
#define BOSS_MEDAL_TENDRIL "Tendril Exterminator"
-#define BOSS_MEDAL_SWARMERS "Swarmer Beacon Killer"
#define BOSS_MEDAL_WENDIGO "Wendigo Killer"
#define BOSS_MEDAL_KINGGOAT "King Goat Killer"
@@ -106,7 +112,6 @@
#define BOSS_MEDAL_DRAKE_CRUSHER "Drake Crusher"
#define BOSS_MEDAL_HIEROPHANT_CRUSHER "Hierophant Crusher"
#define BOSS_MEDAL_LEGION_CRUSHER "Legion Crusher"
-#define BOSS_MEDAL_SWARMERS_CRUSHER "Swarmer Beacon Crusher"
#define BOSS_MEDAL_WENDIGO_CRUSHER "Wendigo Crusher"
#define BOSS_MEDAL_KINGGOAT_CRUSHER "King Goat Crusher"
diff --git a/code/__DEFINES/actions.dm b/code/__DEFINES/actions.dm
index 6e57c445723..066d2d60c1e 100644
--- a/code/__DEFINES/actions.dm
+++ b/code/__DEFINES/actions.dm
@@ -19,6 +19,8 @@ DEFINE_BITFIELD(check_flags, list(
///Action button triggered with right click
#define TRIGGER_SECONDARY_ACTION (1<<0)
+///Action triggered to ignore any availability checks
+#define TRIGGER_FORCE_AVAILABLE (1<<1)
// Defines for formatting cooldown actions for the stat panel.
/// The stat panel the action is displayed in.
diff --git a/code/__DEFINES/ai/ai.dm b/code/__DEFINES/ai/ai.dm
index 1a6829946a1..467fc9d7c0f 100644
--- a/code/__DEFINES/ai/ai.dm
+++ b/code/__DEFINES/ai/ai.dm
@@ -29,7 +29,9 @@
/// Don't move if being pulled
#define STOP_MOVING_WHEN_PULLED (1<<0)
/// Continue processing even if dead
-#define CAN_ACT_WHILE_DEAD (1<<1)
+#define CAN_ACT_WHILE_DEAD (1<<1)
+/// Stop processing while in a progress bar
+#define PAUSE_DURING_DO_AFTER (1<<2)
//Base Subtree defines
diff --git a/code/__DEFINES/ai/ai_blackboard.dm b/code/__DEFINES/ai/ai_blackboard.dm
index 289f7586222..443a51a7eb7 100644
--- a/code/__DEFINES/ai/ai_blackboard.dm
+++ b/code/__DEFINES/ai/ai_blackboard.dm
@@ -44,6 +44,8 @@
/// Generic key for a non-specific targetted action
#define BB_TARGETTED_ACTION "BB_targetted_action"
+/// Generic key for a non-specific action
+#define BB_GENERIC_ACTION "BB_generic_action"
///How long have we spent with no target?
#define BB_TARGETLESS_TIME "BB_targetless_time"
@@ -83,3 +85,14 @@
#define BB_MOD_IMPLANT "BB_mod_implant"
///Range for a MOD AI controller.
#define MOD_AI_RANGE 200
+
+///should we skip the faction check for the targetting datum?
+#define BB_BASIC_MOB_SKIP_FACTION_CHECK "BB_basic_mob_skip_faction_check"
+
+///currently only used by clowns, a list of what can the mob speak randomly
+#define BB_BASIC_MOB_SPEAK_LINES "BB_speech_lines"
+#define BB_EMOTE_SAY "emote_say"
+#define BB_EMOTE_HEAR "emote_hear"
+#define BB_EMOTE_SEE "emote_see"
+#define BB_EMOTE_SOUND "emote_sound"
+#define BB_EMOTE_CHANCE "emote_chance"
diff --git a/code/__DEFINES/ai/monsters.dm b/code/__DEFINES/ai/monsters.dm
index 4915ff9cbc8..927f3736832 100644
--- a/code/__DEFINES/ai/monsters.dm
+++ b/code/__DEFINES/ai/monsters.dm
@@ -59,11 +59,6 @@
/// We increment this counter every time we try to move while dragging an arm and if we go too long we'll give up trying to get out of line of sight and just eat the fingers
#define BB_LOBSTROSITY_FINGER_LUST "BB_lobstrosity_finger_lust"
-/// Key containing overwatch ability information
-#define BB_WATCHER_OVERWATCH "BB_watcher_overwatch"
-/// Key containing gazae ability information
-#define BB_WATCHER_GAZE "BB_watcher_gaze"
-
// eyeball keys
///the death glare ability
#define BB_GLARE_ABILITY "BB_glare_ability"
@@ -119,3 +114,35 @@
#define BB_ORE_TARGET "BB_ore_target"
/// which ore types we will not eat
#define BB_ORE_IGNORE_TYPES "BB_ore_ignore_types"
+
+// minebot keys
+/// key that stores our toggle light ability
+#define BB_MINEBOT_LIGHT_ABILITY "minebot_light_ability"
+/// key that stores our dump ore ability
+#define BB_MINEBOT_DUMP_ABILITY "minebot_dump_ability"
+/// key that stores our target turf
+#define BB_TARGET_MINERAL_TURF "target_mineral_turf"
+/// key that stores list of the turfs we ignore
+#define BB_BLACKLIST_MINERAL_TURFS "blacklist_mineral_turfs"
+/// key that stores the previous blocked wall
+#define BB_PREVIOUS_UNREACHABLE_WALL "previous_unreachable_wall"
+/// key that stores our mining mode
+#define BB_AUTOMATED_MINING "automated_mining"
+/// key that stores the nearest dead human
+#define BB_NEARBY_DEAD_MINER "nearby_dead_miner"
+
+//seedling keys
+/// the water can we will pick up
+#define BB_WATERCAN_TARGET "watercan_target"
+/// the hydrotray we will heal
+#define BB_HYDROPLANT_TARGET "hydroplant_target"
+/// minimum weed levels for us to cure
+#define BB_WEEDLEVEL_THRESHOLD "weedlevel_threshold"
+/// minimum water levels for us to refill
+#define BB_WATERLEVEL_THRESHOLD "waterlevel_threshold"
+/// key holds our solarbeam ability
+#define BB_SOLARBEAM_ABILITY "solarbeam_ability"
+/// key holds our rapid seeds ability
+#define BB_RAPIDSEEDS_ABILITY "rapidseeds_ability"
+/// key holds the tray we will beam
+#define BB_BEAMABLE_HYDROPLANT_TARGET "beamable_hydroplant_target"
diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm
index 7c530b3970e..e74cd6a58bd 100644
--- a/code/__DEFINES/antagonists.dm
+++ b/code/__DEFINES/antagonists.dm
@@ -80,6 +80,7 @@
#define PATH_VOID "Void Path"
#define PATH_BLADE "Blade Path"
#define PATH_COSMIC "Cosmic Path"
+#define PATH_KNOCK "Knock Path"
/// Defines are used in /proc/has_living_heart() to report if the heretic has no heart period, no living heart, or has a living heart.
#define HERETIC_NO_HEART_ORGAN -1
diff --git a/code/__DEFINES/atmospherics/atmos_piping.dm b/code/__DEFINES/atmospherics/atmos_piping.dm
index bb5350ee17e..5e501a83983 100644
--- a/code/__DEFINES/atmospherics/atmos_piping.dm
+++ b/code/__DEFINES/atmospherics/atmos_piping.dm
@@ -47,6 +47,8 @@
#define TANK_DEFAULT_RELEASE_PRESSURE 16
/// The default initial value gas plasmamen tanks releases valves are set to.
#define TANK_PLASMAMAN_RELEASE_PRESSURE 4
+/// The default initial value gas flown tanks releases valves are set to.
+#define TANK_CLOWN_RELEASE_PRESSURE 20
/// The internal temperature in kelvins at which a handheld gas tank begins to take damage.
#define TANK_MELT_TEMPERATURE 1000000
/// The internal pressure in kPa at which a handheld gas tank begins to take damage.
diff --git a/code/__DEFINES/bodyparts.dm b/code/__DEFINES/bodyparts.dm
index 5c575184273..87995d46abb 100644
--- a/code/__DEFINES/bodyparts.dm
+++ b/code/__DEFINES/bodyparts.dm
@@ -1,2 +1,25 @@
///The standard amount of bodyparts a carbon has. Currently 6, HEAD/L_ARM/R_ARM/CHEST/L_LEG/R_LEG
#define BODYPARTS_DEFAULT_MAXIMUM 6
+
+/// The max HP of surplus prosthetics.
+#define PROSTHESIS_MAX_HP 20
+
+// EMP
+// Note most of these values are doubled on heavy EMP
+
+/// The brute damage an augged limb takes from an EMP.
+#define AUGGED_LIMB_EMP_BRUTE_DAMAGE 2
+/// The brute damage an augged limb takes from an EMP.
+#define AUGGED_LIMB_EMP_BURN_DAMAGE 1.5
+
+/// When hit by an EMP, the time an augged limb will be paralyzed for if its above the damage threshold.
+#define AUGGED_LIMB_EMP_PARALYZE_TIME 3 SECONDS
+
+/// When hit by an EMP, the time an augged leg will be knocked down for.
+#define AUGGED_LEG_EMP_KNOCKDOWN_TIME 3 SECONDS
+/// When hit by an EMP, the time a augged chest will cause a hardstun for if its above the damage threshold.
+#define AUGGED_CHEST_EMP_STUN_TIME 3 SECONDS
+/// When hit by an EMP, the time an augged chest will cause the mob to shake() for.
+#define AUGGED_CHEST_EMP_SHAKE_TIME 5 SECONDS
+/// When hit by an EMP, the time an augged head will make vision fucky for.
+#define AUGGED_HEAD_EMP_GLITCH_DURATION 6 SECONDS
diff --git a/code/__DEFINES/clothing.dm b/code/__DEFINES/clothing.dm
index 77d2bced447..95107455c4a 100644
--- a/code/__DEFINES/clothing.dm
+++ b/code/__DEFINES/clothing.dm
@@ -30,3 +30,6 @@
#define ADD_CLOTHING_TRAIT(mob, trait) ADD_TRAIT(mob, trait, "[CLOTHING_TRAIT]_[REF(src)]")
/// Wrapper for removing clothing based traits
#define REMOVE_CLOTHING_TRAIT(mob, trait) REMOVE_TRAIT(mob, trait, "[CLOTHING_TRAIT]_[REF(src)]")
+
+/// How much integrity does a shirt lose every time we bite it?
+#define MOTH_EATING_CLOTHING_DAMAGE 15
diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm
index 4c8e407e8f4..92e7749860b 100644
--- a/code/__DEFINES/combat.dm
+++ b/code/__DEFINES/combat.dm
@@ -99,10 +99,12 @@ DEFINE_BITFIELD(status_flags, list(
//click cooldowns, in tenths of a second, used for various combat actions
#define CLICK_CD_MELEE 8
-#define CLICK_CD_THROW 8
-#define CLICK_CD_RANGE 4
#define CLICK_CD_RAPID 2
#define CLICK_CD_HYPER_RAPID 1
+#define CLICK_CD_SLOW 10
+
+#define CLICK_CD_THROW 8
+#define CLICK_CD_RANGE 4
#define CLICK_CD_CLICK_ABILITY 6
#define CLICK_CD_BREAKOUT 100
#define CLICK_CD_HANDCUFFED 10
diff --git a/code/__DEFINES/dcs/signals/signals_area.dm b/code/__DEFINES/dcs/signals/signals_area.dm
index 0cd24d69ed0..762431788f2 100644
--- a/code/__DEFINES/dcs/signals/signals_area.dm
+++ b/code/__DEFINES/dcs/signals/signals_area.dm
@@ -12,8 +12,6 @@
#define COMSIG_ENTER_AREA "enter_area"
///from base of area/Exited(): (area). Sent to "area-sensitive" movables, see __DEFINES/traits.dm for info.
#define COMSIG_EXIT_AREA "exit_area"
-///from base of /datum/controller/subsystem/atoms/proc/InitAtom(): (atom/new_atom)
-#define COMSIG_AREA_INITIALIZED_IN "area_initialized_in"
// Alarm listener datum signals
///Sent when an alarm is fired and an alarm listener has tracked onto it (alarm, area/source_area)
diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_attack.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_attack.dm
index d47833f84c0..a2198cfb63c 100644
--- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_attack.dm
+++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_attack.dm
@@ -64,3 +64,6 @@
#define ATTACKER_SHOVING (1<<1)
/// The attack is a damaging-type attack
#define ATTACKER_DAMAGING_ATTACK (1<<2)
+
+/// Called on the atom being hit, from /datum/component/anti_magic/on_attack() : (obj/item/weapon, mob/user, antimagic_flags)
+#define COMSIG_ATOM_HOLYATTACK "atom_holyattacked"
diff --git a/code/__DEFINES/dcs/signals/signals_global.dm b/code/__DEFINES/dcs/signals/signals_global.dm
index 9b6960e2730..c75b169b90d 100644
--- a/code/__DEFINES/dcs/signals/signals_global.dm
+++ b/code/__DEFINES/dcs/signals/signals_global.dm
@@ -89,3 +89,8 @@
/// Global signal when light debugging is canceled
#define COMSIG_LIGHT_DEBUG_DISABLED "!light_debug_disabled"
+
+/// Global signal sent when a religious sect is chosen
+#define COMSIG_RELIGIOUS_SECT_CHANGED "!religious_sect_changed"
+/// Global signal sent when a religious sect is reset
+#define COMSIG_RELIGIOUS_SECT_RESET "!religious_sect_reset"
diff --git a/code/__DEFINES/dcs/signals/signals_lazy_templates.dm b/code/__DEFINES/dcs/signals/signals_lazy_templates.dm
new file mode 100644
index 00000000000..1c6ce7926ea
--- /dev/null
+++ b/code/__DEFINES/dcs/signals/signals_lazy_templates.dm
@@ -0,0 +1,2 @@
+/// Fired on the lazy template datum when the template is finished loading. (list/loaded_atom_movables, list/loaded_turfs, list/loaded_areas)
+#define COMSIG_LAZY_TEMPLATE_LOADED "lazy_template_loaded"
diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm
index dd5b38113d3..677a65a7be1 100644
--- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm
+++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm
@@ -25,6 +25,8 @@
// /mob/living/carbon physiology signals
#define COMSIG_CARBON_GAIN_WOUND "carbon_gain_wound" //from /datum/wound/proc/apply_wound() (/mob/living/carbon/C, /datum/wound/W, /obj/item/bodypart/L)
#define COMSIG_CARBON_LOSE_WOUND "carbon_lose_wound" //from /datum/wound/proc/remove_wound() (/mob/living/carbon/C, /datum/wound/W, /obj/item/bodypart/L)
+/// Called after limb AND victim has been unset
+#define COMSIG_CARBON_POST_LOSE_WOUND "carbon_post_lose_wound" //from /datum/wound/proc/remove_wound() (/datum/wound/lost_wound, /obj/item/bodypart/part, ignore_limb, replaced)
///from base of /obj/item/bodypart/proc/can_attach_limb(): (new_limb, special) allows you to fail limb attachment
#define COMSIG_ATTEMPT_CARBON_ATTACH_LIMB "attempt_carbon_attach_limb"
#define COMPONENT_NO_ATTACH (1<<0)
diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm
index bb7d2de4989..d4c3c659c68 100644
--- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm
+++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm
@@ -214,3 +214,6 @@
/// from mob/proc/dropItemToGround()
#define COMSIG_MOB_DROPPING_ITEM "mob_dropping_item"
+
+/// from /mob/proc/change_mob_type_unchecked() : ()
+#define COMSIG_MOB_CHANGED_TYPE "mob_changed_type"
diff --git a/code/__DEFINES/dcs/signals/signals_mod.dm b/code/__DEFINES/dcs/signals/signals_mod.dm
index 2533b698528..c4007d12969 100644
--- a/code/__DEFINES/dcs/signals/signals_mod.dm
+++ b/code/__DEFINES/dcs/signals/signals_mod.dm
@@ -25,6 +25,8 @@
#define MOD_ABORT_USE (1<<0)
/// Called when a module activates, after all checks have passed and cooldown started.
#define COMSIG_MODULE_ACTIVATED "mod_module_activated"
+/// Called when a module starts a cooldown until its next activation. Passed the cooldown time.
+#define COMSIG_MODULE_COOLDOWN_STARTED "mod_module_cooldown_started"
/// Called when a module deactivates, after all checks have passed.
#define COMSIG_MODULE_DEACTIVATED "mod_module_deactivated"
/// Called when a module is used, after all checks have passed and cooldown started.
diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm
index cc17e337791..19286859e9e 100644
--- a/code/__DEFINES/dcs/signals/signals_object.dm
+++ b/code/__DEFINES/dcs/signals/signals_object.dm
@@ -50,6 +50,8 @@
// /obj/machinery/computer/teleporter
/// from /obj/machinery/computer/teleporter/proc/set_target(target, old_target)
#define COMSIG_TELEPORTER_NEW_TARGET "teleporter_new_target"
+/// from /obj/item/beacon/proc/turn_off()
+#define COMSIG_BEACON_DISABLED "beacon_disabled"
// /obj/machinery/power/supermatter_crystal
/// from /obj/machinery/power/supermatter_crystal/process_atmos(); when the SM sounds an audible alarm
@@ -246,6 +248,8 @@
/// Called on component/uplink/OnAttackBy(..)
#define COMSIG_ITEM_ATTEMPT_TC_REIMBURSE "item_attempt_tc_reimburse"
+///Called when a holoparasite/guardiancreator is used.
+#define COMSIG_TRAITOR_ITEM_USED(type) "traitor_item_used_[type]"
// /obj/item/clothing signals
@@ -473,4 +477,3 @@
/// from /obj/structure/cursed_slot_machine/determine_victor() when someone finally wins.
#define COMSIG_GLOB_CURSED_SLOT_MACHINE_WON "cursed_slot_machine_won"
-
diff --git a/code/__DEFINES/dcs/signals/signals_reagent.dm b/code/__DEFINES/dcs/signals/signals_reagent.dm
index 00fdddc6c9e..a73d59a234c 100644
--- a/code/__DEFINES/dcs/signals/signals_reagent.dm
+++ b/code/__DEFINES/dcs/signals/signals_reagent.dm
@@ -6,6 +6,8 @@
#define COMSIG_ATOM_EXPOSE_REAGENTS "atom_expose_reagents"
/// Prevents the atom from being exposed to reagents if returned on [COMSIG_ATOM_EXPOSE_REAGENTS]
#define COMPONENT_NO_EXPOSE_REAGENTS (1<<0)
+///from base of atom/expose_reagents(): (/list, /datum/reagents, methods, volume_modifier, show_message)
+#define COMSIG_ATOM_AFTER_EXPOSE_REAGENTS "atom_after_expose_reagents"
///from base of [/datum/reagent/proc/expose_atom]: (/datum/reagent, reac_volume)
#define COMSIG_ATOM_EXPOSE_REAGENT "atom_expose_reagent"
///from base of [/datum/reagent/proc/expose_atom]: (/atom, reac_volume)
diff --git a/code/__DEFINES/dcs/signals/signals_saboteur.dm b/code/__DEFINES/dcs/signals/signals_saboteur.dm
new file mode 100644
index 00000000000..5b0fef52aee
--- /dev/null
+++ b/code/__DEFINES/dcs/signals/signals_saboteur.dm
@@ -0,0 +1,5 @@
+// Light disruptor. Not to be confused with the light eater, which permanently disables lights.
+
+/// from /obj/projectile/energy/fisher/on_hit() or /obj/item/gun/energy/recharge/fisher when striking a target
+#define COMSIG_HIT_BY_SABOTEUR "HIT_BY_SABOTEUR"
+ #define COMSIG_SABOTEUR_SUCCESS (1<<0)
diff --git a/code/__DEFINES/dcs/signals/signals_wizard.dm b/code/__DEFINES/dcs/signals/signals_wizard.dm
index a4b8f0755c4..5cdebf4f062 100644
--- a/code/__DEFINES/dcs/signals/signals_wizard.dm
+++ b/code/__DEFINES/dcs/signals/signals_wizard.dm
@@ -1,4 +1,4 @@
-/// Signal sent when we finish invoking a rune
+/// Signal sent when we finish invoking a rune. Will also send the amount of cheese sacrificed on the rune : (cheese_sacrificed)
#define COMSIG_GRAND_RUNE_COMPLETE "grand rune complete"
/// Signal sent when we finish 7 grand rituals
#define COMSIG_GRAND_RITUAL_FINAL_COMPLETE "grand ritual finale complete"
diff --git a/code/__DEFINES/events.dm b/code/__DEFINES/events.dm
index ac86e77a4e0..2b1755b22c4 100644
--- a/code/__DEFINES/events.dm
+++ b/code/__DEFINES/events.dm
@@ -36,6 +36,8 @@
/// Return from admin setup to stop the event from triggering entirely.
#define ADMIN_CANCEL_EVENT "cancel event"
+/// Event can never be triggered by wizards
+#define NEVER_TRIGGERED_BY_WIZARDS -1
/// Event can only run on a map set in space
#define EVENT_SPACE_ONLY (1 << 0)
/// Event can only run on a map which is a planet
diff --git a/code/__DEFINES/fishing.dm b/code/__DEFINES/fishing.dm
index 2481f0ae3e7..dc73623f27c 100644
--- a/code/__DEFINES/fishing.dm
+++ b/code/__DEFINES/fishing.dm
@@ -51,14 +51,10 @@
/// Much like FISHING_HOOK_ENSNARE but for the reel.
#define FISHING_LINE_BOUNCY (1 << 2)
-#define FISHING_MINIGAME_RULE_HEAVY_FISH "heavy"
-#define FISHING_MINIGAME_RULE_LUBED_FISH "lubed"
-#define FISHING_MINIGAME_RULE_WEIGHTED_BAIT "weighted"
-#define FISHING_MINIGAME_RULE_LIMIT_LOSS "limit_loss"
-#define FISHING_MINIGAME_RULE_BIDIRECTIONAL "bidirectional"
-#define FISHING_MINIGAME_RULE_NO_ESCAPE "no_escape"
-#define FISHING_MINIGAME_RULE_KILL "kill"
-#define FISHING_MINIGAME_RULE_NO_EXP "no_exp"
+#define FISHING_MINIGAME_RULE_BIDIRECTIONAL (1 << 2)
+#define FISHING_MINIGAME_RULE_NO_ESCAPE (1 << 3)
+#define FISHING_MINIGAME_RULE_KILL (1 << 4)
+#define FISHING_MINIGAME_RULE_NO_EXP (1 << 5)
/// The default additive value for fishing hook catch weight modifiers.
#define FISHING_DEFAULT_HOOK_BONUS_ADDITIVE 0
diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm
index f509b740d26..849b3a28b9c 100644
--- a/code/__DEFINES/flags.dm
+++ b/code/__DEFINES/flags.dm
@@ -88,7 +88,10 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
//TURF FLAGS
/// If a turf cant be jaunted through.
#define NOJAUNT (1<<0)
+/// If a turf is an usused reservation turf awaiting assignment
#define UNUSED_RESERVATION_TURF (1<<1)
+/// If a turf is a reserved turf
+#define RESERVATION_TURF (1<<2)
/// Blocks lava rivers being generated on the turf.
#define NO_LAVA_GEN (1<<3)
/// Blocks ruins spawning on the turf.
diff --git a/code/__DEFINES/food.dm b/code/__DEFINES/food.dm
index 7c6a10644ad..aa7833711eb 100644
--- a/code/__DEFINES/food.dm
+++ b/code/__DEFINES/food.dm
@@ -106,6 +106,70 @@ DEFINE_BITFIELD(foodtypes, list(
#define FOOD_AMAZING 6
#define RACE_DRINK 7 // SKYRAT ADDITION
+#define FOOD_QUALITY_NORMAL 1
+#define FOOD_QUALITY_NICE 2
+#define FOOD_QUALITY_GOOD 3
+#define FOOD_QUALITY_VERYGOOD 4
+#define FOOD_QUALITY_FANTASTIC 5
+#define FOOD_QUALITY_AMAZING 6
+#define FOOD_QUALITY_TOP 7
+
+#define FOOD_COMPLEXITY_0 0
+#define FOOD_COMPLEXITY_1 1
+#define FOOD_COMPLEXITY_2 2
+#define FOOD_COMPLEXITY_3 3
+#define FOOD_COMPLEXITY_4 4
+#define FOOD_COMPLEXITY_5 5
+
+/// Labels for food quality
+GLOBAL_LIST_INIT(food_quality_description, list(
+ FOOD_QUALITY_NORMAL = "okay",
+ FOOD_QUALITY_NICE = "nice",
+ FOOD_QUALITY_GOOD = "good",
+ FOOD_QUALITY_VERYGOOD = "very good",
+ FOOD_QUALITY_FANTASTIC = "fantastic",
+ FOOD_QUALITY_AMAZING = "amazing",
+ FOOD_QUALITY_TOP = "godlike",
+))
+
+/// Mood events for food quality
+GLOBAL_LIST_INIT(food_quality_events, list(
+ FOOD_QUALITY_NORMAL = /datum/mood_event/food,
+ FOOD_QUALITY_NICE = /datum/mood_event/food/nice,
+ FOOD_QUALITY_GOOD = /datum/mood_event/food/good,
+ FOOD_QUALITY_VERYGOOD = /datum/mood_event/food/verygood,
+ FOOD_QUALITY_FANTASTIC = /datum/mood_event/food/fantastic,
+ FOOD_QUALITY_AMAZING = /datum/mood_event/food/amazing,
+ FOOD_QUALITY_TOP = /datum/mood_event/food/top,
+))
+
+/// Crafted food buffs grouped by crafting_complexity
+GLOBAL_LIST_INIT(food_buffs, list(
+ FOOD_COMPLEXITY_1 = list(
+ /datum/status_effect/food/haste = 1,
+ ),
+ FOOD_COMPLEXITY_2 = list(
+ /datum/status_effect/food/haste = 1,
+ ),
+ FOOD_COMPLEXITY_3 = list(
+ /datum/status_effect/food/haste = 1,
+ ),
+ FOOD_COMPLEXITY_4 = list(
+ /datum/status_effect/food/haste = 1,
+ /datum/status_effect/food/trait/shockimmune = 1,
+ ),
+ FOOD_COMPLEXITY_5 = list(
+ /datum/status_effect/food/haste = 1,
+ /datum/status_effect/food/trait/shockimmune = 2,
+ ),
+))
+
+/// Food quality change according to species diet
+#define DISLIKED_FOOD_QUALITY_CHANGE -2
+#define LIKED_FOOD_QUALITY_CHANGE 2
+/// Threshold for food to give a toxic reaction
+#define TOXIC_FOOD_QUALITY_THRESHOLD -8
+
/// Food is "in a container", not in a code sense, but in a literal sense (canned foods)
#define FOOD_IN_CONTAINER (1<<0)
/// Finger food can be eaten while walking / running around
@@ -123,11 +187,6 @@ DEFINE_BITFIELD(food_flags, list(
#define FOOD_MEAT_MUTANT 100
#define FOOD_MEAT_MUTANT_RARE 200
-///Amount of reagents you start with on crafted food excluding the used parts
-#define CRAFTED_FOOD_BASE_REAGENT_MODIFIER 0.7
-///Modifier of reagents you get when crafting food from the parts used
-#define CRAFTED_FOOD_INGREDIENT_REAGENT_MODIFIER 0.5
-
#define IS_EDIBLE(O) (O.GetComponent(/datum/component/edible))
diff --git a/code/__DEFINES/holiday.dm b/code/__DEFINES/holiday.dm
new file mode 100644
index 00000000000..1c35940e718
--- /dev/null
+++ b/code/__DEFINES/holiday.dm
@@ -0,0 +1 @@
+#define HOLIDAY_HAT_CHANCE 20
diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm
index 84c475779cd..a52d2d809e6 100644
--- a/code/__DEFINES/is_helpers.dm
+++ b/code/__DEFINES/is_helpers.dm
@@ -64,6 +64,15 @@ GLOBAL_LIST_INIT(turfs_openspace, typecacheof(list(
#define iscliffturf(A) (istype(A, /turf/open/cliff))
+GLOBAL_LIST_INIT(turfs_pass_meteor, typecacheof(list(
+ /turf/closed/mineral,
+ /turf/open/misc/asteroid,
+ /turf/open/openspace,
+ /turf/open/space
+)))
+
+#define ispassmeteorturf(A) (is_type_in_typecache(A, GLOB.turfs_pass_meteor))
+
//Mobs
#define isliving(A) (istype(A, /mob/living))
@@ -167,7 +176,7 @@ GLOBAL_LIST_INIT(turfs_openspace, typecacheof(list(
#define ismegafauna(A) (istype(A, /mob/living/simple_animal/hostile/megafauna))
-#define isclown(A) (istype(A, /mob/living/simple_animal/hostile/retaliate/clown))
+#define isclown(A) (istype(A, /mob/living/basic/clown))
#define isspider(A) (istype(A, /mob/living/basic/spider/giant))
diff --git a/code/__DEFINES/jobs.dm b/code/__DEFINES/jobs.dm
index 3d740febc61..1445dac8647 100644
--- a/code/__DEFINES/jobs.dm
+++ b/code/__DEFINES/jobs.dm
@@ -137,6 +137,11 @@
#define JOB_SOLFED_LIASON "SolFed Liason"
// SKYRAT EDIT ADDITION END
+#define JOB_GROUP_ENGINEERS list( \
+ JOB_STATION_ENGINEER, \
+ JOB_ATMOSPHERIC_TECHNICIAN, \
+)
+
#define JOB_DISPLAY_ORDER_ASSISTANT 1
#define JOB_DISPLAY_ORDER_CAPTAIN 2
diff --git a/code/__DEFINES/keybinding.dm b/code/__DEFINES/keybinding.dm
index 0f05c0fe12b..33178bc7c8b 100644
--- a/code/__DEFINES/keybinding.dm
+++ b/code/__DEFINES/keybinding.dm
@@ -49,6 +49,8 @@
#define COMSIG_KB_LIVING_TOGGLE_COMBAT_DOWN "keybinding_living_toggle_combat_down"
#define COMSIG_KB_LIVING_ENABLE_COMBAT_DOWN "keybinding_living_enable_combat_down"
#define COMSIG_KB_LIVING_DISABLE_COMBAT_DOWN "keybinding_living_disable_combat_down"
+#define COMSIG_KB_LIVING_TOGGLEMOVEINTENT_DOWN "keybinding_mob_togglemoveintent_down"
+#define COMSIG_KB_LIVING_TOGGLEMOVEINTENTALT_DOWN "keybinding_mob_togglemoveintentalt_down"
//Mob
#define COMSIG_KB_MOB_FACENORTH_DOWN "keybinding_mob_facenorth_down"
@@ -61,8 +63,6 @@
#define COMSIG_KB_MOB_SWAPHANDS_DOWN "keybinding_mob_swaphands_down"
#define COMSIG_KB_MOB_ACTIVATEINHAND_DOWN "keybinding_mob_activateinhand_down"
#define COMSIG_KB_MOB_DROPITEM_DOWN "keybinding_mob_dropitem_down"
-#define COMSIG_KB_MOB_TOGGLEMOVEINTENT_DOWN "keybinding_mob_togglemoveintent_down"
-#define COMSIG_KB_MOB_TOGGLEMOVEINTENTALT_DOWN "keybinding_mob_togglemoveintentalt_down"
#define COMSIG_KB_MOB_TARGETCYCLEHEAD_DOWN "keybinding_mob_targetcyclehead_down"
#define COMSIG_KB_MOB_TARGETEYES_DOWN "keybinding_mob_targeteyes_down"
#define COMSIG_KB_MOB_TARGETMOUTH_DOWN "keybinding_mob_targetmouth_down"
diff --git a/code/__DEFINES/lazy_templates.dm b/code/__DEFINES/lazy_templates.dm
index d075b1e681a..1e8fab8d92c 100644
--- a/code/__DEFINES/lazy_templates.dm
+++ b/code/__DEFINES/lazy_templates.dm
@@ -2,11 +2,13 @@
#define LAZY_TEMPLATE_KEY_WIZARDDEN "LT_WIZARDDEN"
#define LAZY_TEMPLATE_KEY_NINJA_HOLDING_FACILITY "LT_NINJAHOLDING"
#define LAZY_TEMPLATE_KEY_ABDUCTOR_SHIPS "LT_ABDUCTORSHIPS"
+#define LAZY_TEMPLATE_KEY_HERETIC_SACRIFICE "LT_HERETICSACRIFICE"
#define LAZY_TEMPLATE_KEY_LIST_ALL(...) list( \
"Nukie Base" = LAZY_TEMPLATE_KEY_NUKIEBASE, \
"Wizard Den" = LAZY_TEMPLATE_KEY_WIZARDDEN, \
"Ninja Holding" = LAZY_TEMPLATE_KEY_NINJA_HOLDING_FACILITY, \
"Abductor Ships" = LAZY_TEMPLATE_KEY_ABDUCTOR_SHIPS, \
+ "Heretic Sacrifice Level" = LAZY_TEMPLATE_KEY_HERETIC_SACRIFICE, \
"Outpost of Cogs" = LAZY_TEMPLATE_KEY_OUTPOST_OF_COGS, \
) // SKYRAT EDIT ABOVE - OUTPOST OF COGS
diff --git a/code/__DEFINES/maths.dm b/code/__DEFINES/maths.dm
index c40f3c4f59c..eb1b2ecce51 100644
--- a/code/__DEFINES/maths.dm
+++ b/code/__DEFINES/maths.dm
@@ -240,6 +240,9 @@
#define SPT_PROB(prob_per_second_percent, seconds_per_tick) (prob(100*SPT_PROB_RATE((prob_per_second_percent)/100, (seconds_per_tick))))
// )
+// This value per these many units. Very unnecessary but helpful for readability (For example wanting 30 units of synthflesh to heal 50 damage - VALUE_PER(50, 30))
+#define VALUE_PER(value, per) (value / per)
+
#define GET_TRUE_DIST(a, b) (a == null || b == null) ? -1 : max(abs(a.x -b.x), abs(a.y-b.y), abs(a.z-b.z))
//We used to use linear regression to approximate the answer, but Mloc realized this was actually faster.
@@ -248,3 +251,6 @@
/// The number of cells in a taxicab circle (rasterized diamond) of radius X.
#define DIAMOND_AREA(X) (1 + 2*(X)*((X)+1))
+
+/// Returns a random decimal between x and y.
+#define RANDOM_DECIMAL(x, y) LERP((x), (y), rand())
diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index 4f13e711fc3..f90a187a964 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -42,18 +42,29 @@
#define VENTCRAWLER_ALWAYS 2
//Mob bio-types flags
-///The mob is organic, can can heal from medical sutures.
+///The mob is organic, can heal from medical sutures.
#define MOB_ORGANIC (1 << 0)
+///The mob is of a rocky make, most likely a golem. Iron within, iron without!
#define MOB_MINERAL (1 << 1)
+///The mob is a synthetic lifeform, like station borgs.
#define MOB_ROBOTIC (1 << 2)
+///The mob is an shambling undead corpse. Or a halloween species. Pick your poison.
#define MOB_UNDEAD (1 << 3)
+///The mob is a human-sized human-like human-creature.
#define MOB_HUMANOID (1 << 4)
+///The mob is a bug/insect/arachnid/some other kind of scuttly thing.
#define MOB_BUG (1 << 5)
+///The mob is a wild animal. Domestication may apply.
#define MOB_BEAST (1 << 6)
-#define MOB_EPIC (1 << 7) //megafauna
+///The mob is some kind of a creature that should be exempt from certain **fun** interactions for balance reasons, i.e. megafauna or a headslug.
+#define MOB_SPECIAL (1 << 7)
+///The mob is some kind of a scaly reptile creature
#define MOB_REPTILE (1 << 8)
+///The mob is a spooky phantasm or an evil ghast of such nature.
#define MOB_SPIRIT (1 << 9)
+///The mob is a plant-based species, benefitting from light but suffering from darkness and plantkillers.
#define MOB_PLANT (1 << 10)
+///The mob is a goopy creature, probably coming from xenobiology.
#define MOB_SLIME (1 << 11)
//Lung respiration type flags
@@ -392,6 +403,14 @@
#define SHOCK_NOSTUN (1 << 3)
/// No default message is sent from the shock
#define SHOCK_SUPPRESS_MESSAGE (1 << 4)
+/// No skeleton animation if a human was shocked
+#define SHOCK_NO_HUMAN_ANIM (1 << 5)
+/// Ignores TRAIT_STUNIMMUNE
+#define SHOCK_IGNORE_IMMUNITY (1 << 6)
+/// Prevents the immediate stun, instead only gives the delay
+#define SHOCK_DELAY_STUN (1 << 7)
+/// Makes the paralyze into a knockdown
+#define SHOCK_KNOCKDOWN (1 << 8)
#define INCORPOREAL_MOVE_BASIC 1 /// normal movement, see: [/mob/living/var/incorporeal_move]
#define INCORPOREAL_MOVE_SHADOW 2 /// leaves a trail of shadows
@@ -878,12 +897,26 @@ GLOBAL_LIST_INIT(layers_to_offset, list(
/// Get the client from the var
#define CLIENT_FROM_VAR(I) (ismob(I) ? I:client : (istype(I, /client) ? I : (istype(I, /datum/mind) ? I:current?:client : null)))
-/// The mob will vomit a green color
-#define VOMIT_TOXIC 1
-/// The mob will vomit a purple color
-#define VOMIT_PURPLE 2
-/// The mob will vomit a nebula color
-#define VOMIT_NEBULA 3
+// Various flags for carbon mob vomiting
+/// Flag which makes a message send about the vomiting.
+#define MOB_VOMIT_MESSAGE (1<<0)
+/// Flag which makes the mob get stunned upon vomiting.
+#define MOB_VOMIT_STUN (1<<1)
+/// Flag which makes the mob incur damage upon vomiting.
+#define MOB_VOMIT_HARM (1<<2)
+/// Flag which makes the mob vomit blood
+#define MOB_VOMIT_BLOOD (1<<3)
+/// Flag which will cause the mob to fall over when vomiting.
+#define MOB_VOMIT_KNOCKDOWN (1<<4)
+/// Flag which will make the proc skip certain checks when it comes to forcing a vomit.
+#define MOB_VOMIT_FORCE (1<<5)
+
+/// The default. Gives you might typically expect to happen when you vomit.
+#define VOMIT_CATEGORY_DEFAULT (MOB_VOMIT_MESSAGE | MOB_VOMIT_HARM | MOB_VOMIT_STUN)
+/// The vomit you've all come to know and love, but with a little extra "spice" (blood)
+#define VOMIT_CATEGORY_BLOOD (VOMIT_CATEGORY_DEFAULT | MOB_VOMIT_BLOOD)
+/// Another vomit variant that causes you to get knocked down instead of just only getting a stun. Standard otherwise.
+#define VOMIT_CATEGORY_KNOCKDOWN (VOMIT_CATEGORY_DEFAULT | MOB_VOMIT_KNOCKDOWN)
/// Possible value of [/atom/movable/buckle_lying]. If set to a different (positive-or-zero) value than this, the buckling thing will force a lying angle on the buckled.
#define NO_BUCKLE_LYING -1
diff --git a/code/__DEFINES/multiz.dm b/code/__DEFINES/multiz.dm
index 9d167495fa8..370eaa8ba45 100644
--- a/code/__DEFINES/multiz.dm
+++ b/code/__DEFINES/multiz.dm
@@ -1,4 +1,8 @@
/// Attempt to get the turf below the provided one according to Z traits
-#define GET_TURF_BELOW(turf) ((!(turf) || !length(SSmapping.multiz_levels) || !SSmapping.multiz_levels[(turf).z][Z_LEVEL_DOWN]) ? null : get_step((turf), DOWN))
+#define GET_TURF_BELOW(turf) ( \
+ (turf.turf_flags & RESERVATION_TURF) ? SSmapping.get_reservation_from_turf(turf)?.get_turf_below(turf) : \
+ (!(turf) || !length(SSmapping.multiz_levels) || !SSmapping.multiz_levels[(turf).z][Z_LEVEL_DOWN]) ? null : get_step((turf), DOWN))
/// Attempt to get the turf above the provided one according to Z traits
-#define GET_TURF_ABOVE(turf) ((!(turf) || !length(SSmapping.multiz_levels) || !SSmapping.multiz_levels[(turf).z][Z_LEVEL_UP]) ? null : get_step((turf), UP))
+#define GET_TURF_ABOVE(turf) ( \
+ (turf.turf_flags & RESERVATION_TURF) ? SSmapping.get_reservation_from_turf(turf)?.get_turf_above(turf) : \
+ (!(turf) || !length(SSmapping.multiz_levels) || !SSmapping.multiz_levels[(turf).z][Z_LEVEL_UP]) ? null : get_step((turf), UP))
diff --git a/code/__DEFINES/projectiles.dm b/code/__DEFINES/projectiles.dm
index eec9472c2bf..3bc745756aa 100644
--- a/code/__DEFINES/projectiles.dm
+++ b/code/__DEFINES/projectiles.dm
@@ -60,6 +60,9 @@
/// For gunpoints, how many tiles around the target the shooter can roam without losing their shot
#define GUNPOINT_SHOOTER_STRAY_RANGE 2
+/// A spark will be generated for each THIS amount of damage dealt to a robotic limb by a projectile.
+#define PROJECTILE_DAMAGE_PER_ROBOTIC_SPARK 20
+
//Designed for things that need precision trajectories like projectiles.
//Don't use this for anything that you don't absolutely have to use this with (like projectiles!) because it isn't worth using a datum unless you need accuracy down to decimal places in pixels.
diff --git a/code/__DEFINES/radioactive_nebula.dm b/code/__DEFINES/radioactive_nebula.dm
new file mode 100644
index 00000000000..68849ca1bc2
--- /dev/null
+++ b/code/__DEFINES/radioactive_nebula.dm
@@ -0,0 +1,2 @@
+/// Name of the glow we use for the radioation effect outside
+#define GLOW_NEBULA "glow_nebula"
diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm
index e874b68f02b..a6ba5c0ed38 100644
--- a/code/__DEFINES/reagents.dm
+++ b/code/__DEFINES/reagents.dm
@@ -115,6 +115,8 @@
#define REAGENT_NO_RANDOM_RECIPE (1<<7)
///Does this reagent clean things?
#define REAGENT_CLEANS (1<<8)
+///Does this reagent affect wounds? Used to check if some procs should be ran.
+#define REAGENT_AFFECTS_WOUNDS (1<<9)
//Chemical reaction flags, for determining reaction specialties
///Convert into impure/pure on reaction completion
diff --git a/code/__DEFINES/research.dm b/code/__DEFINES/research.dm
index 34794b5b255..52ee2c87f4e 100644
--- a/code/__DEFINES/research.dm
+++ b/code/__DEFINES/research.dm
@@ -71,3 +71,17 @@
#define SCIENTIFIC_COOPERATION_PURCHASE_MULTIPLIER 0.01
/// How much money is one point of gain worth.
#define SCIPAPER_GAIN_TO_MONEY 125
+
+///Connects the 'server_var' to a valid research server on your Z level.
+///Used for machines in LateInitialize, to ensure that RND servers are loaded first.
+#define CONNECT_TO_RND_SERVER_ROUNDSTART(server_var, holder) do { \
+ var/list/found_servers = SSresearch.get_available_servers(get_turf(holder)); \
+ var/obj/machinery/rnd/server/selected_server = length(found_servers) ? found_servers[1] : null; \
+ if (selected_server) { \
+ server_var = selected_server.stored_research; \
+ }; \
+ else { \
+ var/datum/techweb/station_fallback_web = locate(/datum/techweb/science) in SSresearch.techwebs; \
+ server_var = station_fallback_web; \
+ }; \
+} while (FALSE)
diff --git a/code/__DEFINES/shuttles.dm b/code/__DEFINES/shuttles.dm
index 3649bc4a6b0..6f15ea65216 100644
--- a/code/__DEFINES/shuttles.dm
+++ b/code/__DEFINES/shuttles.dm
@@ -63,6 +63,14 @@
#define ENGINE_COEFF_MAX 2
#define ENGINE_DEFAULT_MAXSPEED_ENGINES 5
+// Alert level related
+#define ALERT_COEFF_AUTOEVAC_NORMAL 2.5
+#define ALERT_COEFF_GREEN 2
+#define ALERT_COEFF_BLUE 1
+#define ALERT_COEFF_RED 0.5
+#define ALERT_COEFF_AUTOEVAC_CRITICAL 0.4
+#define ALERT_COEFF_DELTA 0.25
+
//Docking error flags
#define DOCKING_SUCCESS 0
#define DOCKING_BLOCKED (1<<0)
diff --git a/code/__DEFINES/skills.dm b/code/__DEFINES/skills.dm
index 26e66eee1f5..e870e9de7a6 100644
--- a/code/__DEFINES/skills.dm
+++ b/code/__DEFINES/skills.dm
@@ -41,7 +41,5 @@
#define CLEAN_SKILL_GENERIC_WASH_XP 1.5//Value. Higher number = more XP when cleaning non-cleanables (walls/floors/lips)
///The multiplier of the extra experience given by the fishing minigame based on difficulty. At the default difficulty of 15, the bonus will be of 21%.
#define FISHING_SKILL_DIFFIULTY_EXP_MULT 0.015
-///How much exp one would gain per spent playing the fishing minigame at minimum difficulty.
-#define FISHING_SKILL_EXP_PER_SECOND (SKILL_EXP_LEGENDARY / (22 MINUTES))
-///The maximum amount of experience one can get per fishing minigame. I appreciate the effort though.
-#define FISHING_SKILL_EXP_CAP_PER_GAME (SKILL_EXP_LEGENDARY / 5)
+///How much exp one would gain per spent playing the fishing minigame at minimum difficulty. the time is multiplied by 0.1 because deciseconds...
+#define FISHING_SKILL_EXP_PER_SECOND (SKILL_EXP_LEGENDARY / (15 MINUTES * 0.1))
diff --git a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm
index 91aa799c004..3caed7a0622 100644
--- a/code/__DEFINES/sound.dm
+++ b/code/__DEFINES/sound.dm
@@ -151,6 +151,8 @@
#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
diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm
index 4262472475a..50b33eb4c75 100644
--- a/code/__DEFINES/status_effects.dm
+++ b/code/__DEFINES/status_effects.dm
@@ -34,10 +34,9 @@
// Grouped effect sources, see also code/__DEFINES/traits.dm
#define STASIS_MACHINE_EFFECT "stasis_machine"
-
#define STASIS_CHEMICAL_EFFECT "stasis_chemical"
-
#define STASIS_SHAPECHANGE_EFFECT "stasis_shapechange"
+#define STASIS_ADMIN "stasis_admin"
/// 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/subsystems.dm b/code/__DEFINES/subsystems.dm
index b08bc32d8b7..2f452345ef9 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -119,9 +119,12 @@
/// Subsystem initialized sucessfully.
#define SS_INIT_SUCCESS 2
-/// Successful, but don't print anything. Useful if subsystem was disabled.
+/// If your system doesn't need to be initialized (by being disabled or something)
#define SS_INIT_NO_NEED 3
+/// Succesfully initialized, BUT do not announce it to players (generally to hide game mechanics it would otherwise spoil)
+#define SS_INIT_NO_MESSAGE 4
+
//! ### SS initialization load orders
// Subsystem init_order, from highest priority to lowest priority
// Subsystems shutdown in the reverse of the order they initialize in
@@ -323,6 +326,9 @@
#define SSMOBS_DT (SSmobs.wait/10)
#define SSOBJ_DT (SSobj.wait/10)
+// The change in the world's time from the subsystem's last fire in seconds.
+#define DELTA_WORLD_TIME(ss) ((world.time - ss.last_fire) * 0.1)
+
/// The timer key used to know how long subsystem initialization takes
#define SS_INIT_TIMER_KEY "ss_init"
diff --git a/code/__DEFINES/supermatter.dm b/code/__DEFINES/supermatter.dm
index f7e4a1bb51e..bac35207fb5 100644
--- a/code/__DEFINES/supermatter.dm
+++ b/code/__DEFINES/supermatter.dm
@@ -36,6 +36,11 @@
#define SUPERMATTER_WARNING_DELAY (60 SECONDS)
+/// If the crystal is healing faster than this per damage check, we suppress the Common radio notification for the cooldown
+#define SUPERMATTER_FAST_HEALING_RATE 0.025
+
+#define SUPERMATTER_COMMON_RADIO_DELAY (6 MINUTES)
+
#define SM_HALLUCINATION_RANGE(P) (min(7, round(P ** 0.25)))
#define GRAVITATIONAL_ANOMALY "gravitational_anomaly"
@@ -46,7 +51,10 @@
#define VORTEX_ANOMALY "vortex_anomaly"
#define DIMENSIONAL_ANOMALY "dimensional_anomaly"
-#define SUPERMATTER_COUNTDOWN_TIME (30 SECONDS)
+/// How long it takes for the supermatter to delaminate after hitting 0 integrity
+#define SUPERMATTER_COUNTDOWN_TIME (15 SECONDS)
+/// How long it takes for the supermatter to delaminate after hitting 0 integrity if a sliver has been removed
+#define SUPERMATTER_SLIVER_REMOVED_COUNTDOWN_TIME (5 SECONDS)
///to prevent accent sounds from layering
#define SUPERMATTER_ACCENT_SOUND_MIN_COOLDOWN (2 SECONDS)
@@ -55,6 +63,8 @@
#define SLIGHTLY_CHARGED_ZAP_ICON_STATE "sm_arc_supercharged"
#define OVER_9000_ZAP_ICON_STATE "sm_arc_dbz_referance" //Witty I know
+#define SUPERMATTER_DEFAULT_BULLET_ENERGY 2
+
#define SUPERMATTER_CASCADE_PERCENT 80
/// The divisor scaling value for cubic power loss.
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 5a09eb0c122..571f67f5b7d 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -192,6 +192,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// Makes the owner appear as dead to most forms of medical examination
#define TRAIT_FAKEDEATH "fakedeath"
#define TRAIT_DISFIGURED "disfigured"
+/// "Magic" trait that blocks the mob from moving or interacting with anything. Used for transient stuff like mob transformations or incorporality in special cases.
+/// Will block movement, `Life()` (!!!), and other stuff based on the mob.
+#define TRAIT_NO_TRANSFORM "block_transformations"
/// Tracks whether we're gonna be a baby alien's mummy.
#define TRAIT_XENO_HOST "xeno_host"
/// This mob is immune to stun causing status effects and stamcrit.
@@ -1136,7 +1139,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define SPEED_TRAIT "speed_trait"
/// Trait given to mobs that have been autopsied
#define AUTOPSY_TRAIT "autopsy_trait"
-
+/// Trait given by [/datum/status_effect/blessing_of_insanity]
+#define MAD_WIZARD_TRAIT "mad_wizard_trait"
/**
* Trait granted by [/mob/living/carbon/Initialize] and
@@ -1179,6 +1183,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define STATION_TRAIT_RADIOACTIVE_NEBULA "station_trait_radioactive_nebula"
#define STATION_TRAIT_FORESTED "station_trait_forested"
#define STATION_TRAIT_VENDING_SHORTAGE "station_trait_vending_shortage"
+#define STATION_TRAIT_MEDBOT_MANIA "station_trait_medbot_mania"
+#define STATION_TRAIT_LOANER_SHUTTLE "station_trait_loaner_shuttle"
+#define STATION_TRAIT_SHUTTLE_SALE "station_trait_shuttle_sale"
///From the market_crash event
#define MARKET_CRASH_EVENT_TRAIT "crashed_market_event"
@@ -1189,6 +1196,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_MAGNETIC_ID_CARD "magnetic_id_card"
/// ID cards with this trait have special appraisal text.
#define TRAIT_TASTEFULLY_THICK_ID_CARD "impressive_very_nice"
+/// things with this trait are treated as having no access in /obj/proc/check_access(obj/item)
+#define TRAIT_ALWAYS_NO_ACCESS "alwaysnoaccess"
/// Traits granted to items due to their chameleon properties.
#define CHAMELEON_ITEM_TRAIT "chameleon_item_trait"
diff --git a/code/__DEFINES/wires.dm b/code/__DEFINES/wires.dm
index d4f0cb748e1..6f618ac8240 100644
--- a/code/__DEFINES/wires.dm
+++ b/code/__DEFINES/wires.dm
@@ -9,6 +9,8 @@
#define WIRE_ACCEPT "Scan Success"
#define WIRE_ACTIVATE "Activate"
+#define WIRE_LAUNCH "Launch"
+#define WIRE_SAFETIES "Safeties"
#define WIRE_AGELIMIT "Age Limit"
#define WIRE_AI "AI Connection"
#define WIRE_ALARM "Alarm"
diff --git a/code/__DEFINES/wounds.dm b/code/__DEFINES/wounds.dm
index 0a020b2b5a8..19ccd843dd4 100644
--- a/code/__DEFINES/wounds.dm
+++ b/code/__DEFINES/wounds.dm
@@ -1,4 +1,3 @@
-
// ~wound damage/rolling defines
/// the cornerstone of the wound threshold system, your base wound roll for any attack is rand(1, damage^this), after armor reduces said damage. See [/obj/item/bodypart/proc/check_wounding]
#define WOUND_DAMAGE_EXPONENT 1.4
@@ -13,6 +12,10 @@
/// set wound_bonus on an item or attack to this to disable checking wounding for the attack
#define CANT_WOUND -100
+/// If there are multiple possible and valid wounds for the same type and severity, weight will be used to pick among them. See _wound_pregen_data.dm for more details
+/// This is used in pick_weight, so use integers
+#define WOUND_DEFAULT_WEIGHT 50
+
// ~wound severities
/// for jokey/meme wounds like stubbed toe, no standard messages/sounds or second winds
#define WOUND_SEVERITY_TRIVIAL 0
@@ -22,21 +25,26 @@
/// outright dismemberment of limb
#define WOUND_SEVERITY_LOSS 4
+/// A "chronological" list of wound severities, starting at the least severe.
+GLOBAL_LIST_INIT(wound_severities_chronological, list(
+ "[WOUND_SEVERITY_TRIVIAL]",
+ "[WOUND_SEVERITY_MODERATE]",
+ "[WOUND_SEVERITY_SEVERE]",
+ "[WOUND_SEVERITY_CRITICAL]"
+))
-// ~wound categories
+// ~wound categories: wounding_types
/// any brute weapon/attack that doesn't have sharpness. rolls for blunt bone wounds
-#define WOUND_BLUNT 1
+#define WOUND_BLUNT "wound_blunt"
/// any brute weapon/attack with sharpness = SHARP_EDGED. rolls for slash wounds
-#define WOUND_SLASH 2
+#define WOUND_SLASH "wound_slash"
/// any brute weapon/attack with sharpness = SHARP_POINTY. rolls for piercing wounds
-#define WOUND_PIERCE 3
+#define WOUND_PIERCE "wound_pierce"
/// any concentrated burn attack (lasers really). rolls for burning wounds
-#define WOUND_BURN 4
-//SKYRAT EDIT ADDITION BEGIN - MEDICAL
-/// any brute attacks, rolled on a chance
-#define WOUND_MUSCLE 5
-//SKYRAT EDIT ADDITION END
+#define WOUND_BURN "wound_burn"
+/// Mainly a define used for wound_pregen_data, if a pregen data instance expects this, it will accept any and all wound types, even none at all
+#define WOUND_ALL "wound_all"
// ~determination second wind defines
// How much determination reagent to add each time someone gains a new wound in [/datum/wound/proc/second_wind]
@@ -50,36 +58,234 @@
/// While someone has determination in their system, their bleed rate is slightly reduced
#define WOUND_DETERMINATION_BLEED_MOD 0.85
-// ~wound global lists
-// list in order of highest severity to lowest
-GLOBAL_LIST_INIT(global_wound_types, list(
- WOUND_BLUNT = list(/datum/wound/blunt/critical, /datum/wound/blunt/severe, /datum/wound/blunt/moderate),
- WOUND_SLASH = list(/datum/wound/slash/critical, /datum/wound/slash/severe, /datum/wound/slash/moderate),
- WOUND_PIERCE = list(/datum/wound/pierce/critical, /datum/wound/pierce/severe, /datum/wound/pierce/moderate),
- WOUND_BURN = list(/datum/wound/burn/critical, /datum/wound/burn/severe, /datum/wound/burn/moderate),
- WOUND_MUSCLE = list(/datum/wound/muscle/severe, /datum/wound/muscle/moderate), /* SKYRAT EDIT ADD */
+/// Wounds using this competition mode will remove any wounds of a greater severity than itself in a random wound roll. In most cases, you dont want to use this.
+#define WOUND_COMPETITION_OVERPOWER_GREATERS "wound_submit"
+/// Wounds using this competition mode will remove any wounds of a lower severity than itself in a random wound roll. Used for ensuring the worse case scenario of a given injury_roll.
+#define WOUND_COMPETITION_OVERPOWER_LESSERS "wound_dominate"
+
+// ~biology defines
+// What kind of biology a limb has, and what wounds it can suffer
+/// Has absolutely fucking nothing, no wounds
+#define BIO_INORGANIC NONE
+/// Has bone - allows the victim to suffer T2-T3 bone blunt wounds
+#define BIO_BONE (1<<0)
+/// Has flesh - allows the victim to suffer fleshy slash pierce and burn wounds
+#define BIO_FLESH (1<<1)
+/// Has metal - allows the victim to suffer robotic blunt and burn wounds
+#define BIO_METAL (1<<2)
+/// Is wired internally - allows the victim to suffer electrical wounds (robotic T1-T3 slash/pierce)
+#define BIO_WIRED (1<<3)
+/// Has bloodflow - can suffer bleeding wounds and can bleed
+#define BIO_BLOODED (1<<4)
+/// Is connected by a joint - can suffer T1 bone blunt wounds (dislocation)
+#define BIO_JOINTED (1<<5)
+/// Robotic - can suffer all metal/wired wounds, such as: UNIMPLEMENTED PLEASE UPDATE ONCE SYNTH WOUNDS 9/5/2023 ~Niko
+#define BIO_ROBOTIC (BIO_METAL|BIO_WIRED)
+/// Has flesh and bone - See BIO_BONE and BIO_FLESH
+#define BIO_FLESH_BONE (BIO_BONE|BIO_FLESH)
+/// Standard humanoid - can bleed and suffer all flesh/bone wounds, such as: T1-3 slash/pierce/burn/blunt, except dislocations. Think human heads/chests
+#define BIO_STANDARD_UNJOINTED (BIO_FLESH_BONE|BIO_BLOODED)
+/// Standard humanoid limbs - can bleed and suffer all flesh/bone wounds, such as: T1-3 slash/pierce/burn/blunt. Can also bleed, and be dislocated. Think human arms and legs
+#define BIO_STANDARD_JOINTED (BIO_STANDARD_UNJOINTED|BIO_JOINTED)
+
+// "Where" a specific biostate is within a given limb
+// Interior is hard shit, the last line, shit like bones
+// Exterior is soft shit, targetted by slashes and pierces (usually), protects exterior
+// A limb needs both mangled interior and exterior to be dismembered, but slash/pierce must mangle exterior to attack the interior
+// Not having exterior/interior counts as mangled exterior/interior for the purposes of dismemberment
+/// The given biostate is on the "interior" of the limb - hard shit, protected by exterior
+#define ANATOMY_INTERIOR (1<<0)
+/// The given biostate is on the "exterior" of the limb - soft shit, protects interior
+#define ANATOMY_EXTERIOR (1<<1)
+#define ANATOMY_EXTERIOR_AND_INTERIOR (ANATOMY_EXTERIOR|ANATOMY_INTERIOR)
+
+/// A assoc list of BIO_ define to EXTERIOR/INTERIOR defines.
+/// This is where the interior/exterior state of a given biostate is set.
+/// Note that not all biostates are guaranteed to be one of these - and in fact, many are not
+/// IMPORTANT NOTE: All keys are stored as text and must be converted via text2num
+GLOBAL_LIST_INIT(bio_state_anatomy, list(
+ "[BIO_WIRED]" = ANATOMY_EXTERIOR,
+ "[BIO_METAL]" = ANATOMY_INTERIOR,
+ "[BIO_FLESH]" = ANATOMY_EXTERIOR,
+ "[BIO_BONE]" = ANATOMY_INTERIOR,
))
-// every single type of wound that can be rolled naturally, in case you need to pull a random one
-GLOBAL_LIST_INIT(global_all_wound_types, list(
- /datum/wound/blunt/critical,
- /datum/wound/blunt/severe,
- /datum/wound/blunt/moderate,
- /datum/wound/slash/critical,
- /datum/wound/slash/severe,
- /datum/wound/slash/moderate,
- /datum/wound/pierce/critical,
- /datum/wound/pierce/severe,
- /datum/wound/pierce/moderate,
- /datum/wound/burn/critical,
- /datum/wound/burn/severe,
- /datum/wound/burn/moderate,
- /* SKYRAT EDIT ADD START */
- /datum/wound/muscle/severe,
- /datum/wound/muscle/moderate,
- /* SKYRAT EDIT ADD END */
+// Wound series
+// A "wound series" is just a family of wounds that logically follow eachother
+// Multiple wounds in a single series cannot be on a limb - the highest severity will always be prioritized, and lower ones will be skipped
+/// T1-T3 Bleeding slash wounds. Requires flesh. Can cause bleeding, but doesn't require it. From: slash.dm
+#define WOUND_SERIES_FLESH_SLASH_BLEED "wound_series_flesh_slash_bled"
+/// T1-T3 Basic blunt wounds. T1 requires jointed, but 2-3 require bone. From: bone.dm
+#define WOUND_SERIES_BONE_BLUNT_BASIC "wound_series_bone_blunt_basic"
+/// T1-T3 Basic burn wounds. Requires flesh. From: burns.dm
+#define WOUND_SERIES_FLESH_BURN_BASIC "wound_series_flesh_burn_basic"
+/// T1-T3 Bleeding puncture wounds. Requires flesh. Can cause bleeding, but doesn't require it. From: pierce.dm
+#define WOUND_SERIES_FLESH_PUNCTURE_BLEED "wound_series_flesh_puncture_bleed"
+/// Generic loss wounds. See loss.dm
+#define WOUND_SERIES_LOSS_BASIC "wound_series_loss_basic"
+
+// SKYRAT EDIT ADDITION BEGIN - MUSCLE WOUNDS
+// Have to put it here so I can use it in the global list of wound series
+/// See muscle.dm
+#define WOUND_SERIES_MUSCLE_DAMAGE "skyrat_wound_series_muscle_damage" // We use a super high number as realistically speaking TG will never increment to this amount of wound series
+// SKYRAT EDIT ADDITION END
+
+/// A assoc list of (wound typepath -> wound_pregen_data instance). Every wound should have a pregen data.
+GLOBAL_LIST_INIT_TYPED(all_wound_pregen_data, /datum/wound_pregen_data, generate_wound_static_data())
+
+/// Constructs [GLOB.all_wound_pregen_data] by iterating through a typecache of pregen data, ignoring abstract types, and instantiating the rest.
+/proc/generate_wound_static_data()
+ RETURN_TYPE(/list/datum/wound_pregen_data)
+
+ var/list/datum/wound_pregen_data/all_pregen_data = list()
+
+ for (var/datum/wound_pregen_data/iterated_path as anything in typecacheof(path = /datum/wound_pregen_data, ignore_root_path = TRUE))
+ if (initial(iterated_path.abstract))
+ continue
+
+ if (!isnull(all_pregen_data[initial(iterated_path.wound_path_to_generate)]))
+ stack_trace("pre-existing pregen data for [initial(iterated_path.wound_path_to_generate)] when [iterated_path] was being considered: [all_pregen_data[initial(iterated_path.wound_path_to_generate)]]. \
+ this is definitely a bug, and is probably because one of the two pregen data have the wrong wound typepath defined. [iterated_path] will not be instantiated")
+
+ continue
+
+ var/datum/wound_pregen_data/pregen_data = new iterated_path
+ all_pregen_data[pregen_data.wound_path_to_generate] = pregen_data
+
+ return all_pregen_data
+
+// A wound series "collection" is merely a way for us to track what is in what series, and what their types are.
+// Without this, we have no centralized way to determine what type is in what series outside of iterating over every pregen data.
+
+/// A branching assoc list of (series -> list(severity -> list(typepath -> weight))). Allows you to say "I want a generic slash wound",
+/// then "Of severity 2", and get a wound of that description - via get_corresponding_wound_type()
+/// Series: A generic wound_series, such as WOUND_SERIES_BONE_BLUNT_BASIC
+/// Severity: Any wounds held within this will be of this severity.
+/// Typepath, Weight: Merely a pairing of a given typepath to its weight, held for convenience in pickweight.
+GLOBAL_LIST_INIT(wound_series_collections, generate_wound_series_collection())
+
+// Series -> severity -> type -> weight
+/// Generates [wound_series_collections] by iterating through all pregen_data. Refer to the mentioned list for documentation
+/proc/generate_wound_series_collection()
+ RETURN_TYPE(/list/datum/wound)
+
+ var/list/datum/wound/wound_collection = list()
+
+ for (var/datum/wound/wound_typepath as anything in typecacheof(/datum/wound, FALSE, TRUE))
+ var/datum/wound_pregen_data/pregen_data = GLOB.all_wound_pregen_data[wound_typepath]
+ if (!pregen_data)
+ continue
+
+ if (pregen_data.abstract)
+ stack_trace("somehow, a abstract wound_pregen_data instance ([pregen_data.type]) was instantiated and made it to generate_wound_series_collection()! \
+ i literally have no idea how! please fix this!")
+ continue
+
+ var/series = pregen_data.wound_series
+ var/list/datum/wound/series_list = wound_collection[series]
+ if (isnull(series_list))
+ wound_collection[series] = list()
+ series_list = wound_collection[series]
+
+ var/severity = "[(initial(wound_typepath.severity))]"
+ var/list/datum/wound/severity_list = series_list[severity]
+ if (isnull(severity_list))
+ series_list[severity] = list()
+ severity_list = series_list[severity]
+
+ severity_list[wound_typepath] = pregen_data.weight
+
+ return wound_collection
+
+/// A branching assoc list of (wounding_type -> list(wound_series)).
+/// Allows for determining of which wound series are caused by what.
+GLOBAL_LIST_INIT(wounding_types_to_series, list(
+ WOUND_BLUNT = list(
+ WOUND_SERIES_BONE_BLUNT_BASIC,
+ WOUND_SERIES_MUSCLE_DAMAGE, // SKYRAT EDIT -- MUSCLE WOUNDS
+ ),
+ WOUND_SLASH = list(
+ WOUND_SERIES_FLESH_SLASH_BLEED,
+ WOUND_SERIES_MUSCLE_DAMAGE, // SKYRAT EDIT -- MUSCLE WOUNDS
+ ),
+ WOUND_BURN = list(
+ WOUND_SERIES_FLESH_BURN_BASIC,
+ ),
+ WOUND_PUNCTURE = list(
+ WOUND_SERIES_FLESH_PUNCTURE_BLEED,
+ WOUND_SERIES_MUSCLE_DAMAGE, // SKYRAT EDIT -- MUSCLE WOUNDS
+ ),
))
+/// Used in get_corresponding_wound_type(): Will pick the highest severity wound out of severity_min and severity_max
+#define WOUND_PICK_HIGHEST_SEVERITY 1
+/// Used in get_corresponding_wound_type(): Will pick the lowest severity wound out of severity_min and severity_max
+#define WOUND_PICK_LOWEST_SEVERITY 2
+
+/**
+ * Searches through all wounds for any of proper type, series, and biostate, and then returns a single one via pickweight.
+ * Is able to discern between, say, a flesh slash wound, and a metallic slash wound, and will return the respective one for the provided limb.
+ *
+ * The severity_max and severity_pick_mode args mostly exist in case you want a wound in a series that may not have your ideal severity wound, as it lets you
+ * essentially set a "fallback", where if your ideal wound doesnt exist, it'll still return something, trying to get closest to your ideal severity.
+ *
+ * Generally speaking, if you want a critical/severe/moderate wound, you should set severity_min to WOUND_SEVERITY_MODERATE, severity_max to your ideal wound,
+ * and severity_pick_mode to WOUND_PICK_HIGHEST_SEVERITY - UNLESS you for some reason want the LOWEST severity, in which case you should set
+ * severity_max to the highest wound you're willing to tolerate, and severity_pick_mode to WOUND_PICK_LOWEST_SEVERITY.
+ *
+ * Args:
+ * * list/wounding_types: A list of wounding_types. Only wounds that accept these wound types will be considered.
+ * * obj/item/bodypart/part: The limb we are considering. Extremely important for biostates.
+ * * severity_min: The minimum wound severity we will search for.
+ * * severity_max = severity_min: The maximum wound severity we will search for.
+ * * severity_pick_mode = WOUND_PICK_HIGHEST_SEVERITY: The "pick mode" we will use when considering multiple wounds of acceptable severity. See the above defines.
+ * * random_roll = TRUE: If this is considered a "random" consideration. If true, only wounds that can be randomly generated will be considered.
+ * * duplicates_allowed = FALSE: If exact duplicates of a given wound on part are tolerated. Useful for simply getting a path and not instantiating.
+ * * care_about_existing_wounds = TRUE: If we iterate over wounds to see if any are above or at a given wounds severity, and disregard it if any are. Useful for simply getting a path and not instantiating.
+ *
+ * Returns:
+ * A randomly picked wound typepath meeting all the above criteria and being applicable to the part's biotype - or null if there were none.
+ */
+/proc/get_corresponding_wound_type(list/wounding_types, obj/item/bodypart/part, severity_min, severity_max = severity_min, severity_pick_mode = WOUND_PICK_HIGHEST_SEVERITY, random_roll = TRUE, duplicates_allowed = FALSE, care_about_existing_wounds = TRUE)
+ RETURN_TYPE(/datum/wound) // note that just because its set to return this doesnt mean its non-nullable
+
+ var/list/wounding_type_list = list()
+ for (var/wounding_type as anything in wounding_types)
+ wounding_type_list += GLOB.wounding_types_to_series[wounding_type]
+ if (!length(wounding_type_list))
+ return null
+
+ var/list/datum/wound/paths_to_pick_from = list()
+ for (var/series as anything in shuffle(wounding_type_list))
+ var/list/severity_list = GLOB.wound_series_collections[series]
+ if (!length(severity_list))
+ continue
+
+ var/picked_severity
+ for (var/severity_text as anything in shuffle(GLOB.wound_severities_chronological))
+ var/severity = text2num(severity_text)
+ if (severity > severity_min || severity < severity_max)
+ continue
+
+ if (isnull(picked_severity) || ((severity_pick_mode == WOUND_PICK_HIGHEST_SEVERITY && severity > picked_severity) || (severity_pick_mode == WOUND_PICK_LOWEST_SEVERITY && severity < picked_severity)))
+ picked_severity = severity
+
+ var/list/wound_typepaths = severity_list["[picked_severity]"]
+ if (!length(wound_typepaths))
+ continue
+
+ for (var/datum/wound/iterated_path as anything in wound_typepaths)
+ var/datum/wound_pregen_data/pregen_data = GLOB.all_wound_pregen_data[iterated_path]
+ if (pregen_data.can_be_applied_to(part, wounding_types, random_roll = random_roll, duplicates_allowed = duplicates_allowed, care_about_existing_wounds = care_about_existing_wounds))
+ paths_to_pick_from[iterated_path] = wound_typepaths[iterated_path]
+
+ return pick_weight(paths_to_pick_from) // we found our winners!
+
+/// Assoc list of biotype -> ideal scar file to be used and grab stuff from.
+GLOBAL_LIST_INIT(biotypes_to_scar_file, list(
+ "[BIO_FLESH]" = FLESH_SCAR_FILE,
+ "[BIO_BONE]" = BONE_SCAR_FILE
+))
// ~burn wound infection defines
// Thresholds for infection for burn wounds, once infestation hits each threshold, things get steadily worse
@@ -107,43 +313,25 @@ GLOBAL_LIST_INIT(global_all_wound_types, list(
// ~mangling defines
-// With the wounds pt. 2 update, general dismemberment now requires 2 things for a limb to be dismemberable (bone only creatures just need the second):
-// 1. Flesh is mangled: A critical slash or pierce wound on that limb
-// 2. Bone is mangled: At least a severe bone wound on that limb
-// see [/obj/item/bodypart/proc/get_mangled_state] for more information
+// With the wounds pt. 2 update, general dismemberment now requires 2 things for a limb to be dismemberable (exterior/bone only creatures just need the second):
+// 1. Exterior is mangled: A critical slash or pierce wound on that limb
+// 2. Interior is mangled: At least a severe bone wound on that limb
+// Lack of exterior or interior count as mangled exterior/interior respectively
+// see [/obj/item/bodypart/proc/get_mangled_state] for more information, as well as GLOB.bio_state_anatomy
#define BODYPART_MANGLED_NONE NONE
-#define BODYPART_MANGLED_BONE (1<<0)
-#define BODYPART_MANGLED_FLESH (1<<1)
-#define BODYPART_MANGLED_BOTH (BODYPART_MANGLED_BONE | BODYPART_MANGLED_FLESH)
-
-
-// ~biology defines
-// What kind of biology a limb has, and what wounds it can suffer
-/// golems and androids, cannot suffer any wounds
-#define BIO_INORGANIC NONE
-/// skeletons and plasmemes, can only suffer bone wounds, only needs mangled bone to be able to dismember
-#define BIO_BONE (1<<0)
-/// nothing right now, maybe slimepeople in the future, can only suffer slashing, piercing, and burn wounds
-#define BIO_FLESH (1<<1)
-/// standard humanoids, can suffer all wounds, needs mangled bone and flesh to dismember. conveniently, what you get when you combine BIO_BONE and BIO_FLESH
-#define BIO_FLESH_BONE (BIO_BONE | BIO_FLESH)
-
+#define BODYPART_MANGLED_INTERIOR (1<<0)
+#define BODYPART_MANGLED_EXTERIOR (1<<1)
+#define BODYPART_MANGLED_BOTH (BODYPART_MANGLED_INTERIOR | BODYPART_MANGLED_EXTERIOR)
// ~wound flag defines
-/// If this wound requires having the BIO_FLESH biological_state on the limb
-#define FLESH_WOUND (1<<0)
-/// If this wound requires having the BIO_BONE biological_state on the limb
-#define BONE_WOUND (1<<1)
-/// If having this wound counts as mangled flesh for dismemberment
-#define MANGLES_FLESH (1<<2)
-/// If having this wound counts as mangled bone for dismemberment
-#define MANGLES_BONE (1<<3)
+/// If having this wound counts as mangled exterior for dismemberment
+#define MANGLES_EXTERIOR (1<<0)
+/// If having this wound counts as mangled interior for dismemberment
+#define MANGLES_INTERIOR (1<<1)
/// If this wound marks the limb as being allowed to have gauze applied
-#define ACCEPTS_GAUZE (1<<4)
-//SKYRAT EDIT ADDITION BEGIN - MEDICAL
-/// If this wound marks the limb as being allowed to have gauze applied as a splint
-#define ACCEPTS_SPLINT (1<<5)
-//SKYRAT EDIT ADDITION END
+#define ACCEPTS_GAUZE (1<<2)
+/// If this wound allows the victim to grasp it
+#define CAN_BE_GRASPED (1<<3)
// ~scar persistence defines
// The following are the order placements for persistent scar save formats
@@ -161,11 +349,13 @@ GLOBAL_LIST_INIT(global_all_wound_types, list(
#define SCAR_SAVE_BIOLOGY 6
/// Which character slot this was saved to
#define SCAR_SAVE_CHAR_SLOT 7
+/// if the scar will check for any or all biostates on the limb (defaults to FALSE, so all)
+#define SCAR_SAVE_CHECK_ANY_BIO 8
///how many fields we save for each scar (so the number of above fields)
-#define SCAR_SAVE_LENGTH 7
+#define SCAR_SAVE_LENGTH 8
/// saved scars with a version lower than this will be discarded, increment when you update the persistent scarring format in a way that invalidates previous saved scars (new fields, reordering, etc)
-#define SCAR_CURRENT_VERSION 3
+#define SCAR_CURRENT_VERSION 4
/// how many scar slots, per character slot, we have to cycle through for persistent scarring, if enabled in character prefs
#define PERSISTENT_SCAR_SLOTS 3
diff --git a/code/__DEFINES/~skyrat_defines/_organ_defines.dm b/code/__DEFINES/~skyrat_defines/_organ_defines.dm
index 4571ca57af2..78bed9213e3 100644
--- a/code/__DEFINES/~skyrat_defines/_organ_defines.dm
+++ b/code/__DEFINES/~skyrat_defines/_organ_defines.dm
@@ -8,6 +8,9 @@
#define ORGAN_SLOT_BREASTS "breasts"
#define ORGAN_SLOT_ANUS "anus"
#define ORGAN_SLOT_NIPPLES "nipples"
-#define ORGAN_ERP_LIST list(ORGAN_SLOT_PENIS, ORGAN_SLOT_WOMB, ORGAN_SLOT_VAGINA, ORGAN_SLOT_TESTICLES, ORGAN_SLOT_BREASTS, ORGAN_SLOT_ANUS, ORGAN_SLOT_NIPPLES)
+#define ORGAN_SLOT_TAIL "tail"
+#define ORGAN_SLOT_SLIT "slit"
+#define ORGAN_SLOT_SHEATH "sheath"
+#define ORGAN_ERP_LIST list(ORGAN_SLOT_PENIS, ORGAN_SLOT_WOMB, ORGAN_SLOT_VAGINA, ORGAN_SLOT_TESTICLES, ORGAN_SLOT_BREASTS, ORGAN_SLOT_ANUS, ORGAN_SLOT_NIPPLES, ORGAN_SLOT_TAIL, ORGAN_SLOT_SLIT, ORGAN_SLOT_SHEATH)
#define ORGAN_SLOT_WINGS "wings"
diff --git a/code/__DEFINES/~skyrat_defines/combat.dm b/code/__DEFINES/~skyrat_defines/combat.dm
index 1451b99381f..7bd9e7e56f7 100644
--- a/code/__DEFINES/~skyrat_defines/combat.dm
+++ b/code/__DEFINES/~skyrat_defines/combat.dm
@@ -173,6 +173,16 @@
/// Attempts to perform a limb dislocation, with the user violently twisting one of target's limbs (as passed in). Only useful for extremities, because only extremities can eat dislocations.
/datum/species/proc/try_dislocate(mob/living/carbon/human/user, mob/living/carbon/human/target, obj/item/bodypart/affecting)
+ var/datum/wound_pregen_data/pregen_data = GLOB.all_wound_pregen_data[/datum/wound/blunt/bone/moderate]
+ if (!pregen_data)
+ stack_trace("/datum/wound/blunt/bone/moderate has no pregen data!")
+ return FALSE // shouldnt happen but sanity
+
+ if (!pregen_data.can_be_applied_to(affecting, random_roll = FALSE))
+ if (!(affecting.biological_state & BIO_JOINTED))
+ to_chat(user, span_warning("[target]'s [affecting.plaintext_zone] has no joint to dislocate!"))
+ return FALSE
+
user.changeNext_move(4 SECONDS)
target.visible_message(span_danger("[user.name] twists [target.name]'s [affecting.name] violently!"), \
span_userdanger("[user.name] twists your [affecting.name] violently!"), ignored_mobs=user)
@@ -182,7 +192,7 @@
target.visible_message(span_danger("[user.name] dislocates [target.name]'s [affecting.name]!"), \
span_userdanger("[user.name] dislocates your [affecting.name]!"), ignored_mobs=user)
to_chat(user, span_danger("You dislocate [target.name]'s [affecting.name]!"))
- affecting.force_wound_upwards(/datum/wound/blunt/moderate)
+ affecting.force_wound_upwards(/datum/wound/blunt/bone/moderate)
log_combat(user, target, "dislocates", "the [affecting.name]")
return TRUE
diff --git a/code/__DEFINES/~skyrat_defines/flavor_defines.dm b/code/__DEFINES/~skyrat_defines/flavor_defines.dm
index ccc055f0da0..c7804a0d956 100644
--- a/code/__DEFINES/~skyrat_defines/flavor_defines.dm
+++ b/code/__DEFINES/~skyrat_defines/flavor_defines.dm
@@ -7,3 +7,5 @@
/// The message displayed when someone received the View Crew Exploitables verb.
#define VIEW_CREW_EXPLOITABLES_GAIN_TEXT "You now have access to the View Crew Exploitables verb, which shows all crew who currently have exploitable info and a link to view it!"
+/// How many characters will be displayed in the temporary flavor text preview before we cut it off?
+#define TEMPORARY_FLAVOR_PREVIEW_LIMIT 110
diff --git a/code/__DEFINES/~skyrat_defines/jobs.dm b/code/__DEFINES/~skyrat_defines/jobs.dm
index 92af0760c94..f00d0a72a66 100644
--- a/code/__DEFINES/~skyrat_defines/jobs.dm
+++ b/code/__DEFINES/~skyrat_defines/jobs.dm
@@ -4,6 +4,7 @@
#define JOB_UNAVAILABLE_SPECIES (JOB_UNAVAILABLE_QUIRK + 1)
#define JOB_UNAVAILABLE_LANGUAGE (JOB_UNAVAILABLE_SPECIES + 1)
#define JOB_UNAVAILABLE_FLAVOUR (JOB_UNAVAILABLE_LANGUAGE + 1)
+#define JOB_UNAVAILABLE_AUGMENT (JOB_UNAVAILABLE_FLAVOUR + 1)
#define SEC_RESTRICTED_QUIRKS "Blind" = TRUE, "Brain Tumor" = TRUE, "Deaf" = TRUE, "Paraplegic" = TRUE, "Hemiplegic" = TRUE, "Mute" = TRUE, "Foreigner" = TRUE, "Pacifist" = TRUE, "Chunky Fingers" = TRUE, "No Guns" = TRUE, "Illiterate" = TRUE, "Nerve Stapled" = TRUE
#define HEAD_RESTRICTED_QUIRKS "Blind" = TRUE, "Deaf" = TRUE, "Mute" = TRUE, "Foreigner" = TRUE, "Chunky Fingers" = TRUE, "Brain Tumor" = TRUE, "Illiterate" = TRUE
@@ -11,3 +12,6 @@
#define GUARD_RESTRICTED_QUIRKS "Blind" = TRUE, "Deaf" = TRUE, "Foreigner" = TRUE, "Pacifist" = TRUE, "Nerve Stapled" = TRUE
#define RESTRICTED_QUIRKS_EXCEPTIONS list("Mute" = "Signer")
+
+#define HEAD_RESTRICTED_AUGMENTS /obj/item/bodypart/arm/left/self_destruct, /obj/item/bodypart/arm/right/self_destruct, /obj/item/bodypart/leg/left/self_destruct, /obj/item/bodypart/leg/right/self_destruct
+#define SEC_RESTRICTED_AUGMENTS /obj/item/bodypart/arm/left/self_destruct, /obj/item/bodypart/arm/right/self_destruct, /obj/item/bodypart/leg/left/self_destruct, /obj/item/bodypart/leg/right/self_destruct
diff --git a/code/__DEFINES/~skyrat_defines/medical_defines.dm b/code/__DEFINES/~skyrat_defines/medical_defines.dm
index 098c801a101..c32d18bbd4f 100644
--- a/code/__DEFINES/~skyrat_defines/medical_defines.dm
+++ b/code/__DEFINES/~skyrat_defines/medical_defines.dm
@@ -2,9 +2,3 @@
#define DAMAGED_BODYPART_BONUS_WOUNDING_BONUS 30 //After this threshold we dont get any wounding bonuses form damaged bodyparts
#define DAMAGED_BODYPART_BONUS_WOUNDING_THRESHOLD 0.5 //How much extra % of wounding dmg we'll have if a bodypart is damaged enough
#define DAMAGED_BODYPART_BONUS_WOUNDING_COEFF 15 //This is multiplied by the sustained damage %. Keep in mind the % limit //Currently: 15/0.5=7.5
-
-#define GAUZE_STAIN_BLOOD 1
-#define GAUZE_STAIN_PUS 2
-
-#define COMSIG_BODYPART_SPLINTED "bodypart_splinted" // from /obj/item/bodypart/proc/apply_gauze(/obj/item/stack/gauze)
-#define COMSIG_BODYPART_SPLINT_DESTROYED "bodypart_desplinted" // from [/obj/item/bodypart/proc/seep_gauze] when it runs out of absorption
diff --git a/code/__DEFINES/~skyrat_defines/mobs.dm b/code/__DEFINES/~skyrat_defines/mobs.dm
index c7b11412b10..14385b1364b 100644
--- a/code/__DEFINES/~skyrat_defines/mobs.dm
+++ b/code/__DEFINES/~skyrat_defines/mobs.dm
@@ -6,12 +6,10 @@
#define HUMAN_MAXHEALTH MAX_LIVING_HEALTH * HUMAN_HEALTH_MODIFIER
-/// Used for Nanite Slurry vomit. The mob will vomit a nanite puddle.
-#define VOMIT_NANITE 3
-
#define UNDERWEAR_HIDE_SOCKS (1<<0)
#define UNDERWEAR_HIDE_SHIRT (1<<1)
#define UNDERWEAR_HIDE_UNDIES (1<<2)
+#define UNDERWEAR_HIDE_BRA (1<<3)
//Appends to the bottom of Defib fails - DNR TRAIT
//#define DEFIB_FAIL_DNR (1<<11) //BUBBER EDIT REMOVAL
diff --git a/code/__DEFINES/~skyrat_defines/wounds.dm b/code/__DEFINES/~skyrat_defines/wounds.dm
new file mode 100644
index 00000000000..f6a9275db8e
--- /dev/null
+++ b/code/__DEFINES/~skyrat_defines/wounds.dm
@@ -0,0 +1,2 @@
+/// If this wound, when bandaged, will cause a splint overlay to generate rather than a bandage overlay.
+#define SPLINT_OVERLAY (1<<200) // we use a big number since tg realistically wouldnt go to it
diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm
index 4a4bc828cf8..34512b95952 100644
--- a/code/__HELPERS/_lists.dm
+++ b/code/__HELPERS/_lists.dm
@@ -17,6 +17,37 @@
///Remove an untyped item to a list, taking care to handle list items by wrapping them in a list to remove the footgun
#define UNTYPED_LIST_REMOVE(list, item) (list -= LIST_VALUE_WRAP_LISTS(item))
+/*
+ * ## Lazylists
+ *
+ * * What is a lazylist?
+ *
+ * True to its name a lazylist is a lazy instantiated list.
+ * It is a list that is only created when necessary (when it has elements) and is null when empty.
+ *
+ * * Why use a lazylist?
+ *
+ * Lazylists save memory - an empty list that is never used takes up more memory than just `null`.
+ *
+ * * When to use a lazylist?
+ *
+ * Lazylists are best used on hot types when making lists that are not always used.
+ *
+ * For example, if you were adding a list to all atoms that tracks the names of people who touched it,
+ * you would want to use a lazylist because most atoms will never be touched by anyone.
+ *
+ * * How do I use a lazylist?
+ *
+ * A lazylist is just a list you defined as `null` rather than `list()`.
+ * Then, you use the LAZY* macros to interact with it, which are essentially null-safe ways to interact with a list.
+ *
+ * Note that you probably should not be using these macros if your list is not a lazylist.
+ * This will obfuscate the code and make it a bit harder to read and debug.
+ *
+ * Generally speaking you shouldn't be checking if your lazylist is `null` yourself, the macros will do that for you.
+ * Remember that LAZYLEN (and by extension, length) will return 0 if the list is null.
+ */
+
///Initialize the lazylist
#define LAZYINITLIST(L) if (!L) { L = list(); }
///If the provided list is empty, set it to null
@@ -60,14 +91,14 @@
#define LAZYCLEARLIST(L) if(L) L.Cut()
///Returns the list if it's actually a valid list, otherwise will initialize it
#define SANITIZE_LIST(L) ( islist(L) ? L : list() )
-#define reverseList(L) reverse_range(L.Copy())
-
/// Performs an insertion on the given lazy list with the given key and value. If the value already exists, a new one will not be made.
#define LAZYORASSOCLIST(lazy_list, key, value) \
LAZYINITLIST(lazy_list); \
LAZYINITLIST(lazy_list[key]); \
lazy_list[key] |= value;
+#define reverseList(L) reverse_range(L.Copy())
+
/// Passed into BINARY_INSERT to compare keys
#define COMPARE_KEY __BIN_LIST[__BIN_MID]
/// Passed into BINARY_INSERT to compare values
diff --git a/code/__HELPERS/byond_status.dm b/code/__HELPERS/byond_status.dm
deleted file mode 100644
index 1985080418c..00000000000
--- a/code/__HELPERS/byond_status.dm
+++ /dev/null
@@ -1,7 +0,0 @@
-/// Returns the debug status, including sleeping procs.
-/// If this blame is older than a month, please revert the PR that added it.
-/proc/byond_status()
- if (world.system_type == UNIX)
- return LIBCALL("libbyond_sleeping_procs.so", "get_status")()
- else
- return "byond_status is not supported on [world.system_type]"
diff --git a/code/__HELPERS/dynamic_human_icon_gen.dm b/code/__HELPERS/dynamic_human_icon_gen.dm
index f23af0e45a5..31957a27600 100644
--- a/code/__HELPERS/dynamic_human_icon_gen.dm
+++ b/code/__HELPERS/dynamic_human_icon_gen.dm
@@ -14,6 +14,7 @@ GLOBAL_LIST_EMPTY(dynamic_human_appearances)
dummy.underwear = "Nude"
dummy.undershirt = "Nude"
dummy.socks = "Nude"
+ dummy.bra = "Nude" // SKYRAT EDIT ADDITION - Underwear and bra split
if(outfit_path)
var/datum/outfit/outfit = new outfit_path()
if(r_hand != NO_REPLACE) //we can still override to be null, no replace means just use outfit's
@@ -54,5 +55,6 @@ GLOBAL_LIST_EMPTY(dynamic_human_appearances)
/proc/set_dynamic_human_appearance(list/arguments)
var/atom/target = arguments[1] //1st argument is the target
var/dynamic_appearance = get_dynamic_human_appearance(arglist(arguments.Copy(2))) //the rest of the arguments starting from 2 matter to the proc
- target.icon = null
+ target.icon = 'icons/blanks/32x32.dmi'
+ target.icon_state = "nothing"
target.copy_overlays(dynamic_appearance, cut_old = TRUE)
diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm
index 659c2c0144e..994aa6cfa81 100644
--- a/code/__HELPERS/global_lists.dm
+++ b/code/__HELPERS/global_lists.dm
@@ -34,6 +34,9 @@
init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_antennae, GLOB.moth_antennae_list)
init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_markings, GLOB.moth_markings_list)
*/ //SKYRAT EDIT REMOVAL END
+ //bras
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/bra, GLOB.bra_list, GLOB.bra_m, GLOB.bra_f) // SKYRAT EDIT ADDITION
+
init_sprite_accessory_subtypes(/datum/sprite_accessory/wings/moth, GLOB.moth_wings_list) // SKYRAT EDIT ADDITION - Customization
init_sprite_accessory_subtypes(/datum/sprite_accessory/pod_hair, GLOB.pod_hair_list, add_blank = TRUE) // SKYRAT EDIT - Customization - ORIGINAL: init_sprite_accessory_subtypes(/datum/sprite_accessory/pod_hair, GLOB.pod_hair_list)
diff --git a/code/__HELPERS/hallucinations.dm b/code/__HELPERS/hallucinations.dm
index 9deb27b9040..525114cea28 100644
--- a/code/__HELPERS/hallucinations.dm
+++ b/code/__HELPERS/hallucinations.dm
@@ -10,7 +10,7 @@ GLOBAL_LIST_EMPTY(all_ongoing_hallucinations)
#define HALLUCINATION_ARGLIST 3
/// Biotypes which cannot hallucinate for balance and logic reasons (not code)
-#define NO_HALLUCINATION_BIOTYPES (MOB_ROBOTIC|MOB_SPIRIT|MOB_EPIC)
+#define NO_HALLUCINATION_BIOTYPES (MOB_ROBOTIC|MOB_SPIRIT|MOB_SPECIAL)
// Macro wrapper for _cause_hallucination so we can cheat in named arguments, like AddComponent.
/**
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index 6bb147721fd..de9ed493b62 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -110,7 +110,7 @@
"moth_wings" = pick(GLOB.moth_wings_list),
"moth_antennae" = pick(GLOB.moth_antennae_list),
"moth_markings" = pick(GLOB.moth_markings_list),
- "tail_monkey" = "None",
+ "tail_monkey" = "Monkey",
"pod_hair" = pick(GLOB.pod_hair_list),
))
*/
@@ -363,7 +363,7 @@ GLOBAL_LIST_EMPTY(species_list)
X.flags_1 |= ADMIN_SPAWNED_1
return X //return the last mob spawned
-/proc/spawn_and_random_walk(spawn_type, target, amount, walk_chance=100, max_walk=3, always_max_walk=FALSE, admin_spawn=FALSE)
+/proc/spawn_and_random_walk(spawn_type, target, amount, walk_chance=100, max_walk=3, always_max_walk=FALSE, admin_spawn=FALSE, cardinals_only = TRUE)
var/turf/T = get_turf(target)
var/step_count = 0
if(!T)
@@ -392,7 +392,7 @@ GLOBAL_LIST_EMPTY(species_list)
step_count = rand(1, max_walk)
for(var/i in 1 to step_count)
- step(X, pick(NORTH, SOUTH, EAST, WEST))
+ step(X, cardinals_only ? pick(GLOB.cardinals) : pick(GLOB.alldirs))
return spawned_mobs
diff --git a/code/__HELPERS/mouse_control.dm b/code/__HELPERS/mouse_control.dm
index 8896afb3ec6..0c99e53e7a0 100644
--- a/code/__HELPERS/mouse_control.dm
+++ b/code/__HELPERS/mouse_control.dm
@@ -1,18 +1,22 @@
-/proc/mouse_angle_from_client(client/client)
- var/list/modifiers = params2list(client.mouseParams)
- if(LAZYACCESS(modifiers, SCREEN_LOC) && client)
- var/list/screen_loc_params = splittext(LAZYACCESS(modifiers, SCREEN_LOC), ",")
- var/list/screen_loc_X = splittext(screen_loc_params[1],":")
- var/list/screen_loc_Y = splittext(screen_loc_params[2],":")
- var/x = (text2num(screen_loc_X[1]) * 32 + text2num(screen_loc_X[2]) - 32)
- var/y = (text2num(screen_loc_Y[1]) * 32 + text2num(screen_loc_Y[2]) - 32)
- var/list/screenview = getviewsize(client.view)
- var/screenviewX = screenview[1] * world.icon_size
- var/screenviewY = screenview[2] * world.icon_size
- var/ox = round(screenviewX/2) - client.pixel_x //"origin" x
- var/oy = round(screenviewY/2) - client.pixel_y //"origin" y
- var/angle = SIMPLIFY_DEGREES(ATAN2(y - oy, x - ox))
- return angle
+///Returns an angle in degrees relative to the position of the mouse and that of the client eye.
+/proc/mouse_angle_from_client(client/client, params)
+ if(!client)
+ return
+ var/list/modifiers = params2list(params)
+ if(!LAZYACCESS(modifiers, SCREEN_LOC))
+ return
+ var/list/screen_loc_params = splittext(LAZYACCESS(modifiers, SCREEN_LOC), ",")
+ var/list/screen_loc_X = splittext(screen_loc_params[1],":")
+ var/list/screen_loc_Y = splittext(screen_loc_params[2],":")
+ var/x = (text2num(screen_loc_X[1]) * 32 + text2num(screen_loc_X[2]) - 32)
+ var/y = (text2num(screen_loc_Y[1]) * 32 + text2num(screen_loc_Y[2]) - 32)
+ var/list/screenview = getviewsize(client.view)
+ var/screenviewX = screenview[1] * world.icon_size
+ var/screenviewY = screenview[2] * world.icon_size
+ var/ox = round(screenviewX/2) - client.pixel_x //"origin" x
+ var/oy = round(screenviewY/2) - client.pixel_y //"origin" y
+ var/angle = SIMPLIFY_DEGREES(ATAN2(y - oy, x - ox))
+ return angle
//Wow, specific name!
/proc/mouse_absolute_datum_map_position_from_client(client/client)
diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm
index 681f525bd5e..7c8fb23f4c3 100644
--- a/code/__HELPERS/roundend.dm
+++ b/code/__HELPERS/roundend.dm
@@ -190,18 +190,27 @@ GLOBAL_LIST_INIT(achievements_unlocked, list())
if(!human_mob.hardcore_survival_score) ///no score no glory
return FALSE
- if(human_mob.mind && (human_mob.mind.special_role || length(human_mob.mind.antag_datums) > 0))
- var/didthegamerwin = TRUE
+ if(human_mob.mind && (length(human_mob.mind.antag_datums) > 0))
for(var/datum/antagonist/antag_datums as anything in human_mob.mind.antag_datums)
+ if(!antag_datums.hardcore_random_bonus) //dont give bonusses to dumb stuff like revs or hypnos
+ continue
+ if(initial(antag_datums.can_assign_self_objectives) && !antag_datums.can_assign_self_objectives)
+ continue // You don't get a prize if you picked your own objective, you can't fail those
+
+ var/greentexted = TRUE
for(var/datum/objective/objective_datum as anything in antag_datums.objectives)
if(!objective_datum.check_completion())
- didthegamerwin = FALSE
- if(!didthegamerwin)
- return FALSE
- player_client.give_award(/datum/award/score/hardcore_random, human_mob, round(human_mob.hardcore_survival_score * 2))
- else if(considered_escaped(human_mob.mind))
- player_client.give_award(/datum/award/score/hardcore_random, human_mob, round(human_mob.hardcore_survival_score))
+ greentexted = FALSE
+ break
+ if(greentexted)
+ var/score = round(human_mob.hardcore_survival_score * 2)
+ player_client.give_award(/datum/award/score/hardcore_random, human_mob, score)
+ log_admin("[player_client] gained [score] hardcore random points, including greentext bonus!")
+ return
+ if(considered_escaped(human_mob.mind))
+ player_client.give_award(/datum/award/score/hardcore_random, human_mob, round(human_mob.hardcore_survival_score))
+ log_admin("[player_client] gained [round(human_mob.hardcore_survival_score)] hardcore random points.")
/datum/controller/subsystem/ticker/proc/declare_completion(was_forced = END_ROUND_AS_NORMAL)
set waitfor = FALSE
@@ -590,7 +599,7 @@ GLOBAL_LIST_INIT(achievements_unlocked, list())
if(!ishuman(i))
continue
var/mob/living/carbon/human/human_player = i
- if(!human_player.hardcore_survival_score || !human_player.onCentCom() || human_player.stat == DEAD) ///gotta escape nerd
+ if(!human_player.hardcore_survival_score || !considered_escaped(human_player.mind) || human_player.stat == DEAD) ///gotta escape nerd
continue
if(!human_player.mind)
continue
@@ -726,10 +735,7 @@ GLOBAL_LIST_INIT(achievements_unlocked, list())
var/list/objective_parts = list()
var/count = 1
for(var/datum/objective/objective in objectives)
- if(objective.check_completion())
- objective_parts += "[objective.objective_name] #[count]: [objective.explanation_text] [span_greentext("Success!")]"
- else
- objective_parts += "[objective.objective_name] #[count]: [objective.explanation_text] [span_redtext("Fail.")]"
+ objective_parts += "[objective.objective_name] #[count]: [objective.explanation_text] [objective.get_roundend_success_suffix()]"
count++
return objective_parts.Join(" ")
diff --git a/code/__HELPERS/view.dm b/code/__HELPERS/view.dm
index 6a4210bc535..dc25dcc0249 100644
--- a/code/__HELPERS/view.dm
+++ b/code/__HELPERS/view.dm
@@ -1,11 +1,16 @@
/proc/getviewsize(view)
+ if(!view) // Just to avoid any runtimes that could otherwise cause constant disconnect loops.
+ stack_trace("Missing value for 'view' in getviewsize(), defaulting to world.view!")
+ view = world.view
+
if(isnum(view))
var/totalviewrange = (view < 0 ? -1 : 1) + 2 * view
return list(totalviewrange, totalviewrange)
else
- var/list/viewrangelist = splittext(view,"x")
+ var/list/viewrangelist = splittext(view, "x")
return list(text2num(viewrangelist[1]), text2num(viewrangelist[2]))
+
/// Takes a string or num view, and converts it to pixel width/height in a list(pixel_width, pixel_height)
/proc/view_to_pixels(view)
if(!view)
diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index 80d9d3e9b09..fad0deb0bd8 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -75,6 +75,7 @@ DEFINE_BITFIELD(turf_flags, list(
"NOJAUNT" = NOJAUNT,
"IS_SOLID" = IS_SOLID,
"UNUSED_RESERVATION_TURF" = UNUSED_RESERVATION_TURF,
+ "RESERVATION_TURF" = RESERVATION_TURF,
))
DEFINE_BITFIELD(car_traits, list(
@@ -249,16 +250,16 @@ DEFINE_BITFIELD(mecha_flags, list(
DEFINE_BITFIELD(mob_biotypes, list(
"MOB_BEAST" = MOB_BEAST,
"MOB_BUG" = MOB_BUG,
- "MOB_EPIC" = MOB_EPIC,
"MOB_HUMANOID" = MOB_HUMANOID,
"MOB_MINERAL" = MOB_MINERAL,
"MOB_ORGANIC" = MOB_ORGANIC,
+ "MOB_PLANT" = MOB_PLANT,
"MOB_REPTILE" = MOB_REPTILE,
"MOB_ROBOTIC" = MOB_ROBOTIC,
+ "MOB_SLIME" = MOB_SLIME,
+ "MOB_SPECIAL" = MOB_SPECIAL,
"MOB_SPIRIT" = MOB_SPIRIT,
"MOB_UNDEAD" = MOB_UNDEAD,
- "MOB_PLANT" = MOB_PLANT,
- "MOB_SLIME" = MOB_SLIME,
))
DEFINE_BITFIELD(mob_respiration_type, list(
@@ -552,3 +553,11 @@ DEFINE_BITFIELD(gun_flags, list(
"TOY_FIREARM_OVERLAY" = TOY_FIREARM_OVERLAY,
"TURRET_INCOMPATIBLE" = TURRET_INCOMPATIBLE,
))
+
+DEFINE_BITFIELD(bot_mode_flags, list(
+ "POWER_ON" = BOT_MODE_ON,
+ "AUTO_PATROL" = BOT_MODE_AUTOPATROL,
+ "REMOTE_CONTROL" = BOT_MODE_REMOTE_ENABLED,
+ "SAPIENCE_ALLOWED" = BOT_MODE_CAN_BE_SAPIENT,
+ "STARTS_POSSESSABLE" = BOT_MODE_ROUNDSTART_POSSESSION,
+))
diff --git a/code/_globalvars/lists/achievements.dm b/code/_globalvars/lists/achievements.dm
index 2963dfb4139..283931f9984 100755
--- a/code/_globalvars/lists/achievements.dm
+++ b/code/_globalvars/lists/achievements.dm
@@ -1,3 +1,9 @@
GLOBAL_LIST_EMPTY(commendations)
///A list of the current achievement categories supported by the UI and checked by the achievement unit test
GLOBAL_LIST_INIT(achievement_categories, list("Bosses", "Jobs", "Skills", "Misc", "Mafia", "Scores"))
+///A list of sounds that can be played when unlocking an achievement, set in the preferences.
+GLOBAL_LIST_INIT(achievement_sounds, list(
+ CHEEVO_SOUND_PING = sound('sound/effects/glockenspiel_ping.ogg', volume = 70),
+ CHEEVO_SOUND_JINGLE = sound('sound/effects/beeps_jingle.ogg', volume = 70),
+ CHEEVO_SOUND_TADA = sound('sound/effects/tada_fanfare.ogg', volume = 30),
+))
diff --git a/code/_globalvars/lists/ambience.dm b/code/_globalvars/lists/ambience.dm
index a46ed882bef..60d3dfad789 100644
--- a/code/_globalvars/lists/ambience.dm
+++ b/code/_globalvars/lists/ambience.dm
@@ -128,6 +128,8 @@ GLOBAL_LIST_INIT(maint_ambience,list(
'sound/ambience/ambimaint3.ogg',
'sound/ambience/ambimaint4.ogg',
'sound/ambience/ambimaint5.ogg',
+ 'sound/ambience/ambimaint6.ogg',
+ 'sound/ambience/ambimaint7.ogg',
'sound/ambience/ambitech2.ogg',
'sound/voice/lowHiss1.ogg',
'sound/voice/lowHiss2.ogg',
diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm
index 7f3341eb26b..dbf9a47f9f7 100644
--- a/code/_globalvars/lists/flavor_misc.dm
+++ b/code/_globalvars/lists/flavor_misc.dm
@@ -298,7 +298,16 @@ GLOBAL_LIST_INIT(status_display_approved_pictures, list(
"default",
"biohazard",
"lockdown",
+ "greenalert",
+ "bluealert",
+ "violetalert", // SKYRAT EDIT ADD - Alert Levels
+ "orangealert", // SKYRAT EDIT ADD - Alert Levels
+ "amberalert", // SKYRAT EDIT ADD - Alert Levels
"redalert",
+ "deltaalert",
+ "gammaalert", // SKYRAT EDIT ADD - Alert Levels
+ "radiation",
+ "currentalert", //For automatic set of status display on current level
))
// Members of status_display_approved_pictures that are actually states and not alert values
diff --git a/code/_globalvars/lists/maintenance_loot.dm b/code/_globalvars/lists/maintenance_loot.dm
index 8727084b0a9..775f62b87b8 100644
--- a/code/_globalvars/lists/maintenance_loot.dm
+++ b/code/_globalvars/lists/maintenance_loot.dm
@@ -172,7 +172,7 @@ GLOBAL_LIST_INIT(uncommon_loot, list(//uncommon: useful items
/obj/item/pen/fountain = 1,
/obj/item/restraints/handcuffs/cable = 1,
/obj/item/restraints/legcuffs/bola = 1,
- /obj/item/roller = 1,
+ /obj/item/emergency_bed = 1,
/obj/item/spear = 1,
/obj/item/weldingtool/largetank = 1,
/obj/item/market_uplink/blackmarket = 1,
diff --git a/code/_globalvars/lists/mapping.dm b/code/_globalvars/lists/mapping.dm
index be439d8217f..8ac2f0d3ddf 100644
--- a/code/_globalvars/lists/mapping.dm
+++ b/code/_globalvars/lists/mapping.dm
@@ -127,6 +127,9 @@ GLOBAL_LIST_EMPTY(emergencyresponseteamspawn)
GLOBAL_LIST_EMPTY(ruin_landmarks)
GLOBAL_LIST_EMPTY(bar_areas)
+/// List of all the maps that have been cached for /proc/load_map
+GLOBAL_LIST_EMPTY(cached_maps)
+
/// Away missions
GLOBAL_LIST_EMPTY(vr_spawnpoints)
diff --git a/code/_globalvars/phobias.dm b/code/_globalvars/phobias.dm
index 309b31ceb37..a6cb2dedb32 100644
--- a/code/_globalvars/phobias.dm
+++ b/code/_globalvars/phobias.dm
@@ -366,8 +366,10 @@ GLOBAL_LIST_INIT(phobia_objs, list(
"heresy" = typecacheof(list(
/obj/effect/floating_blade,
/obj/effect/forcefield/cosmic_field,
- /obj/effect/heretic_rune,
+ /obj/effect/forcefield/wizard/heretic,
/obj/effect/heretic_influence,
+ /obj/effect/heretic_rune,
+ /obj/effect/knock_portal,
/obj/effect/visible_heretic_influence,
/obj/item/ammo_box/strilka310/lionhunter,
/obj/item/ammo_casing/strilka310/lionhunter,
@@ -379,6 +381,7 @@ GLOBAL_LIST_INIT(phobia_objs, list(
/obj/item/codex_cicatrix,
/obj/item/coin/eldritch,
/obj/item/gun/ballistic/rifle/lionhunter,
+ /obj/item/heretic_lintel,
/obj/item/melee/rune_carver,
/obj/item/melee/sickly_blade,
/obj/item/melee/touch_attack/mansus_fist,
@@ -387,6 +390,7 @@ GLOBAL_LIST_INIT(phobia_objs, list(
/obj/item/toy/reality_pierce,
/obj/projectile/curse_hand,
/obj/structure/destructible/eldritch_crucible,
+ /obj/structure/knock_tear,
)),
"insects" = typecacheof(list(
/obj/item/clothing/mask/animal/small/bee,
diff --git a/code/_globalvars/religion.dm b/code/_globalvars/religion.dm
index 164491a0a3a..063ff0e8642 100644
--- a/code/_globalvars/religion.dm
+++ b/code/_globalvars/religion.dm
@@ -14,3 +14,37 @@ GLOBAL_LIST_EMPTY(chaplain_altars)
//gear
GLOBAL_VAR(holy_weapon_type)
GLOBAL_VAR(holy_armor_type)
+
+/// Sets a new religious sect used by all chaplains int he round
+/proc/set_new_religious_sect(path, reset_existing = FALSE)
+ if(!ispath(path, /datum/religion_sect))
+ message_admins("[ADMIN_LOOKUPFLW(usr)] has tried to spawn an item when selecting a sect.")
+ return
+
+ if(!isnull(GLOB.religious_sect))
+ if (!reset_existing)
+ return
+ reset_religious_sect()
+
+ GLOB.religious_sect = new path()
+ for(var/i in GLOB.player_list)
+ if(!isliving(i))
+ continue
+ var/mob/living/am_i_holy_living = i
+ if(!am_i_holy_living.mind?.holy_role)
+ continue
+ GLOB.religious_sect.on_conversion(am_i_holy_living)
+ SEND_GLOBAL_SIGNAL(COMSIG_RELIGIOUS_SECT_CHANGED)
+
+/// Removes any existing religious sect from chaplains, allowing another to be selected
+/proc/reset_religious_sect()
+ for(var/i in GLOB.player_list)
+ if(!isliving(i))
+ continue
+ var/mob/living/am_i_holy_living = i
+ if(!am_i_holy_living.mind?.holy_role)
+ continue
+ GLOB.religious_sect.on_deconversion(am_i_holy_living)
+
+ GLOB.religious_sect = null
+ SEND_GLOBAL_SIGNAL(COMSIG_RELIGIOUS_SECT_RESET)
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index e4d3e2f449e..4b24b20c846 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -69,7 +69,7 @@
return
next_click = world.time + 1
- if(check_click_intercept(params,A) || notransform)
+ if(check_click_intercept(params,A) || HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
return
var/list/modifiers = params2list(params)
diff --git a/code/_onclick/drag_drop.dm b/code/_onclick/drag_drop.dm
index c4f8de8e63b..edecd0ba78f 100644
--- a/code/_onclick/drag_drop.dm
+++ b/code/_onclick/drag_drop.dm
@@ -96,9 +96,6 @@
while(selected_target[1])
Click(selected_target[1], location, control, selected_target[2])
sleep(delay)
- active_mousedown_item = mob.canMobMousedown(object, location, params)
- if(active_mousedown_item)
- active_mousedown_item.onMouseDown(object, location, params, mob)
/client/MouseUp(object, location, control, params)
if(SEND_SIGNAL(src, COMSIG_CLIENT_MOUSEUP, object, location, control, params) & COMPONENT_CLIENT_MOUSEUP_INTERCEPT)
@@ -106,9 +103,6 @@
if(mouse_up_icon)
mouse_pointer_icon = mouse_up_icon
selected_target[1] = null
- if(active_mousedown_item)
- active_mousedown_item.onMouseUp(object, location, params, mob)
- active_mousedown_item = null
/mob/proc/CanMobAutoclick(object, location, params)
@@ -119,25 +113,8 @@
if(h)
. = h.CanItemAutoclick(object, location, params)
-/mob/proc/canMobMousedown(atom/object, location, params)
-
-/mob/living/carbon/canMobMousedown(atom/object, location, params)
- var/obj/item/H = get_active_held_item()
- if(H)
- . = H.canItemMouseDown(object, location, params)
-
/obj/item/proc/CanItemAutoclick(object, location, params)
-/obj/item/proc/canItemMouseDown(object, location, params)
- if(canMouseDown)
- return src
-
-/obj/item/proc/onMouseDown(object, location, params, mob)
- return
-
-/obj/item/proc/onMouseUp(object, location, params, mob)
- return
-
/atom/proc/IsAutoclickable()
return TRUE
@@ -165,14 +142,9 @@
if(selected_target[1] && over_object?.IsAutoclickable())
selected_target[1] = over_object
selected_target[2] = params
- if(active_mousedown_item)
- active_mousedown_item.onMouseDrag(src_object, over_object, src_location, over_location, params, mob)
SEND_SIGNAL(src, COMSIG_CLIENT_MOUSEDRAG, src_object, over_object, src_location, over_location, src_control, over_control, params)
return ..()
-/obj/item/proc/onMouseDrag(src_object, over_object, src_location, over_location, params, mob)
- return
-
/client/MouseDrop(atom/src_object, atom/over_object, atom/src_location, atom/over_location, src_control, over_control, params)
if (IS_WEAKREF_OF(src_object, middle_drag_atom_ref))
middragtime = 0
diff --git a/code/_onclick/hud/parallax/parallax.dm b/code/_onclick/hud/parallax/parallax.dm
index 00dffa7687a..8d4e68c911d 100755
--- a/code/_onclick/hud/parallax/parallax.dm
+++ b/code/_onclick/hud/parallax/parallax.dm
@@ -273,6 +273,9 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer)
/atom/movable/screen/parallax_layer/Initialize(mapload, datum/hud/hud_owner, template = FALSE)
. = ..()
+ // Parallax layers are independant of hud, they care about client
+ // Not doing this will just create a bunch of hard deletes
+ hud = null
if(template)
return
diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm
index 30eb87618a3..b5fc855da31 100644
--- a/code/controllers/configuration/entries/general.dm
+++ b/code/controllers/configuration/entries/general.dm
@@ -628,6 +628,12 @@
/datum/config_entry/flag/auto_profile
+/datum/config_entry/number/drift_dump_threshold
+ default = 4 SECONDS
+
+/datum/config_entry/number/drift_profile_delay
+ default = 15 SECONDS
+
/datum/config_entry/string/centcom_ban_db // URL for the CentCom Galactic Ban DB API
/datum/config_entry/string/centcom_source_whitelist
diff --git a/code/controllers/master.dm b/code/controllers/master.dm
index ff168d47407..da98580d5e0 100644
--- a/code/controllers/master.dm
+++ b/code/controllers/master.dm
@@ -32,6 +32,8 @@ GLOBAL_REAL(Master, /datum/controller/master)
var/init_timeofday
var/init_time
var/tickdrift = 0
+ /// Tickdrift as of last tick, w no averaging going on
+ var/olddrift = 0
/// How long is the MC sleeping between runs, read only (set by Loop() based off of anti-tick-contention heuristics)
var/sleep_delta = 1
@@ -60,6 +62,10 @@ GLOBAL_REAL(Master, /datum/controller/master)
/// Outside of initialization, returns null.
var/current_initializing_subsystem = null
+ /// The last decisecond we force dumped profiling information
+ /// Used to avoid spamming profile reads since they can be expensive (string memes)
+ var/last_profiled = 0
+
var/static/restart_clear = 0
var/static/restart_timeout = 0
var/static/restart_count = 0
@@ -286,6 +292,7 @@ GLOBAL_REAL(Master, /datum/controller/master)
SS_INIT_NONE,
SS_INIT_SUCCESS,
SS_INIT_NO_NEED,
+ SS_INIT_NO_MESSAGE,
)
if (subsystem.flags & SS_NO_INIT || subsystem.initialized) //Don't init SSs with the corresponding flag or if they already are initialized
@@ -331,7 +338,7 @@ GLOBAL_REAL(Master, /datum/controller/master)
if(SS_INIT_FAILURE)
message_prefix = "Failed to initialize [subsystem.name] subsystem after"
chat_warning = TRUE
- if(SS_INIT_SUCCESS)
+ if(SS_INIT_SUCCESS, SS_INIT_NO_MESSAGE)
message_prefix = "Initialized [subsystem.name] subsystem within"
if(SS_INIT_NO_NEED)
// This SS is disabled or is otherwise shy.
@@ -346,7 +353,8 @@ GLOBAL_REAL(Master, /datum/controller/master)
// var/chat_message = chat_warning ? span_boldwarning(message) : span_boldannounce(message)
// SKYRAT EDIT REMOVAL END
- add_startup_message(message, chat_warning) //SKYRAT EDIT CHANGE - ORIGINAL: to_chat(world, chat_message)
+ if(result != SS_INIT_NO_MESSAGE)
+ add_startup_message(message, chat_warning) //SKYRAT EDIT CHANGE - ORIGINAL: to_chat(world, chat_message)
log_world(message)
/datum/controller/master/proc/SetRunLevel(new_runlevel)
@@ -446,9 +454,14 @@ GLOBAL_REAL(Master, /datum/controller/master)
canary.use_variable()
//the actual loop.
while (1)
- tickdrift = max(0, MC_AVERAGE_FAST(tickdrift, (((REALTIMEOFDAY - init_timeofday) - (world.time - init_time)) / world.tick_lag)))
+ var/newdrift = ((REALTIMEOFDAY - init_timeofday) - (world.time - init_time)) / world.tick_lag
+ tickdrift = max(0, MC_AVERAGE_FAST(tickdrift, newdrift))
var/starting_tick_usage = TICK_USAGE
+ if(newdrift - olddrift >= CONFIG_GET(number/drift_dump_threshold))
+ AttemptProfileDump(CONFIG_GET(number/drift_profile_delay))
+ olddrift = newdrift
+
if (init_stage != init_stage_completed)
return MC_LOOP_RTN_NEWSTAGES
if (processing <= 0)
@@ -807,3 +820,11 @@ GLOBAL_REAL(Master, /datum/controller/master)
for (var/thing in subsystems)
var/datum/controller/subsystem/SS = thing
SS.OnConfigLoad()
+
+/// Attempts to dump our current profile info into a file, triggered if the MC thinks shit is going down
+/// Accepts a delay in deciseconds of how long ago our last dump can be, this saves causing performance problems ourselves
+/datum/controller/master/proc/AttemptProfileDump(delay)
+ if(REALTIMEOFDAY - last_profiled <= delay)
+ return FALSE
+ last_profiled = REALTIMEOFDAY
+ SSprofiler.DumpFile(allow_yield = FALSE)
diff --git a/code/controllers/subsystem/communications.dm b/code/controllers/subsystem/communications.dm
index 29dbe8ff8d6..19939880d74 100644
--- a/code/controllers/subsystem/communications.dm
+++ b/code/controllers/subsystem/communications.dm
@@ -37,7 +37,10 @@ SUBSYSTEM_DEF(communications)
COOLDOWN_START(src, silicon_message_cooldown, COMMUNICATION_COOLDOWN_AI)
else
var/list/message_data = user.treat_message(input)
- priority_announce(html_decode(message_data["message"]), null, ANNOUNCER_CAPTAIN, "[syndicate? "Syndicate " : ""]Captain", has_important_message = TRUE, players = players)
+ if(syndicate)
+ priority_announce(html_decode(message_data["message"]), null, 'sound/misc/announce_syndi.ogg', "Syndicate Captain", has_important_message = TRUE, players = players)
+ else
+ priority_announce(html_decode(message_data["message"]), null, ANNOUNCER_CAPTAIN, "Captain", has_important_message = TRUE, players = players) // SKYRAT EDIT CHANGE - Announcer Sounds
COOLDOWN_START(src, nonsilicon_message_cooldown, COMMUNICATION_COOLDOWN)
user.log_talk(input, LOG_SAY, tag="priority announcement")
message_admins("[ADMIN_LOOKUPFLW(user)] has made a priority announcement.")
diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm
index 9b85f6e464c..5c957445526 100644
--- a/code/controllers/subsystem/job.dm
+++ b/code/controllers/subsystem/job.dm
@@ -24,6 +24,9 @@ SUBSYSTEM_DEF(job)
var/list/unassigned = list() //Players who need jobs
var/initial_players_to_assign = 0 //used for checking against population caps
+ // Whether to run DivideOccupations pure so that there are no side-effects from calling it other than
+ // a player's assigned_role being set to some value.
+ var/run_divide_occupation_pure = FALSE
var/list/prioritized_jobs = list()
var/list/latejoin_trackers = list()
@@ -369,11 +372,11 @@ SUBSYSTEM_DEF(job)
* fills var "assigned_role" for all ready players.
* This proc must not have any side effect besides of modifying "assigned_role".
**/
-/datum/controller/subsystem/job/proc/DivideOccupations()
+/datum/controller/subsystem/job/proc/DivideOccupations(pure = FALSE, allow_all = FALSE)
//Setup new player list and get the jobs list
- JobDebug("Running DO")
-
- SEND_SIGNAL(src, COMSIG_OCCUPATIONS_DIVIDED)
+ JobDebug("Running DO, allow_all = [allow_all], pure = [pure]")
+ run_divide_occupation_pure = pure
+ SEND_SIGNAL(src, COMSIG_OCCUPATIONS_DIVIDED, pure, allow_all)
//Get the players who are ready
for(var/i in GLOB.new_player_list)
@@ -441,8 +444,9 @@ SUBSYSTEM_DEF(job)
// Loop through all unassigned players
for(var/mob/dead/new_player/player in unassigned)
- if(PopcapReached())
- RejectPlayer(player)
+ if(!allow_all)
+ if(PopcapReached())
+ RejectPlayer(player)
// Loop through all jobs
for(var/datum/job/job in shuffledoccupations) // SHUFFLE ME BABY
@@ -480,7 +484,7 @@ SUBSYSTEM_DEF(job)
// Hand out random jobs to the people who didn't get any in the last check
// Also makes sure that they got their preference correct
for(var/mob/dead/new_player/player in unassigned)
- HandleUnassigned(player)
+ HandleUnassigned(player, allow_all)
JobDebug("DO, Ending handle unassigned.")
JobDebug("DO, Handle unrejectable unassigned")
@@ -490,21 +494,23 @@ SUBSYSTEM_DEF(job)
if(!AssignRole(player, GetJobType(overflow_role))) //If everything is already filled, make them an assistant
JobDebug("DO, Forced antagonist could not be assigned any random job or the overflow role. DivideOccupations failed.")
JobDebug("---------------------------------------------------")
+ run_divide_occupation_pure = FALSE
return FALSE //Living on the edge, the forced antagonist couldn't be assigned to overflow role (bans, client age) - just reroll
JobDebug("DO, Ending handle unrejectable unassigned")
JobDebug("All divide occupations tasks completed.")
JobDebug("---------------------------------------------------")
-
+ run_divide_occupation_pure = FALSE
return TRUE
//We couldn't find a job from prefs for this guy.
-/datum/controller/subsystem/job/proc/HandleUnassigned(mob/dead/new_player/player)
+/datum/controller/subsystem/job/proc/HandleUnassigned(mob/dead/new_player/player, allow_all = FALSE)
var/jobless_role = player.client.prefs.read_preference(/datum/preference/choiced/jobless_role)
- if(PopcapReached())
- RejectPlayer(player)
- return
+ if(!allow_all)
+ if(PopcapReached())
+ RejectPlayer(player)
+ return
switch (jobless_role)
if (BEOVERFLOW)
@@ -698,10 +704,11 @@ SUBSYSTEM_DEF(job)
if(PopcapReached())
JobDebug("Popcap overflow Check observer located, Player: [player]")
JobDebug("Player rejected :[player]")
- to_chat(player, "You have failed to qualify for any job you desired.")
unassigned -= player
- player.ready = PLAYER_NOT_READY
- player.client << output(player.ready, "lobby_browser:imgsrc") //SKYRAT EDIT ADDITION
+ if(!run_divide_occupation_pure)
+ to_chat(player, "You have failed to qualify for any job you desired.")
+ player.ready = PLAYER_NOT_READY
+ player.client << output(player.ready, "lobby_browser:imgsrc") //SKYRAT EDIT ADDITION
/datum/controller/subsystem/job/Recover()
@@ -961,6 +968,10 @@ SUBSYSTEM_DEF(job)
JobDebug("[debug_prefix] Error: [get_job_unavailable_error_message(JOB_UNAVAILABLE_FLAVOUR)], Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]")
return JOB_UNAVAILABLE_FLAVOUR
+ if(possible_job.has_banned_augment(player.client.prefs))
+ JobDebug("[debug_prefix] Error: [get_job_unavailable_error_message(JOB_UNAVAILABLE_AUGMENT)], Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]")
+ return JOB_UNAVAILABLE_AUGMENT
+
//SKYRAT EDIT END
@@ -973,4 +984,27 @@ SUBSYSTEM_DEF(job)
return JOB_AVAILABLE
+/**
+ * Check if the station manifest has at least a certain amount of this staff type.
+ * If a matching head of staff is on the manifest, automatically passes (returns TRUE)
+ *
+ * Arguments:
+ * * crew_threshold - amount of crew to meet the requirement
+ * * jobs - a list of jobs that qualify the requirement
+ * * head_jobs - a list of head jobs that qualify the requirement
+ *
+*/
+/datum/controller/subsystem/job/proc/has_minimum_jobs(crew_threshold, list/jobs = list(), list/head_jobs = list())
+ var/employees = 0
+ for(var/datum/record/crew/target in GLOB.manifest.general)
+ if(target.trim in head_jobs)
+ return TRUE
+ if(target.trim in jobs)
+ employees++
+
+ if(employees > crew_threshold)
+ return TRUE
+
+ return FALSE
+
#undef VERY_LATE_ARRIVAL_TOAST_PROB
diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm
index a65ba66ed6c..681658caa3b 100644
--- a/code/controllers/subsystem/mapping.dm
+++ b/code/controllers/subsystem/mapping.dm
@@ -190,7 +190,7 @@ SUBSYSTEM_DEF(mapping)
unused_turfs["[T.z]"] |= T
var/area/old_area = T.loc
old_area.turfs_to_uncontain += T
- T.flags_1 |= UNUSED_RESERVATION_TURF
+ T.turf_flags = UNUSED_RESERVATION_TURF
world_contents += T
world_turf_contents += T
packet.len--
@@ -250,7 +250,7 @@ SUBSYSTEM_DEF(mapping)
var/list/ice_ruins = levels_by_trait(ZTRAIT_ICE_RUINS)
if (ice_ruins.len)
// needs to be whitelisted for underground too so place_below ruins work
- seedRuins(ice_ruins, CONFIG_GET(number/icemoon_budget), list(/area/icemoon/surface/outdoors/unexplored), themed_ruins[ZTRAIT_ICE_RUINS], clear_below = TRUE)
+ seedRuins(ice_ruins, CONFIG_GET(number/icemoon_budget), list(/area/icemoon/surface/outdoors/unexplored, /area/icemoon/underground/unexplored), themed_ruins[ZTRAIT_ICE_RUINS], clear_below = TRUE)
var/list/ice_ruins_underground = levels_by_trait(ZTRAIT_ICE_RUINS_UNDERGROUND)
if (ice_ruins_underground.len)
@@ -309,6 +309,10 @@ SUBSYSTEM_DEF(mapping)
returning += M
qdel(T, TRUE)
+/datum/controller/subsystem/mapping/proc/get_reservation_from_turf(turf/T)
+ RETURN_TYPE(/datum/turf_reservation)
+ return used_turfs[T]
+
/* Nuke threats, for making the blue tiles on the station go RED
Used by the AI doomsday and the self-destruct nuke.
*/
@@ -695,26 +699,34 @@ GLOBAL_LIST_EMPTY(the_station_areas)
num_of_res_levels++
return add_new_zlevel("Transit/Reserved #[num_of_res_levels]", list(ZTRAIT_RESERVED = TRUE))
-/datum/controller/subsystem/mapping/proc/RequestBlockReservation(width, height, z, type = /datum/turf_reservation, turf_type_override)
- UNTIL((!z || reservation_ready["[z]"]) && !clearing_reserved_turfs)
- var/datum/turf_reservation/reserve = new type
- if(turf_type_override)
+/// Requests a /datum/turf_reservation based on the given width, height, and z_size. You can specify a z_reservation to use a specific z level, or leave it null to use any z level.
+/datum/controller/subsystem/mapping/proc/request_turf_block_reservation(
+ width,
+ height,
+ z_size = 1,
+ z_reservation = null,
+ reservation_type = /datum/turf_reservation,
+ turf_type_override = null,
+)
+ UNTIL((!z_reservation || reservation_ready["[z_reservation]"]) && !clearing_reserved_turfs)
+ var/datum/turf_reservation/reserve = new reservation_type
+ if(!isnull(turf_type_override))
reserve.turf_type = turf_type_override
- if(!z)
+ if(!z_reservation)
for(var/i in levels_by_trait(ZTRAIT_RESERVED))
- if(reserve.Reserve(width, height, i))
+ if(reserve.reserve(width, height, z_size, i))
return reserve
//If we didn't return at this point, theres a good chance we ran out of room on the exisiting reserved z levels, so lets try a new one
var/datum/space_level/newReserved = add_reservation_zlevel()
initialize_reserved_level(newReserved.z_value)
- if(reserve.Reserve(width, height, newReserved.z_value))
+ if(reserve.reserve(width, height, z_size, newReserved.z_value))
return reserve
else
- if(!level_trait(z, ZTRAIT_RESERVED))
+ if(!level_trait(z_reservation, ZTRAIT_RESERVED))
qdel(reserve)
return
else
- if(reserve.Reserve(width, height, z))
+ if(reserve.reserve(width, height, z_size, z_reservation))
return reserve
QDEL_NULL(reserve)
@@ -732,7 +744,7 @@ GLOBAL_LIST_EMPTY(the_station_areas)
var/block = block(A, B)
for(var/turf/T as anything in block)
// No need to empty() these, because they just got created and are already /turf/open/space/basic.
- T.flags_1 |= UNUSED_RESERVATION_TURF
+ T.turf_flags = UNUSED_RESERVATION_TURF
CHECK_TICK
// Gotta create these suckers if we've not done so already
diff --git a/code/controllers/subsystem/npcpool.dm b/code/controllers/subsystem/npcpool.dm
index 34cad5d7f86..6fbfdadf682 100644
--- a/code/controllers/subsystem/npcpool.dm
+++ b/code/controllers/subsystem/npcpool.dm
@@ -29,7 +29,7 @@ SUBSYSTEM_DEF(npcpool)
stack_trace("Found a null in simple_animals active list [SA.type]!")
continue
- if(!SA.ckey && !SA.notransform)
+ if(!SA.ckey && !HAS_TRAIT(SA, TRAIT_NO_TRANSFORM))
if(SA.stat != DEAD)
SA.handle_automated_movement()
if(SA.stat != DEAD)
diff --git a/code/controllers/subsystem/processing/fishing.dm b/code/controllers/subsystem/processing/fishing.dm
new file mode 100644
index 00000000000..da10d3d631a
--- /dev/null
+++ b/code/controllers/subsystem/processing/fishing.dm
@@ -0,0 +1,7 @@
+/**
+ * So far, only used by the fishing minigame. Feel free to rename it to something like veryfastprocess
+ * if you need one that fires 10 times a second
+ */
+PROCESSING_SUBSYSTEM_DEF(fishing)
+ name = "Fishing"
+ wait = 0.1 SECONDS
diff --git a/code/controllers/subsystem/processing/quirks.dm b/code/controllers/subsystem/processing/quirks.dm
index 278b5c804c4..adf6baa01a5 100644
--- a/code/controllers/subsystem/processing/quirks.dm
+++ b/code/controllers/subsystem/processing/quirks.dm
@@ -23,6 +23,7 @@ GLOBAL_LIST_INIT_TYPED(quirk_blacklist, /list/datum/quirk, list(
list(/datum/quirk/spacer_born, /datum/quirk/paraplegic, /datum/quirk/item_quirk/settler),
list(/datum/quirk/photophobia, /datum/quirk/nyctophobia),
list(/datum/quirk/item_quirk/settler, /datum/quirk/freerunning),
+ list(/datum/quirk/numb, /datum/quirk/selfaware),
//SKYRAT EDIT ADDITION BEGIN
list(/datum/quirk/equipping/nerve_staple, /datum/quirk/nonviolent),
list(/datum/quirk/equipping/nerve_staple, /datum/quirk/item_quirk/nearsighted),
diff --git a/code/controllers/subsystem/profiler.dm b/code/controllers/subsystem/profiler.dm
index 4b3a1a99711..dc06c2bc6ae 100644
--- a/code/controllers/subsystem/profiler.dm
+++ b/code/controllers/subsystem/profiler.dm
@@ -21,13 +21,20 @@ SUBSYSTEM_DEF(profiler)
StopProfiling() //Stop the early start profiler
return SS_INIT_SUCCESS
-/datum/controller/subsystem/profiler/fire()
+/datum/controller/subsystem/profiler/OnConfigLoad()
if(CONFIG_GET(flag/auto_profile))
- DumpFile()
+ StartProfiling()
+ can_fire = TRUE
+ else
+ StopProfiling()
+ can_fire = FALSE
+
+/datum/controller/subsystem/profiler/fire()
+ DumpFile()
/datum/controller/subsystem/profiler/Shutdown()
if(CONFIG_GET(flag/auto_profile))
- DumpFile()
+ DumpFile(allow_yield = FALSE)
world.Profile(PROFILE_CLEAR, type = "sendmaps")
return ..()
@@ -39,13 +46,13 @@ SUBSYSTEM_DEF(profiler)
world.Profile(PROFILE_STOP)
world.Profile(PROFILE_STOP, type = "sendmaps")
-
-/datum/controller/subsystem/profiler/proc/DumpFile()
+/datum/controller/subsystem/profiler/proc/DumpFile(allow_yield = TRUE)
var/timer = TICK_USAGE_REAL
var/current_profile_data = world.Profile(PROFILE_REFRESH, format = "json")
var/current_sendmaps_data = world.Profile(PROFILE_REFRESH, type = "sendmaps", format="json")
fetch_cost = MC_AVERAGE(fetch_cost, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
- CHECK_TICK
+ if(allow_yield)
+ CHECK_TICK
if(!length(current_profile_data)) //Would be nice to have explicit proc to check this
stack_trace("Warning, profiling stopped manually before dump.")
diff --git a/code/controllers/subsystem/radioactive_nebula.dm b/code/controllers/subsystem/radioactive_nebula.dm
new file mode 100644
index 00000000000..3b11a7870af
--- /dev/null
+++ b/code/controllers/subsystem/radioactive_nebula.dm
@@ -0,0 +1,64 @@
+/// Trait for tracking if something already has the fake irradiation effect, so we don't waste time on effect operations if otherwise unnecessary
+#define TRAIT_RADIOACTIVE_NEBULA_FAKE_IRRADIATED "radioactive_nebula_fake_irradiated"
+
+/// Controls making objects irradiated when Radioactive Nebula is in effect.
+SUBSYSTEM_DEF(radioactive_nebula)
+ name = "Radioactive Nebula"
+ flags = SS_BACKGROUND
+ wait = 30 SECONDS
+
+ VAR_PRIVATE
+ datum/station_trait/nebula/hostile/radiation/radioactive_nebula
+
+/datum/controller/subsystem/radioactive_nebula/Initialize()
+ radioactive_nebula = locate() in SSstation.station_traits
+ if (!radioactive_nebula)
+ can_fire = FALSE
+ return SS_INIT_NO_NEED
+
+ // We don't *really* care that this happens by the time the server is ready to play.
+ ASYNC
+ irradiate_everything()
+
+ // Don't leak that the station trait has been picked
+ return SS_INIT_NO_MESSAGE
+
+/// Makes something appear irradiated for the purposes of the Radioactive Nebula
+/datum/controller/subsystem/radioactive_nebula/proc/fake_irradiate(atom/movable/target)
+ if (HAS_TRAIT(target, TRAIT_RADIOACTIVE_NEBULA_FAKE_IRRADIATED))
+ return
+
+ ADD_TRAIT(target, TRAIT_RADIOACTIVE_NEBULA_FAKE_IRRADIATED, REF(src))
+
+ if(iscarbon(target))//Don't actually make EVERY. SINGLE. THING. RADIOACTIVE. Just irradiate people
+ target.AddComponent( \
+ /datum/component/radioactive_exposure, \
+ minimum_exposure_time = NEBULA_RADIATION_MINIMUM_EXPOSURE_TIME, \
+ irradiation_chance_base = RADIATION_EXPOSURE_NEBULA_BASE_CHANCE, \
+ irradiation_chance_increment = RADIATION_EXPOSURE_NEBULA_CHANCE_INCREMENT, \
+ irradiation_interval = RADIATION_EXPOSURE_NEBULA_CHECK_INTERVAL, \
+ source = src, \
+ radioactive_areas = radioactive_nebula.radioactive_areas, \
+ )
+ else if(isobj(target)) //and fake the rest
+ //outline clashes too much with other outlines and creates pretty ugly lines
+ target.add_filter(GLOW_NEBULA, 2, list("type" = "drop_shadow", "color" = radioactive_nebula.nebula_radglow, "size" = 2))
+
+/datum/controller/subsystem/radioactive_nebula/fire()
+ irradiate_everything()
+
+/// Loop through radioactive space (with lag checks) and make it all radioactive!
+/datum/controller/subsystem/radioactive_nebula/proc/irradiate_everything()
+ for (var/area/area as anything in get_areas(radioactive_nebula.radioactive_areas))
+ for (var/turf/turf as anything in area.get_contained_turfs())
+ for (var/atom/movable/target as anything in turf)
+ fake_irradiate(target)
+
+ CHECK_TICK
+
+/// Remove the fake radiation. The compontent we add to mobs handles its own removal
+/datum/controller/subsystem/radioactive_nebula/proc/fake_unirradiate(atom/movable/leaver)
+ REMOVE_TRAIT(leaver, TRAIT_RADIOACTIVE_NEBULA_FAKE_IRRADIATED, REF(src))
+ leaver.remove_filter(GLOW_NEBULA)
+
+#undef TRAIT_RADIOACTIVE_NEBULA_FAKE_IRRADIATED
diff --git a/code/controllers/subsystem/research.dm b/code/controllers/subsystem/research.dm
index 735dd1cdc57..7f0b52d471b 100644
--- a/code/controllers/subsystem/research.dm
+++ b/code/controllers/subsystem/research.dm
@@ -8,12 +8,9 @@ SUBSYSTEM_DEF(research)
var/list/techweb_nodes = list() //associative id = node datum
var/list/techweb_designs = list() //associative id = node datum
- ///List of all techwebs.
+ ///List of all techwebs, generating points or not.
+ ///Autolathes, Mechfabs, and others all have shared techwebs, for example.
var/list/datum/techweb/techwebs = list()
- ///The default Science Techweb.
- var/datum/techweb/science/science_tech
- ///The default Admin Techweb.
- var/datum/techweb/admin/admin_tech
var/datum/techweb_node/error_node/error_node //These two are what you get if a node/design is deleted and somehow still stored in a console.
var/datum/design/error_design/error_design
@@ -74,8 +71,9 @@ SUBSYSTEM_DEF(research)
initialize_all_techweb_designs()
initialize_all_techweb_nodes()
populate_ordnance_experiments()
- science_tech = new /datum/techweb/science
- admin_tech = new /datum/techweb/admin
+ new /datum/techweb/science
+ new /datum/techweb/admin
+ new /datum/techweb/oldstation
autosort_categories()
error_design = new
error_node = new
@@ -308,3 +306,29 @@ SUBSYSTEM_DEF(research)
for (var/datum/experiment/ordnance/ordnance_experiment as anything in ordnance_experiments)
partner.accepted_experiments += ordnance_experiment.type
scientific_partners += partner
+
+/**
+ * Goes through all techwebs and goes through their servers to find ones on a valid z-level
+ * Returns the full list of all techweb servers.
+ */
+/datum/controller/subsystem/research/proc/get_available_servers(turf/location)
+ var/list/local_servers = list()
+ for (var/datum/techweb/individual_techweb as anything in techwebs)
+ var/list/servers = find_valid_servers(location, individual_techweb)
+ if(length(servers))
+ local_servers += servers
+ return local_servers
+
+/**
+ * Goes through an individual techweb's servers and finds one on a valid z-level
+ * Returns a list of existing ones, or an empty list otherwise.
+ * Args:
+ * - checking_web - The techweb we're checking the servers of.
+ */
+/datum/controller/subsystem/research/proc/find_valid_servers(turf/location, datum/techweb/checking_web)
+ var/list/valid_servers = list()
+ for(var/obj/machinery/rnd/server/server as anything in checking_web.techweb_servers)
+ if(!is_valid_z_level(get_turf(server), location))
+ continue
+ valid_servers += server
+ return valid_servers
diff --git a/code/controllers/subsystem/security_level.dm b/code/controllers/subsystem/security_level.dm
index 9bd803602df..d4fb13d9988 100644
--- a/code/controllers/subsystem/security_level.dm
+++ b/code/controllers/subsystem/security_level.dm
@@ -41,8 +41,6 @@ SUBSYSTEM_DEF(security_level)
announce_security_level(selected_level) // We want to announce BEFORE updating to the new level
- var/old_shuttle_call_time_mod = current_security_level.shuttle_call_time_mod // Need this before we set the new one
-
SSsecurity_level.current_security_level = selected_level
if(selected_level.looping_sound)
@@ -52,9 +50,7 @@ SUBSYSTEM_DEF(security_level)
can_fire = FALSE
if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) // By god this is absolutely shit
- old_shuttle_call_time_mod = 1 / old_shuttle_call_time_mod
- SSshuttle.emergency.modTimer(old_shuttle_call_time_mod)
- SSshuttle.emergency.modTimer(selected_level.shuttle_call_time_mod)
+ SSshuttle.emergency.alert_coeff_change(selected_level.shuttle_call_time_mod)
SEND_SIGNAL(src, COMSIG_SECURITY_LEVEL_CHANGED, selected_level.number_level)
SSnightshift.check_nightshift()
diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm
index 4e568b70d25..0e5ed6ca685 100644
--- a/code/controllers/subsystem/shuttle.dm
+++ b/code/controllers/subsystem/shuttle.dm
@@ -266,12 +266,12 @@ SUBSYSTEM_DEF(shuttle)
log_shuttle("[msg] Alive: [alive], Roundstart: [total], Threshold: [threshold]")
emergency_no_recall = TRUE
priority_announce("Catastrophic casualties detected: crisis shuttle protocols activated - jamming recall signals across all frequencies.")
- if(emergency.timeLeft(1) > emergency_call_time * 0.4)
- emergency.request(null, set_coefficient = 0.4)
+ if(emergency.timeLeft(1) > emergency_call_time * ALERT_COEFF_AUTOEVAC_CRITICAL)
+ emergency.request(null, set_coefficient = ALERT_COEFF_AUTOEVAC_CRITICAL)
/datum/controller/subsystem/shuttle/proc/block_recall(lockout_timer)
if(admin_emergency_no_recall)
- priority_announce("Error!", "Emergency Shuttle Uplink Alert", 'sound/misc/announce_dig.ogg')
+ priority_announce("Error!", "Emergency Shuttle Uplink Alert", ANNOUNCER_SHUTTLE) // SKYRAT EDIT CHANGE - Announcer Sounds
addtimer(CALLBACK(src, PROC_REF(unblock_recall)), lockout_timer)
return
emergency_no_recall = TRUE
@@ -279,7 +279,7 @@ SUBSYSTEM_DEF(shuttle)
/datum/controller/subsystem/shuttle/proc/unblock_recall()
if(admin_emergency_no_recall)
- priority_announce("Error!", "Emergency Shuttle Uplink Alert", 'sound/misc/announce_dig.ogg')
+ priority_announce("Error!", "Emergency Shuttle Uplink Alert", ANNOUNCER_SHUTTLE) // SKYRAT EDIT CHANGE - Announcer Sounds
return
emergency_no_recall = FALSE
@@ -473,7 +473,7 @@ SUBSYSTEM_DEF(shuttle)
if(callShuttle)
if(EMERGENCY_IDLE_OR_RECALLED)
- emergency.request(null, set_coefficient = 2.5)
+ emergency.request(null, set_coefficient = ALERT_COEFF_AUTOEVAC_NORMAL)
log_shuttle("There is no means of calling the emergency shuttle anymore. Shuttle automatically called.")
message_admins("All the communications consoles were destroyed and all AIs are inactive. Shuttle called.")
@@ -617,12 +617,18 @@ SUBSYSTEM_DEF(shuttle)
if(WEST)
transit_path = /turf/open/space/transit/west
- var/datum/turf_reservation/proposal = SSmapping.RequestBlockReservation(transit_width, transit_height, null, /datum/turf_reservation/transit, transit_path)
+ var/datum/turf_reservation/proposal = SSmapping.request_turf_block_reservation(
+ transit_width,
+ transit_height,
+ 1,
+ reservation_type = /datum/turf_reservation/transit,
+ turf_type_override = transit_path,
+ )
if(!istype(proposal))
return FALSE
- var/turf/bottomleft = locate(proposal.bottom_left_coords[1], proposal.bottom_left_coords[2], proposal.bottom_left_coords[3])
+ var/turf/bottomleft = proposal.bottom_left_turfs[1]
// Then create a transit docking port in the middle
var/coords = M.return_coords(0, 0, dock_dir)
/* 0------2
@@ -893,10 +899,15 @@ SUBSYSTEM_DEF(shuttle)
/datum/controller/subsystem/shuttle/proc/load_template(datum/map_template/shuttle/loading_template)
. = FALSE
// Load shuttle template to a fresh block reservation.
- preview_reservation = SSmapping.RequestBlockReservation(loading_template.width, loading_template.height, type = /datum/turf_reservation/transit)
+ preview_reservation = SSmapping.request_turf_block_reservation(
+ loading_template.width,
+ loading_template.height,
+ 1,
+ reservation_type = /datum/turf_reservation/transit,
+ )
if(!preview_reservation)
CRASH("failed to reserve an area for shuttle template loading")
- var/turf/bottom_left = TURF_FROM_COORDS_LIST(preview_reservation.bottom_left_coords)
+ var/turf/bottom_left = preview_reservation.bottom_left_turfs[1]
loading_template.load(bottom_left, centered = FALSE, register = FALSE)
var/affected = loading_template.get_affected_turfs(bottom_left, centered=FALSE)
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index c86ffa72d9a..1aaf01ee85f 100644
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -1,4 +1,5 @@
#define ROUND_START_MUSIC_LIST "strings/round_start_sounds.txt"
+#define SS_TICKER_TRAIT "SS_Ticker"
SUBSYSTEM_DEF(ticker)
name = "Ticker"
@@ -491,19 +492,18 @@ SUBSYSTEM_DEF(ticker)
var/mob/living = player.transfer_character()
if(living)
qdel(player)
- living.notransform = TRUE
+ ADD_TRAIT(living, TRAIT_NO_TRANSFORM, SS_TICKER_TRAIT)
if(living.client)
var/atom/movable/screen/splash/S = new(null, living.client, TRUE)
S.Fade(TRUE)
living.client.init_verbs()
livings += living
if(livings.len)
- addtimer(CALLBACK(src, PROC_REF(release_characters), livings), 30, TIMER_CLIENT_TIME)
+ addtimer(CALLBACK(src, PROC_REF(release_characters), livings), 3 SECONDS, TIMER_CLIENT_TIME)
/datum/controller/subsystem/ticker/proc/release_characters(list/livings)
- for(var/I in livings)
- var/mob/living/L = I
- L.notransform = FALSE
+ for(var/mob/living/living_mob as anything in livings)
+ REMOVE_TRAIT(living_mob, TRAIT_NO_TRANSFORM, SS_TICKER_TRAIT)
/datum/controller/subsystem/ticker/proc/check_queue()
if(!queued_players.len)
@@ -783,3 +783,4 @@ SUBSYSTEM_DEF(ticker)
return "[global.config.directory]/reboot_themes/[pick(possible_themes)]"
#undef ROUND_START_MUSIC_LIST
+#undef SS_TICKER_TRAIT
diff --git a/code/controllers/subsystem/traitor.dm b/code/controllers/subsystem/traitor.dm
index cd035fedc7d..6ad6fca0893 100644
--- a/code/controllers/subsystem/traitor.dm
+++ b/code/controllers/subsystem/traitor.dm
@@ -19,7 +19,7 @@ SUBSYSTEM_DEF(traitor)
var/configuration_data = list()
/// The coefficient multiplied by the current_global_progression for new joining traitors to calculate their progression
- var/newjoin_progression_coeff = 0.6
+ var/newjoin_progression_coeff = 1
/// The current progression that all traitors should be at in the round
var/current_global_progression = 0
/// The amount of deviance from the current global progression before you start getting 2x the current scaling or no scaling at all
@@ -44,6 +44,9 @@ SUBSYSTEM_DEF(traitor)
category_handler = new()
traitor_debug_panel = new(category_handler)
+ for(var/theft_item in subtypesof(/datum/objective_item/steal))
+ new theft_item
+
if(fexists(configuration_path))
var/list/data = json_decode(file2text(file(configuration_path)))
for(var/typepath in data)
diff --git a/code/datums/achievements/_awards.dm b/code/datums/achievements/_awards.dm
index b7500d54d45..7a7701e0cf1 100644
--- a/code/datums/achievements/_awards.dm
+++ b/code/datums/achievements/_awards.dm
@@ -110,6 +110,10 @@
. = ..()
to_chat(user, span_greenannounce("Achievement unlocked: [name]!"))
user.client.give_award(/datum/award/score/achievements_score, user, 1)
+ var/sound/sound_to_send = LAZYACCESS(GLOB.achievement_sounds, user.client.prefs.read_preference(/datum/preference/choiced/sound_achievement))
+ if(sound_to_send)
+ SEND_SOUND(user, sound_to_send)
+
times_achieved++
if(SSachievements.most_unlocked_achievement?.times_achieved < times_achieved)
SSachievements.most_unlocked_achievement = src
diff --git a/code/datums/achievements/boss_achievements.dm b/code/datums/achievements/boss_achievements.dm
index f58f25664f3..a378b703e46 100644
--- a/code/datums/achievements/boss_achievements.dm
+++ b/code/datums/achievements/boss_achievements.dm
@@ -55,12 +55,6 @@
database_id = BOSS_MEDAL_LEGION
icon = "legion"
-/datum/award/achievement/boss/swarmer_beacon_kill
- name = "Swarm Beacon Killer"
- desc = "GET THEM OFF OF ME!"
- database_id = BOSS_MEDAL_SWARMERS
- icon = "swarmer"
-
/datum/award/achievement/boss/wendigo_kill
name = "Wendigo Killer"
desc = "You've now ruined years of mythical storytelling."
@@ -109,12 +103,6 @@
database_id = BOSS_MEDAL_LEGION_CRUSHER
icon = "legion"
-/datum/award/achievement/boss/swarmer_beacon_crusher
- name = "Swarm Beacon Crusher"
- desc = "GET THEM OFF OF ME!"
- database_id = BOSS_MEDAL_SWARMERS_CRUSHER
- icon = "swarmer"
-
/datum/award/achievement/boss/wendigo_crusher
name = "Wendigo Crusher"
desc = "You've now ruined years of mythical storytelling."
diff --git a/code/datums/achievements/job_achievements.dm b/code/datums/achievements/job_achievements.dm
index 2bcc1ff91ce..10835b895b8 100644
--- a/code/datums/achievements/job_achievements.dm
+++ b/code/datums/achievements/job_achievements.dm
@@ -2,7 +2,27 @@
/datum/award/achievement/jobs
category = "Jobs"
-//chemistry
+//engineering
+
+/datum/award/achievement/jobs/theoretical_limits
+ name = "All Within Theoretical Limits"
+ desc = "I never thought I'd see a resonance cascade, let alone prevent one..."
+ database_id = MEDAL_THEORETICAL_LIMITS
+ icon = "theoreticallimits"
+
+//medical
+
+/datum/award/achievement/jobs/sandman
+ name = "Mister Sandman"
+ desc = "Mechanically speaking, there's no real benefit to being unconscious during surgery. Weird how insistent this doctor is about using the N2O anyway though, huh?"
+ database_id = MEDAL_SANDMAN
+ icon = "basemisc"
+
+/datum/award/achievement/jobs/helbitaljanken
+ name = "Helbitaljanken"
+ desc = "You janked hard"
+ database_id = MEDAL_HELBITALJANKEN
+ icon = "helbital"
/datum/award/achievement/jobs/chemistry_tut
name = "Perfect chemistry blossom"
@@ -10,6 +30,28 @@
database_id = MEDAL_CHEM_TUT
icon = "chem_tut"
+//mining
+
+/datum/award/achievement/jobs/frenching
+ name = "Frenching"
+ desc = "Just a taste, for science!"
+ database_id = MEDAL_FRENCHING
+ icon = "frenchingthebubble"
+
+//science
+
+/datum/award/achievement/jobs/feat_of_strength
+ name = "Feat of Strength"
+ desc = "If the rod is immovable, is it passing you or are you passing it?"
+ database_id = MEDAL_RODSUPLEX
+ icon = "featofstrength"
+
+/datum/award/achievement/jobs/snail
+ name = "KKKiiilll mmmeee"
+ desc = "You were a little too ambitious, but hey, I guess you're still alive?"
+ database_id = MEDAL_SNAIL
+ icon = "snail"
+
//all of service! hip hip!
/datum/award/achievement/jobs/service_bad
diff --git a/code/datums/achievements/misc_achievements.dm b/code/datums/achievements/misc_achievements.dm
index 1dd047ac244..f83f2cde7b0 100644
--- a/code/datums/achievements/misc_achievements.dm
+++ b/code/datums/achievements/misc_achievements.dm
@@ -20,12 +20,6 @@
database_id = MEDAL_TIMEWASTE
icon = "timewaste"
-/datum/award/achievement/misc/feat_of_strength
- name = "Feat of Strength"
- desc = "If the rod is immovable, is it passing you or are you passing it?"
- database_id = MEDAL_RODSUPLEX
- icon = "featofstrength"
-
/datum/award/achievement/misc/round_and_full
name = "Round and Full"
desc = "Well at least you aren't down the river, I hear they eat people there."
@@ -38,12 +32,6 @@
database_id = MEDAL_THANKSALOT
icon = "clownthanks"
-/datum/award/achievement/misc/helbitaljanken
- name = "Helbitaljanken"
- desc = "You janked hard"
- database_id = MEDAL_HELBITALJANKEN
- icon = "helbital"
-
/datum/award/achievement/misc/getting_an_upgrade
name = "Getting an upgrade"
desc = "Make your first unique material item!"
@@ -76,11 +64,6 @@
desc = "If you saw someone casually club themselves upside the head with a toolbox anywhere in the galaxy but here, you'd probably be pretty concerned for them."
database_id = MEDAL_SELFOUCH
-/datum/award/achievement/misc/sandman
- name = "Mister Sandman"
- desc = "Mechanically speaking, there's no real benefit to being unconscious during surgery. Weird how insistent this doctor is about using the N2O anyway though, huh?"
- database_id = MEDAL_SANDMAN
-
/datum/award/achievement/misc/cleanboss
name = "One Lean, Mean, Cleaning Machine"
desc = "How does it feel to know that your workplace values a mop bucket on wheels more than you?" // i can do better than this give me time
@@ -98,12 +81,6 @@
database_id = MEDAL_LONGSHIFT
icon = "longshift"
-/datum/award/achievement/misc/snail
- name = "KKKiiilll mmmeee"
- desc = "You were a little too ambitious, but hey, I guess you're still alive?"
- database_id = MEDAL_SNAIL
- icon = "snail"
-
/datum/award/achievement/misc/lookoutsir
name = "Look Out, Sir!"
desc = "Either awarded for making the ultimate sacrifice for your comrades, or a really dumb attempt at grenade jumping."
@@ -122,12 +99,6 @@
database_id = MEDAL_ASCENSION
icon = "ascension"
-/datum/award/achievement/misc/frenching
- name = "Frenching"
- desc = "Just a taste, for science!"
- database_id = MEDAL_FRENCHING
- icon = "frenchingthebubble"
-
/datum/award/achievement/misc/ash_ascension
name = "Nightwatcher's Eyes"
desc = "You've risen above the flames, became one with the ashes. You've been reborn as one with the Nightwatcher."
@@ -164,6 +135,12 @@
database_id = MEDAL_COSMOS_ASCENSION
icon = "cosmicascend"
+/datum/award/achievement/misc/knock_ascension
+ name = "Secrets behind the Spider Door"
+ desc = "You managed to open a gate into the mansus."
+ database_id = MEDAL_KNOCK_ASCENSION
+ icon = "knockascend"
+
/datum/award/achievement/misc/grand_ritual_finale
name = "Archmage"
desc = "Made a big impression on the station with your phenomenal cosmic power."
@@ -242,8 +219,3 @@
database_id = MEDAL_DEBT_EXTINGUISHED
icon = "outdebted"
-/datum/award/achievement/misc/theoretical_limits
- name = "All Within Theoretical Limits"
- desc = "I never thought I'd see a resonance cascade, let alone prevent one..."
- database_id = MEDAL_THEORETICAL_LIMITS
- icon = "theoreticallimits"
diff --git a/code/datums/actions/action.dm b/code/datums/actions/action.dm
index 746e8ad757b..b43220fb7d4 100644
--- a/code/datums/actions/action.dm
+++ b/code/datums/actions/action.dm
@@ -139,7 +139,7 @@
/// Actually triggers the effects of the action.
/// Called when the on-screen button is clicked, for example.
/datum/action/proc/Trigger(trigger_flags)
- if(!IsAvailable(feedback = TRUE))
+ if(!(trigger_flags & TRIGGER_FORCE_AVAILABLE) && !IsAvailable(feedback = TRUE))
return FALSE
if(SEND_SIGNAL(src, COMSIG_ACTION_TRIGGER, src) & COMPONENT_ACTION_BLOCK_TRIGGER)
return FALSE
diff --git a/code/datums/actions/mobs/lava_swoop.dm b/code/datums/actions/mobs/lava_swoop.dm
index 0c4eb959919..9c305ceb13b 100644
--- a/code/datums/actions/mobs/lava_swoop.dm
+++ b/code/datums/actions/mobs/lava_swoop.dm
@@ -96,19 +96,14 @@
owner.mouse_opacity = initial(owner.mouse_opacity)
playsound(owner.loc, 'sound/effects/meteorimpact.ogg', 200, TRUE)
for(var/mob/living/L in orange(1, owner) - owner)
- if(L.stat)
- owner.visible_message(span_warning("[owner] slams down on [L], crushing [L.p_them()]!"))
- L.investigate_log("has been gibbed by lava swoop.", INVESTIGATE_DEATHS)
- L.gib()
- else
- L.adjustBruteLoss(75)
- if(L && !QDELETED(L)) // Some mobs are deleted on death
- var/throw_dir = get_dir(owner, L)
- if(L.loc == owner.loc)
- throw_dir = pick(GLOB.alldirs)
- var/throwtarget = get_edge_target_turf(owner, throw_dir)
- L.throw_at(throwtarget, 3)
- owner.visible_message(span_warning("[L] is thrown clear of [owner]!"))
+ L.adjustBruteLoss(75)
+ if(!QDELETED(L)) // Some mobs are deleted on death
+ var/throw_dir = get_dir(owner, L)
+ if(L.loc == owner.loc)
+ throw_dir = pick(GLOB.alldirs)
+ var/throwtarget = get_edge_target_turf(owner, throw_dir)
+ L.throw_at(throwtarget, 3)
+ owner.visible_message(span_warning("[L] is thrown clear of [owner]!"))
for(var/obj/vehicle/sealed/mecha/M in orange(1, owner))
M.take_damage(75, BRUTE, MELEE, 1)
diff --git a/code/datums/actions/mobs/projectileattack.dm b/code/datums/actions/mobs/projectileattack.dm
index 7866e0831ca..5f97081186d 100644
--- a/code/datums/actions/mobs/projectileattack.dm
+++ b/code/datums/actions/mobs/projectileattack.dm
@@ -297,6 +297,7 @@
colossus = firer
colossus.say("Perish.", spans = list("colossus", "yell"))
+ SLEEP_CHECK_DEATH(0.5 SECONDS, firer) //gives dumbasses in melee range a slim chance to retreat
var/finale_counter = 10
for(var/i in 1 to 20)
if(finale_counter > 4 && colossus)
diff --git a/code/datums/ai/_ai_controller.dm b/code/datums/ai/_ai_controller.dm
index c396771a033..9ce83becc17 100644
--- a/code/datums/ai/_ai_controller.dm
+++ b/code/datums/ai/_ai_controller.dm
@@ -349,6 +349,11 @@ multiple modular subtrees with behaviors
minimum_distance = iter_behavior.required_distance
return minimum_distance
+/// Returns true if we have a blackboard key with the provided key and it is not qdeleting
+/datum/ai_controller/proc/blackboard_key_exists(key)
+ var/datum/key_value = blackboard[key]
+ return !QDELETED(key_value)
+
/**
* Used to manage references to datum by AI controllers
*
diff --git a/code/datums/ai/babies/babies_subtrees.dm b/code/datums/ai/babies/babies_subtrees.dm
index 0c71b6d757b..aad92f8422e 100644
--- a/code/datums/ai/babies/babies_subtrees.dm
+++ b/code/datums/ai/babies/babies_subtrees.dm
@@ -20,13 +20,8 @@
if(is_type_in_list(controller.pawn, baby_types))
return
- var/atom/target = controller.blackboard[BB_BABIES_TARGET]
-
// Find target
- if(QDELETED(target))
- controller.queue_behavior(/datum/ai_behavior/find_partner, BB_BABIES_TARGET, BB_BABIES_PARTNER_TYPES, BB_BABIES_CHILD_TYPES)
- return
-
- // Do target
- controller.queue_behavior(/datum/ai_behavior/make_babies, BB_BABIES_TARGET, BB_BABIES_CHILD_TYPES)
- return SUBTREE_RETURN_FINISH_PLANNING
+ if(controller.blackboard_key_exists(BB_BABIES_TARGET))
+ controller.queue_behavior(/datum/ai_behavior/make_babies, BB_BABIES_TARGET, BB_BABIES_CHILD_TYPES)
+ return SUBTREE_RETURN_FINISH_PLANNING
+ controller.queue_behavior(/datum/ai_behavior/find_partner, BB_BABIES_TARGET, BB_BABIES_PARTNER_TYPES, BB_BABIES_CHILD_TYPES)
diff --git a/code/datums/ai/basic_mobs/base_basic_controller.dm b/code/datums/ai/basic_mobs/base_basic_controller.dm
index b4f7c27c2f9..3eb79a815ad 100644
--- a/code/datums/ai/basic_mobs/base_basic_controller.dm
+++ b/code/datums/ai/basic_mobs/base_basic_controller.dm
@@ -15,10 +15,13 @@
/datum/ai_controller/basic_controller/able_to_run()
. = ..()
- if(isliving(pawn))
- var/mob/living/living_pawn = pawn
- if(IS_DEAD_OR_INCAP(living_pawn))
- return FALSE
+ if(!isliving(pawn))
+ return
+ var/mob/living/living_pawn = pawn
+ if(!(ai_traits & CAN_ACT_WHILE_DEAD) && IS_DEAD_OR_INCAP(living_pawn))
+ return FALSE
+ if(ai_traits & PAUSE_DURING_DO_AFTER && LAZYLEN(living_pawn.do_afters))
+ return FALSE
/datum/ai_controller/basic_controller/proc/update_speed(mob/living/basic/basic_mob)
SIGNAL_HANDLER
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 fee9160e5c0..6683fb02f93 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
@@ -1,11 +1,10 @@
/datum/ai_behavior/basic_melee_attack
- action_cooldown = 2 SECONDS
+ action_cooldown = 0.2 SECONDS // We gotta check unfortunately often because we're in a race condition with nextmove
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
/datum/ai_behavior/basic_melee_attack/setup(datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
. = ..()
- var/datum/targetting_datum/targetting_datum = controller.blackboard[targetting_datum_key]
- if(isnull(targetting_datum))
+ if(!controller.blackboard_key_exists(targetting_datum_key))
CRASH("No target datum was supplied in the blackboard for [controller.pawn]")
//Hiding location is priority
@@ -16,6 +15,11 @@
set_movement_target(controller, target)
/datum/ai_behavior/basic_melee_attack/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
+ if (isliving(controller.pawn))
+ var/mob/living/pawn = controller.pawn
+ if (world.time < pawn.next_move)
+ return
+
. = ..()
var/mob/living/basic/basic_mob = controller.pawn
//targetting datum will kill the action if not real anymore
@@ -41,17 +45,12 @@
if(!succeeded)
controller.clear_blackboard_key(target_key)
-/datum/ai_behavior/basic_melee_attack/average_speed
- action_cooldown = 1 SECONDS
-
/datum/ai_behavior/basic_ranged_attack
action_cooldown = 0.6 SECONDS
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_MOVE_AND_PERFORM
required_distance = 3
- /// How many shots to fire
- var/shots = 1
- /// The interval between individual shots in a burst
- var/burst_interval = 0.2 SECONDS
+ /// range we will try chasing the target before giving up
+ var/chase_range = 9
/datum/ai_behavior/basic_ranged_attack/setup(datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
. = ..()
@@ -61,13 +60,12 @@
set_movement_target(controller, target)
/datum/ai_behavior/basic_ranged_attack/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
- . = ..()
var/mob/living/basic/basic_mob = controller.pawn
//targetting datum will kill the action if not real anymore
var/atom/target = controller.blackboard[target_key]
var/datum/targetting_datum/targetting_datum = controller.blackboard[targetting_datum_key]
- if(!targetting_datum.can_attack(basic_mob, target))
+ if(!targetting_datum.can_attack(basic_mob, target, chase_range))
finish_action(controller, FALSE, target_key)
return
@@ -75,19 +73,11 @@
var/atom/final_target = hiding_target ? hiding_target : target
if(!can_see(basic_mob, final_target, required_distance))
- finish_action(controller, FALSE, target_key)
return
controller.set_blackboard_key(hiding_location_key, hiding_target)
-
- if(shots>1)
- var/atom/burst_target = final_target
- var/datum/callback/callback = CALLBACK(basic_mob, TYPE_PROC_REF(/mob/living/basic,RangedAttack), burst_target)
- for(var/i in 2 to shots)
- addtimer(callback, (i - 1) * burst_interval)
- callback.Invoke()
- else
- basic_mob.RangedAttack(final_target)
+ basic_mob.RangedAttack(final_target)
+ return ..() //only start the cooldown when the shot is shot
/datum/ai_behavior/basic_ranged_attack/finish_action(datum/ai_controller/controller, succeeded, target_key, targetting_datum_key, hiding_location_key)
. = ..()
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/find_mineable_wall.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/find_mineable_wall.dm
new file mode 100644
index 00000000000..ad5749c9161
--- /dev/null
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/find_mineable_wall.dm
@@ -0,0 +1,33 @@
+//behavior to find mineable mineral walls
+/datum/ai_behavior/find_mineral_wall
+
+/datum/ai_behavior/find_mineral_wall/perform(seconds_per_tick, datum/ai_controller/controller, found_wall_key)
+ . = ..()
+ var/mob/living_pawn = controller.pawn
+
+ for(var/turf/closed/mineral/potential_wall in oview(9, living_pawn))
+ if(!check_if_mineable(controller, potential_wall)) //check if its surrounded by walls
+ continue
+ controller.set_blackboard_key(found_wall_key, potential_wall) //closest wall first!
+ finish_action(controller, TRUE)
+ return
+
+ finish_action(controller, FALSE)
+
+/datum/ai_behavior/find_mineral_wall/proc/check_if_mineable(datum/ai_controller/controller, turf/target_wall)
+ var/mob/living/source = controller.pawn
+ var/direction_to_turf = get_dir(target_wall, source)
+ if(!ISDIAGONALDIR(direction_to_turf))
+ return TRUE
+ var/list/directions_to_check = list()
+ for(var/direction_check in GLOB.cardinals)
+ if(direction_check & direction_to_turf)
+ directions_to_check += direction_check
+
+ for(var/direction in directions_to_check)
+ var/turf/test_turf = get_step(target_wall, direction)
+ if(isnull(test_turf))
+ continue
+ if(!test_turf.is_blocked_turf(ignore_atoms = list(source)))
+ return TRUE
+ return FALSE
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/targeted_mob_ability.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/targeted_mob_ability.dm
index c0bd9d1323b..04cb9b171dd 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/targeted_mob_ability.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/targeted_mob_ability.dm
@@ -19,12 +19,6 @@
var/atom/target = controller.blackboard[target_key]
if (QDELETED(target))
controller.clear_blackboard_key(target_key)
- return
- if (!isliving(target))
- return
- var/mob/living/living_target = target
- if(living_target.stat >= UNCONSCIOUS)
- controller.clear_blackboard_key(target_key)
/datum/ai_behavior/targeted_mob_ability/proc/get_ability_to_use(datum/ai_controller/controller, ability_key)
return controller.blackboard[ability_key]
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/attack_adjacent_target.dm b/code/datums/ai/basic_mobs/basic_subtrees/attack_adjacent_target.dm
new file mode 100644
index 00000000000..c3d334165d9
--- /dev/null
+++ b/code/datums/ai/basic_mobs/basic_subtrees/attack_adjacent_target.dm
@@ -0,0 +1,33 @@
+/// Attack something which is already adjacent to us, without ending planning
+/datum/ai_planning_subtree/basic_melee_attack_subtree/opportunistic
+ melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/opportunistic
+ end_planning = FALSE
+
+/datum/ai_planning_subtree/basic_melee_attack_subtree/opportunistic/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
+ . = ..()
+ var/atom/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]
+ if(QDELETED(target) || !controller.pawn.Adjacent(target))
+ return
+ if (isliving(controller.pawn))
+ var/mob/living/pawn = controller.pawn
+ if (LAZYLEN(pawn.do_afters))
+ return
+ controller.queue_behavior(melee_attack_behavior, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETTING_DATUM, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
+
+/// Attack something which is already adjacent to us without moving
+/datum/ai_behavior/basic_melee_attack/opportunistic
+ action_cooldown = 0.2 SECONDS // We gotta check unfortunately often because we're in a race condition with nextmove
+ behavior_flags = AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
+
+/datum/ai_behavior/basic_melee_attack/opportunistic/setup(datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
+ if (!controller.blackboard_key_exists(targetting_datum_key))
+ CRASH("No target datum was supplied in the blackboard for [controller.pawn]")
+ return controller.blackboard_key_exists(target_key)
+
+/datum/ai_behavior/basic_melee_attack/opportunistic/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
+ var/atom/movable/atom_pawn = controller.pawn
+ if(!atom_pawn.CanReach(controller.blackboard[target_key]))
+ finish_action(controller, TRUE, target_key) // Don't clear target
+ return FALSE
+ . = ..()
+ finish_action(controller, TRUE, target_key) // Try doing something else
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/climb_tree.dm b/code/datums/ai/basic_mobs/basic_subtrees/climb_tree.dm
index 6827f3eee99..1beab6ec907 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/climb_tree.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/climb_tree.dm
@@ -7,11 +7,8 @@
if(!SPT_PROB(climb_chance, seconds_per_tick))
return
- var/obj/structure/flora/tree/target = controller.blackboard[BB_CLIMBED_TREE]
+ if(controller.blackboard_key_exists(BB_CLIMBED_TREE))
+ controller.queue_behavior(/datum/ai_behavior/climb_tree, BB_CLIMBED_TREE)
+ return SUBTREE_RETURN_FINISH_PLANNING
- if(QDELETED(target))
- controller.queue_behavior(/datum/ai_behavior/find_and_set/valid_tree, BB_CLIMBED_TREE, /obj/structure/flora/tree)
- return
-
- controller.queue_behavior(/datum/ai_behavior/climb_tree, BB_CLIMBED_TREE)
- return SUBTREE_RETURN_FINISH_PLANNING
+ controller.queue_behavior(/datum/ai_behavior/find_and_set/valid_tree, BB_CLIMBED_TREE, /obj/structure/flora/tree)
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/find_food.dm b/code/datums/ai/basic_mobs/basic_subtrees/find_food.dm
index 8d20df7b9c7..b02ec8eaa85 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/find_food.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/find_food.dm
@@ -3,8 +3,7 @@
/datum/ai_planning_subtree/find_food/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
. = ..()
- var/atom/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]
- if(!QDELETED(target))
+ if(controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET))
// Busy with something
return
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/find_paper_and_write.dm b/code/datums/ai/basic_mobs/basic_subtrees/find_paper_and_write.dm
index 900d13e0a04..0d2d0c3e3b4 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/find_paper_and_write.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/find_paper_and_write.dm
@@ -1,10 +1,9 @@
/datum/ai_planning_subtree/find_paper_and_write
/datum/ai_planning_subtree/find_paper_and_write/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
- var/obj/item/inhand_paper = controller.blackboard[BB_SIMPLE_CARRY_ITEM]
var/mob/living/basic/wizard = controller.pawn
- if(!QDELETED(inhand_paper))
+ if(controller.blackboard_key_exists(BB_SIMPLE_CARRY_ITEM))
controller.queue_behavior(/datum/ai_behavior/write_on_paper, BB_SIMPLE_CARRY_ITEM, BB_WRITING_LIST)
return SUBTREE_RETURN_FINISH_PLANNING
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 6ae7885618b..a4982fa660e 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/flee_target.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/flee_target.dm
@@ -9,10 +9,7 @@
/datum/ai_planning_subtree/flee_target/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
. = ..()
- if (!controller.blackboard[BB_BASIC_MOB_FLEEING])
- return
- var/atom/target = controller.blackboard[target_key]
- if(QDELETED(target))
+ if (!controller.blackboard[BB_BASIC_MOB_FLEEING] || !controller.blackboard_key_exists(target_key))
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/move_to_cardinal.dm b/code/datums/ai/basic_mobs/basic_subtrees/move_to_cardinal.dm
new file mode 100644
index 00000000000..c98878e0fd7
--- /dev/null
+++ b/code/datums/ai/basic_mobs/basic_subtrees/move_to_cardinal.dm
@@ -0,0 +1,71 @@
+/// Try to line up with a cardinal direction of your target
+/datum/ai_planning_subtree/move_to_cardinal
+ /// Behaviour to execute to line ourselves up
+ var/move_behaviour = /datum/ai_behavior/move_to_cardinal
+ /// Blackboard key in which to store selected target
+ var/target_key = BB_BASIC_MOB_CURRENT_TARGET
+
+/datum/ai_planning_subtree/move_to_cardinal/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
+ . = ..()
+ if(!controller.blackboard_key_exists(target_key))
+ return
+ controller.queue_behavior(move_behaviour, target_key)
+
+/// Try to line up with a cardinal direction of your target
+/datum/ai_behavior/move_to_cardinal
+ required_distance = 0
+ behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_MOVE_AND_PERFORM | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
+ /// How close to our target is too close?
+ var/minimum_distance = 1
+ /// How far away is too far?
+ var/maximum_distance = 9
+
+/datum/ai_behavior/move_to_cardinal/setup(datum/ai_controller/controller, target_key)
+ var/atom/target = controller.blackboard[target_key]
+ if(QDELETED(target))
+ return FALSE
+ target_nearest_cardinal(controller, target)
+ return TRUE
+
+/// Set our movement target to the closest cardinal space to our target
+/datum/ai_behavior/move_to_cardinal/proc/target_nearest_cardinal(datum/ai_controller/controller, atom/target)
+ var/atom/move_target
+ var/closest = INFINITY
+
+ for (var/dir in GLOB.cardinals)
+ var/turf/cardinal_turf = get_ranged_target_turf(target, dir, minimum_distance)
+ if (cardinal_turf.is_blocked_turf())
+ continue
+ var/distance_to = get_dist(controller.pawn, cardinal_turf)
+ if (distance_to >= closest)
+ continue
+ closest = distance_to
+ move_target = cardinal_turf
+
+ if (isnull(move_target))
+ move_target = target
+ if (controller.current_movement_target == move_target)
+ return
+ set_movement_target(controller, move_target)
+
+/datum/ai_behavior/move_to_cardinal/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
+ var/atom/target = controller.blackboard[target_key]
+ if (QDELETED(target))
+ finish_action(controller = controller, succeeded = FALSE, target_key = target_key)
+ return
+ if (!(get_dir(controller.pawn, target) in GLOB.cardinals))
+ target_nearest_cardinal(controller, target)
+ return
+ var/distance_to_target = get_dist(controller.pawn, target)
+ if (distance_to_target < minimum_distance)
+ target_nearest_cardinal(controller, target)
+ return
+ if (distance_to_target > maximum_distance)
+ return
+ finish_action(controller = controller, succeeded = TRUE, target_key = target_key)
+ return
+
+/datum/ai_behavior/move_to_cardinal/finish_action(datum/ai_controller/controller, succeeded, target_key)
+ if (!succeeded)
+ controller.clear_blackboard_key(target_key)
+ return ..()
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/ranged_skirmish.dm b/code/datums/ai/basic_mobs/basic_subtrees/ranged_skirmish.dm
index 07fb6f8b0dc..1ff752d925f 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/ranged_skirmish.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/ranged_skirmish.dm
@@ -8,8 +8,7 @@
/datum/ai_planning_subtree/ranged_skirmish/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
. = ..()
- var/atom/target = controller.blackboard[target_key]
- if(QDELETED(target))
+ if(!controller.blackboard_key_exists(target_key))
return
controller.queue_behavior(attack_behavior, target_key, BB_TARGETTING_DATUM, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/simple_attack_target.dm b/code/datums/ai/basic_mobs/basic_subtrees/simple_attack_target.dm
index 90379fcac0a..210aaf0aa8b 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/simple_attack_target.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/simple_attack_target.dm
@@ -1,16 +1,16 @@
/datum/ai_planning_subtree/basic_melee_attack_subtree
+ /// What do we do in order to attack someone?
var/datum/ai_behavior/basic_melee_attack/melee_attack_behavior = /datum/ai_behavior/basic_melee_attack
+ /// Is this the last thing we do? (if we set a movement target, this will usually be yes)
+ var/end_planning = TRUE
/datum/ai_planning_subtree/basic_melee_attack_subtree/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
. = ..()
- var/atom/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]
- if(QDELETED(target))
+ if(!controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET))
return
controller.queue_behavior(melee_attack_behavior, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETTING_DATUM, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
- return SUBTREE_RETURN_FINISH_PLANNING //we are going into battle...no distractions.
-
-/datum/ai_planning_subtree/basic_melee_attack_subtree/average_speed
- melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/average_speed
+ if (end_planning)
+ return SUBTREE_RETURN_FINISH_PLANNING //we are going into battle...no distractions.
/datum/ai_planning_subtree/basic_ranged_attack_subtree
operational_datums = list(/datum/component/ranged_attacks)
@@ -18,8 +18,7 @@
/datum/ai_planning_subtree/basic_ranged_attack_subtree/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
. = ..()
- var/atom/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]
- if(QDELETED(target))
+ if(!controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET))
return
controller.queue_behavior(ranged_attack_behavior, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETTING_DATUM, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
return SUBTREE_RETURN_FINISH_PLANNING //we are going into battle...no distractions.
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/sleep_with_no_target.dm b/code/datums/ai/basic_mobs/basic_subtrees/sleep_with_no_target.dm
index ccd67d6d1e7..93499cf673c 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/sleep_with_no_target.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/sleep_with_no_target.dm
@@ -16,7 +16,7 @@
/datum/ai_behavior/sleep_after_targetless_time/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
var/atom/target = controller.blackboard[target_key]
- finish_action(controller, succeeded = !target, seconds_per_tick = seconds_per_tick)
+ finish_action(controller, succeeded = QDELETED(target), seconds_per_tick = seconds_per_tick)
/datum/ai_behavior/sleep_after_targetless_time/finish_action(datum/ai_controller/controller, succeeded, seconds_per_tick)
. = ..()
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 a04765b1a88..005a9ee835d 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm
@@ -199,3 +199,19 @@
speech_chance = 5
emote_hear = list("rawrs.","grumbles.","grawls.", "stomps!")
emote_see = list("stares ferociously.")
+
+/datum/ai_planning_subtree/random_speech/blackboard //literal tower of babel, subtree form
+ speech_chance = 1
+
+/datum/ai_planning_subtree/random_speech/blackboard/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
+ 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)
+ 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/target_retaliate.dm b/code/datums/ai/basic_mobs/basic_subtrees/target_retaliate.dm
index 2d553fe4b2f..6133759183d 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/target_retaliate.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/target_retaliate.dm
@@ -7,10 +7,15 @@
var/target_key = BB_BASIC_MOB_CURRENT_TARGET
/// Blackboard key in which to store selected target's hiding place
var/hiding_place_key = BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION
+ /// do we check for faction?
+ var/check_faction = FALSE
/datum/ai_planning_subtree/target_retaliate/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
. = ..()
- controller.queue_behavior(/datum/ai_behavior/target_from_retaliate_list, BB_BASIC_MOB_RETALIATE_LIST, target_key, targetting_datum_key, hiding_place_key)
+ controller.queue_behavior(/datum/ai_behavior/target_from_retaliate_list, BB_BASIC_MOB_RETALIATE_LIST, target_key, targetting_datum_key, hiding_place_key, check_faction)
+
+/datum/ai_planning_subtree/target_retaliate/check_faction
+ check_faction = TRUE
/// Places a mob which you can see and who has recently attacked you into some 'run away from this' AI keys
/// Can use a different targetting datum than you use to select attack targets
@@ -29,20 +34,28 @@
/// How far can we see stuff?
var/vision_range = 9
-/datum/ai_behavior/target_from_retaliate_list/perform(seconds_per_tick, datum/ai_controller/controller, shitlist_key, target_key, targetting_datum_key, hiding_location_key)
+/datum/ai_behavior/target_from_retaliate_list/perform(seconds_per_tick, datum/ai_controller/controller, shitlist_key, target_key, targetting_datum_key, hiding_location_key, check_faction)
. = ..()
var/mob/living/living_mob = controller.pawn
var/datum/targetting_datum/targetting_datum = controller.blackboard[targetting_datum_key]
if(!targetting_datum)
CRASH("No target datum was supplied in the blackboard for [controller.pawn]")
- var/list/enemies_list = controller.blackboard[shitlist_key]
- if (!length(enemies_list))
- finish_action(controller, succeeded = FALSE)
+
+ var/list/enemies_list = list()
+
+ for(var/mob/living/potential_target as anything in controller.blackboard[shitlist_key])
+ if(!targetting_datum.can_attack(living_mob, potential_target, vision_range, check_faction))
+ continue
+ enemies_list += potential_target
+
+
+ if(!length(enemies_list))
+ finish_action(controller, succeeded = FALSE, check_faction = check_faction)
return
if (controller.blackboard[target_key] in enemies_list) // Don't bother changing
- finish_action(controller, succeeded = FALSE)
+ finish_action(controller, succeeded = TRUE, check_faction = check_faction)
return
var/atom/new_target = pick_final_target(controller, enemies_list)
@@ -53,18 +66,15 @@
if(potential_hiding_location) //If they're hiding inside of something, we need to know so we can go for that instead initially.
controller.set_blackboard_key(hiding_location_key, potential_hiding_location)
- finish_action(controller, succeeded = TRUE)
-
-/// Returns true if this target is valid for attacking based on current conditions
-/datum/ai_behavior/target_from_retaliate_list/proc/can_attack_target(mob/living/living_mob, atom/target, datum/targetting_datum/targetting_datum)
- if (!target)
- return FALSE
- if (target == living_mob)
- return FALSE
- if (!can_see(living_mob, target, vision_range))
- return FALSE
- return targetting_datum.can_attack(living_mob, target)
+ finish_action(controller, succeeded = TRUE, check_faction = check_faction)
/// Returns the desired final target from the filtered list of enemies
/datum/ai_behavior/target_from_retaliate_list/proc/pick_final_target(datum/ai_controller/controller, list/enemies_list)
return pick(enemies_list)
+
+
+/datum/ai_behavior/target_from_retaliate_list/finish_action(datum/ai_controller/controller, succeeded, target_key, check_faction)
+ . = ..()
+ if(check_faction)
+ return
+ controller.set_blackboard_key(BB_BASIC_MOB_SKIP_FACTION_CHECK, succeeded)
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 b6b4d286df1..8d75f797163 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
@@ -13,9 +13,11 @@
if (!ability_key)
CRASH("You forgot to tell this mob where to find its ability")
- var/mob/living/target = controller.blackboard[target_key]
+ if (!controller.blackboard_key_exists(target_key))
+ return
+
var/datum/action/cooldown/using_action = controller.blackboard[ability_key]
- if (QDELETED(target) || QDELETED(using_action) || !using_action.IsAvailable())
+ if (!using_action?.IsAvailable())
return
controller.queue_behavior(use_ability_behaviour, ability_key, target_key)
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/use_mob_ability.dm b/code/datums/ai/basic_mobs/basic_subtrees/use_mob_ability.dm
index 2c618e98e72..fb83b8f8684 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/use_mob_ability.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/use_mob_ability.dm
@@ -4,7 +4,7 @@
*/
/datum/ai_planning_subtree/use_mob_ability
/// Blackboard key for the ability
- var/ability_key
+ var/ability_key = BB_GENERIC_ACTION
/// Behaviour to perform using ability
var/use_ability_behaviour = /datum/ai_behavior/use_mob_ability
/// If true we terminate planning after trying to use the ability.
@@ -15,7 +15,7 @@
CRASH("You forgot to tell this mob where to find its ability")
var/datum/action/cooldown/using_action = controller.blackboard[ability_key]
- if (QDELETED(using_action) || !using_action.IsAvailable())
+ if (!using_action?.IsAvailable())
return
controller.queue_behavior(use_ability_behaviour, ability_key)
diff --git a/code/datums/ai/basic_mobs/targetting_datums/basic_targetting_datum.dm b/code/datums/ai/basic_mobs/targetting_datums/basic_targetting_datum.dm
index 643089bb5ea..570088ce4d6 100644
--- a/code/datums/ai/basic_mobs/targetting_datums/basic_targetting_datum.dm
+++ b/code/datums/ai/basic_mobs/targetting_datums/basic_targetting_datum.dm
@@ -20,7 +20,12 @@
///Whether we care for seeing the target or not
var/ignore_sight = FALSE
-/datum/targetting_datum/basic/can_attack(mob/living/living_mob, atom/the_target, vision_range)
+/datum/targetting_datum/basic/can_attack(mob/living/living_mob, atom/the_target, vision_range, check_faction = TRUE)
+ var/datum/ai_controller/basic_controller/our_controller = living_mob.ai_controller
+
+ if(isnull(our_controller))
+ return FALSE
+
if(isturf(the_target) || !the_target) // bail out on invalids
return FALSE
@@ -44,9 +49,13 @@
return FALSE
if(isliving(the_target)) //Targeting vs living mobs
- var/mob/living/L = the_target
- if(faction_check(living_mob, L) || (L.stat > stat_attack))
+ var/mob/living/living_target = the_target
+ var/bypass_faction_check = !check_faction || our_controller.blackboard[BB_BASIC_MOB_SKIP_FACTION_CHECK]
+ if(faction_check(living_mob, living_target) && !bypass_faction_check)
return FALSE
+ if(living_target.stat > stat_attack)
+ return FALSE
+
return TRUE
if(ismecha(the_target)) //Targeting vs mechas
@@ -115,3 +124,9 @@
/datum/targetting_datum/basic/of_size/larger
find_smaller = FALSE
inclusive = FALSE
+
+/datum/targetting_datum/basic/attack_until_dead
+ stat_attack = HARD_CRIT
+
+/datum/targetting_datum/basic/attack_even_if_dead
+ stat_attack = DEAD
diff --git a/code/datums/ai/dog/dog_behaviors.dm b/code/datums/ai/dog/dog_behaviors.dm
index 7bd0d5824a1..6c9cb779bb3 100644
--- a/code/datums/ai/dog/dog_behaviors.dm
+++ b/code/datums/ai/dog/dog_behaviors.dm
@@ -4,7 +4,6 @@
* Adds a floor to the melee damage of the dog, as most pet dogs don't actually have any melee strength
*/
/datum/ai_behavior/basic_melee_attack/dog
- action_cooldown = 0.8 SECONDS
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_MOVE_AND_PERFORM
required_distance = 3
diff --git a/code/datums/ai/generic/find_and_set.dm b/code/datums/ai/generic/find_and_set.dm
index 443febae2a0..eb09506a282 100644
--- a/code/datums/ai/generic/find_and_set.dm
+++ b/code/datums/ai/generic/find_and_set.dm
@@ -8,8 +8,7 @@
/datum/ai_behavior/find_and_set/perform(seconds_per_tick, datum/ai_controller/controller, set_key, locate_path, search_range)
. = ..()
- var/atom/current_target = controller.blackboard[set_key]
- if (!QDELETED(current_target))
+ if (controller.blackboard_key_exists(set_key))
return
var/find_this_thing = search_tactic(controller, locate_path, search_range)
if(find_this_thing)
diff --git a/code/datums/ai/hunting_behavior/hunting_behaviors.dm b/code/datums/ai/hunting_behavior/hunting_behaviors.dm
index 777cb851ee4..036176dc85e 100644
--- a/code/datums/ai/hunting_behavior/hunting_behaviors.dm
+++ b/code/datums/ai/hunting_behavior/hunting_behaviors.dm
@@ -16,6 +16,8 @@
var/hunt_range = 2
/// What are the chances we hunt something at any given moment
var/hunt_chance = 100
+ ///do we finish planning subtree
+ var/finish_planning = TRUE
/datum/ai_planning_subtree/find_and_hunt_target/New()
. = ..()
@@ -35,13 +37,15 @@
// We're not hunting anything, look around for something
if(isnull(hunted))
controller.queue_behavior(finding_behavior, target_key, hunt_targets, hunt_range)
+ return
// We ARE hunting something, execute the hunt.
// Note that if our AI controller has multiple hunting subtrees set,
// we may accidentally be executing another tree's hunt - not ideal,
// try to set a unique target key if you have multiple
- else
- controller.queue_behavior(hunting_behavior, target_key, BB_HUNTING_COOLDOWN)
+
+ controller.queue_behavior(hunting_behavior, target_key, BB_HUNTING_COOLDOWN)
+ if(finish_planning)
return SUBTREE_RETURN_FINISH_PLANNING //If we're hunting we're too busy for anything else
/// Finds a specific atom type to hunt.
@@ -124,3 +128,19 @@
/datum/ai_behavior/hunt_target/unarmed_attack_target/target_caught(mob/living/hunter, obj/structure/cable/hunted)
hunter.UnarmedAttack(hunted, TRUE)
+
+/datum/ai_behavior/hunt_target/use_ability_on_target
+ always_reset_target = TRUE
+ ///the ability we will use
+ var/ability_key
+
+/datum/ai_behavior/hunt_target/use_ability_on_target/perform(seconds_per_tick, datum/ai_controller/controller, hunting_target_key, hunting_cooldown_key)
+ var/datum/action/cooldown/ability = controller.blackboard[ability_key]
+ if(QDELETED(ability) || !ability.IsAvailable())
+ finish_action(controller, FALSE, hunting_target_key)
+ return ..()
+
+/datum/ai_behavior/hunt_target/use_ability_on_target/target_caught(mob/living/hunter, atom/hunted)
+ var/datum/action/cooldown/ability = hunter.ai_controller.blackboard[ability_key]
+ ability.InterceptClickOn(hunter, null, hunted)
+
diff --git a/code/datums/ai/idle_behaviors/idle_random_walk.dm b/code/datums/ai/idle_behaviors/idle_random_walk.dm
index b25f983f313..d5a3972a3d0 100644
--- a/code/datums/ai/idle_behaviors/idle_random_walk.dm
+++ b/code/datums/ai/idle_behaviors/idle_random_walk.dm
@@ -14,3 +14,13 @@
/datum/idle_behavior/idle_random_walk/less_walking
walk_chance = 10
+
+/// Only walk if we don't have a target
+/datum/idle_behavior/idle_random_walk/no_target
+ /// Where do we look for a target?
+ var/target_key = BB_BASIC_MOB_CURRENT_TARGET
+
+/datum/idle_behavior/idle_random_walk/no_target/perform_idle_behavior(seconds_per_tick, datum/ai_controller/controller)
+ if (!controller.blackboard_key_exists(target_key))
+ return
+ return ..()
diff --git a/code/datums/beam.dm b/code/datums/beam.dm
index a2542afcdb4..6b138387290 100644
--- a/code/datums/beam.dm
+++ b/code/datums/beam.dm
@@ -41,7 +41,21 @@
/// If set will be used instead of targets's pixel_y in offset calculations
var/override_target_pixel_y = null
-/datum/beam/New(origin, target, icon = 'icons/effects/beam.dmi', icon_state = "b_beam", time = INFINITY, max_distance = INFINITY, beam_type = /obj/effect/ebeam, beam_color = null, emissive = TRUE, override_origin_pixel_x = null, override_origin_pixel_y = null, override_target_pixel_x = null, override_target_pixel_y = null)
+/datum/beam/New(
+ origin,
+ target,
+ icon = 'icons/effects/beam.dmi',
+ icon_state = "b_beam",
+ time = INFINITY,
+ max_distance = INFINITY,
+ beam_type = /obj/effect/ebeam,
+ beam_color = null,
+ emissive = TRUE,
+ override_origin_pixel_x = null,
+ override_origin_pixel_y = null,
+ override_target_pixel_x = null,
+ override_target_pixel_y = null,
+)
src.origin = origin
src.target = target
src.icon = icon
@@ -65,8 +79,7 @@
visuals.icon = icon
visuals.icon_state = icon_state
visuals.color = beam_color
- visuals.layer = ABOVE_ALL_MOB_LAYER
- visuals.vis_flags = VIS_INHERIT_PLANE
+ visuals.vis_flags = VIS_INHERIT_PLANE|VIS_INHERIT_LAYER
visuals.emissive = emissive
visuals.update_appearance()
Draw()
@@ -166,6 +179,8 @@
/obj/effect/ebeam
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ plane = GAME_PLANE_UPPER_FOV_HIDDEN
+ layer = ABOVE_ALL_MOB_LAYER
anchored = TRUE
var/emissive = TRUE
var/datum/beam/owner
diff --git a/code/datums/brain_damage/mild.dm b/code/datums/brain_damage/mild.dm
index 5275ff97150..52731852c11 100644
--- a/code/datums/brain_damage/mild.dm
+++ b/code/datums/brain_damage/mild.dm
@@ -89,7 +89,7 @@
if(SPT_PROB(2.5, seconds_per_tick))
switch(rand(1,11))
if(1)
- owner.vomit()
+ owner.vomit(VOMIT_CATEGORY_DEFAULT)
if(2,3)
owner.adjust_dizzy(20 SECONDS)
if(4,5)
diff --git a/code/datums/cinematics/_cinematic.dm b/code/datums/cinematics/_cinematic.dm
index 36b15998bf1..a0344434ec4 100644
--- a/code/datums/cinematics/_cinematic.dm
+++ b/code/datums/cinematics/_cinematic.dm
@@ -1,3 +1,5 @@
+#define CINEMATIC_SOURCE "cinematic"
+
/**
* Plays a cinematic, duh. Can be to a select few people, or everyone.
*
@@ -30,7 +32,7 @@
/datum/cinematic
/// A list of all clients watching the cinematic
var/list/client/watching = list()
- /// A list of all mobs who have notransform set while watching the cinematic
+ /// A list of all mobs who have TRAIT_NO_TRANSFORM set while watching the cinematic
var/list/datum/weakref/locked = list()
/// Whether the cinematic is a global cinematic or not
var/is_global = FALSE
@@ -106,11 +108,7 @@
/datum/cinematic/proc/show_to(mob/watching_mob, client/watching_client)
SIGNAL_HANDLER
- // We could technically rip people out of notransform who shouldn't be,
- // so we'll only lock down all viewing mobs who don't have it already set.
- // This does potentially mean some mobs could lose their notrasnform and
- // not be locked down by cinematics, but that should be very unlikely.
- if(!watching_mob.notransform)
+ if(!HAS_TRAIT_FROM(watching_mob, TRAIT_NO_TRANSFORM, CINEMATIC_SOURCE))
lock_mob(watching_mob)
// Only show the actual cinematic to cliented mobs.
@@ -152,14 +150,14 @@
/// Locks a mob, preventing them from moving, being hurt, or acting
/datum/cinematic/proc/lock_mob(mob/to_lock)
locked += WEAKREF(to_lock)
- to_lock.notransform = TRUE
+ ADD_TRAIT(to_lock, TRAIT_NO_TRANSFORM, CINEMATIC_SOURCE)
/// Unlocks a previously locked weakref
/datum/cinematic/proc/unlock_mob(datum/weakref/mob_ref)
var/mob/locked_mob = mob_ref.resolve()
if(isnull(locked_mob))
return
- locked_mob.notransform = FALSE
+ REMOVE_TRAIT(locked_mob, TRAIT_NO_TRANSFORM, CINEMATIC_SOURCE)
UnregisterSignal(locked_mob, COMSIG_MOB_CLIENT_LOGIN)
/// Removes the passed client from our watching list.
@@ -171,8 +169,10 @@
UnregisterSignal(no_longer_watching, COMSIG_QDELETING)
// We'll clear the cinematic if they have a mob which has one,
- // but we won't remove notransform. Wait for the cinematic end to do that.
+ // but we won't remove TRAIT_NO_TRANSFORM. Wait for the cinematic end to do that.
no_longer_watching.mob?.clear_fullscreen("cinematic")
no_longer_watching.screen -= screen
watching -= no_longer_watching
+
+#undef CINEMATIC_SOURCE
diff --git a/code/datums/components/anti_magic.dm b/code/datums/components/anti_magic.dm
index d3d53237777..059bc2f787d 100644
--- a/code/datums/components/anti_magic.dm
+++ b/code/datums/components/anti_magic.dm
@@ -44,6 +44,7 @@
if(isitem(parent))
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(on_equip))
RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(on_drop))
+ RegisterSignals(parent, list(COMSIG_ITEM_ATTACK, COMSIG_ITEM_ATTACK_ATOM), PROC_REF(on_attack))
else if(ismob(parent))
register_antimagic_signals(parent)
else
@@ -131,3 +132,7 @@
return COMPONENT_MAGIC_BLOCKED
return NONE
+
+/datum/component/anti_magic/proc/on_attack(atom/movable/source, atom/target, mob/user)
+ SIGNAL_HANDLER
+ SEND_SIGNAL(target, COMSIG_ATOM_HOLYATTACK, source, user, antimagic_flags)
diff --git a/code/datums/components/appearance_on_aggro.dm b/code/datums/components/appearance_on_aggro.dm
index 85690a579ae..affb926d28d 100644
--- a/code/datums/components/appearance_on_aggro.dm
+++ b/code/datums/components/appearance_on_aggro.dm
@@ -10,6 +10,8 @@
var/alpha_on_aggro
/// visibility of our icon when deaggroed
var/alpha_on_deaggro
+ /// 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))
@@ -22,28 +24,49 @@
src.alpha_on_deaggro = alpha_on_deaggro
/datum/component/appearance_on_aggro/RegisterWithParent()
- RegisterSignal(parent, COMSIG_AI_BLACKBOARD_KEY_SET(target_key), PROC_REF(change_appearance))
- RegisterSignal(parent, COMSIG_AI_BLACKBOARD_KEY_CLEARED(target_key), PROC_REF(revert_appearance))
+ 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))
/datum/component/appearance_on_aggro/UnregisterFromParent()
. = ..()
UnregisterSignal(parent, list(COMSIG_AI_BLACKBOARD_KEY_SET(target_key), COMSIG_AI_BLACKBOARD_KEY_CLEARED(target_key)))
-/datum/component/appearance_on_aggro/proc/change_appearance(mob/living/source)
+/datum/component/appearance_on_aggro/proc/on_set_target(mob/living/source)
SIGNAL_HANDLER
var/atom/target = source.ai_controller.blackboard[target_key]
if(isnull(target))
return
+ current_target = target
+ RegisterSignal(target, COMSIG_QDELETING, PROC_REF(on_clear_target))
if(overlay_path)
- source.add_overlay(overlay_path)
+ source.update_appearance(UPDATE_OVERLAYS)
if(alpha_on_aggro)
animate(source, alpha = alpha_on_aggro, time = 2 SECONDS)
-/datum/component/appearance_on_aggro/proc/revert_appearance(mob/living/source)
+/datum/component/appearance_on_aggro/Destroy()
+ if(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.cut_overlay(overlay_path)
+ source.update_appearance(UPDATE_OVERLAYS)
if(alpha_on_deaggro)
animate(source, alpha = alpha_on_deaggro, time = 2 SECONDS)
+
+/datum/component/appearance_on_aggro/proc/change_overlays(atom/source, list/overlays)
+ SIGNAL_HANDLER
+
+ if(isnull(current_target))
+ return
+
+ overlays += overlay_path
diff --git a/code/datums/components/bakeable.dm b/code/datums/components/bakeable.dm
index a5367769f68..5aa60cd89a7 100644
--- a/code/datums/components/bakeable.dm
+++ b/code/datums/components/bakeable.dm
@@ -67,6 +67,8 @@
var/atom/original_object = parent
var/obj/item/plate/oven_tray/used_tray = original_object.loc
var/atom/baked_result = new bake_result(used_tray)
+ baked_result.reagents.clear_reagents()
+ original_object.reagents?.trans_to(baked_result, original_object.reagents.total_volume)
if(who_baked_us)
ADD_TRAIT(baked_result, TRAIT_FOOD_CHEF_MADE, who_baked_us)
@@ -104,4 +106,4 @@
else if(current_bake_time <= required_bake_time)
examine_list += span_notice("[parent] seems to be almost finished baking!")
else
- examine_list += span_danger("[parent] should probably not be baked for much longer!")
+ examine_list += span_danger("[parent] should probably not be put in the oven.")
diff --git a/code/datums/components/basic_mob_attack_telegraph.dm b/code/datums/components/basic_mob_attack_telegraph.dm
index 6467fbd7bbc..5473dbd0fa0 100644
--- a/code/datums/components/basic_mob_attack_telegraph.dm
+++ b/code/datums/components/basic_mob_attack_telegraph.dm
@@ -73,7 +73,7 @@
return
ADD_TRAIT(source, TRAIT_BASIC_ATTACK_FORECAST, REF(src))
forget_target(target)
- source.melee_attack(target)
+ source.melee_attack(target, ignore_cooldown = TRUE) // We already started the cooldown when we triggered the forecast
/// The guy we're trying to attack moved, is he still in range?
/datum/component/basic_mob_attack_telegraph/proc/target_moved(atom/target)
diff --git a/code/datums/components/butchering.dm b/code/datums/components/butchering.dm
index 6aa4555f3aa..0ed00e7dd94 100644
--- a/code/datums/components/butchering.dm
+++ b/code/datums/components/butchering.dm
@@ -91,10 +91,8 @@
log_combat(user, H, "wounded via throat slitting", source)
H.apply_damage(source.force, BRUTE, BODY_ZONE_HEAD, wound_bonus=CANT_WOUND) // easy tiger, we'll get to that in a sec
var/obj/item/bodypart/slit_throat = H.get_bodypart(BODY_ZONE_HEAD)
- if(slit_throat)
- var/datum/wound/slash/critical/screaming_through_a_slit_throat = new
- screaming_through_a_slit_throat.apply_wound(slit_throat, wound_source = "throat slit")
- H.apply_status_effect(/datum/status_effect/neck_slice)
+ if (H.cause_wound_of_type_and_severity(WOUND_SLASH, slit_throat, WOUND_SEVERITY_CRITICAL))
+ H.apply_status_effect(/datum/status_effect/neck_slice)
/**
* Handles a user butchering a target
diff --git a/code/datums/components/chasm.dm b/code/datums/components/chasm.dm
index 9b59420b715..fc93123921c 100644
--- a/code/datums/components/chasm.dm
+++ b/code/datums/components/chasm.dm
@@ -29,6 +29,7 @@
/obj/effect/wisp,
/obj/effect/ebeam,
/obj/effect/fishing_lure,
+ /obj/effect/constructing_effect,
))
/datum/component/chasm/Initialize(turf/target, mapload)
@@ -157,7 +158,7 @@
dropped_thing.visible_message(span_boldwarning("[dropped_thing] falls into [parent]!"), span_userdanger("[oblivion_message]"))
if (isliving(dropped_thing))
var/mob/living/falling_mob = dropped_thing
- falling_mob.notransform = TRUE
+ ADD_TRAIT(falling_mob, TRAIT_NO_TRANSFORM, REF(src))
falling_mob.Paralyze(20 SECONDS)
var/oldtransform = dropped_thing.transform
@@ -198,7 +199,7 @@
else if(isliving(dropped_thing))
var/mob/living/fallen_mob = dropped_thing
- fallen_mob.notransform = FALSE
+ REMOVE_TRAIT(fallen_mob, TRAIT_NO_TRANSFORM, REF(src))
if (fallen_mob.stat != DEAD)
fallen_mob.investigate_log("has died from falling into a chasm.", INVESTIGATE_DEATHS)
fallen_mob.death(TRUE)
@@ -235,13 +236,13 @@ GLOBAL_LIST_EMPTY(chasm_fallen_mobs)
/obj/effect/abstract/chasm_storage/Entered(atom/movable/arrived)
. = ..()
- if (isliving(arrived))
+ if(isliving(arrived))
RegisterSignal(arrived, COMSIG_LIVING_REVIVE, PROC_REF(on_revive))
GLOB.chasm_fallen_mobs += arrived
/obj/effect/abstract/chasm_storage/Exited(atom/movable/gone)
. = ..()
- if (isliving(gone))
+ if(isliving(gone))
UnregisterSignal(gone, COMSIG_LIVING_REVIVE)
GLOB.chasm_fallen_mobs -= gone
diff --git a/code/datums/components/crafting/crafting.dm b/code/datums/components/crafting/crafting.dm
index 056d81f9236..9f17b3d1d7e 100644
--- a/code/datums/components/crafting/crafting.dm
+++ b/code/datums/components/crafting/crafting.dm
@@ -178,36 +178,44 @@
return TRUE
-/datum/component/personal_crafting/proc/construct_item(atom/a, datum/crafting_recipe/R)
- var/list/contents = get_surroundings(a,R.blacklist)
+/datum/component/personal_crafting/proc/construct_item(atom/crafter, datum/crafting_recipe/recipe)
+ if(!crafter)
+ return ", unknown error!" // This should never happen, but in the event that it does...
+
+ if(!recipe)
+ return ", invalid recipe!" // This can happen, I can't really explain why, but it can. Better safe than sorry.
+
+ var/list/contents = get_surroundings(crafter, recipe.blacklist)
var/send_feedback = 1
- if(check_contents(a, R, contents))
- if(check_tools(a, R, contents))
- if(R.one_per_turf)
- for(var/content in get_turf(a))
- if(istype(content, R.result))
+ if(check_contents(crafter, recipe, contents))
+ if(check_tools(crafter, recipe, contents))
+ if(recipe.one_per_turf)
+ for(var/content in get_turf(crafter))
+ if(istype(content, recipe.result))
return ", object already present."
//If we're a mob we'll try a do_after; non mobs will instead instantly construct the item
- if(ismob(a) && !do_after(a, R.time, target = a))
+ if(ismob(crafter) && !do_after(crafter, recipe.time, target = crafter))
return "."
- contents = get_surroundings(a,R.blacklist)
- if(!check_contents(a, R, contents))
+ contents = get_surroundings(crafter, recipe.blacklist)
+ if(!check_contents(crafter, recipe, contents))
return ", missing component."
- if(!check_tools(a, R, contents))
+ if(!check_tools(crafter, recipe, contents))
return ", missing tool."
- var/list/parts = del_reqs(R, a)
- var/atom/movable/I
- if(ispath(R.result, /obj/item/stack))
- I = new R.result (get_turf(a.loc), R.result_amount || 1)
+ var/list/parts = del_reqs(recipe, crafter)
+ var/atom/movable/result
+ if(ispath(recipe.result, /obj/item/stack))
+ result = new recipe.result(get_turf(crafter.loc), recipe.result_amount || 1)
else
- I = new R.result (get_turf(a.loc))
- if(I.atom_storage && R.delete_contents)
- for(var/obj/item/thing in I)
+ result = new recipe.result(get_turf(crafter.loc))
+ if(result.atom_storage && recipe.delete_contents)
+ for(var/obj/item/thing in result)
qdel(thing)
- I.CheckParts(parts, R)
+ if (IsEdible(result))
+ result.reagents?.clear_reagents()
+ result.CheckParts(parts, recipe)
if(send_feedback)
- SSblackbox.record_feedback("tally", "object_crafted", 1, I.type)
- return I //Send the item back to whatever called this proc so it can handle whatever it wants to do with the new item
+ SSblackbox.record_feedback("tally", "object_crafted", 1, result.type)
+ return result //Send the item back to whatever called this proc so it can handle whatever it wants to do with the new item
return ", missing tool."
return ", missing component."
@@ -462,7 +470,7 @@
else
if(!istype(result, /obj/effect/spawner))
result.forceMove(user.drop_location())
- to_chat(user, span_notice("Constructed [crafting_recipe.name]."))
+ to_chat(user, span_notice("[crafting_recipe.name] crafted."))
user.investigate_log("crafted [crafting_recipe]", INVESTIGATE_CRAFTING)
crafting_recipe.on_craft_completion(user, result)
else
diff --git a/code/datums/components/crafting/furniture.dm b/code/datums/components/crafting/furniture.dm
index bdd7372f170..6cfe215a4b7 100644
--- a/code/datums/components/crafting/furniture.dm
+++ b/code/datums/components/crafting/furniture.dm
@@ -36,3 +36,14 @@
/obj/item/stack/sheet/mineral/silver = 2,
)
category = CAT_FURNITURE
+
+/datum/crafting_recipe/surgery_tray
+ name = "Surgery Tray"
+ reqs = list(
+ /obj/item/stack/sheet/mineral/silver = 1,
+ /obj/item/stack/rods = 2
+ )
+ result = /obj/item/surgery_tray
+ tool_behaviors = list(TOOL_SCREWDRIVER)
+ category = CAT_FURNITURE
+ time = 5 SECONDS
diff --git a/code/datums/components/crafting/ranged_weapon.dm b/code/datums/components/crafting/ranged_weapon.dm
index ac7b6eb39af..a8d631c6266 100644
--- a/code/datums/components/crafting/ranged_weapon.dm
+++ b/code/datums/components/crafting/ranged_weapon.dm
@@ -45,14 +45,12 @@
/datum/crafting_recipe/advancedegun
name = "Advanced Energy Gun"
- tool_behaviors = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
result = /obj/item/gun/energy/e_gun/nuclear
reqs = list(
/obj/item/gun/energy/e_gun = 1,
- /obj/item/stack/cable_coil = 5,
/obj/item/weaponcrafting/gunkit/nuclear = 1,
)
- time = 20 SECONDS
+ time = 10 SECONDS
category = CAT_WEAPON_RANGED
/datum/crafting_recipe/advancedegun/New()
@@ -61,14 +59,12 @@
/datum/crafting_recipe/tempgun
name = "Temperature Gun"
- tool_behaviors = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
result = /obj/item/gun/energy/temperature
reqs = list(
- /obj/item/gun/energy/e_gun = 1,
- /obj/item/stack/cable_coil = 5,
+ /obj/item/gun/energy/disabler = 1,
/obj/item/weaponcrafting/gunkit/temperature = 1,
)
- time = 20 SECONDS
+ time = 10 SECONDS
category = CAT_WEAPON_RANGED
/datum/crafting_recipe/tempgun/New()
@@ -77,16 +73,14 @@
/datum/crafting_recipe/beam_rifle
name = "Particle Acceleration Rifle"
- tool_behaviors = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
result = /obj/item/gun/energy/beam_rifle
reqs = list(
/obj/item/gun/energy/e_gun = 1,
/obj/item/assembly/signaler/anomaly/flux = 1,
/obj/item/assembly/signaler/anomaly/grav = 1,
- /obj/item/stack/cable_coil = 5,
/obj/item/weaponcrafting/gunkit/beam_rifle = 1,
)
- time = 20 SECONDS
+ time = 10 SECONDS
category = CAT_WEAPON_RANGED
/datum/crafting_recipe/beam_rifle/New()
@@ -95,27 +89,23 @@
/datum/crafting_recipe/ebow
name = "Energy Crossbow"
- tool_behaviors = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
result = /obj/item/gun/energy/recharge/ebow/large
reqs = list(
/obj/item/gun/energy/recharge/kinetic_accelerator = 1,
- /obj/item/stack/cable_coil = 5,
/obj/item/weaponcrafting/gunkit/ebow = 1,
/datum/reagent/uranium/radium = 15,
)
- time = 20 SECONDS
+ time = 10 SECONDS
category = CAT_WEAPON_RANGED
/datum/crafting_recipe/xraylaser
name = "X-ray Laser Gun"
- tool_behaviors = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
result = /obj/item/gun/energy/xray
reqs = list(
/obj/item/gun/energy/laser = 1,
- /obj/item/stack/cable_coil = 5,
/obj/item/weaponcrafting/gunkit/xray = 1,
)
- time = 20 SECONDS
+ time = 10 SECONDS
category = CAT_WEAPON_RANGED
/datum/crafting_recipe/xraylaser/New()
@@ -124,14 +114,12 @@
/datum/crafting_recipe/hellgun
name = "Hellfire Laser Gun"
- tool_behaviors = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
result = /obj/item/gun/energy/laser/hellgun
reqs = list(
/obj/item/gun/energy/laser = 1,
- /obj/item/stack/cable_coil = 5,
/obj/item/weaponcrafting/gunkit/hellgun = 1,
)
- time = 20 SECONDS
+ time = 10 SECONDS
category = CAT_WEAPON_RANGED
/datum/crafting_recipe/hellgun/New()
@@ -140,14 +128,12 @@
/datum/crafting_recipe/ioncarbine
name = "Ion Carbine"
- tool_behaviors = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
result = /obj/item/gun/energy/ionrifle/carbine
reqs = list(
/obj/item/gun/energy/laser = 1,
- /obj/item/stack/cable_coil = 5,
/obj/item/weaponcrafting/gunkit/ion = 1,
)
- time = 20 SECONDS
+ time = 10 SECONDS
category = CAT_WEAPON_RANGED
/datum/crafting_recipe/ioncarbine/New()
@@ -156,16 +142,14 @@
/datum/crafting_recipe/decloner
name = "Biological Demolecularisor"
- tool_behaviors = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
result = /obj/item/gun/energy/decloner
reqs = list(
/obj/item/gun/energy/laser = 1,
- /obj/item/stack/cable_coil = 5,
/obj/item/weaponcrafting/gunkit/decloner = 1,
/datum/reagent/baldium = 30,
/datum/reagent/toxin/mutagen = 4,
)
- time = 20 SECONDS
+ time = 10 SECONDS
category = CAT_WEAPON_RANGED
/datum/crafting_recipe/decloner/New()
@@ -174,14 +158,12 @@
/datum/crafting_recipe/teslacannon
name = "Tesla Cannon"
- tool_behaviors = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
result = /obj/item/gun/energy/tesla_cannon
reqs = list(
/obj/item/assembly/signaler/anomaly/flux = 1,
- /obj/item/stack/cable_coil = 5,
/obj/item/weaponcrafting/gunkit/tesla = 1,
)
- time = 20 SECONDS
+ time = 10 SECONDS
category = CAT_WEAPON_RANGED
/datum/crafting_recipe/improvised_pneumatic_cannon //Pretty easy to obtain but
diff --git a/code/datums/components/crafting/tailoring.dm b/code/datums/components/crafting/tailoring.dm
index 80c0d04534e..8cb6ac1459c 100644
--- a/code/datums/components/crafting/tailoring.dm
+++ b/code/datums/components/crafting/tailoring.dm
@@ -284,6 +284,46 @@
)
category = CAT_CLOTHING
+/datum/crafting_recipe/poppy_crown
+ name = "Poppy Crown"
+ result = /obj/item/clothing/head/costume/garland/poppy
+ time = 1 SECONDS
+ reqs = list(
+ /obj/item/food/grown/poppy = 5,
+ /obj/item/stack/cable_coil = 3,
+ )
+ category = CAT_CLOTHING
+
+/datum/crafting_recipe/lily_crown
+ name = "Lily Crown"
+ result = /obj/item/clothing/head/costume/garland/lily
+ time = 1 SECONDS
+ reqs = list(
+ /obj/item/food/grown/poppy/lily = 5,
+ /obj/item/stack/cable_coil = 3,
+ )
+ category = CAT_CLOTHING
+
+/datum/crafting_recipe/sunflower_crown
+ name = "Sunflower Crown"
+ result = /obj/item/clothing/head/costume/garland/sunflower
+ time = 1 SECONDS
+ reqs = list(
+ /obj/item/food/grown/sunflower = 5,
+ /obj/item/stack/cable_coil = 3,
+ )
+ category = CAT_CLOTHING
+
+/datum/crafting_recipe/rainbow_bunch_crown
+ name = "Rainbow Flower Crown"
+ result = /obj/item/clothing/head/costume/garland/rainbowbunch
+ time = 1 SECONDS
+ reqs = list(
+ /obj/item/food/grown/rainbow_flower = 5,
+ /obj/item/stack/cable_coil = 3,
+ )
+ category = CAT_CLOTHING
+
/datum/crafting_recipe/pillow_suit
name = "pillow suit"
result = /obj/item/clothing/suit/pillow_suit
@@ -317,7 +357,7 @@
)
category = CAT_CLOTHING
-
+
/datum/crafting_recipe/atmospherics_gas_mask
name = "atmospherics gas mask"
result = /obj/item/clothing/mask/gas/atmos
@@ -327,7 +367,7 @@
/obj/item/stack/sheet/mineral/metal_hydrogen = 1,
/obj/item/stack/sheet/mineral/zaukerite = 1,
)
-
+
category = CAT_CLOTHING
/datum/crafting_recipe/paper_hat
diff --git a/code/datums/components/crafting/weapon_ammo.dm b/code/datums/components/crafting/weapon_ammo.dm
index fd6993220ec..206adbaefb1 100644
--- a/code/datums/components/crafting/weapon_ammo.dm
+++ b/code/datums/components/crafting/weapon_ammo.dm
@@ -65,6 +65,7 @@
reqs = list(
/obj/item/stack/sheet/iron = 2,
/obj/item/stack/cable_coil = 1,
+ /obj/item/shard = 1,
/datum/reagent/fuel = 10,
)
tool_behaviors = list(TOOL_SCREWDRIVER)
diff --git a/code/datums/components/customizable_reagent_holder.dm b/code/datums/components/customizable_reagent_holder.dm
index 79ebf651d3f..36c84fc94af 100644
--- a/code/datums/components/customizable_reagent_holder.dm
+++ b/code/datums/components/customizable_reagent_holder.dm
@@ -2,7 +2,7 @@
* # Custom Atom Component
*
* When added to an atom, item ingredients can be put into that.
- * The sprite is updated and reagents are transfered.
+ * The sprite is updated and reagents are transferred.
*
* If the component is added to something that is processed, creating new objects (being cut, for example),
* the replacement type needs to also have the component. The ingredients will be copied over. Reagents are not
diff --git a/code/datums/components/embedded.dm b/code/datums/components/embedded.dm
index 8abb32e0e53..f4d7b5d7369 100644
--- a/code/datums/components/embedded.dm
+++ b/code/datums/components/embedded.dm
@@ -93,7 +93,8 @@
if(harmful)
victim.throw_alert(ALERT_EMBEDDED_OBJECT, /atom/movable/screen/alert/embeddedobject)
playsound(victim,'sound/weapons/bladeslice.ogg', 40)
- weapon.add_mob_blood(victim)//it embedded itself in you, of course it's bloody!
+ if (limb.can_bleed())
+ weapon.add_mob_blood(victim)//it embedded itself in you, of course it's bloody!
damage += weapon.w_class * impact_pain_mult
victim.add_mood_event("embedded", /datum/mood_event/embedded)
@@ -206,14 +207,18 @@
qdel(src)
return
if(harmful)
- var/damage = weapon.w_class * remove_pain_mult
- limb.receive_damage(brute=(1-pain_stam_pct) * damage, sharpness=SHARP_EDGED) //It hurts to rip it out, get surgery you dingus. unlike the others, this CAN wound + increase slash bloodflow
- victim.adjustStaminaLoss(pain_stam_pct * damage)
- victim.emote("scream")
+ damaging_removal(victim, I, limb)
victim.visible_message(span_notice("[victim] successfully rips [weapon] [harmful ? "out" : "off"] of [victim.p_their()] [limb.plaintext_zone]!"), span_notice("You successfully remove [weapon] from your [limb.plaintext_zone]."))
safeRemove(victim)
+/// Proc that actually does the damage associated with ripping something out of yourself. Call this before safeRemove.
+/datum/component/embedded/proc/damaging_removal(mob/living/carbon/victim, obj/item/removed, obj/item/bodypart/limb, ouch_multiplier = 1)
+ var/damage = weapon.w_class * remove_pain_mult * ouch_multiplier
+ limb.receive_damage(brute=(1-pain_stam_pct) * damage, sharpness=SHARP_EDGED) //It hurts to rip it out, get surgery you dingus. unlike the others, this CAN wound + increase slash bloodflow
+ victim.adjustStaminaLoss(pain_stam_pct * damage)
+ victim.emote("scream")
+
/// This proc handles the final step and actual removal of an embedded/stuck item from a carbon, whether or not it was actually removed safely.
/// If you want the thing to go into someone's hands rather than the floor, pass them in to_hands
/datum/component/embedded/proc/safeRemove(mob/to_hands)
@@ -248,7 +253,7 @@
/datum/component/embedded/proc/checkTweeze(mob/living/carbon/victim, obj/item/possible_tweezers, mob/user)
SIGNAL_HANDLER
- if(!istype(victim) || possible_tweezers.tool_behaviour != TOOL_HEMOSTAT || user.zone_selected != limb.body_zone)
+ if(!istype(victim) || (possible_tweezers.tool_behaviour != TOOL_HEMOSTAT && possible_tweezers.tool_behaviour != TOOL_WIRECUTTER) || user.zone_selected != limb.body_zone)
return
if(weapon != limb.embedded_objects[1]) // just pluck the first one, since we can't easily coordinate with other embedded components affecting this limb who is highest priority
@@ -265,18 +270,21 @@
/// The actual action for pulling out an embedded object with a hemostat
/datum/component/embedded/proc/tweezePluck(obj/item/possible_tweezers, mob/user)
var/mob/living/carbon/victim = parent
-
var/self_pluck = (user == victim)
+ // quality of the tool we're using
+ var/tweezer_speed = possible_tweezers.toolspeed
+ // is this an actual piece of medical equipment
+ var/tweezer_safe = (possible_tweezers.tool_behaviour == TOOL_HEMOSTAT)
+ var/pluck_time = rip_time * (weapon.w_class * 0.3) * (self_pluck ? 1.5 : 1) * tweezer_speed * (tweezer_safe ? 1 : 1.5)
if(self_pluck)
- user.visible_message(span_danger("[user] begins plucking [weapon] from [user.p_their()] [limb.plaintext_zone]"), span_notice("You start plucking [weapon] from your [limb.plaintext_zone]..."),\
+ user.visible_message(span_danger("[user] begins plucking [weapon] from [user.p_their()] [limb.plaintext_zone] with [possible_tweezers]..."), span_notice("You start plucking [weapon] from your [limb.plaintext_zone] with [possible_tweezers]... (It will take [DisplayTimeText(pluck_time)].)"),\
vision_distance=COMBAT_MESSAGE_RANGE, ignored_mobs=victim)
else
- user.visible_message(span_danger("[user] begins plucking [weapon] from [victim]'s [limb.plaintext_zone]"),span_notice("You start plucking [weapon] from [victim]'s [limb.plaintext_zone]..."), \
+ user.visible_message(span_danger("[user] begins plucking [weapon] from [victim]'s [limb.plaintext_zone] with [possible_tweezers]..."),span_notice("You start plucking [weapon] from [victim]'s [limb.plaintext_zone] with [possible_tweezers]... (It will take [DisplayTimeText(pluck_time)]."), \
vision_distance=COMBAT_MESSAGE_RANGE, ignored_mobs=victim)
- to_chat(victim, span_userdanger("[user] begins plucking [weapon] from your [limb.plaintext_zone]..."))
+ to_chat(victim, span_userdanger("[user] begins plucking [weapon] from your [limb.plaintext_zone] with [possible_tweezers]... (It will take [DisplayTimeText(pluck_time)]."))
- var/pluck_time = 2.5 SECONDS * weapon.w_class * (self_pluck ? 2 : 1)
if(!do_after(user, pluck_time, victim))
if(self_pluck)
to_chat(user, span_danger("You fail to pluck [weapon] from your [limb.plaintext_zone]."))
@@ -285,8 +293,11 @@
to_chat(victim, span_danger("[user] fails to pluck [weapon] from your [limb.plaintext_zone]."))
return
- to_chat(user, span_notice("You successfully pluck [weapon] from [victim]'s [limb.plaintext_zone]."))
- to_chat(victim, span_notice("[user] plucks [weapon] from your [limb.plaintext_zone]."))
+ to_chat(user, span_notice("You successfully pluck [weapon] from [victim]'s [limb.plaintext_zone][tweezer_safe ? "." : ", but hurt [victim.p_them()] in the process."]"))
+ to_chat(victim, span_notice("[user] plucks [weapon] from your [limb.plaintext_zone][tweezer_safe ? "." : ", but it's not perfect."]"))
+ if(!tweezer_safe)
+ // sure it still hurts but it sucks less
+ damaging_removal(victim, weapon, limb, (0.4 * possible_tweezers.w_class))
safeRemove(user)
/// Called when an object is ripped out of someone's body by magic or other abnormal means
@@ -303,7 +314,7 @@
return
var/damage = weapon.w_class * remove_pain_mult
limb.receive_damage(brute=(1-pain_stam_pct) * damage * 1.5, sharpness=SHARP_EDGED) // Performs exit wounds and flings the user to the caster if nearby
- limb.force_wound_upwards(/datum/wound/pierce/moderate)
+ victim.cause_wound_of_type_and_severity(WOUND_PIERCE, limb, WOUND_SEVERITY_MODERATE)
victim.adjustStaminaLoss(pain_stam_pct * damage)
playsound(get_turf(victim), 'sound/effects/wounds/blood2.ogg', 50, TRUE)
diff --git a/code/datums/components/food/edible.dm b/code/datums/components/food/edible.dm
index 9a2ad6973f8..7c86ddc2243 100644
--- a/code/datums/components/food/edible.dm
+++ b/code/datums/components/food/edible.dm
@@ -46,7 +46,7 @@ Behavior that's still missing from this component that original food items had t
food_flags = NONE,
foodtypes = NONE,
volume = 50,
- eat_time = 10,
+ eat_time = 1 SECONDS,
list/tastes,
list/eatverbs = list("bite", "chew", "nibble", "gnaw", "gobble", "chomp"),
bite_consumption = 2,
@@ -54,6 +54,7 @@ Behavior that's still missing from this component that original food items had t
datum/callback/after_eat,
datum/callback/on_consume,
datum/callback/check_liked,
+ reagent_purity = 0.5,
)
if(!isatom(parent))
return COMPONENT_INCOMPATIBLE
@@ -70,7 +71,7 @@ Behavior that's still missing from this component that original food items had t
src.tastes = string_assoc_list(tastes)
src.check_liked = check_liked
- setup_initial_reagents(initial_reagents)
+ setup_initial_reagents(initial_reagents, reagent_purity)
/datum/component/edible/RegisterWithParent()
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(examine))
@@ -193,7 +194,7 @@ Behavior that's still missing from this component that original food items had t
return ..()
/// Sets up the initial reagents of the food.
-/datum/component/edible/proc/setup_initial_reagents(list/reagents)
+/datum/component/edible/proc/setup_initial_reagents(list/reagents, reagent_purity)
var/atom/owner = parent
if(owner.reagents)
owner.reagents.maximum_volume = volume
@@ -203,31 +204,63 @@ Behavior that's still missing from this component that original food items had t
for(var/rid in reagents)
var/amount = reagents[rid]
if(length(tastes) && (rid == /datum/reagent/consumable/nutriment || rid == /datum/reagent/consumable/nutriment/vitamin))
- owner.reagents.add_reagent(rid, amount, tastes.Copy())
+ owner.reagents.add_reagent(rid, amount, tastes.Copy(), added_purity = reagent_purity)
else
- owner.reagents.add_reagent(rid, amount)
+ owner.reagents.add_reagent(rid, amount, added_purity = reagent_purity)
/datum/component/edible/proc/examine(datum/source, mob/user, list/examine_list)
SIGNAL_HANDLER
+ var/atom/owner = parent
+
if(foodtypes)
var/list/types = bitfield_to_list(foodtypes, FOOD_FLAGS)
examine_list += span_notice("It is [lowertext(english_list(types))].")
+ var/quality = get_perceived_food_quality(user)
+ if(quality > 0)
+ var/quality_label = GLOB.food_quality_description[quality]
+ examine_list += span_green("You find this meal [quality_label].")
+ else if (quality == 0)
+ examine_list += span_notice("You find this meal edible.")
+ else if (quality <= TOXIC_FOOD_QUALITY_THRESHOLD)
+ examine_list += span_warning("You find this meal disgusting!")
+ else
+ examine_list += span_warning("You find this meal inedible.")
+
+ if(owner.reagents.total_volume > 0)
+ var/purity = owner.reagents.get_average_purity(/datum/reagent/consumable)
+ switch(purity)
+ if(0 to 0.2)
+ examine_list += span_warning("It is made of terrible ingredients shortening the effect...")
+ if(0.2 to 0.4)
+ examine_list += span_warning("It is made of synthetic ingredients shortening the effect.")
+ if(0.4 to 0.6)
+ examine_list += span_notice("It is made of average quality ingredients.")
+ if(0.6 to 0.8)
+ examine_list += span_green("It is made of organic ingredients prolonging the effect.")
+ if(0.8 to 1)
+ examine_list += span_green("It is made of finest ingredients prolonging the effect!")
+
var/datum/mind/mind = user.mind
- if(mind && HAS_TRAIT_FROM(parent, TRAIT_FOOD_CHEF_MADE, REF(mind)))
- examine_list += span_green("[parent] was made by you!")
+ if(mind && HAS_TRAIT_FROM(owner, TRAIT_FOOD_CHEF_MADE, REF(mind)))
+ examine_list += span_green("[owner] was made by you!")
if(!(food_flags & FOOD_IN_CONTAINER))
switch(bitecount)
if(0)
// pass
if(1)
- examine_list += span_notice("[parent] was bitten by someone!")
+ examine_list += span_notice("[owner] was bitten by someone!")
if(2, 3)
- examine_list += span_notice("[parent] was bitten [bitecount] times!")
+ examine_list += span_notice("[owner] was bitten [bitecount] times!")
else
- examine_list += span_notice("[parent] was bitten multiple times!")
+ examine_list += span_notice("[owner] was bitten multiple times!")
+
+ if(GLOB.Debug2)
+ examine_list += span_notice("Reagent purities:")
+ for(var/datum/reagent/reagent as anything in owner.reagents.reagent_list)
+ examine_list += span_notice("- [reagent.name] [reagent.volume]u: [round(reagent.purity * 100)]% pure")
/datum/component/edible/proc/UseFromHand(obj/item/source, mob/living/M, mob/living/user)
SIGNAL_HANDLER
@@ -267,15 +300,11 @@ Behavior that's still missing from this component that original food items had t
var/atom/this_food = parent
- this_food.reagents.multiply_reagents(CRAFTED_FOOD_BASE_REAGENT_MODIFIER)
- this_food.reagents.maximum_volume *= CRAFTED_FOOD_BASE_REAGENT_MODIFIER
-
for(var/obj/item/food/crafted_part in parts_list)
if(!crafted_part.reagents)
continue
-
- this_food.reagents.maximum_volume += crafted_part.reagents.maximum_volume * CRAFTED_FOOD_INGREDIENT_REAGENT_MODIFIER
- crafted_part.reagents.trans_to(this_food.reagents, crafted_part.reagents.maximum_volume, CRAFTED_FOOD_INGREDIENT_REAGENT_MODIFIER)
+ this_food.reagents.maximum_volume += crafted_part.reagents.maximum_volume
+ crafted_part.reagents.trans_to(this_food.reagents, crafted_part.reagents.maximum_volume)
this_food.reagents.maximum_volume = ROUND_UP(this_food.reagents.maximum_volume) // Just because I like whole numbers for this.
@@ -323,7 +352,7 @@ Behavior that's still missing from this component that original food items had t
time_to_eat *= (fullness / NUTRITION_LEVEL_FAT) * EAT_TIME_VORACIOUS_FULL_MULT // takes longer to eat the more well fed you are
if(eater == feeder)//If you're eating it yourself.
- if(eat_time && !do_after(feeder, time_to_eat, eater, timed_action_flags = food_flags & FOOD_FINGER_FOOD ? IGNORE_USER_LOC_CHANGE | IGNORE_TARGET_LOC_CHANGE : NONE)) //Gotta pass the minimal eat time
+ if(eat_time > 0 && !do_after(feeder, time_to_eat, eater, timed_action_flags = food_flags & FOOD_FINGER_FOOD ? IGNORE_USER_LOC_CHANGE | IGNORE_TARGET_LOC_CHANGE : NONE)) //Gotta pass the minimal eat time
return
if(IsFoodGone(owner, feeder))
return
@@ -404,7 +433,7 @@ Behavior that's still missing from this component that original food items had t
TakeBite(eater, feeder)
//If we're not force-feeding and there's an eat delay, try take another bite
- if(eater == feeder && eat_time)
+ if(eater == feeder && eat_time > 0)
INVOKE_ASYNC(src, PROC_REF(TryToEat), eater, feeder)
#undef EAT_TIME_FORCE_FEED
@@ -428,10 +457,17 @@ Behavior that's still missing from this component that original food items had t
if(sig_return & DESTROY_FOOD)
qdel(owner)
return
+
+ //Give a buff when the dish is hand-crafted and unbitten
+ if(bitecount == 0)
+ apply_buff(eater)
+
var/fraction = min(bite_consumption / owner.reagents.total_volume, 1)
- owner.reagents.trans_to(eater, bite_consumption, transfered_by = feeder, methods = INGEST)
+ owner.reagents.trans_to(eater, bite_consumption, transferred_by = feeder, methods = INGEST)
bitecount++
+
checkLiked(fraction, eater)
+
if(!owner.reagents.total_volume)
On_Consume(eater, feeder)
@@ -465,6 +501,24 @@ Behavior that's still missing from this component that original food items had t
return
return TRUE
+///Applies food buffs according to the crafting complexity
+/datum/component/edible/proc/apply_buff(mob/eater)
+ var/buff
+ var/recipe_complexity = get_recipe_complexity()
+ if(recipe_complexity == 0)
+ return
+ var/obj/item/food/food = parent
+ if(!isnull(food.crafted_food_buff))
+ buff = food.crafted_food_buff
+ else
+ buff = pick_weight(GLOB.food_buffs[recipe_complexity])
+ if(!isnull(buff))
+ var/mob/living/living_eater = eater
+ var/atom/owner = parent
+ var/timeout_mod = owner.reagents.get_average_purity(/datum/reagent/consumable) * 2 // buff duration is 100% at average purity of 50%
+ var/strength = recipe_complexity
+ living_eater.apply_status_effect(buff, timeout_mod, strength)
+
///Check foodtypes to see if we should send a moodlet
/datum/component/edible/proc/checkLiked(fraction, mob/eater)
if(last_check_time + 50 > world.time)
@@ -477,26 +531,75 @@ Behavior that's still missing from this component that original food items had t
gourmand.add_mood_event("breakfast", /datum/mood_event/breakfast)
last_check_time = world.time
- var/food_taste_reaction
+ var/food_quality = get_perceived_food_quality(gourmand, parent)
+ if(food_quality <= TOXIC_FOOD_QUALITY_THRESHOLD)
+ to_chat(gourmand,span_warning("What the hell was that thing?!"))
+ gourmand.adjust_disgust(25 + 30 * fraction)
+ gourmand.add_mood_event("toxic_food", /datum/mood_event/disgusting_food)
+ else if(food_quality < 0)
+ to_chat(gourmand,span_notice("That didn't taste very good..."))
+ gourmand.adjust_disgust(11 + 15 * fraction)
+ gourmand.add_mood_event("gross_food", /datum/mood_event/gross_food)
+ else if(food_quality > 0)
+ food_quality = min(food_quality, FOOD_QUALITY_TOP)
+ var/atom/owner = parent
+ var/timeout_mod = owner.reagents.get_average_purity(/datum/reagent/consumable) * 2 // mood event duration is 100% at average purity of 50%
+ var/event = GLOB.food_quality_events[food_quality]
+ gourmand.add_mood_event("quality_food", event, timeout_mod)
+ gourmand.adjust_disgust(-5 + -2 * food_quality * fraction)
+ var/quality_label = GLOB.food_quality_description[food_quality]
+ to_chat(gourmand, span_notice("That's \an [quality_label] meal."))
+
+ if(istype(parent, /obj/item/food))
+ var/obj/item/food/food = parent
+ if(food.venue_value >= FOOD_PRICE_EXOTIC)
+ gourmand.add_mob_memory(/datum/memory/good_food, food = parent)
+
+/// Get the complexity of the crafted food
+/datum/component/edible/proc/get_recipe_complexity()
+ if(!HAS_TRAIT(parent, TRAIT_FOOD_CHEF_MADE) || !istype(parent, /obj/item/food))
+ return 0 // It is factory made. Soulless.
+ var/obj/item/food/food = parent
+ return food.crafting_complexity
+
+/// Get food quality adjusted according to eater's preferences
+/datum/component/edible/proc/get_perceived_food_quality(mob/living/carbon/human/eater)
+ var/food_quality = get_recipe_complexity()
+
+ if(HAS_TRAIT(parent, TRAIT_FOOD_SILVER)) // it's not real food
+ if(!isjellyperson(eater)) //if you aren't a jellyperson, it makes you sick no matter how nice it looks
+ return TOXIC_FOOD_QUALITY_THRESHOLD
+ food_quality += LIKED_FOOD_QUALITY_CHANGE
+
if(check_liked) //Callback handling; use this as an override for special food like donuts
- food_taste_reaction = check_liked.Invoke(fraction, gourmand)
+ var/special_reaction = check_liked.Invoke(eater)
+ switch(special_reaction) //return early for special foods
+ if(FOOD_LIKED)
+ return LIKED_FOOD_QUALITY_CHANGE
+ if(FOOD_DISLIKED)
+ return DISLIKED_FOOD_QUALITY_CHANGE
+ if(FOOD_TOXIC)
+ return TOXIC_FOOD_QUALITY_THRESHOLD
- if(!food_taste_reaction)
- food_taste_reaction = gourmand.get_food_taste_reaction(parent, foodtypes)
+ if(ishuman(eater))
+ if(count_matching_foodtypes(foodtypes, eater.get_toxic_foodtypes())) //if the food is toxic, we don't care about anything else
+ return TOXIC_FOOD_QUALITY_THRESHOLD
+ if(HAS_TRAIT(eater, TRAIT_AGEUSIA)) //if you can't taste it, it doesn't taste good
+ return 0
+ food_quality += DISLIKED_FOOD_QUALITY_CHANGE * count_matching_foodtypes(foodtypes, eater.get_disliked_foodtypes())
+ food_quality += LIKED_FOOD_QUALITY_CHANGE * count_matching_foodtypes(foodtypes, eater.get_liked_foodtypes())
- switch(food_taste_reaction)
- if(FOOD_TOXIC)
- to_chat(gourmand,span_warning("What the hell was that thing?!"))
- gourmand.adjust_disgust(25 + 30 * fraction)
- gourmand.add_mood_event("toxic_food", /datum/mood_event/disgusting_food)
- if(FOOD_DISLIKED)
- to_chat(gourmand,span_notice("That didn't taste very good..."))
- gourmand.adjust_disgust(11 + 15 * fraction)
- gourmand.add_mood_event("gross_food", /datum/mood_event/gross_food)
- if(FOOD_LIKED)
- to_chat(gourmand,span_notice("I love this taste!"))
- gourmand.adjust_disgust(-5 + -2.5 * fraction)
- gourmand.add_mood_event("fav_food", /datum/mood_event/favorite_food)
+ return food_quality
+
+/// Get the number of matching food types in provided bitfields
+/datum/component/edible/proc/count_matching_foodtypes(bitfield_one, bitfield_two)
+ var/count = 0
+ var/matching_bits = bitfield_one & bitfield_two
+ while (matching_bits > 0)
+ if (matching_bits & 1)
+ count++
+ matching_bits >>= 1
+ return count
///Delete the item when it is fully eaten
/datum/component/edible/proc/On_Consume(mob/living/eater, mob/living/feeder)
@@ -556,7 +659,7 @@ Behavior that's still missing from this component that original food items had t
if(foodtypes & edible_flags)
var/atom/eaten_food = parent
- eaten_food.reagents.trans_to(eater, eaten_food.reagents.total_volume, transfered_by = eater)
+ eaten_food.reagents.trans_to(eater, eaten_food.reagents.total_volume, transferred_by = eater)
eater.visible_message(span_warning("[src] eats [eaten_food]!"), span_notice("You eat [eaten_food]."))
playsound(get_turf(eater),'sound/items/eatfood.ogg', rand(30,50), TRUE)
qdel(eaten_food)
diff --git a/code/datums/components/food/ghost_edible.dm b/code/datums/components/food/ghost_edible.dm
new file mode 100644
index 00000000000..25207800a74
--- /dev/null
+++ b/code/datums/components/food/ghost_edible.dm
@@ -0,0 +1,59 @@
+/**
+ * Allows ghosts to eat this by orbiting it
+ * They do this by consuming the reagents in the object, so if it doesn't have any then it won't work
+ */
+/datum/component/ghost_edible
+ /// Amount of reagents which will be consumed by each bite
+ var/bite_consumption
+ /// Chance per ghost that a bite will be taken
+ var/bite_chance
+ /// Minimum size the food will display as before being deleted
+ var/minimum_scale
+ /// How many reagents this had on initialisation, used to figure out how eaten we are
+ var/initial_reagent_volume = 0
+
+/datum/component/ghost_edible/Initialize(bite_consumption = 3, bite_chance = 20, minimum_scale = 0.6)
+ . = ..()
+ if (!isatom(parent))
+ return COMPONENT_INCOMPATIBLE
+ var/atom/atom_parent = parent
+ if (isnull(atom_parent.reagents) || atom_parent.reagents.total_volume == 0)
+ return COMPONENT_INCOMPATIBLE
+ src.bite_consumption = bite_consumption
+ src.bite_chance = bite_chance
+ src.minimum_scale = minimum_scale
+ initial_reagent_volume = atom_parent.reagents.total_volume
+ notify_ghosts("[parent] is edible by ghosts!", source = parent, action = NOTIFY_ORBIT, header="Something Tasty!")
+
+/datum/component/ghost_edible/RegisterWithParent()
+ START_PROCESSING(SSdcs, src)
+
+/datum/component/ghost_edible/UnregisterFromParent()
+ STOP_PROCESSING(SSdcs, src)
+
+/datum/component/ghost_edible/Destroy(force, silent)
+ STOP_PROCESSING(SSdcs, src)
+ return ..()
+
+/datum/component/ghost_edible/process(seconds_per_tick)
+ var/atom/atom_parent = parent
+ // Ghosts can eat this burger
+ var/munch_chance = 0
+ for(var/mob/dead/observer/ghost in atom_parent.orbiters?.orbiter_list)
+ munch_chance += bite_chance
+ if (munch_chance >= 100)
+ break
+ if (!prob(munch_chance))
+ return
+ playsound(atom_parent.loc,'sound/items/eatfood.ogg', vol = rand(10,50), vary = TRUE)
+ atom_parent.reagents.remove_any(bite_consumption)
+ if (atom_parent.reagents.total_volume <= 0)
+ atom_parent.visible_message(span_notice("[atom_parent] disappears completely!"))
+ new /obj/item/ectoplasm(atom_parent.loc)
+ qdel(parent)
+ return
+
+ var/final_transform = matrix().Scale(LERP(minimum_scale, 1, atom_parent.reagents.total_volume / initial_reagent_volume))
+ var/animate_transform = matrix(final_transform).Scale(0.8)
+ animate(parent, transform = animate_transform, time = 0.1 SECONDS)
+ animate(transform = final_transform, time = 0.1 SECONDS)
diff --git a/code/datums/components/food/golem_food.dm b/code/datums/components/food/golem_food.dm
index 79ac0a3e604..c2540f54cc1 100644
--- a/code/datums/components/food/golem_food.dm
+++ b/code/datums/components/food/golem_food.dm
@@ -46,18 +46,22 @@
if (!snack_type.can_consume(target))
source.balloon_alert(user, "can't consume!")
return COMPONENT_CANCEL_ATTACK_CHAIN
- if (!golem_snack)
- golem_snack = new(
- /* loc = */ null,
- /* name = */ source.name,
- /* consume_food = */ consume_on_eat,
- /* food_buff = */ snack_type,
- /* owner = */ parent,
- )
- RegisterSignal(golem_snack, COMSIG_QDELETING, PROC_REF(on_food_destroyed))
+ if (isnull(golem_snack))
+ create_golem_snack(source)
golem_snack.attack(target, user, click_parameters)
return COMPONENT_CANCEL_ATTACK_CHAIN
+/// Creates our golem snack atom instance
+/datum/component/golem_food/proc/create_golem_snack(atom/source)
+ golem_snack = new(null)
+ golem_snack.setup(
+ name = source.name,
+ consume_food = consume_on_eat,
+ food_buff = snack_type,
+ owner = parent,
+ )
+ RegisterSignal(golem_snack, COMSIG_QDELETING, PROC_REF(on_food_destroyed))
+
/// Reference handling for abstract food object
/datum/component/golem_food/proc/on_food_destroyed()
SIGNAL_HANDLER
@@ -84,13 +88,17 @@
/// Golem food buff to apply on consumption
var/datum/golem_food_buff/food_buff
-/obj/item/food/golem_food/Initialize(mapload, name, consume_food, datum/golem_food_buff/food_buff, atom/owner)
- . = ..()
+/// Set up some properties based on a passed-in item that the golem will pretend to eat
+/obj/item/food/golem_food/proc/setup(
+ name,
+ consume_food = TRUE,
+ datum/golem_food_buff/food_buff,
+ atom/owner,
+)
src.name = name
src.consume_food = consume_food
src.food_buff = food_buff
src.owner = owner
-
RegisterSignal(owner, COMSIG_QDELETING, PROC_REF(on_parent_destroyed))
/// Clean ourselves up if our parent dies
diff --git a/code/datums/components/gags_recolorable.dm b/code/datums/components/gags_recolorable.dm
deleted file mode 100644
index 96dceaf95d8..00000000000
--- a/code/datums/components/gags_recolorable.dm
+++ /dev/null
@@ -1,64 +0,0 @@
-/datum/component/gags_recolorable
-
-/datum/component/gags_recolorable/RegisterWithParent()
- RegisterSignal(parent, COMSIG_ATOM_ATTACKBY, PROC_REF(on_attackby))
-
-/datum/component/gags_recolorable/UnregisterFromParent()
- UnregisterSignal(parent, COMSIG_ATOM_ATTACKBY)
-
-/datum/component/gags_recolorable/proc/on_attackby(datum/source, obj/item/attacking_item, mob/user)
- SIGNAL_HANDLER
-
- if(!isatom(parent))
- return
-
- if(!istype(attacking_item, /obj/item/toy/crayon/spraycan))
- return
- var/obj/item/toy/crayon/spraycan/can = attacking_item
-
- if(can.is_capped || can.check_empty())
- return
-
- INVOKE_ASYNC(src, PROC_REF(open_ui), user, can)
- return COMPONENT_NO_AFTERATTACK
-
-/datum/component/gags_recolorable/proc/open_ui(mob/user, obj/item/toy/crayon/spraycan/can)
- var/atom/atom_parent = parent
- var/list/allowed_configs = list()
- var/config = initial(atom_parent.greyscale_config)
- if(!config)
- return
- allowed_configs += "[config]"
- if(ispath(atom_parent, /obj/item))
- var/obj/item/item = atom_parent
- if(initial(item.greyscale_config_worn))
- allowed_configs += "[initial(item.greyscale_config_worn)]"
- if(initial(item.greyscale_config_inhand_left))
- allowed_configs += "[initial(item.greyscale_config_inhand_left)]"
- if(initial(item.greyscale_config_inhand_right))
- allowed_configs += "[initial(item.greyscale_config_inhand_right)]"
-
- var/datum/greyscale_modify_menu/spray_paint/menu = new(
- atom_parent, user, allowed_configs, CALLBACK(src, PROC_REF(recolor), user, can),
- starting_icon_state = initial(atom_parent.icon_state),
- starting_config = initial(atom_parent.greyscale_config),
- starting_colors = atom_parent.greyscale_colors,
- used_spraycan = can
- )
- menu.ui_interact(user)
-
-/datum/component/gags_recolorable/proc/recolor(mob/user, obj/item/toy/crayon/spraycan/can, datum/greyscale_modify_menu/menu)
- if(!isatom(parent))
- return
- var/atom/atom_parent = parent
-
- if(can.is_capped || can.check_empty(user))
- menu.ui_close()
- return
-
- can.use_charges()
- if(can.pre_noise)
- atom_parent.audible_message(span_hear("You hear spraying."))
- playsound(atom_parent.loc, 'sound/effects/spray.ogg', 5, TRUE, 5)
-
- atom_parent.set_greyscale(menu.split_colors)
diff --git a/code/datums/components/grillable.dm b/code/datums/components/grillable.dm
index bd9ab66fb31..f1fe80fe9fb 100644
--- a/code/datums/components/grillable.dm
+++ b/code/datums/components/grillable.dm
@@ -108,8 +108,10 @@
if(original_object.custom_materials)
grilled_result.set_custom_materials(original_object.custom_materials)
- if(IS_EDIBLE(grilled_result))
+ if(IsEdible(grilled_result))
BLACKBOX_LOG_FOOD_MADE(grilled_result.type)
+ grilled_result.reagents.clear_reagents()
+ original_object.reagents?.trans_to(grilled_result, original_object.reagents.total_volume)
SEND_SIGNAL(parent, COMSIG_ITEM_GRILLED, grilled_result)
if(who_placed_us)
@@ -138,7 +140,7 @@
else if(current_cook_time <= required_cook_time)
examine_list += span_notice("[parent] seems to be almost finished cooking!")
else
- examine_list += span_danger("[parent] should probably not be cooked for much longer!")
+ examine_list += span_danger("[parent] should probably not be put on the grill.")
///Ran when an object moves from the grill
/datum/component/grillable/proc/on_moved(atom/source, atom/OldLoc, Dir, Forced)
diff --git a/code/datums/components/itembound.dm b/code/datums/components/itembound.dm
index ae29949961b..f742c1233fd 100644
--- a/code/datums/components/itembound.dm
+++ b/code/datums/components/itembound.dm
@@ -11,19 +11,39 @@
if(QDELETED(passed_container))
return
containerref = WEAKREF(passed_container)
+ RegisterSignal(passed_container, COMSIG_ATOM_EXAMINE_MORE, PROC_REF(on_examined))
move_tracker = new(parent, CALLBACK(src, PROC_REF(verify_containment)))
+
+/datum/component/itembound/RegisterWithParent()
+ . = ..()
ADD_TRAIT(parent, TRAIT_INCAPACITATED, SMITE_TRAIT)
+ if (isliving(parent))
+ var/mob/living/living_parent = parent
+ living_parent.apply_status_effect(/datum/status_effect/grouped/stasis, STASIS_ADMIN)
+
+/datum/component/itembound/UnregisterFromParent()
+ REMOVE_TRAIT(parent, TRAIT_INCAPACITATED, SMITE_TRAIT)
+ if (isliving(parent))
+ var/mob/living/living_parent = parent
+ living_parent.remove_status_effect(/datum/status_effect/grouped/stasis, STASIS_ADMIN)
+ return ..()
+
+/datum/component/itembound/proc/on_examined(atom/source, mob/user, list/examine_list)
+ SIGNAL_HANDLER
+ examine_list += span_notice("If you hold it up to your ear, you can hear the screams of the damned.")
/// Ensure that when we move, we still are in the container. If not in the container, remove all the traits.
/datum/component/itembound/proc/verify_containment()
var/atom/movable/container = containerref.resolve()
if(!QDELETED(container) && container.contains(parent))
return
- REMOVE_TRAIT(parent, TRAIT_INCAPACITATED, SMITE_TRAIT)
qdel(src)
/datum/component/itembound/Destroy(force, silent)
+ var/atom/movable/container = containerref?.resolve()
+ if (!QDELETED(container))
+ UnregisterSignal(container, COMSIG_ATOM_EXAMINE_MORE)
containerref = null
QDEL_NULL(move_tracker)
return ..()
diff --git a/code/datums/components/ling_decoy_brain.dm b/code/datums/components/ling_decoy_brain.dm
new file mode 100644
index 00000000000..7bcb4e38c8f
--- /dev/null
+++ b/code/datums/components/ling_decoy_brain.dm
@@ -0,0 +1,68 @@
+/// Component applied to ling brains to make them into decoy brains, as ling brains are vestigial and don't do anything
+/datum/component/ling_decoy_brain
+ /// The ling this brain is linked to
+ VAR_FINAL/datum/antagonist/changeling/parent_ling
+ /// A talk action that is granted to the ling when this decoy enters an MMI
+ VAR_FINAL/datum/action/changeling/mmi_talk/talk_action
+
+/datum/component/ling_decoy_brain/Initialize(datum/antagonist/changeling/ling)
+ if(!istype(parent, /obj/item/organ/internal/brain))
+ return COMPONENT_INCOMPATIBLE
+ if(isnull(ling))
+ stack_trace("[type] instantiated without a changeling to link to.")
+ return COMPONENT_INCOMPATIBLE
+
+ parent_ling = ling
+ RegisterSignal(parent_ling, COMSIG_QDELETING, PROC_REF(clear_decoy))
+
+/datum/component/ling_decoy_brain/Destroy()
+ UnregisterSignal(parent_ling, COMSIG_QDELETING)
+ parent_ling = null
+ QDEL_NULL(talk_action)
+ return ..()
+
+/datum/component/ling_decoy_brain/RegisterWithParent()
+ var/obj/item/organ/internal/brain/ling_brain = parent
+ ling_brain.organ_flags &= ~ORGAN_VITAL
+ ling_brain.decoy_override = TRUE
+ RegisterSignal(ling_brain, COMSIG_ATOM_ENTERING, PROC_REF(entered_mmi))
+
+/datum/component/ling_decoy_brain/UnregisterFromParent()
+ var/obj/item/organ/internal/brain/ling_brain = parent
+ ling_brain.organ_flags |= ORGAN_VITAL
+ ling_brain.decoy_override = FALSE
+ UnregisterSignal(ling_brain, COMSIG_ATOM_ENTERING, PROC_REF(entered_mmi))
+
+/**
+ * Signal proc for [COMSIG_ATOM_ENTERING], when the brain enters an MMI grant the MMI talk action to the ling
+ *
+ * Unfortunately this is hooked on Entering rather than its own dedicated MMI signal becuase MMI code is a fuck
+ */
+/datum/component/ling_decoy_brain/proc/entered_mmi(obj/item/organ/internal/brain/source, atom/entering, atom/old_loc, ...)
+ SIGNAL_HANDLER
+
+ var/mob/living/the_real_ling = parent_ling.owner.current
+ if(!istype(the_real_ling))
+ return
+
+ if(istype(source.loc, /obj/item/mmi) && talk_action?.owner != the_real_ling)
+ if(isnull(talk_action))
+ talk_action = new() // Not linked to anything, we manage the reference (and don't want it disappearing on us)
+ talk_action.brain_ref = source
+
+ if(the_real_ling.key)
+ to_chat(the_real_ling, span_ghostalert("We detect our decoy brain has been placed within a Man-Machine Interface. \
+ We can use the \"MMI Talk\" action to command it to speak."))
+ else
+ the_real_ling.notify_ghost_cloning("Your decoy brain has been placed in an MMI, re-enter your body to talk via it!", source = the_real_ling, flashwindow = TRUE)
+ talk_action.Grant(the_real_ling)
+
+ else if(talk_action?.owner == the_real_ling)
+ to_chat(the_real_ling, span_ghostalert("We can no longer detect our decoy brain."))
+ talk_action.Remove(the_real_ling)
+
+/// Clear up the decoy if the ling is de-linged
+/datum/component/ling_decoy_brain/proc/clear_decoy(datum/source)
+ SIGNAL_HANDLER
+
+ qdel(src)
diff --git a/code/datums/components/material/material_container.dm b/code/datums/components/material/material_container.dm
index 7f07c6cb91d..d26e427b1db 100644
--- a/code/datums/components/material/material_container.dm
+++ b/code/datums/components/material/material_container.dm
@@ -462,7 +462,7 @@
*
* Arguments:
* - [I][obj/item]: the item whos materials must be retrieved
- * - breakdown_flags: how this item must be broken down to retrive its materials
+ * - breakdown_flags: how this item must be broken down to retrieve its materials
*/
/datum/component/material_container/proc/get_item_material_amount(obj/item/I, breakdown_flags = mat_container_flags)
if(!istype(I) || !I.custom_materials)
@@ -596,16 +596,26 @@
//eject sheets based on available amount after each iteration
var/count = 0
while(sheet_amt > 0)
- //create sheets in null space so it doesn't merge & delete itself
- var/obj/item/stack/sheet/new_sheets = new material.sheet_type(null, min(sheet_amt, MAX_STACK_SIZE), FALSE, list((material) = SHEET_MATERIAL_AMOUNT))
+ //don't merge yet. we need to do stuff with it first
+ var/obj/item/stack/sheet/new_sheets = new material.sheet_type(target, min(sheet_amt, MAX_STACK_SIZE), FALSE)
count += new_sheets.amount
//use material & deduct work needed
use_amount_mat(new_sheets.amount * SHEET_MATERIAL_AMOUNT, material)
sheet_amt -= new_sheets.amount
//send signal
SEND_SIGNAL(src, COMSIG_MATCONTAINER_SHEETS_RETRIEVED, new_sheets, context)
- //now move to target so it gets merged
- new_sheets.forceMove(target)
+ //no point merging anything into an already full stack
+ if(new_sheets.amount == new_sheets.max_amount)
+ continue
+ //now we can merge since we are done with it
+ for(var/obj/item/stack/item_stack in target)
+ if(item_stack == new_sheets || item_stack.type != material.sheet_type) //don't merge with self or different type
+ continue
+ //speed merge
+ var/merge_amount = min(item_stack.amount, new_sheets.max_amount - new_sheets.get_amount())
+ item_stack.use(merge_amount)
+ new_sheets.add(merge_amount)
+ break
return count
/**
diff --git a/code/datums/components/material/remote_materials.dm b/code/datums/components/material/remote_materials.dm
index c9677ecec44..17561581083 100644
--- a/code/datums/components/material/remote_materials.dm
+++ b/code/datums/components/material/remote_materials.dm
@@ -145,16 +145,27 @@ handles linking back and forth.
if(!check_z_level(M.buffer))
to_chat(user, span_warning("[parent] is too far away to get a connection signal!"))
return COMPONENT_BLOCK_TOOL_ATTACK
+
+ var/obj/machinery/ore_silo/new_silo = M.buffer
+ var/datum/component/material_container/new_container = new_silo.GetComponent(/datum/component/material_container)
if (silo)
silo.ore_connected_machines -= src
silo.holds -= src
silo.updateUsrDialog()
else if (mat_container)
+ //transfer all mats to silo. whatever cannot be transfered is dumped out as sheets
+ if(mat_container.total_amount())
+ for(var/datum/material/mat as anything in mat_container.materials)
+ var/mat_amount = mat_container.materials[mat]
+ if(!mat_amount || !new_container.has_space(mat_amount) || !new_container.can_hold_material(mat))
+ continue
+ new_container.materials[mat] += mat_amount
+ mat_container.materials[mat] = 0
qdel(mat_container)
- silo = M.buffer
+ silo = new_silo
silo.ore_connected_machines += src
silo.updateUsrDialog()
- mat_container = silo.GetComponent(/datum/component/material_container)
+ mat_container = new_container
RegisterSignal(parent, COMSIG_ATOM_ATTACKBY, TYPE_PROC_REF(/datum/component/remote_materials, SiloAttackBy))
to_chat(user, span_notice("You connect [parent] to [silo] from the multitool's buffer."))
return COMPONENT_BLOCK_TOOL_ATTACK
diff --git a/code/datums/components/omen.dm b/code/datums/components/omen.dm
index 93888d0a436..4f3b17a7473 100644
--- a/code/datums/components/omen.dm
+++ b/code/datums/components/omen.dm
@@ -138,6 +138,7 @@
switch(rand(1, 5))
if(1)
to_chat(living_guy, span_warning("The mirror explodes into a million pieces! Wait, does that mean you're even more unlucky?"))
+ evil_mirror.take_damage(evil_mirror.max_integrity, BRUTE, MELEE, FALSE)
if(prob(50 * luck_mod)) // sometimes
luck_mod += 0.25
damage_mod += 0.25
diff --git a/code/datums/components/pellet_cloud.dm b/code/datums/components/pellet_cloud.dm
index 40381df8e86..fbd32fe5e4f 100644
--- a/code/datums/components/pellet_cloud.dm
+++ b/code/datums/components/pellet_cloud.dm
@@ -311,7 +311,7 @@
var/damage_dealt = wound_info_by_part[hit_part][CLOUD_POSITION_DAMAGE]
var/w_bonus = wound_info_by_part[hit_part][CLOUD_POSITION_W_BONUS]
var/bw_bonus = wound_info_by_part[hit_part][CLOUD_POSITION_BW_BONUS]
- var/wound_type = (initial(P.damage_type) == BRUTE) ? WOUND_BLUNT : WOUND_BURN // sharpness is handled in the wound rolling
+ var/wounding_type = (initial(P.damage_type) == BRUTE) ? WOUND_BLUNT : WOUND_BURN // sharpness is handled in the wound rolling
wound_info_by_part -= hit_part
// technically this only checks armor worn the moment that all the pellets resolve rather than as each one hits you,
@@ -324,7 +324,7 @@
armor_factor *= ARMOR_WEAKENED_MULTIPLIER
damage_dealt *= max(0, 1 - armor_factor*0.01)
- hit_part.painless_wound_roll(wound_type, damage_dealt, w_bonus, bw_bonus, initial(P.sharpness))
+ hit_part.painless_wound_roll(wounding_type, damage_dealt, w_bonus, bw_bonus, initial(P.sharpness))
var/limb_hit_text = ""
if(hit_part)
diff --git a/code/datums/components/pet_commands/pet_commands_basic.dm b/code/datums/components/pet_commands/pet_commands_basic.dm
index 40ec41aa3d6..ff29b8f37d2 100644
--- a/code/datums/components/pet_commands/pet_commands_basic.dm
+++ b/code/datums/components/pet_commands/pet_commands_basic.dm
@@ -111,7 +111,7 @@
pointed_reaction = "and growls"
/// Balloon alert to display if providing an invalid target
var/refuse_reaction = "shakes head"
- /// Attack behaviour to use, generally you will want to override this to add some kind of cooldown
+ /// Attack behaviour to use
var/attack_behaviour = /datum/ai_behavior/basic_melee_attack
// Refuse to target things we can't target, chiefly other friends
@@ -185,6 +185,8 @@
/datum/pet_command/protect_owner/execute_action(datum/ai_controller/controller)
var/datum/targetting_datum/basic/targetting = controller.blackboard[BB_TARGETTING_DATUM]
var/mob/living/victim = controller.blackboard[BB_CURRENT_PET_TARGET]
+ if(QDELETED(victim))
+ return
if(victim.stat > targetting.stat_attack)
controller.clear_blackboard_key(BB_ACTIVE_PET_COMMAND)
return
diff --git a/code/datums/components/ranged_attacks.dm b/code/datums/components/ranged_attacks.dm
index 0d76c21aaf7..f75d29a10f4 100644
--- a/code/datums/components/ranged_attacks.dm
+++ b/code/datums/components/ranged_attacks.dm
@@ -8,6 +8,10 @@
var/projectile_type
/// Sound to play when we fire our projectile
var/projectile_sound
+ /// how many shots we will fire
+ var/burst_shots
+ /// intervals between shots
+ var/burst_intervals
/// Time to wait between shots
var/cooldown_time
/// Tracks time between shots
@@ -17,6 +21,8 @@
casing_type,
projectile_type,
projectile_sound = 'sound/weapons/gun/pistol/shot.ogg',
+ burst_shots,
+ burst_intervals = 0.2 SECONDS,
cooldown_time = 3 SECONDS,
)
. = ..()
@@ -32,6 +38,10 @@
CRASH("Set both casing type and projectile type in [parent]'s ranged attacks component! uhoh! stinky!")
if (!casing_type && !projectile_type)
CRASH("Set neither casing type nor projectile type in [parent]'s ranged attacks component! What are they supposed to be attacking with, air?")
+ if(burst_shots <= 1)
+ return
+ src.burst_shots = burst_shots
+ src.burst_intervals = burst_intervals
/datum/component/ranged_attacks/RegisterWithParent()
. = ..()
@@ -49,12 +59,17 @@
return
COOLDOWN_START(src, fire_cooldown, cooldown_time)
INVOKE_ASYNC(src, PROC_REF(async_fire_ranged_attack), firer, target, modifiers)
- SEND_SIGNAL(parent, COMSIG_BASICMOB_POST_ATTACK_RANGED, target, modifiers)
+ if(isnull(burst_shots))
+ return
+ for(var/i in 1 to (burst_shots - 1))
+ addtimer(CALLBACK(src, PROC_REF(async_fire_ranged_attack), firer, target, modifiers), i * burst_intervals)
/// Actually fire the damn thing
/datum/component/ranged_attacks/proc/async_fire_ranged_attack(mob/living/basic/firer, atom/target, modifiers)
+ firer.face_atom(target)
if(projectile_type)
firer.fire_projectile(projectile_type, target, projectile_sound)
+ SEND_SIGNAL(parent, COMSIG_BASICMOB_POST_ATTACK_RANGED, target, modifiers)
return
playsound(firer, projectile_sound, 100, TRUE)
var/turf/startloc = get_turf(firer)
@@ -68,5 +83,6 @@
casing.fire_casing(target, firer, null, null, null, target_zone, 0, firer)
casing.update_appearance()
casing.AddElement(/datum/element/temporary_atom, 30 SECONDS)
+ SEND_SIGNAL(parent, COMSIG_BASICMOB_POST_ATTACK_RANGED, target, modifiers)
return
diff --git a/code/datums/components/religious_tool.dm b/code/datums/components/religious_tool.dm
index fabed36595c..e64e28f83a3 100644
--- a/code/datums/components/religious_tool.dm
+++ b/code/datums/components/religious_tool.dm
@@ -27,6 +27,8 @@
after_sect_select_cb = _after_sect_select_cb
if(override_catalyst_type)
catalyst_type = override_catalyst_type
+ RegisterSignal(SSdcs, COMSIG_RELIGIOUS_SECT_CHANGED, PROC_REF(SetGlobalToLocal))
+ RegisterSignal(SSdcs, COMSIG_RELIGIOUS_SECT_RESET, PROC_REF(on_sect_reset))
/datum/component/religious_tool/Destroy(force, silent)
easy_access_sect = null
@@ -46,15 +48,21 @@
* Sets the easy access variable to the global if it exists.
*/
/datum/component/religious_tool/proc/SetGlobalToLocal()
+ SIGNAL_HANDLER
if(easy_access_sect)
return TRUE
if(!GLOB.religious_sect)
return FALSE
easy_access_sect = GLOB.religious_sect
- if(after_sect_select_cb)
- after_sect_select_cb.Invoke()
+ after_sect_select_cb?.Invoke()
return TRUE
+/// Sets the easy access variable to null in case an admin needed to change it
+/datum/component/religious_tool/proc/on_sect_reset()
+ SIGNAL_HANDLER
+ easy_access_sect = null
+ after_sect_select_cb?.Invoke()
+
/**
* Since all of these involve attackby, we require mega proc. Handles Invocation, Sacrificing, And Selection of Sects.
*/
@@ -66,7 +74,7 @@
/**********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)
return COMPONENT_NO_AFTERATTACK
@@ -123,27 +131,13 @@
/// Select the sect, called from [/datum/component/religious_tool/proc/AttemptActions]
/datum/component/religious_tool/proc/select_sect(mob/living/user, path)
- if(!ispath(text2path(path), /datum/religion_sect))
- message_admins("[ADMIN_LOOKUPFLW(usr)] has tried to spawn an item when selecting a sect.")
- return
if(user.mind.holy_role != HOLY_ROLE_HIGHPRIEST)
to_chat(user, span_warning("You are not the high priest, and therefore cannot select a religious sect."))
return
if(!user.can_perform_action(parent, FORBID_TELEKINESIS_REACH))
to_chat(user,span_warning("You cannot select a sect at this time."))
return
- if(GLOB.religious_sect)
- return
- GLOB.religious_sect = new path()
- for(var/i in GLOB.player_list)
- if(!isliving(i))
- continue
- var/mob/living/am_i_holy_living = i
- if(!am_i_holy_living.mind?.holy_role)
- continue
- GLOB.religious_sect.on_conversion(am_i_holy_living)
- easy_access_sect = GLOB.religious_sect
- after_sect_select_cb.Invoke()
+ set_new_religious_sect(text2path(path))
/// Perform the rite, called from [/datum/component/religious_tool/proc/AttemptActions]
/datum/component/religious_tool/proc/perform_rite(mob/living/user, path)
@@ -212,7 +206,7 @@
* Generates an english list (so string) of wanted sac items. Returns null if no targets!
*/
/datum/component/religious_tool/proc/generate_sacrifice_list()
- if(!easy_access_sect.desired_items)
+ if(!length(easy_access_sect?.desired_items))
return //specifically null so the data sends as such
var/list/item_names = list()
for(var/atom/sac_type as anything in easy_access_sect.desired_items)
@@ -238,7 +232,7 @@
if(!can_i_see)
return
examine_list += span_notice("Use a bible to interact with this.")
- if(!easy_access_sect)
+ if(isnull(easy_access_sect))
if(operation_flags & RELIGION_TOOL_SECTSELECT)
examine_list += span_notice("This looks like it can be used to select a sect.")
return
diff --git a/code/datums/components/seclight_attachable.dm b/code/datums/components/seclight_attachable.dm
index 56761cfd1bf..b3f36fe041a 100644
--- a/code/datums/components/seclight_attachable.dm
+++ b/code/datums/components/seclight_attachable.dm
@@ -98,6 +98,7 @@
RegisterSignal(parent, COMSIG_ATOM_ATTACKBY, PROC_REF(on_attackby))
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine))
RegisterSignal(parent, COMSIG_QDELETING, PROC_REF(on_parent_deleted))
+ RegisterSignal(parent, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur))
/datum/component/seclite_attachable/UnregisterFromParent()
UnregisterSignal(parent, list(
@@ -156,12 +157,10 @@
if(!light)
return FALSE
- light.on = !light.on
- light.update_brightness()
- if(user)
- user.balloon_alert(user, "[light.name] toggled [light.on ? "on":"off"]")
-
- playsound(light, 'sound/weapons/empty.ogg', 100, TRUE)
+ var/successful_toggle = light.toggle_light(user)
+ if(!successful_toggle)
+ return TRUE
+ user.balloon_alert(user, "[light.name] toggled [light.on ? "on":"off"]")
update_light()
return TRUE
@@ -296,3 +295,9 @@
// Yes, this might mess with other icon state alterations,
// but that's the downside of using icon states over overlays.
source.icon_state = base_state
+
+/// Signal proc for [COMSIG_HIT_BY_SABOTEUR] that turns the light off for a few seconds.
+/datum/component/seclite_attachable/proc/on_saboteur(datum/source, disrupt_duration)
+ SIGNAL_HANDLER
+ . = light.on_saboteur(source, disrupt_duration)
+ update_light()
diff --git a/code/datums/components/spawner.dm b/code/datums/components/spawner.dm
index abb93154099..3f660d5fcbd 100644
--- a/code/datums/components/spawner.dm
+++ b/code/datums/components/spawner.dm
@@ -38,6 +38,8 @@
/// Try to create a new mob
/datum/component/spawner/proc/try_spawn_mob()
+ if(!length(spawn_types))
+ return
if(!COOLDOWN_FINISHED(src, spawn_delay))
return
validate_references()
diff --git a/code/datums/components/spin2win.dm b/code/datums/components/spin2win.dm
index 19eebfed509..0812258f769 100644
--- a/code/datums/components/spin2win.dm
+++ b/code/datums/components/spin2win.dm
@@ -4,6 +4,8 @@
* Component that attaches to items, making their attack_self begin a spin 2 win
*/
/datum/component/spin2win
+ /// How long you spin for
+ var/spin_duration = 5 SECONDS
///the cooldown for spinning to winning
COOLDOWN_DECLARE(spin_cooldown)
///how long a spin2win takes to recharge.
@@ -76,14 +78,14 @@
/datum/component/spin2win/proc/start_spinning(mob/living/spinning_user)
//user will always exist for the start
spinning = TRUE
- spinning_user.changeNext_move(5 SECONDS)
+ spinning_user.changeNext_move(spin_duration)
if(on_spin_callback)
- on_spin_callback.Invoke(spinning_user)
+ on_spin_callback.Invoke(spinning_user, spin_duration)
if(start_spin_message)
var/message = replacetext(start_spin_message, "%USER", spinning_user)
spinning_user.visible_message(message)
playsound(spinning_user, 'sound/weapons/fwoosh.ogg', 75, FALSE)
- stop_spinning_timer_id = addtimer(CALLBACK(src, PROC_REF(stop_spinning), spinning_user), 5 SECONDS, TIMER_STOPPABLE|TIMER_DELETE_ME)
+ stop_spinning_timer_id = addtimer(CALLBACK(src, PROC_REF(stop_spinning), spinning_user), spin_duration, TIMER_STOPPABLE|TIMER_DELETE_ME)
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(on_spin_equipped))
RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(on_spin_dropped))
START_PROCESSING(SSprocessing, src)
@@ -98,7 +100,7 @@
var/message = replacetext(end_spin_message, "%USER", user)
user.visible_message(message)
if(on_unspin_callback)
- on_unspin_callback.Invoke(user, 5 SECONDS)
+ on_unspin_callback.Invoke(user, spin_duration)
COOLDOWN_START(src, spin_cooldown, spin_cooldown_time)
spinning = FALSE
diff --git a/code/datums/components/supermatter_crystal.dm b/code/datums/components/supermatter_crystal.dm
index 65c11ce2417..a9bdfc5b154 100644
--- a/code/datums/components/supermatter_crystal.dm
+++ b/code/datums/components/supermatter_crystal.dm
@@ -60,6 +60,10 @@
/datum/component/supermatter_crystal/proc/paw_hit(datum/source, mob/user, list/modifiers)
SIGNAL_HANDLER
+ if(isliving(user))
+ var/mob/living/living_mob = user
+ if(living_mob.incorporeal_move || living_mob.status_flags & GODMODE)
+ return
if(isalien(user))
dust_mob(source, user, cause = "alien attack")
return
@@ -67,6 +71,8 @@
/datum/component/supermatter_crystal/proc/animal_hit(datum/source, mob/living/simple_animal/user, list/modifiers)
SIGNAL_HANDLER
+ if(user.incorporeal_move || user.status_flags & GODMODE)
+ return
var/atom/atom_source = source
var/murder
if(!user.melee_damage_upper && !user.melee_damage_lower)
@@ -84,6 +90,10 @@
/datum/component/supermatter_crystal/proc/unarmed_hit(datum/source, mob/user, list/modifiers)
SIGNAL_HANDLER
+ if(isliving(user))
+ var/mob/living/living_mob = user
+ if(living_mob.incorporeal_move || living_mob.status_flags & GODMODE)
+ return
var/atom/atom_source = source
if(iscyborg(user) && atom_source.Adjacent(user))
dust_mob(source, user, cause = "cyborg attack")
@@ -96,14 +106,12 @@
/datum/component/supermatter_crystal/proc/hand_hit(datum/source, mob/living/user, list/modifiers)
SIGNAL_HANDLER
- var/atom/atom_source = source
if(user.incorporeal_move || user.status_flags & GODMODE)
return
-
if(user.zone_selected != BODY_ZONE_PRECISE_MOUTH)
dust_mob(source, user, cause = "hand")
return
-
+ var/atom/atom_source = source
if(!user.is_mouth_covered())
if(user.combat_mode)
dust_mob(source, user,
@@ -185,6 +193,8 @@
return
if(atom_source.Adjacent(user)) //if the item is stuck to the person, kill the person too instead of eating just the item.
+ if(user.incorporeal_move || user.status_flags & GODMODE)
+ return
var/vis_msg = span_danger("[user] reaches out and touches [atom_source] with [item], inducing a resonance... [item] starts to glow briefly before the light continues up to [user]'s body. [user.p_They()] burst[user.p_s()] into flames before flashing into dust!")
var/mob_msg = span_userdanger("You reach out and touch [atom_source] with [item]. Everything starts burning and all you can hear is ringing. Your last thought is \"That was not a wise decision.\"")
dust_mob(source, user, vis_msg, mob_msg)
@@ -198,6 +208,10 @@
/datum/component/supermatter_crystal/proc/bumped_hit(datum/source, atom/movable/hit_object)
SIGNAL_HANDLER
+ if(isliving(hit_object))
+ var/mob/living/hit_mob = hit_object
+ if(hit_mob.incorporeal_move || hit_mob.status_flags & GODMODE)
+ return
var/atom/atom_source = source
var/obj/machinery/power/supermatter_crystal/our_supermatter = parent // Why is this a component?
if(istype(our_supermatter))
@@ -224,9 +238,9 @@
return FALL_INTERCEPTED | FALL_NO_MESSAGE
/datum/component/supermatter_crystal/proc/dust_mob(datum/source, mob/living/nom, vis_msg, mob_msg, cause)
- var/atom/atom_source = source
if(nom.incorporeal_move || nom.status_flags & GODMODE) //try to keep supermatter sliver's + hemostat's dust conditions in sync with this too
return
+ var/atom/atom_source = source
if(!vis_msg)
vis_msg = span_danger("[nom] reaches out and touches [atom_source], inducing a resonance... [nom.p_their()] body starts to glow and burst into flames before flashing into dust!")
if(!mob_msg)
@@ -252,6 +266,9 @@
message_admins("[atom_source] has consumed [key_name_admin(consumed_mob)] [ADMIN_JMP(atom_source)].")
atom_source.investigate_log("has consumed [key_name(consumed_mob)].", INVESTIGATE_ENGINE)
consumed_mob.investigate_log("has been dusted by [atom_source].", INVESTIGATE_DEATHS)
+ if(istype(consumed_mob, /mob/living/simple_animal/parrot/poly)) // Dusting Poly creates a power surge
+ force_event(/datum/round_event_control/supermatter_surge/poly, "Poly's revenge")
+ notify_ghosts("[consumed_mob] has been dusted by [atom_source]!", source = atom_source, action = NOTIFY_JUMP, header = "Polytechnical Difficulties")
consumed_mob.dust(force = TRUE)
matter_increase += 100 * object_size
if(is_clown_job(consumed_mob.mind?.assigned_role))
diff --git a/code/datums/components/twohanded.dm b/code/datums/components/twohanded.dm
index 3b015c95383..37df7308217 100644
--- a/code/datums/components/twohanded.dm
+++ b/code/datums/components/twohanded.dm
@@ -63,7 +63,7 @@
return ..()
// Inherit the new values passed to the component
-/datum/component/two_handed/InheritComponent(datum/component/two_handed/new_comp, original, require_twohands, wieldsound, unwieldsound, \
+/datum/component/two_handed/InheritComponent(datum/component/two_handed/new_comp, original, require_twohands, wieldsound, unwieldsound, attacksound, \
force_multiplier, force_wielded, force_unwielded, icon_wielded, \
datum/callback/wield_callback, datum/callback/unwield_callback)
if(!original)
diff --git a/code/datums/components/udder.dm b/code/datums/components/udder.dm
index bd622a944d7..c1f0ff03245 100644
--- a/code/datums/components/udder.dm
+++ b/code/datums/components/udder.dm
@@ -94,7 +94,7 @@
* also useful for changing initial amounts in reagent holder (cows start with milk, gutlunches start empty)
*/
/obj/item/udder/proc/initial_conditions()
- reagents.add_reagent(reagent_produced_typepath, 20)
+ reagents.add_reagent(reagent_produced_typepath, 20, added_purity = 1)
START_PROCESSING(SSobj, src)
/**
@@ -102,7 +102,7 @@
*/
/obj/item/udder/proc/generate()
if(prob(5))
- reagents.add_reagent(reagent_produced_typepath, rand(5, 10))
+ reagents.add_reagent(reagent_produced_typepath, rand(5, 10), added_purity = 1)
if(on_generate_callback)
on_generate_callback.Invoke(reagents.total_volume, reagents.maximum_volume)
@@ -117,8 +117,8 @@
if(milk_holder.reagents.total_volume >= milk_holder.volume)
to_chat(user, span_warning("[milk_holder] is full."))
return
- var/transfered = reagents.trans_to(milk_holder, rand(5,10))
- if(transfered)
+ var/transferred = reagents.trans_to(milk_holder, rand(5,10))
+ if(transferred)
user.visible_message(span_notice("[user] milks [src] using \the [milk_holder]."), span_notice("You milk [src] using \the [milk_holder]."))
else
to_chat(user, span_warning("The udder is dry. Wait a bit longer..."))
@@ -163,7 +163,7 @@
/obj/item/udder/gutlunch/generate()
var/made_something = FALSE
if(prob(60))
- reagents.add_reagent(/datum/reagent/consumable/cream, rand(2, 5))
+ reagents.add_reagent(/datum/reagent/consumable/cream, rand(2, 5), added_purity = 1)
made_something = TRUE
if(prob(45))
reagents.add_reagent(/datum/reagent/medicine/salglu_solution, rand(2,5))
diff --git a/code/datums/components/uplink.dm b/code/datums/components/uplink.dm
index 1f47e15b79a..03740417678 100644
--- a/code/datums/components/uplink.dm
+++ b/code/datums/components/uplink.dm
@@ -259,6 +259,7 @@
data["current_stock"] = remaining_stock
data["shop_locked"] = uplink_handler.shop_locked
data["purchased_items"] = length(uplink_handler.purchase_log?.purchase_log)
+ data["can_renegotiate"] = user.mind == uplink_handler.owner && uplink_handler.can_replace_objectives?.Invoke() == TRUE
return data
/datum/component/uplink/ui_static_data(mob/user)
@@ -300,6 +301,9 @@
if(!lockable)
return TRUE
lock_uplink()
+ if("renegotiate_objectives")
+ uplink_handler.replace_objectives?.Invoke()
+ SStgui.update_uis(src)
if(!uplink_handler.has_objectives)
return TRUE
diff --git a/code/datums/components/wall_mounted.dm b/code/datums/components/wall_mounted.dm
new file mode 100644
index 00000000000..6164d39b001
--- /dev/null
+++ b/code/datums/components/wall_mounted.dm
@@ -0,0 +1,78 @@
+// This element should be applied to wall-mounted machines/structures, so that if the wall it's "hanging" from is broken or deconstructed, the wall-hung structure will deconstruct.
+/datum/component/wall_mounted
+ dupe_mode = COMPONENT_DUPE_ALLOWED
+ /// The wall our object is currently linked to.
+ var/turf/hanging_wall_turf
+ /// Callback to the parent's proc to call on the linked object when the wall disappear's or changes.
+ var/datum/callback/on_drop
+
+/datum/component/wall_mounted/Initialize(target_wall, on_drop_callback)
+ . = ..()
+ if(!isobj(parent))
+ return COMPONENT_INCOMPATIBLE
+ if(!isturf(target_wall))
+ return COMPONENT_INCOMPATIBLE
+ hanging_wall_turf = target_wall
+ on_drop = on_drop_callback
+
+/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(parent, COMSIG_MOVABLE_MOVED, PROC_REF(drop_wallmount))
+ RegisterSignal(parent, COMSIG_QDELETING, PROC_REF(on_linked_destroyed))
+
+/datum/component/wall_mounted/UnregisterFromParent()
+ UnregisterSignal(hanging_wall_turf, list(COMSIG_ATOM_EXAMINE, COMSIG_TURF_CHANGE))
+ UnregisterSignal(parent, list(COMSIG_QDELETING, COMSIG_MOVABLE_MOVED))
+ hanging_wall_turf = null
+
+/**
+ * Basic reference handling if the hanging/linked object is destroyed first.
+ */
+/datum/component/wall_mounted/proc/on_linked_destroyed()
+ SIGNAL_HANDLER
+ if(!QDELING(src))
+ qdel(src)
+
+/**
+ * When the wall is examined, explains that it's supporting the linked object.
+ */
+/datum/component/wall_mounted/proc/on_examine(datum/source, mob/user, list/examine_list)
+ 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")].")
+
+/**
+ * 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.
+ */
+/datum/component/wall_mounted/proc/drop_wallmount()
+ SIGNAL_HANDLER
+ var/obj/hanging_parent = parent
+
+ if(on_drop)
+ hanging_parent.visible_message(message = span_warning("\The [hanging_parent] falls off the wall!"), vision_distance = 5)
+ on_drop.Invoke(hanging_parent)
+ else
+ hanging_parent.visible_message(message = span_warning("\The [hanging_parent] falls apart!"), vision_distance = 5)
+ hanging_parent.deconstruct()
+
+ if(!QDELING(src))
+ qdel(src) //Well, we fell off the wall, so we're done here.
+/**
+ * Checks object direction and then verifies if there's a wall in that direction. Finally, applies a wall_mounted component to the object.
+ *
+ * @param directional If TRUE, will use the direction of the object to determine the wall to attach to. If FALSE, will use the object's loc.
+ * @param custom_drop_callback If set, will use this callback instead of the default deconstruct callback.
+ */
+/obj/proc/find_and_hang_on_wall(directional = TRUE, custom_drop_callback)
+ if(istype(get_area(src), /area/shuttle))
+ return FALSE //For now, we're going to keep the component off of shuttles to avoid the turf changing issue. We'll hit that later really;
+ var/turf/attachable_wall
+ if(directional)
+ attachable_wall = get_step(src, dir)
+ else
+ attachable_wall = loc ///Pull from the curent object loc
+ if(!iswallturf(attachable_wall))
+ return FALSE//Nothing to latch onto, or not the right thing.
+ src.AddComponent(/datum/component/wall_mounted, attachable_wall, custom_drop_callback)
+ return TRUE
diff --git a/code/datums/diseases/advance/symptoms/confusion.dm b/code/datums/diseases/advance/symptoms/confusion.dm
index 2c6afe4b80d..159eccfbd1c 100644
--- a/code/datums/diseases/advance/symptoms/confusion.dm
+++ b/code/datums/diseases/advance/symptoms/confusion.dm
@@ -20,7 +20,6 @@
symptom_delay_min = 10
symptom_delay_max = 30
threshold_descs = list(
- "Stage Speed 6" = "Prevents any form of reading or writing.",
"Resistance 6" = "Causes brain damage over time.",
"Transmission 6" = "Increases confusion duration and strength.",
"Stealth 4" = "The symptom remains hidden until active.",
@@ -43,7 +42,6 @@
/datum/symptom/confusion/End(datum/disease/advance/advanced_disease)
advanced_disease.affected_mob.remove_status_effect(/datum/status_effect/confusion)
- REMOVE_TRAIT(advanced_disease.affected_mob, TRAIT_ILLITERATE, DISEASE_TRAIT)
return ..()
/datum/symptom/confusion/Activate(datum/disease/advance/advanced_disease)
@@ -57,17 +55,8 @@
to_chat(infected_mob, span_warning("[pick("Your head hurts.", "Your mind blanks for a moment.")]"))
else
to_chat(infected_mob, span_userdanger("You can't think straight!"))
- infected_mob.adjust_confusion(16 SECONDS * power)
+ infected_mob.adjust_confusion_up_to(16 SECONDS * power, 30 SECONDS)
if(brain_damage)
infected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3 * power, 80)
infected_mob.updatehealth()
return
-
-/datum/symptom/confusion/on_stage_change(datum/disease/advance/advanced_disease)
- . = ..()
- if(!.)
- return FALSE
- var/mob/living/carbon/infected_mob = advanced_disease.affected_mob
- if(advanced_disease.stage >= 5 && causes_illiteracy)
- ADD_TRAIT(infected_mob, TRAIT_ILLITERATE, DISEASE_TRAIT)
- return TRUE
diff --git a/code/datums/diseases/advance/symptoms/heal.dm b/code/datums/diseases/advance/symptoms/heal.dm
index d9345d0107c..8754eb3b71d 100644
--- a/code/datums/diseases/advance/symptoms/heal.dm
+++ b/code/datums/diseases/advance/symptoms/heal.dm
@@ -75,7 +75,7 @@
/datum/symptom/heal/starlight/proc/CanTileHealDirectional(turf/turf_to_check, direction)
if(direction == UP)
- turf_to_check = turf_to_check.above()
+ turf_to_check = GET_TURF_ABOVE(turf_to_check)
if(!turf_to_check)
return STARLIGHT_CANNOT_HEAL
var/area/area_to_check = get_area(turf_to_check)
@@ -98,9 +98,9 @@
if(istransparentturf(turf_to_check) || istype(turf_to_check, /turf/open/openspace))
// Check above or below us
if(direction == UP)
- turf_to_check = turf_to_check.above()
+ turf_to_check = GET_TURF_ABOVE(turf_to_check)
else
- turf_to_check = turf_to_check.below()
+ turf_to_check = GET_TURF_BELOW(turf_to_check)
// If we found a turf above or below us,
// then we can rerun the loop on the newly found turf / area
diff --git a/code/datums/diseases/advance/symptoms/vomit.dm b/code/datums/diseases/advance/symptoms/vomit.dm
index 72558f69ba9..ee695ffd5bc 100644
--- a/code/datums/diseases/advance/symptoms/vomit.dm
+++ b/code/datums/diseases/advance/symptoms/vomit.dm
@@ -53,11 +53,21 @@ and your disease can spread via people walking on vomit.
else
vomit(M)
-/datum/symptom/vomit/proc/vomit(mob/living/carbon/M)
+/datum/symptom/vomit/proc/vomit(mob/living/carbon/vomiter)
+ var/deductable_nutrition = 0
+ var/constructed_flags = (MOB_VOMIT_MESSAGE | MOB_VOMIT_HARM)
+ var/type_of_vomit = /obj/effect/decal/cleanable/vomit/toxic
if(vomit_nebula)
- M.vomit(lost_nutrition = 10, blood = vomit_blood, vomit_type = VOMIT_NEBULA, stun = FALSE, distance = proj_vomit)
+ type_of_vomit = /obj/effect/decal/cleanable/vomit/nebula
+ deductable_nutrition = 10
else
- M.vomit(lost_nutrition = 20, blood = vomit_blood, distance = proj_vomit)
+ constructed_flags |= MOB_VOMIT_STUN
+ deductable_nutrition = 20
+
+ if(vomit_blood)
+ constructed_flags |= MOB_VOMIT_BLOOD
+
+ vomiter.vomit(vomit_flags = constructed_flags, vomit_type = type_of_vomit, lost_nutrition = deductable_nutrition, distance = proj_vomit)
/datum/symptom/vomit/nebula
name = "Nebula Vomiting"
diff --git a/code/datums/diseases/chronic_illness.dm b/code/datums/diseases/chronic_illness.dm
index 6ba86484aa3..fc51138199c 100644
--- a/code/datums/diseases/chronic_illness.dm
+++ b/code/datums/diseases/chronic_illness.dm
@@ -35,7 +35,7 @@
if(SPT_PROB(0.5, seconds_per_tick))
to_chat(affected_mob, span_danger("You feel a very sharp pain in your chest!"))
if(prob(45))
- affected_mob.vomit(20,TRUE)
+ affected_mob.vomit(VOMIT_CATEGORY_BLOOD, lost_nutrition = 20)
if(SPT_PROB(0.5, seconds_per_tick))
to_chat(affected_mob, span_userdanger("[pick("You feel your heart slowing...", "You relax and slow your heartbeat.")]"))
affected_mob.adjustStaminaLoss(70, FALSE)
@@ -50,7 +50,7 @@
if(SPT_PROB(1, seconds_per_tick))
to_chat(affected_mob, span_danger("You feel a gruesome pain in your chest!"))
if(prob(75))
- affected_mob.vomit(45,TRUE)
+ affected_mob.vomit(VOMIT_CATEGORY_BLOOD, lost_nutrition = 45)
if(SPT_PROB(1, seconds_per_tick))
affected_mob.adjustStaminaLoss(100, FALSE)
affected_mob.visible_message(span_warning("[affected_mob] collapses!"))
diff --git a/code/datums/diseases/death_sandwich_poisoning.dm b/code/datums/diseases/death_sandwich_poisoning.dm
index 5d52ac7281c..f865f4fb5be 100644
--- a/code/datums/diseases/death_sandwich_poisoning.dm
+++ b/code/datums/diseases/death_sandwich_poisoning.dm
@@ -47,7 +47,7 @@
if(SPT_PROB(10, seconds_per_tick))
affected_mob.emote("gasp")
if(SPT_PROB(2.5, seconds_per_tick))
- affected_mob.vomit(20, TRUE)
+ affected_mob.vomit(VOMIT_CATEGORY_BLOOD, lost_nutrition = 20)
if(SPT_PROB(2.5, seconds_per_tick))
to_chat(affected_mob, span_danger("Your body feels hot!"))
if(prob(60))
diff --git a/code/datums/diseases/gastrolisis.dm b/code/datums/diseases/gastrolisis.dm
index 455e0773e33..f82f8b3269f 100644
--- a/code/datums/diseases/gastrolisis.dm
+++ b/code/datums/diseases/gastrolisis.dm
@@ -65,7 +65,7 @@
if(shell && eyes && tongue && SPT_PROB(2.5, seconds_per_tick))
affected_mob.set_species(/datum/species/snail)
- affected_mob.client?.give_award(/datum/award/achievement/misc/snail, affected_mob)
+ affected_mob.client?.give_award(/datum/award/achievement/jobs/snail, affected_mob)
affected_mob.visible_message(span_warning("[affected_mob] turns into a snail!"), \
span_boldnotice("You turned into a snail person! You feel an urge to cccrrraaawwwlll..."))
cure()
diff --git a/code/datums/diseases/heart_failure.dm b/code/datums/diseases/heart_failure.dm
index 1a4f05bfb8a..45d4e6672fb 100644
--- a/code/datums/diseases/heart_failure.dm
+++ b/code/datums/diseases/heart_failure.dm
@@ -48,7 +48,7 @@
if(SPT_PROB(1.5, seconds_per_tick))
to_chat(affected_mob, span_danger("You feel a sharp pain in your chest!"))
if(prob(25))
- affected_mob.vomit(95)
+ affected_mob.vomit(VOMIT_CATEGORY_DEFAULT, lost_nutrition = 95)
affected_mob.emote("cough")
affected_mob.Paralyze(40)
affected_mob.losebreath += 4
diff --git a/code/datums/diseases/parasitic_infection.dm b/code/datums/diseases/parasitic_infection.dm
index 8eb7f9f2b19..64bb59f01fd 100644
--- a/code/datums/diseases/parasitic_infection.dm
+++ b/code/datums/diseases/parasitic_infection.dm
@@ -41,7 +41,7 @@
affected_mob.adjust_nutrition(-12)
else
to_chat(affected_mob, span_warning("You feel much, MUCH lighter!"))
- affected_mob.vomit(20, TRUE)
+ affected_mob.vomit(VOMIT_CATEGORY_BLOOD, lost_nutrition = 20)
// disease code already checks if the liver exists otherwise it is cured
var/obj/item/organ/internal/liver/affected_liver = affected_mob.get_organ_slot(ORGAN_SLOT_LIVER)
affected_liver.Remove(affected_mob)
diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm
index 15f56f8ec2f..a3449e366df 100644
--- a/code/datums/diseases/transformation.dm
+++ b/code/datums/diseases/transformation.dm
@@ -58,9 +58,9 @@
to_chat(affected_mob, pick(stage5))
if(QDELETED(affected_mob))
return
- if(affected_mob.notransform)
+ if(HAS_TRAIT_FROM(affected_mob, TRAIT_NO_TRANSFORM, REF(src)))
return
- affected_mob.notransform = 1
+ ADD_TRAIT(affected_mob, TRAIT_NO_TRANSFORM, REF(src))
for(var/obj/item/W in affected_mob.get_equipped_items(include_pockets = TRUE))
affected_mob.dropItemToGround(W)
for(var/obj/item/I in affected_mob.held_items)
diff --git a/code/datums/diseases/tuberculosis.dm b/code/datums/diseases/tuberculosis.dm
index 16ce69fc181..dd75ea7cc62 100644
--- a/code/datums/diseases/tuberculosis.dm
+++ b/code/datums/diseases/tuberculosis.dm
@@ -51,7 +51,7 @@
to_chat(affected_mob, span_userdanger("You feel your mind relax and your thoughts drift!"))
affected_mob.adjust_confusion_up_to(8 SECONDS, 100 SECONDS)
if(SPT_PROB(5, seconds_per_tick))
- affected_mob.vomit(20)
+ affected_mob.vomit(VOMIT_CATEGORY_DEFAULT, lost_nutrition = 20)
if(SPT_PROB(1.5, seconds_per_tick))
to_chat(affected_mob, span_warning("[pick("Your stomach silently rumbles...", "Your stomach seizes up and falls limp, muscles dead and lifeless.", "You could eat a crayon")]"))
affected_mob.overeatduration = max(affected_mob.overeatduration - (200 SECONDS), 0)
diff --git a/code/datums/dna.dm b/code/datums/dna.dm
index 8261718dc3c..5034a863f56 100644
--- a/code/datums/dna.dm
+++ b/code/datums/dna.dm
@@ -912,7 +912,7 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block())
var/list/elligible_organs = list()
for(var/obj/item/organ/internal/internal_organ in organs) //make sure we dont get an implant or cavity item
elligible_organs += internal_organ
- vomit(20, TRUE)
+ vomit(VOMIT_CATEGORY_DEFAULT, lost_nutrition = 10)
if(elligible_organs.len)
var/obj/item/organ/O = pick(elligible_organs)
O.Remove(src)
diff --git a/code/datums/dog_fashion.dm b/code/datums/dog_fashion.dm
index 84913c234be..c2154736cc0 100644
--- a/code/datums/dog_fashion.dm
+++ b/code/datums/dog_fashion.dm
@@ -236,3 +236,10 @@
speak = list() //they're very patient and focused on holding the butter on 'em
emote_see = list("shakes a little.", "looks around.")
emote_hear = list("licks a trickle of the butter up.", "smiles.")
+
+/datum/dog_fashion/head/eyepatch
+ name = "Punished %REAL_NAME%"
+ desc = "%REAL_NAME% has really been going through it today."
+ obj_icon_state = "eyepatch"
+ emote_hear = list("sighs gruffly.", "groans.")
+ emote_see = list("considers their own mortality.", "stares bleakly into the middle distance.", "ponders the horrors of warfare.")
diff --git a/code/datums/elements/bombable_turf.dm b/code/datums/elements/bombable_turf.dm
new file mode 100644
index 00000000000..11a83c79340
--- /dev/null
+++ b/code/datums/elements/bombable_turf.dm
@@ -0,0 +1,45 @@
+/**
+ * Apply this to a turf (usually a wall) and it will be destroyed instantly by any explosion.
+ * Most walls can already be destroyed by explosions so this is largely for usually indestructible ones.
+ * For applying it in a map editor, use /obj/effect/mapping_helpers/bombable_wall
+ */
+/datum/element/bombable_turf
+
+/datum/element/bombable_turf/Attach(turf/target)
+ . = ..()
+ if(!isturf(target))
+ return ELEMENT_INCOMPATIBLE
+ target.explosive_resistance = 1
+
+ RegisterSignal(target, COMSIG_ATOM_EX_ACT, PROC_REF(detonate))
+ RegisterSignal(target, COMSIG_TURF_CHANGE, PROC_REF(turf_changed))
+ RegisterSignal(target, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_update_overlays))
+ RegisterSignal(target, COMSIG_ATOM_EXAMINE, PROC_REF(on_examined))
+
+ target.update_appearance(UPDATE_OVERLAYS)
+
+/datum/element/bombable_turf/Detach(turf/source)
+ UnregisterSignal(source, list(COMSIG_ATOM_EX_ACT, COMSIG_TURF_CHANGE, COMSIG_ATOM_UPDATE_OVERLAYS, COMSIG_ATOM_EXAMINE))
+ source.explosive_resistance = initial(source.explosive_resistance)
+ source.update_appearance(UPDATE_OVERLAYS)
+ return ..()
+
+/// If we get blowed up, move to the next turf
+/datum/element/bombable_turf/proc/detonate(turf/source)
+ SIGNAL_HANDLER
+ source.ScrapeAway()
+
+/// If this turf becomes something else we either just went off or regardless don't want this any more
+/datum/element/bombable_turf/proc/turf_changed(turf/source)
+ SIGNAL_HANDLER
+ Detach(source)
+
+/// Show a little crack on here
+/datum/element/bombable_turf/proc/on_update_overlays(turf/source, list/overlays)
+ SIGNAL_HANDLER
+ overlays += mutable_appearance('icons/turf/overlays.dmi', "explodable", source.layer + 0.1)
+
+/// Show a little extra on examine
+/datum/element/bombable_turf/proc/on_examined(turf/source, mob/user, list/examine_list)
+ SIGNAL_HANDLER
+ examine_list += span_notice("It seems to be slightly cracked...")
diff --git a/code/datums/elements/can_barricade.dm b/code/datums/elements/can_barricade.dm
index 49be7f5aafd..175738be5f6 100644
--- a/code/datums/elements/can_barricade.dm
+++ b/code/datums/elements/can_barricade.dm
@@ -11,23 +11,18 @@
return ELEMENT_INCOMPATIBLE
RegisterSignal(target, COMSIG_ATOM_ATTACKBY, PROC_REF(on_start_barricade))
- RegisterSignal(target, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine))
target.flags_1 |= HAS_CONTEXTUAL_SCREENTIPS_1
RegisterSignal(target, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, PROC_REF(on_requesting_context_from_item))
/datum/element/can_barricade/Detach(atom/target)
- UnregisterSignal(target, list(COMSIG_ATOM_ATTACKBY, COMSIG_ATOM_EXAMINE, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM))
+ UnregisterSignal(target, list(COMSIG_ATOM_ATTACKBY, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM))
// We don't remove HAS_CONTEXTUAL_SCREENTIPS_1, since there could be other stuff still hooked to it,
// and being set without signals is not dangerous, just less performant.
// A lot of things don't do this, perhaps make a proc that checks if any signals are still set, and if not,
// remove the flag.
return ..()
-/datum/element/can_barricade/proc/on_examine(atom/source, mob/user, list/examine_texts)
- SIGNAL_HANDLER
- examine_texts += span_notice("This looks like it can be barricaded with planks of wood.")
-
/datum/element/can_barricade/proc/on_start_barricade(atom/source, obj/item/stack/sheet/mineral/wood/plank, mob/living/user, params)
SIGNAL_HANDLER
diff --git a/code/datums/elements/chemical_transfer.dm b/code/datums/elements/chemical_transfer.dm
index 09391cbf390..9802f0cc059 100644
--- a/code/datums/elements/chemical_transfer.dm
+++ b/code/datums/elements/chemical_transfer.dm
@@ -58,7 +58,7 @@
return
var/built_attacker_message = replacetext(attacker_message, "%VICTIM", transfer_victim)
var/built_victim_message = replacetext(attacker_message, "%ATTACKER", transfer_attacker)
- transfer_attacker.reagents?.trans_to(transfer_victim, transfer_attacker.reagents.total_volume, multiplier = 1, preserve_data = 1, no_react = 0, transfered_by = transfer_attacker)
+ transfer_attacker.reagents?.trans_to(transfer_victim, transfer_attacker.reagents.total_volume, multiplier = 1, preserve_data = 1, no_react = 0, transferred_by = transfer_attacker)
to_chat(transfer_attacker, built_attacker_message)
to_chat(transfer_victim, built_victim_message)
diff --git a/code/datums/elements/content_barfer.dm b/code/datums/elements/content_barfer.dm
index e683db3782a..e30294bc08a 100644
--- a/code/datums/elements/content_barfer.dm
+++ b/code/datums/elements/content_barfer.dm
@@ -4,18 +4,17 @@
* Used for morphs and bileworms!
*/
/datum/element/content_barfer
- argument_hash_start_idx = 2
-/datum/element/content_barfer/Attach(datum/target, tally_string)
+/datum/element/content_barfer/Attach(datum/target)
. = ..()
if(!isliving(target))
return ELEMENT_INCOMPATIBLE
- RegisterSignals(target, list(COMSIG_LIVING_DEATH, COMSIG_LIVING_ON_WABBAJACKED, COMSIG_LIVING_UNSHAPESHIFTED), PROC_REF(barf_contents))
+ RegisterSignals(target, list(COMSIG_LIVING_DEATH, COMSIG_LIVING_ON_WABBAJACKED, COMSIG_LIVING_UNSHAPESHIFTED, COMSIG_MOB_CHANGED_TYPE), PROC_REF(barf_contents))
/datum/element/content_barfer/Detach(datum/target)
- UnregisterSignal(target, list(COMSIG_LIVING_DEATH, COMSIG_LIVING_ON_WABBAJACKED, COMSIG_LIVING_UNSHAPESHIFTED))
+ UnregisterSignal(target, list(COMSIG_LIVING_DEATH, COMSIG_LIVING_ON_WABBAJACKED, COMSIG_LIVING_UNSHAPESHIFTED, COMSIG_MOB_CHANGED_TYPE))
return ..()
/datum/element/content_barfer/proc/barf_contents(mob/living/target)
diff --git a/code/datums/elements/dryable.dm b/code/datums/elements/dryable.dm
index 2985f4b7f1e..c17547971b5 100644
--- a/code/datums/elements/dryable.dm
+++ b/code/datums/elements/dryable.dm
@@ -29,7 +29,6 @@
ADD_TRAIT(resulting_atom, TRAIT_DRIED, ELEMENT_TRAIT(type))
resulting_atom.forceMove(source.drop_location())
return
-
else if(isstack(source)) //Check if its a sheet
var/obj/item/stack/itemstack = dried_atom
for(var/i in 1 to itemstack.amount)
@@ -37,6 +36,14 @@
ADD_TRAIT(resulting_atom, TRAIT_DRIED, ELEMENT_TRAIT(type))
qdel(source)
return
+ else if(istype(source, /obj/item/food) && ispath(dry_result, /obj/item/food))
+ var/obj/item/food/source_food = source
+ var/obj/item/food/resulting_food = new dry_result(source.drop_location())
+ resulting_food.reagents.clear_reagents()
+ source_food.reagents.trans_to(resulting_food, source_food.reagents.total_volume)
+ ADD_TRAIT(resulting_food, TRAIT_DRIED, ELEMENT_TRAIT(type))
+ qdel(source)
+ return
else
var/atom/movable/resulting_atom = new dry_result(source.drop_location())
ADD_TRAIT(resulting_atom, TRAIT_DRIED, ELEMENT_TRAIT(type))
diff --git a/code/datums/elements/embed.dm b/code/datums/elements/embed.dm
index 0ba3a581d9a..1bc70dc500f 100644
--- a/code/datums/elements/embed.dm
+++ b/code/datums/elements/embed.dm
@@ -76,6 +76,9 @@
if(blocked || !istype(victim) || HAS_TRAIT(victim, TRAIT_PIERCEIMMUNE))
return FALSE
+
+ if(victim.status_flags & GODMODE)
+ return FALSE
var/flying_speed = throwingdatum?.speed || weapon.throw_speed
diff --git a/code/datums/elements/food/dunkable.dm b/code/datums/elements/food/dunkable.dm
index a948772ce00..d413119e285 100644
--- a/code/datums/elements/food/dunkable.dm
+++ b/code/datums/elements/food/dunkable.dm
@@ -3,7 +3,7 @@
/datum/element/dunkable
element_flags = ELEMENT_BESPOKE
argument_hash_start_idx = 2
- var/dunk_amount // the amount of reagents that will be transfered from the container to the item on each click
+ var/dunk_amount // the amount of reagents that will be transferred from the container to the item on each click
/datum/element/dunkable/Attach(datum/target, amount_per_dunk)
. = ..()
@@ -28,7 +28,7 @@
to_chat(user, span_warning("[container] is unable to be dunked in!"))
return COMPONENT_AFTERATTACK_PROCESSED_ITEM
var/obj/item/I = source // the item that has the dunkable element
- if(container.reagents.trans_to(I, dunk_amount, transfered_by = user)) //if reagents were transfered, show the message
+ if(container.reagents.trans_to(I, dunk_amount, transferred_by = user)) //if reagents were transferred, show the message
to_chat(user, span_notice("You dunk \the [I] into \the [container]."))
return COMPONENT_AFTERATTACK_PROCESSED_ITEM
if(!container.reagents.total_volume)
diff --git a/code/datums/elements/food/food_trash.dm b/code/datums/elements/food/food_trash.dm
index 6d2b21a400d..0a9d5540609 100644
--- a/code/datums/elements/food/food_trash.dm
+++ b/code/datums/elements/food/food_trash.dm
@@ -48,8 +48,14 @@
/datum/element/food_trash/proc/async_generate_trash(datum/source)
var/atom/edible_object = source
+ var/obj/item/trash_item
- var/obj/item/trash_item = generate_trash_procpath ? call(source, generate_trash_procpath)() : new trash(edible_object.drop_location())
+ if(istype(source, /obj/item/food/grown) && ispath(trash, /obj/item/food))
+ var/obj/item/food/grown/plant = source
+ var/reagent_purity = plant.seed.get_reagent_purity()
+ trash_item = new trash(edible_object.drop_location(), reagent_purity)
+ else
+ trash_item = generate_trash_procpath ? call(source, generate_trash_procpath)() : new trash(edible_object.drop_location())
if(isliving(edible_object.loc))
var/mob/living/food_holding_mob = edible_object.loc
diff --git a/code/datums/elements/food/microwavable.dm b/code/datums/elements/food/microwavable.dm
index 86a43c0603c..3ad3e272d34 100644
--- a/code/datums/elements/food/microwavable.dm
+++ b/code/datums/elements/food/microwavable.dm
@@ -35,7 +35,6 @@
if(isstack(source))
var/obj/item/stack/stack_source = source
result = new result_typepath(result_loc, stack_source.amount)
-
else
result = new result_typepath(result_loc)
@@ -45,8 +44,7 @@
if(IS_EDIBLE(result))
if(microwaver && microwaver.mind)
ADD_TRAIT(result, TRAIT_FOOD_CHEF_MADE, REF(microwaver.mind))
-
- result.reagents?.multiply_reagents(efficiency * CRAFTED_FOOD_BASE_REAGENT_MODIFIER)
+ result.reagents.clear_reagents()
source.reagents?.trans_to(result, source.reagents.total_volume)
BLACKBOX_LOG_FOOD_MADE(result.type)
diff --git a/code/datums/elements/gags_recolorable.dm b/code/datums/elements/gags_recolorable.dm
new file mode 100644
index 00000000000..bf37a4ba973
--- /dev/null
+++ b/code/datums/elements/gags_recolorable.dm
@@ -0,0 +1,62 @@
+///An element that lets players recolor the item through the greyscale menu with the help of a spraycan.
+/datum/element/gags_recolorable
+
+/datum/element/gags_recolorable/Attach(datum/target)
+ . = ..()
+ if(!isatom(target))
+ return ELEMENT_INCOMPATIBLE
+ RegisterSignal(target, COMSIG_ATOM_ATTACKBY, PROC_REF(on_attackby))
+ RegisterSignal(target, COMSIG_ATOM_EXAMINE_MORE, PROC_REF(on_examine))
+
+/datum/element/gags_recolorable/proc/on_examine(atom/source, mob/user, list/examine_text)
+ SIGNAL_HANDLER
+ examine_text += span_notice("You could recolor [source.p_them()] with a spraycan...")
+
+/datum/element/gags_recolorable/proc/on_attackby(datum/source, obj/item/attacking_item, mob/user)
+ SIGNAL_HANDLER
+
+ if(!istype(attacking_item, /obj/item/toy/crayon/spraycan))
+ return
+ var/obj/item/toy/crayon/spraycan/can = attacking_item
+
+ if(can.is_capped || can.check_empty())
+ return
+
+ INVOKE_ASYNC(src, PROC_REF(open_ui), user, can, source)
+ return COMPONENT_NO_AFTERATTACK
+
+/datum/element/gags_recolorable/proc/open_ui(mob/user, obj/item/toy/crayon/spraycan/can, atom/target)
+ var/list/allowed_configs = list()
+ var/config = initial(target.greyscale_config)
+ if(!config)
+ return
+ allowed_configs += "[config]"
+ if(isitem(target))
+ var/obj/item/item = target
+ if(initial(item.greyscale_config_worn))
+ allowed_configs += "[initial(item.greyscale_config_worn)]"
+ if(initial(item.greyscale_config_inhand_left))
+ allowed_configs += "[initial(item.greyscale_config_inhand_left)]"
+ if(initial(item.greyscale_config_inhand_right))
+ allowed_configs += "[initial(item.greyscale_config_inhand_right)]"
+
+ var/datum/greyscale_modify_menu/spray_paint/menu = new(
+ target, user, allowed_configs, CALLBACK(src, PROC_REF(recolor), user, can, target),
+ starting_icon_state = initial(target.icon_state),
+ starting_config = initial(target.greyscale_config),
+ starting_colors = target.greyscale_colors,
+ used_spraycan = can,
+ )
+ menu.ui_interact(user)
+
+/datum/element/gags_recolorable/proc/recolor(mob/user, obj/item/toy/crayon/spraycan/can, atom/target, datum/greyscale_modify_menu/menu)
+ if(can.is_capped || can.check_empty(user))
+ menu.ui_close()
+ return
+
+ can.use_charges()
+ if(can.pre_noise)
+ target.audible_message(span_hear("You hear spraying."))
+ playsound(target.loc, 'sound/effects/spray.ogg', 5, TRUE, 5)
+
+ target.set_greyscale(menu.split_colors)
diff --git a/code/datums/elements/kneecapping.dm b/code/datums/elements/kneecapping.dm
index f652a196323..340938c430c 100644
--- a/code/datums/elements/kneecapping.dm
+++ b/code/datums/elements/kneecapping.dm
@@ -80,9 +80,11 @@
if(do_after(attacker, 3 SECONDS, target, interaction_key = weapon))
attacker.visible_message(span_warning("[attacker] swings [attacker.p_their()] [weapon] at [target]'s kneecaps!"), span_danger("You swing \the [weapon] at [target]'s kneecaps!"))
- var/datum/wound/blunt/severe/severe_wound_type = /datum/wound/blunt/severe
- var/datum/wound/blunt/critical/critical_wound_type = /datum/wound/blunt/critical
- leg.receive_damage(brute = weapon.force, wound_bonus = rand(initial(severe_wound_type.threshold_minimum), initial(critical_wound_type.threshold_minimum) + 10), damage_source = "kneecapping")
+
+ var/min_wound = leg.get_wound_threshold_of_wound_type(WOUND_BLUNT, WOUND_SEVERITY_SEVERE, return_value_if_no_wound = 30, wound_source = weapon)
+ var/max_wound = leg.get_wound_threshold_of_wound_type(WOUND_BLUNT, WOUND_SEVERITY_CRITICAL, return_value_if_no_wound = 50, wound_source = weapon)
+
+ leg.receive_damage(brute = weapon.force, wound_bonus = rand(min_wound, max_wound + 10), damage_source = "kneecapping")
target.emote("scream")
log_combat(attacker, target, "broke the kneecaps of", weapon)
target.update_damage_overlays()
diff --git a/code/datums/elements/light_eater.dm b/code/datums/elements/light_eater.dm
index f60a922b9d7..b4f7cf1042f 100644
--- a/code/datums/elements/light_eater.dm
+++ b/code/datums/elements/light_eater.dm
@@ -83,6 +83,9 @@
* - [eater][/datum]: The light eater eating the morsel. This is the datum that the element is attached to that started this chain.
*/
/datum/element/light_eater/proc/devour(atom/morsel, datum/eater)
+ var/static/list/undevourable = typecacheof(list(/turf/open/space))
+ if(is_type_in_typecache(morsel, undevourable))
+ return FALSE
if(morsel.light_power <= 0 || morsel.light_range <= 0 || !morsel.light_on)
return FALSE
if(SEND_SIGNAL(morsel, COMSIG_LIGHT_EATER_ACT, eater) & COMPONENT_BLOCK_LIGHT_EATER)
diff --git a/code/datums/elements/mob_grabber.dm b/code/datums/elements/mob_grabber.dm
new file mode 100644
index 00000000000..a85c5dc48b2
--- /dev/null
+++ b/code/datums/elements/mob_grabber.dm
@@ -0,0 +1,30 @@
+/// Grab onto mobs we attack
+/datum/element/mob_grabber
+ element_flags = ELEMENT_BESPOKE
+ argument_hash_start_idx = 2
+ /// What state must the mob be in to be grabbed?
+ var/minimum_stat
+ /// If someone else is already grabbing this, will we take it?
+ var/steal_from_others
+
+/datum/element/mob_grabber/Attach(datum/target, minimum_stat = SOFT_CRIT, steal_from_others = TRUE)
+ . = ..()
+ if (!isliving(target))
+ return ELEMENT_INCOMPATIBLE
+ src.minimum_stat = minimum_stat
+ src.steal_from_others = steal_from_others
+ RegisterSignals(target, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, COMSIG_HOSTILE_PRE_ATTACKINGTARGET), PROC_REF(grab_mob))
+
+/datum/element/mob_grabber/Detach(datum/source)
+ UnregisterSignal(source, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, COMSIG_HOSTILE_PRE_ATTACKINGTARGET))
+ . = ..()
+
+/// Try and grab something we attacked
+/datum/element/mob_grabber/proc/grab_mob(mob/living/source, mob/living/target)
+ SIGNAL_HANDLER
+ if (!isliving(target) || !source.Adjacent(target) || target.stat < minimum_stat)
+ return
+ var/atom/currently_pulled = target.pulledby
+ if (!isnull(currently_pulled) && (!steal_from_others || currently_pulled == source))
+ return
+ INVOKE_ASYNC(target, TYPE_PROC_REF(/mob/living, grabbedby), source)
diff --git a/code/datums/elements/movement_turf_changer.dm b/code/datums/elements/movement_turf_changer.dm
index 1147c3a8353..c42ef287f81 100644
--- a/code/datums/elements/movement_turf_changer.dm
+++ b/code/datums/elements/movement_turf_changer.dm
@@ -26,7 +26,7 @@
SIGNAL_HANDLER
var/turf/destination = target.loc
- if(!isturf(destination) || istype(destination, turf_type) || isopenspaceturf(destination))
+ if(!isturf(destination) || istype(destination, turf_type) || isgroundlessturf(destination))
return
destination.PlaceOnTop(turf_type)
diff --git a/code/datums/elements/openspace_item_click_handler.dm b/code/datums/elements/openspace_item_click_handler.dm
index 43c7a60d1ef..c9de01f381c 100644
--- a/code/datums/elements/openspace_item_click_handler.dm
+++ b/code/datums/elements/openspace_item_click_handler.dm
@@ -21,7 +21,7 @@
return
var/turf/checked_turf = get_turf(target)
while(!isnull(checked_turf))
- checked_turf = checked_turf.above()
+ checked_turf = GET_TURF_ABOVE(checked_turf)
if(checked_turf?.z == user.z)
INVOKE_ASYNC(source, TYPE_PROC_REF(/obj/item, handle_openspace_click), checked_turf, user, user.CanReach(checked_turf, source), click_parameters)
break
diff --git a/code/datums/elements/turf_transparency.dm b/code/datums/elements/turf_transparency.dm
index ab3a17dc40d..b050dd0866f 100644
--- a/code/datums/elements/turf_transparency.dm
+++ b/code/datums/elements/turf_transparency.dm
@@ -103,7 +103,7 @@ GLOBAL_LIST_EMPTY(pillars_by_z)
if(!holding)
return
- var/turf/visual_target = to_display.above()
+ var/turf/visual_target = GET_TURF_ABOVE(to_display)
/// Basically, if we used to be under a non transparent turf, but are no longer in that position
/// Then we add to the transparent turf we're now under, and nuke the old object
if(!istransparentturf(visual_target))
@@ -120,7 +120,7 @@ GLOBAL_LIST_EMPTY(pillars_by_z)
turf_sources[to_display] = sources
sources |= source
- var/turf/visual_target = to_display.above()
+ var/turf/visual_target = GET_TURF_ABOVE(to_display)
if(istransparentturf(visual_target) || isopenspaceturf(visual_target))
visual_target.vis_contents += to_display
else
@@ -142,7 +142,7 @@ GLOBAL_LIST_EMPTY(pillars_by_z)
if(holding)
qdel(holding)
else
- var/turf/visual_target = to_hide.above()
+ var/turf/visual_target = GET_TURF_ABOVE(to_hide)
visual_target.vis_contents -= to_hide
if(!length(turf_sources) && !QDELETED(src))
@@ -201,7 +201,7 @@ GLOBAL_LIST_EMPTY(pillars_by_z)
///Updates the viscontents or underlays below this tile.
/datum/element/turf_z_transparency/proc/update_multi_z(turf/our_turf)
- var/turf/below_turf = our_turf.below()
+ var/turf/below_turf = GET_TURF_BELOW(our_turf)
if(below_turf) // If we actually have something below us, display it.
for(var/turf/partner in range(1, below_turf))
// We use our z here to ensure the pillar is actually on our level
@@ -228,7 +228,7 @@ GLOBAL_LIST_EMPTY(pillars_by_z)
return TRUE
/datum/element/turf_z_transparency/proc/clear_multiz(turf/our_turf)
- var/turf/below_turf = our_turf.below()
+ var/turf/below_turf = GET_TURF_BELOW(our_turf)
if(below_turf) // If we actually have something below us, we need to clear ourselves from it
for(var/turf/partner in range(1, below_turf))
// We use our z here to ensure the pillar is actually on our level
diff --git a/code/datums/elements/uplink_reimburse.dm b/code/datums/elements/uplink_reimburse.dm
index 5387f245d8c..3ff182ec231 100644
--- a/code/datums/elements/uplink_reimburse.dm
+++ b/code/datums/elements/uplink_reimburse.dm
@@ -1,5 +1,5 @@
/**
- * Uplinik Reimburse element.
+ * Uplink Reimburse element.
* When element is applied onto items, it allows them to be reimbursed if an user pokes an item with a uplink component with them.
*
* Element is only compatible with items.
@@ -21,9 +21,11 @@
RegisterSignal(target, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine))
RegisterSignal(target, COMSIG_ITEM_ATTEMPT_TC_REIMBURSE, PROC_REF(reimburse))
-
+ RegisterSignal(target,COMSIG_TRAITOR_ITEM_USED(target.type), PROC_REF(used))
+
/datum/element/uplink_reimburse/Detach(datum/target)
- UnregisterSignal(target, list(COMSIG_ATOM_ATTACKBY, COMSIG_ATOM_EXAMINE))
+ UnregisterSignal(target, list(COMSIG_ATOM_EXAMINE, COMSIG_TRAITOR_ITEM_USED(target.type), COMSIG_ITEM_ATTEMPT_TC_REIMBURSE))
+
return ..()
@@ -47,3 +49,8 @@
do_sparks(2, source = uplink_comp.uplink_handler)
uplink_comp.add_telecrystals(refundable_tc)
qdel(refund_item)
+/// If the item is used, it needs to no longer be refundable
+/datum/element/uplink_reimburse/proc/used(datum/target)
+ SIGNAL_HANDLER
+
+ Detach(target)
diff --git a/code/datums/emotes.dm b/code/datums/emotes.dm
index 96a525eecd9..f1f7eb12433 100644
--- a/code/datums/emotes.dm
+++ b/code/datums/emotes.dm
@@ -216,6 +216,10 @@
/datum/emote/proc/select_message_type(mob/user, msg, intentional)
// Basically, we don't care that the others can use datum variables, because they're never going to change.
. = msg
+ if(!isliving(user))
+ return .
+ var/mob/living/living_user = user
+
if(!muzzle_ignore && user.is_muzzled() && emote_type & EMOTE_AUDIBLE)
return "makes a [pick("strong ", "weak ", "")]noise."
if(HAS_MIND_TRAIT(user, TRAIT_MIMING) && message_mime)
@@ -224,15 +228,17 @@
. = message_alien
else if(islarva(user) && message_larva)
. = message_larva
- else if(iscyborg(user) && message_robot)
- . = message_robot
else if(isAI(user) && message_AI)
. = message_AI
else if(ismonkey(user) && message_monkey)
. = message_monkey
+ else if((iscyborg(user) || (living_user.mob_biotypes & MOB_ROBOTIC)) && message_robot)
+ . = message_robot
else if(isanimal_or_basicmob(user) && message_animal_or_basic)
. = message_animal_or_basic
+ return .
+
/**
* Replaces the %t in the message in message_param by params.
*
diff --git a/code/datums/greyscale/README.md b/code/datums/greyscale/README.md
index d650bda5d13..65f5c488790 100644
--- a/code/datums/greyscale/README.md
+++ b/code/datums/greyscale/README.md
@@ -9,7 +9,9 @@ If you're wanting to add easy recolors for your sprite then this is the system f
## Other Documents
+- [Troubleshooting help](https://hackmd.io/@tgstation/GAGS-Troubleshooting)
- [Basic follow along guide on hackmd](https://hackmd.io/@tgstation/GAGS-Walkthrough)
+- [Layer types list](https://hackmd.io/@tgstation/GAGS-Layer-Types)
## Broad overview
diff --git a/code/datums/greyscale/config_types/greyscale_configs/greyscale_clothes.dm b/code/datums/greyscale/config_types/greyscale_configs/greyscale_clothes.dm
index 95a27524bd0..5ff1fde7c27 100644
--- a/code/datums/greyscale/config_types/greyscale_configs/greyscale_clothes.dm
+++ b/code/datums/greyscale/config_types/greyscale_configs/greyscale_clothes.dm
@@ -497,6 +497,15 @@ SKYRAT EDIT END */
name = "Worn Marisa Sneakers (Worn)"
icon_file = 'icons/mob/clothing/feet.dmi'
+/datum/greyscale_config/glow_shoes
+ name = "Glow Shoes"
+ icon_file = 'icons/obj/clothing/shoes.dmi'
+ json_config = 'code/datums/greyscale/json_configs/glow_shoes.json'
+
+/datum/greyscale_config/glow_shoes/worn
+ name = "Glow Shoes (Worn)"
+ icon_file = 'icons/mob/clothing/feet.dmi'
+
//
// ACCESSORIES
//
@@ -628,3 +637,51 @@ SKYRAT EDIT END */
/datum/greyscale_config/witch_hat/worn
name = "Witch Hat (Worn)"
icon_file = 'icons/mob/clothing/head/wizard.dmi'
+
+/datum/greyscale_config/wellworn_shirt
+ name = "Well-Worn Shirt"
+ icon_file = 'icons/obj/clothing/suits/costume.dmi'
+ json_config = 'code/datums/greyscale/json_configs/wellworn_shirt.json'
+
+/datum/greyscale_config/wellworn_shirt/worn
+ name = "Well-Worn Shirt (Worn)"
+ icon_file = 'icons/mob/clothing/suits/costume.dmi'
+
+/datum/greyscale_config/wellworn_shirt_graphic
+ name = "Well-Worn Shirt (Graphic)"
+ icon_file = 'icons/obj/clothing/suits/costume.dmi'
+ json_config = 'code/datums/greyscale/json_configs/wellworn_shirt_graphic.json'
+
+/datum/greyscale_config/wellworn_shirt_graphic/worn
+ name = "Well-Worn Shirt (Graphic)(Worn)"
+ icon_file = 'icons/mob/clothing/suits/costume.dmi'
+
+/datum/greyscale_config/wellworn_shirt/wornout
+ name = "Worn-Out Shirt"
+
+/datum/greyscale_config/wellworn_shirt/worn/wornout
+ name = "Worn-Out Shirt (Worn)"
+
+/datum/greyscale_config/wornout_shirt_graphic
+ name = "Worn-Out Shirt (Graphic)"
+ icon_file = 'icons/obj/clothing/suits/costume.dmi'
+ json_config = 'code/datums/greyscale/json_configs/wornout_shirt_graphic.json'
+
+/datum/greyscale_config/wornout_shirt_graphic/worn
+ name = "Worn-Out Shirt (Graphic)(Worn)"
+ icon_file = 'icons/mob/clothing/suits/costume.dmi'
+
+/datum/greyscale_config/wellworn_shirt/messy
+ name = "Messy Worn Shirt"
+
+/datum/greyscale_config/wellworn_shirt/worn/messy
+ name = "Messy Worn Shirt (Worn)"
+
+/datum/greyscale_config/messyworn_shirt_graphic
+ name = "Messy Shirt (Graphic)"
+ icon_file = 'icons/obj/clothing/suits/costume.dmi'
+ json_config = 'code/datums/greyscale/json_configs/messyworn_shirt_graphic.json'
+
+/datum/greyscale_config/messyworn_shirt_graphic/worn
+ name = "Messy Shirt (Graphic (Worn)"
+ icon_file = 'icons/mob/clothing/suits/costume.dmi'
diff --git a/code/datums/greyscale/json_configs/glow_shoes.json b/code/datums/greyscale/json_configs/glow_shoes.json
new file mode 100644
index 00000000000..d78fe5b7de0
--- /dev/null
+++ b/code/datums/greyscale/json_configs/glow_shoes.json
@@ -0,0 +1,16 @@
+{
+ "glow_shoes": [
+ {
+ "type": "icon_state",
+ "icon_state": "glow_shoes_back",
+ "blend_mode": "overlay",
+ "color_ids": [ 1 ]
+ },
+ {
+ "type": "icon_state",
+ "icon_state": "glow_shoes_front",
+ "blend_mode": "overlay",
+ "color_ids": [ 2 ]
+ }
+ ]
+}
diff --git a/code/datums/greyscale/json_configs/messyworn_shirt_graphic.json b/code/datums/greyscale/json_configs/messyworn_shirt_graphic.json
new file mode 100644
index 00000000000..85950d388e2
--- /dev/null
+++ b/code/datums/greyscale/json_configs/messyworn_shirt_graphic.json
@@ -0,0 +1,40 @@
+{
+ "messyworn_shirt_gamer": [
+ {
+ "type": "icon_state",
+ "icon_state": "worn_messy",
+ "blend_mode": "overlay",
+ "color_ids": [ 1 ]
+ },
+ {
+ "type": "icon_state",
+ "icon_state": "nerd_overlay",
+ "blend_mode": "overlay",
+ "color_ids": [ 2 ]
+ },
+ {
+ "type": "icon_state",
+ "icon_state": "nerd_base",
+ "blend_mode": "overlay"
+ }
+ ],
+ "messyworn_shirt_ian": [
+ {
+ "type": "icon_state",
+ "icon_state": "worn_messy",
+ "blend_mode": "overlay",
+ "color_ids": [ 1 ]
+ },
+ {
+ "type": "icon_state",
+ "icon_state": "ian_overlay",
+ "blend_mode": "overlay",
+ "color_ids": [ 2 ]
+ },
+ {
+ "type": "icon_state",
+ "icon_state": "ian_base",
+ "blend_mode": "overlay"
+ }
+ ]
+}
diff --git a/code/datums/greyscale/json_configs/wellworn_shirt.json b/code/datums/greyscale/json_configs/wellworn_shirt.json
new file mode 100644
index 00000000000..d58335abc4c
--- /dev/null
+++ b/code/datums/greyscale/json_configs/wellworn_shirt.json
@@ -0,0 +1,26 @@
+{
+ "wellworn_shirt": [
+ {
+ "type": "icon_state",
+ "icon_state": "worn_clean",
+ "blend_mode": "overlay",
+ "color_ids": [ 1 ]
+ }
+ ],
+ "wornout_shirt": [
+ {
+ "type": "icon_state",
+ "icon_state": "worn_out",
+ "blend_mode": "overlay",
+ "color_ids": [ 1 ]
+ }
+ ],
+ "messyworn_shirt": [
+ {
+ "type": "icon_state",
+ "icon_state": "worn_messy",
+ "blend_mode": "overlay",
+ "color_ids": [ 1 ]
+ }
+ ]
+}
diff --git a/code/datums/greyscale/json_configs/wellworn_shirt_graphic.json b/code/datums/greyscale/json_configs/wellworn_shirt_graphic.json
new file mode 100644
index 00000000000..a9226607f29
--- /dev/null
+++ b/code/datums/greyscale/json_configs/wellworn_shirt_graphic.json
@@ -0,0 +1,41 @@
+{
+ "wellworn_shirt_gamer": [
+ {
+ "type": "icon_state",
+ "icon_state": "worn_clean",
+ "blend_mode": "overlay",
+ "color_ids": [ 1 ]
+ },
+ {
+ "type": "icon_state",
+ "icon_state": "nerd_overlay",
+ "blend_mode": "overlay",
+ "color_ids": [ 2 ]
+
+ },
+ {
+ "type": "icon_state",
+ "icon_state": "nerd_base",
+ "blend_mode": "overlay"
+ }
+ ],
+ "wellworn_shirt_ian": [
+ {
+ "type": "icon_state",
+ "icon_state": "worn_clean",
+ "blend_mode": "overlay",
+ "color_ids": [ 1 ]
+ },
+ {
+ "type": "icon_state",
+ "icon_state": "ian_overlay",
+ "blend_mode": "overlay",
+ "color_ids": [ 2 ]
+ },
+ {
+ "type": "icon_state",
+ "icon_state": "ian_base",
+ "blend_mode": "overlay"
+ }
+ ]
+}
diff --git a/code/datums/greyscale/json_configs/wornout_shirt_graphic.json b/code/datums/greyscale/json_configs/wornout_shirt_graphic.json
new file mode 100644
index 00000000000..6ca12b5db68
--- /dev/null
+++ b/code/datums/greyscale/json_configs/wornout_shirt_graphic.json
@@ -0,0 +1,40 @@
+{
+ "wornout_shirt_gamer": [
+ {
+ "type": "icon_state",
+ "icon_state": "worn_out",
+ "blend_mode": "overlay",
+ "color_ids": [ 1 ]
+ },
+ {
+ "type": "icon_state",
+ "icon_state": "nerd_overlay",
+ "blend_mode": "overlay",
+ "color_ids": [ 2 ]
+ },
+ {
+ "type": "icon_state",
+ "icon_state": "nerd_base",
+ "blend_mode": "overlay"
+ }
+ ],
+ "wornout_shirt_ian": [
+ {
+ "type": "icon_state",
+ "icon_state": "worn_out",
+ "blend_mode": "overlay",
+ "color_ids": [ 1 ]
+ },
+ {
+ "type": "icon_state",
+ "icon_state": "ian_overlay",
+ "blend_mode": "overlay",
+ "color_ids": [ 2 ]
+ },
+ {
+ "type": "icon_state",
+ "icon_state": "ian_base",
+ "blend_mode": "overlay"
+ }
+ ]
+}
diff --git a/code/datums/keybinding/living.dm b/code/datums/keybinding/living.dm
index f0f306344b5..84e3685f5f8 100644
--- a/code/datums/keybinding/living.dm
+++ b/code/datums/keybinding/living.dm
@@ -119,3 +119,38 @@
return
var/mob/living/user_mob = user.mob
user_mob.set_combat_mode(FALSE, silent = FALSE)
+
+/datum/keybinding/living/toggle_move_intent
+ hotkey_keys = list("Alt") //SKYRAT EDIT CHANGE - C IS FOR COMBAT INDICATOR - ORIGINAL: hotkey_keys = list("C")
+ name = "toggle_move_intent"
+ full_name = "Hold to toggle move intent"
+ description = "Held down to cycle to the other move intent, release to cycle back"
+ keybind_signal = COMSIG_KB_LIVING_TOGGLEMOVEINTENT_DOWN
+
+/datum/keybinding/living/toggle_move_intent/down(client/user)
+ . = ..()
+ if(.)
+ return
+ var/mob/living/M = user.mob
+ M.toggle_move_intent()
+ return TRUE
+
+/datum/keybinding/living/toggle_move_intent/up(client/user)
+ var/mob/living/M = user.mob
+ M.toggle_move_intent()
+ return TRUE
+
+/datum/keybinding/living/toggle_move_intent_alternative
+ hotkey_keys = list("Unbound")
+ name = "toggle_move_intent_alt"
+ full_name = "press to cycle move intent"
+ description = "Pressing this cycle to the opposite move intent, does not cycle back"
+ keybind_signal = COMSIG_KB_LIVING_TOGGLEMOVEINTENTALT_DOWN
+
+/datum/keybinding/living/toggle_move_intent_alternative/down(client/user)
+ . = ..()
+ if(.)
+ return
+ var/mob/living/M = user.mob
+ M.toggle_move_intent()
+ return TRUE
diff --git a/code/datums/keybinding/mob.dm b/code/datums/keybinding/mob.dm
index a53e3390e12..def4ec36fb2 100644
--- a/code/datums/keybinding/mob.dm
+++ b/code/datums/keybinding/mob.dm
@@ -71,41 +71,6 @@
user.mob.dropItemToGround(I)
return TRUE
-/datum/keybinding/mob/toggle_move_intent
- hotkey_keys = list("Alt") //SKYRAT EDIT CHANGE - COMBAT_INDICATOR
- name = "toggle_move_intent"
- full_name = "Hold to toggle move intent"
- description = "Held down to cycle to the other move intent, release to cycle back"
- keybind_signal = COMSIG_KB_MOB_TOGGLEMOVEINTENT_DOWN
-
-/datum/keybinding/mob/toggle_move_intent/down(client/user)
- . = ..()
- if(.)
- return
- var/mob/living/M = user.mob
- M.toggle_move_intent()
- return TRUE
-
-/datum/keybinding/mob/toggle_move_intent/up(client/user)
- var/mob/living/M = user.mob
- M.toggle_move_intent()
- return TRUE
-
-/datum/keybinding/mob/toggle_move_intent_alternative
- hotkey_keys = list("Unbound")
- name = "toggle_move_intent_alt"
- full_name = "press to cycle move intent"
- description = "Pressing this cycle to the opposite move intent, does not cycle back"
- keybind_signal = COMSIG_KB_MOB_TOGGLEMOVEINTENTALT_DOWN
-
-/datum/keybinding/mob/toggle_move_intent_alternative/down(client/user)
- . = ..()
- if(.)
- return
- var/mob/living/M = user.mob
- M.toggle_move_intent()
- return TRUE
-
/datum/keybinding/mob/target/down(client/user)
. = ..()
if(.)
diff --git a/code/datums/lazy_template.dm b/code/datums/lazy_template.dm
index af6df50e96f..0b8b2999f69 100644
--- a/code/datums/lazy_template.dm
+++ b/code/datums/lazy_template.dm
@@ -10,8 +10,6 @@
var/key
var/map_dir = "_maps/templates/lazy_templates"
var/map_name
- var/map_width
- var/map_height
/datum/lazy_template/New()
reservations = list()
@@ -46,25 +44,53 @@
if(!load_path || !fexists(load_path))
CRASH("lazy template [type] has an invalid load_path: '[load_path]', check directory and map name!")
- var/datum/map_template/loading = new(path = load_path, cache = TRUE)
- if(!loading.cached_map)
+ var/datum/parsed_map/parsed_template = load_map(
+ file(load_path),
+ measure_only = TRUE,
+ )
+ if(isnull(parsed_template.parsed_bounds))
CRASH("Failed to cache lazy template for loading: '[key]'")
- var/datum/turf_reservation/reservation = SSmapping.RequestBlockReservation(loading.width, loading.height)
+ var/width = parsed_template.parsed_bounds[MAP_MAXX] - parsed_template.parsed_bounds[MAP_MINX] + 1
+ var/height = parsed_template.parsed_bounds[MAP_MAXY] - parsed_template.parsed_bounds[MAP_MINY] + 1
+ var/datum/turf_reservation/reservation = SSmapping.request_turf_block_reservation(
+ width,
+ height,
+ parsed_template.parsed_bounds[MAP_MAXZ],
+ )
if(!reservation)
CRASH("Failed to reserve a block for lazy template: '[key]'")
- if(!loading.load(coords2turf(reservation.bottom_left_coords)))
- CRASH("Failed to load lazy template: '[key]'")
- reservations += reservation
+ var/list/loaded_atom_movables = list()
+ var/list/loaded_turfs = list()
+ var/list/loaded_areas = list()
+ for(var/z_idx in parsed_template.parsed_bounds[MAP_MAXZ] to 1 step -1)
+ var/turf/bottom_left = reservation.bottom_left_turfs[z_idx]
+ var/turf/top_right = reservation.top_right_turfs[z_idx]
+ load_map(
+ file(load_path),
+ bottom_left.x,
+ bottom_left.y,
+ bottom_left.z,
+ z_upper = z_idx,
+ z_lower = z_idx,
+ )
+ for(var/turf/turf as anything in block(bottom_left, top_right))
+ loaded_turfs += turf
+ loaded_areas |= get_area(turf)
+ for(var/thing in turf.get_all_contents())
+ // atoms can actually be in the contents of two or more turfs based on its icon/bound size
+ // see https://www.byond.com/docs/ref/index.html#/atom/var/contents
+ loaded_atom_movables |= thing
+ SSatoms.InitializeAtoms(loaded_atom_movables + loaded_turfs + loaded_areas)
+ SEND_SIGNAL(src, COMSIG_LAZY_TEMPLATE_LOADED, loaded_atom_movables, loaded_turfs, loaded_areas)
+ reservations += reservation
return reservation
/datum/lazy_template/nukie_base
key = LAZY_TEMPLATE_KEY_NUKIEBASE
map_name = "nukie_base"
- map_width = 89
- map_height = 100
/datum/lazy_template/wizard_dem
key = LAZY_TEMPLATE_KEY_WIZARDDEN
@@ -77,3 +103,7 @@
/datum/lazy_template/abductor_ship
key = LAZY_TEMPLATE_KEY_ABDUCTOR_SHIPS
map_name = "abductor_ships"
+
+/datum/lazy_template/heretic_sacrifice_room
+ key = LAZY_TEMPLATE_KEY_HERETIC_SACRIFICE
+ map_name = "heretic_sacrifice"
diff --git a/code/datums/mapgen/Cavegens/LavalandGenerator.dm b/code/datums/mapgen/Cavegens/LavalandGenerator.dm
index be8294fada6..6f8aa7ed1bb 100644
--- a/code/datums/mapgen/Cavegens/LavalandGenerator.dm
+++ b/code/datums/mapgen/Cavegens/LavalandGenerator.dm
@@ -8,8 +8,8 @@
/obj/effect/spawner/random/lavaland_mob/legion = 30,
/obj/effect/spawner/random/lavaland_mob/watcher = 40,
/mob/living/basic/mining/bileworm = 20,
+ /mob/living/basic/mining/brimdemon = 20,
/mob/living/basic/mining/lobstrosity/lava = 20,
- /mob/living/simple_animal/hostile/asteroid/brimdemon = 20,
/mob/living/basic/mining/goldgrub = 10,
/obj/structure/spawner/lavaland = 2,
/obj/structure/spawner/lavaland/goliath = 3,
diff --git a/code/datums/martial/plasma_fist.dm b/code/datums/martial/plasma_fist.dm
index ed8ac5fe812..1bc353cc698 100644
--- a/code/datums/martial/plasma_fist.dm
+++ b/code/datums/martial/plasma_fist.dm
@@ -98,6 +98,7 @@
human_attacker.underwear = "Nude"
human_attacker.undershirt = "Nude"
human_attacker.socks = "Nude"
+ human_attacker.bra = "Nude" // SKYRAT EDIT ADDITION - Underwear and bra split
human_attacker.update_body()
var/turf/boomspot = get_turf(user)
diff --git a/code/datums/materials/meat.dm b/code/datums/materials/meat.dm
index 07b477b39d8..eebf3abe29a 100644
--- a/code/datums/materials/meat.dm
+++ b/code/datums/materials/meat.dm
@@ -31,7 +31,7 @@
var/nutriment_count = 3 * (amount / SHEET_MATERIAL_AMOUNT)
var/oil_count = 2 * (amount / SHEET_MATERIAL_AMOUNT)
source.AddComponent(/datum/component/edible, \
- initial_reagents = list(/datum/reagent/consumable/nutriment = nutriment_count, /datum/reagent/consumable/cooking_oil = oil_count), \
+ initial_reagents = list(/datum/reagent/consumable/nutriment = nutriment_count, /datum/reagent/consumable/nutriment/fat/oil = oil_count), \
foodtypes = RAW | MEAT | GROSS, \
eat_time = 3 SECONDS, \
tastes = list("Fleshy"))
diff --git a/code/datums/materials/pizza.dm b/code/datums/materials/pizza.dm
index 6a7c4a6922a..588018576be 100644
--- a/code/datums/materials/pizza.dm
+++ b/code/datums/materials/pizza.dm
@@ -29,7 +29,7 @@
var/nutriment_count = 3 * (amount / SHEET_MATERIAL_AMOUNT)
var/oil_count = 2 * (amount / SHEET_MATERIAL_AMOUNT)
source.AddComponent(/datum/component/edible, \
- initial_reagents = list(/datum/reagent/consumable/nutriment = nutriment_count, /datum/reagent/consumable/cooking_oil = oil_count), \
+ initial_reagents = list(/datum/reagent/consumable/nutriment = nutriment_count, /datum/reagent/consumable/nutriment/fat/oil = oil_count), \
foodtypes = GRAIN | MEAT | DAIRY | VEGETABLES, \
eat_time = 3 SECONDS, \
tastes = list("crust", "tomato", "cheese", "meat"))
diff --git a/code/datums/mind/_mind.dm b/code/datums/mind/_mind.dm
index 1087855265f..fa9114a5284 100644
--- a/code/datums/mind/_mind.dm
+++ b/code/datums/mind/_mind.dm
@@ -8,7 +8,7 @@
ghost.mind is however used as a reference to the ghost's corpse
- When creating a new mob for an existing IC character (e.g. cloning a dead guy or borging a brain of a human)
- the existing mind of the old mob should be transfered to the new mob like so:
+ the existing mind of the old mob should be transferred to the new mob like so:
mind.transfer_to(new_mob)
@@ -357,6 +357,41 @@
objective.completed = !objective.completed
log_admin("[key_name(usr)] toggled the win state for [current]'s objective: [objective.explanation_text]")
+ else if(href_list["obj_prompt_custom"])
+ var/datum/antagonist/target_antag
+ if(href_list["target_antag"])
+ var/datum/antagonist/found_datum = locate(href_list["target_antag"]) in antag_datums
+ if(found_datum)
+ target_antag = found_datum
+ if(isnull(target_antag))
+ switch(length(antag_datums))
+ if(0)
+ target_antag = add_antag_datum(/datum/antagonist/custom)
+ if(1)
+ target_antag = antag_datums[1]
+ else
+ var/datum/antagonist/target = input("Which antagonist gets the objective:", "Antagonist", "(new custom antag)") as null|anything in sort_list(antag_datums) + "(new custom antag)"
+ if (QDELETED(target))
+ return
+ else if(target == "(new custom antag)")
+ target_antag = add_antag_datum(/datum/antagonist/custom)
+ else
+ target_antag = target
+ var/replace_existing = input("Replace existing objectives?","Replace objectives?") in list("Yes", "No")
+ if (isnull(replace_existing))
+ return
+ replace_existing = replace_existing == "Yes"
+ var/replace_escape
+ if (!replace_existing)
+ replace_escape = FALSE
+ else
+ replace_escape = input("Replace survive/escape/martyr objectives?","Replace objectives?") in list("Yes", "No")
+ if (isnull(replace_escape))
+ return
+ replace_escape = replace_escape == "Yes"
+ target_antag.submit_player_objective(retain_existing = !replace_existing, retain_escape = !replace_escape, force = TRUE)
+ log_admin("[key_name(usr)] prompted [current] to enter their own objectives for [target_antag].")
+
else if (href_list["silicon"])
switch(href_list["silicon"])
if("unemag")
diff --git a/code/datums/mood.dm b/code/datums/mood.dm
index fa5fe5563ff..76f08641ecb 100644
--- a/code/datums/mood.dm
+++ b/code/datums/mood.dm
@@ -139,8 +139,9 @@
* Arguments:
* * category - (text) category of the mood event - see /datum/mood_event for category explanation
* * type - (path) any /datum/mood_event
+ * * timeout_mod - (number) /datum/mood_event timeout modifier
*/
-/datum/mood/proc/add_mood_event(category, type, ...)
+/datum/mood/proc/add_mood_event(category, type, timeout_mod = 1, ...)
if (!ispath(type, /datum/mood_event))
CRASH("A non path ([type]), was used to add a mood event. This shouldn't be happening.")
if (!istext(category))
@@ -153,6 +154,7 @@
clear_mood_event(category)
else
if (the_event.timeout)
+ the_event.timeout = initial(the_event.timeout) * timeout_mod
addtimer(CALLBACK(src, PROC_REF(clear_mood_event), category), the_event.timeout, (TIMER_UNIQUE|TIMER_OVERRIDE))
return // Don't need to update the event.
var/list/params = args.Copy(3)
@@ -162,8 +164,9 @@
if (QDELETED(the_event)) // the mood event has been deleted for whatever reason (requires a job, etc)
return
- mood_events[category] = the_event
+ the_event.timeout *= timeout_mod
the_event.category = category
+ mood_events[category] = the_event
update_mood()
if (the_event.timeout)
diff --git a/code/datums/mood_events/food_events.dm b/code/datums/mood_events/food_events.dm
new file mode 100644
index 00000000000..7d2dcc439de
--- /dev/null
+++ b/code/datums/mood_events/food_events.dm
@@ -0,0 +1,46 @@
+/datum/mood_event/favorite_food
+ description = "I really enjoyed eating that."
+ mood_change = 5
+ timeout = 4 MINUTES
+
+/datum/mood_event/gross_food
+ description = "I really didn't like that food."
+ mood_change = -2
+ timeout = 4 MINUTES
+
+/datum/mood_event/disgusting_food
+ description = "That food was disgusting!"
+ mood_change = -6
+ timeout = 4 MINUTES
+
+/datum/mood_event/breakfast
+ description = "Nothing like a hearty breakfast to start the shift."
+ mood_change = 2
+ timeout = 10 MINUTES
+
+/datum/mood_event/food
+ timeout = 5 MINUTES
+ var/quality = FOOD_QUALITY_NORMAL
+
+/datum/mood_event/food/New(mob/M, ...)
+ . = ..()
+ mood_change = 2 + 2 * quality
+ description = "That food was [GLOB.food_quality_description[quality]]."
+
+/datum/mood_event/food/nice
+ quality = FOOD_QUALITY_NICE
+
+/datum/mood_event/food/good
+ quality = FOOD_QUALITY_GOOD
+
+/datum/mood_event/food/verygood
+ quality = FOOD_QUALITY_VERYGOOD
+
+/datum/mood_event/food/fantastic
+ quality = FOOD_QUALITY_FANTASTIC
+
+/datum/mood_event/food/amazing
+ quality = FOOD_QUALITY_AMAZING
+
+/datum/mood_event/food/top
+ quality = FOOD_QUALITY_TOP
diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm
index 28526d9b8b3..a5aa648ecee 100644
--- a/code/datums/mood_events/generic_negative_events.dm
+++ b/code/datums/mood_events/generic_negative_events.dm
@@ -48,7 +48,7 @@
timeout = 4 MINUTES
/datum/mood_event/cascade // Big boi delamination
- description = "The engineers have finally done it, we are all going to die..."
+ description = "I never thought I'd see a resonance cascade, let alone experience one..."
mood_change = -8
timeout = 5 MINUTES
@@ -78,13 +78,13 @@
timeout = 60 SECONDS
/datum/mood_event/dismembered
- description = "AHH! I WAS USING THAT LIMB!"
+ description = "AHH! MY LIMB! I WAS USING THAT!"
mood_change = -10
timeout = 8 MINUTES
/datum/mood_event/dismembered/add_effects(obj/item/bodypart/limb)
if(limb)
- description = "AHH! I WAS USING THAT [full_capitalize(limb.plaintext_zone)]"
+ description = "AHH! MY [uppertext(limb.plaintext_zone)]! I WAS USING THAT!"
/datum/mood_event/reattachment
description = "Ouch! My limb feels like I fell asleep on it."
@@ -430,3 +430,9 @@
/datum/mood_event/unsatisfied_nomad
description = "I've been here too long! I want to go out and explore space!"
mood_change = -3
+
+///Wizard cheesy grand finale - what everyone but the wizard gets
+/datum/mood_event/madness_despair
+ description = "UNWORTHY, UNWORTHY, UNWORTHY!!!"
+ mood_change = -200
+ special_screen_obj = "mood_despair"
diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm
index 4d7457d6bec..29b414440e1 100644
--- a/code/datums/mood_events/generic_positive_events.dm
+++ b/code/datums/mood_events/generic_positive_events.dm
@@ -374,3 +374,8 @@
description = "Slam dunk! Boom, shakalaka!"
mood_change = 2
timeout = 5 MINUTES
+
+///Wizard cheesy grand finale - what the wizard gets
+/datum/mood_event/madness_elation
+ description = "Madness truly is the greatest of blessings..."
+ mood_change = 200
diff --git a/code/datums/mood_events/needs_events.dm b/code/datums/mood_events/needs_events.dm
index 01281963cc1..ceee687918e 100644
--- a/code/datums/mood_events/needs_events.dm
+++ b/code/datums/mood_events/needs_events.dm
@@ -67,26 +67,6 @@
timeout = 4 MINUTES
//Generic needs events
-/datum/mood_event/favorite_food
- description = "I really enjoyed eating that."
- mood_change = 5
- timeout = 4 MINUTES
-
-/datum/mood_event/gross_food
- description = "I really didn't like that food."
- mood_change = -2
- timeout = 4 MINUTES
-
-/datum/mood_event/disgusting_food
- description = "That food was disgusting!"
- mood_change = -6
- timeout = 4 MINUTES
-
-/datum/mood_event/breakfast
- description = "Nothing like a hearty breakfast to start the shift."
- mood_change = 2
- timeout = 10 MINUTES
-
/datum/mood_event/nice_shower
description = "I have recently had a nice shower."
mood_change = 4
diff --git a/code/datums/mutations/hulk.dm b/code/datums/mutations/hulk.dm
index 0de7daa6589..9ab5d4b86ef 100644
--- a/code/datums/mutations/hulk.dm
+++ b/code/datums/mutations/hulk.dm
@@ -63,13 +63,19 @@
*arg1 is the arm to evaluate damage of and possibly break.
*/
/datum/mutation/human/hulk/proc/break_an_arm(obj/item/bodypart/arm)
+ var/severity
switch(arm.brute_dam)
if(45 to 50)
- arm.force_wound_upwards(/datum/wound/blunt/critical, wound_source = "hulk smashing")
+ severity = WOUND_SEVERITY_CRITICAL
if(41 to 45)
- arm.force_wound_upwards(/datum/wound/blunt/severe, wound_source = "hulk smashing")
+ severity = WOUND_SEVERITY_SEVERE
if(35 to 41)
- arm.force_wound_upwards(/datum/wound/blunt/moderate, wound_source = "hulk smashing")
+ severity = WOUND_SEVERITY_MODERATE
+
+ if (isnull(severity))
+ return
+
+ owner.cause_wound_of_type_and_severity(WOUND_BLUNT, arm, severity, wound_source = "hulk smashing")
/datum/mutation/human/hulk/on_life(seconds_per_tick, times_fired)
if(owner.health < owner.crit_threshold)
diff --git a/code/datums/mutations/tongue_spike.dm b/code/datums/mutations/tongue_spike.dm
index cde1bcaf6fe..5d210c344b5 100644
--- a/code/datums/mutations/tongue_spike.dm
+++ b/code/datums/mutations/tongue_spike.dm
@@ -130,7 +130,7 @@
return
var/datum/action/send_chems/chem_action = new(src)
- chem_action.transfered_ref = WEAKREF(embedded_mob)
+ chem_action.transferred_ref = WEAKREF(embedded_mob)
chem_action.Grant(fired_by)
to_chat(fired_by, span_notice("Link established! Use the \"Transfer Chemicals\" ability \
@@ -154,7 +154,7 @@
check_flags = AB_CHECK_CONSCIOUS
/// Weakref to the mob target that we transfer chemicals to on activation
- var/datum/weakref/transfered_ref
+ var/datum/weakref/transferred_ref
/datum/action/send_chems/New(Target)
. = ..()
@@ -168,12 +168,12 @@
if(!ishuman(owner) || !owner.reagents)
return FALSE
var/mob/living/carbon/human/transferer = owner
- var/mob/living/carbon/human/transfered = transfered_ref?.resolve()
- if(!ishuman(transfered))
+ var/mob/living/carbon/human/transferred = transferred_ref?.resolve()
+ if(!ishuman(transferred))
return FALSE
- to_chat(transfered, span_warning("You feel a tiny prick!"))
- transferer.reagents.trans_to(transfered, transferer.reagents.total_volume, 1, 1, 0, transfered_by = transferer)
+ to_chat(transferred, span_warning("You feel a tiny prick!"))
+ transferer.reagents.trans_to(transferred, transferer.reagents.total_volume, 1, 1, 0, transferred_by = transferer)
var/obj/item/hardened_spike/chem/chem_spike = target
var/obj/item/bodypart/spike_location = chem_spike.check_embedded()
diff --git a/code/datums/mutations/void_magnet.dm b/code/datums/mutations/void_magnet.dm
index 56b22d664a8..d6636b0b630 100644
--- a/code/datums/mutations/void_magnet.dm
+++ b/code/datums/mutations/void_magnet.dm
@@ -60,7 +60,7 @@
/datum/action/cooldown/spell/void/cursed/proc/on_life(mob/living/source, seconds_per_tick, times_fired)
SIGNAL_HANDLER
- if(!isliving(source) || IS_IN_STASIS(source) || source.stat == DEAD || source.notransform)
+ if(!isliving(source) || IS_IN_STASIS(source) || source.stat == DEAD || HAS_TRAIT(source, TRAIT_NO_TRANSFORM))
return
if(!is_valid_target(source))
diff --git a/code/datums/outfit.dm b/code/datums/outfit.dm
index 8dc2c99f632..784e7a1b06f 100644
--- a/code/datums/outfit.dm
+++ b/code/datums/outfit.dm
@@ -220,6 +220,12 @@
if(socks)
user.socks = initial(socks.name)
+
+ // SKYRAT EDIT ADDITION START - Underwear and bra split
+ if(bra)
+ user.bra = initial(bra.name)
+ // SKYRAT EDIT END
+
if(accessory)
var/obj/item/clothing/under/U = user.w_uniform
if(U)
diff --git a/code/datums/quirks/negative_quirks/allergic.dm b/code/datums/quirks/negative_quirks/allergic.dm
new file mode 100644
index 00000000000..d6a510f62b6
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/allergic.dm
@@ -0,0 +1,71 @@
+/datum/quirk/item_quirk/allergic
+ name = "Extreme Medicine Allergy"
+ desc = "Ever since you were a kid, you've been allergic to certain chemicals..."
+ icon = FA_ICON_PRESCRIPTION_BOTTLE
+ value = -6
+ gain_text = span_danger("You feel your immune system shift.")
+ lose_text = span_notice("You feel your immune system phase back into perfect shape.")
+ medical_record_text = "Patient's immune system responds violently to certain chemicals."
+ hardcore_value = 3
+ quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES
+ mail_goodies = list(/obj/item/reagent_containers/hypospray/medipen) // epinephrine medipen stops allergic reactions
+ var/list/allergies = list()
+ var/list/blacklist = list(
+ /datum/reagent/medicine/c2,
+ /datum/reagent/medicine/epinephrine,
+ /datum/reagent/medicine/adminordrazine,
+ /datum/reagent/medicine/adminordrazine/quantum_heal,
+ /datum/reagent/medicine/omnizine/godblood,
+ /datum/reagent/medicine/cordiolis_hepatico,
+ /datum/reagent/medicine/synaphydramine,
+ /datum/reagent/medicine/diphenhydramine,
+ /datum/reagent/medicine/sansufentanyl
+ )
+ var/allergy_string
+
+/datum/quirk/item_quirk/allergic/add_unique(client/client_source)
+ var/list/chem_list = subtypesof(/datum/reagent/medicine) - blacklist
+ var/list/allergy_chem_names = list()
+ for(var/i in 0 to 5)
+ var/datum/reagent/medicine/chem_type = pick_n_take(chem_list)
+ allergies += chem_type
+ allergy_chem_names += initial(chem_type.name)
+
+ allergy_string = allergy_chem_names.Join(", ")
+ name = "Extreme [allergy_string] Allergies"
+ medical_record_text = "Patient's immune system responds violently to [allergy_string]"
+
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ var/obj/item/clothing/accessory/dogtag/allergy/dogtag = new(get_turf(human_holder), allergy_string)
+
+ give_item_to_holder(dogtag, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS), flavour_text = "Make sure medical staff can see this...")
+
+/datum/quirk/item_quirk/allergic/post_add()
+ quirk_holder.add_mob_memory(/datum/memory/key/quirk_allergy, allergy_string = allergy_string)
+ to_chat(quirk_holder, span_boldnotice("You are allergic to [allergy_string], make sure not to consume any of these!"))
+
+/datum/quirk/item_quirk/allergic/process(seconds_per_tick)
+ if(!iscarbon(quirk_holder))
+ return
+
+ if(IS_IN_STASIS(quirk_holder))
+ return
+
+ if(quirk_holder.stat == DEAD)
+ return
+
+ var/mob/living/carbon/carbon_quirk_holder = quirk_holder
+ for(var/allergy in allergies)
+ var/datum/reagent/instantiated_med = carbon_quirk_holder.reagents.has_reagent(allergy)
+ if(!instantiated_med)
+ continue
+ //Just halts the progression, I'd suggest you run to medbay asap to get it fixed
+ if(carbon_quirk_holder.reagents.has_reagent(/datum/reagent/medicine/epinephrine))
+ instantiated_med.reagent_removal_skip_list |= ALLERGIC_REMOVAL_SKIP
+ return //intentionally stops the entire proc so we avoid the organ damage after the loop
+ instantiated_med.reagent_removal_skip_list -= ALLERGIC_REMOVAL_SKIP
+ carbon_quirk_holder.adjustToxLoss(3 * seconds_per_tick)
+ carbon_quirk_holder.reagents.add_reagent(/datum/reagent/toxin/histamine, 3 * seconds_per_tick)
+ if(SPT_PROB(10, seconds_per_tick))
+ carbon_quirk_holder.vomit(VOMIT_CATEGORY_DEFAULT)
+ carbon_quirk_holder.adjustOrganLoss(pick(ORGAN_SLOT_BRAIN,ORGAN_SLOT_APPENDIX,ORGAN_SLOT_LUNGS,ORGAN_SLOT_HEART,ORGAN_SLOT_LIVER,ORGAN_SLOT_STOMACH),10)
diff --git a/code/datums/quirks/negative_quirks/bad_back.dm b/code/datums/quirks/negative_quirks/bad_back.dm
new file mode 100644
index 00000000000..b7c40636159
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/bad_back.dm
@@ -0,0 +1,50 @@
+/datum/quirk/badback
+ name = "Bad Back"
+ desc = "Thanks to your poor posture, backpacks and other bags never sit right on your back. More evenly weighted objects are fine, though."
+ icon = FA_ICON_HIKING
+ value = -8
+ quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_MOODLET_BASED
+ gain_text = span_danger("Your back REALLY hurts!")
+ lose_text = span_notice("Your back feels better.")
+ medical_record_text = "Patient scans indicate severe and chronic back pain."
+ hardcore_value = 4
+ mail_goodies = list(/obj/item/cane)
+ var/datum/weakref/backpack
+
+/datum/quirk/badback/add(client/client_source)
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ var/obj/item/storage/backpack/equipped_backpack = human_holder.back
+ if(istype(equipped_backpack))
+ quirk_holder.add_mood_event("back_pain", /datum/mood_event/back_pain)
+ RegisterSignal(human_holder.back, COMSIG_ITEM_POST_UNEQUIP, PROC_REF(on_unequipped_backpack))
+ else
+ RegisterSignal(quirk_holder, COMSIG_MOB_EQUIPPED_ITEM, PROC_REF(on_equipped_item))
+
+/datum/quirk/badback/remove()
+ UnregisterSignal(quirk_holder, COMSIG_MOB_EQUIPPED_ITEM)
+
+ var/obj/item/storage/equipped_backpack = backpack?.resolve()
+ if(equipped_backpack)
+ UnregisterSignal(equipped_backpack, COMSIG_ITEM_POST_UNEQUIP)
+ quirk_holder.clear_mood_event("back_pain")
+
+/// Signal handler for when the quirk_holder equips an item. If it's a backpack, adds the back_pain mood event.
+/datum/quirk/badback/proc/on_equipped_item(mob/living/source, obj/item/equipped_item, slot)
+ SIGNAL_HANDLER
+
+ if(!(slot & ITEM_SLOT_BACK) || !istype(equipped_item, /obj/item/storage/backpack))
+ return
+
+ quirk_holder.add_mood_event("back_pain", /datum/mood_event/back_pain)
+ RegisterSignal(equipped_item, COMSIG_ITEM_POST_UNEQUIP, PROC_REF(on_unequipped_backpack))
+ UnregisterSignal(quirk_holder, COMSIG_MOB_EQUIPPED_ITEM)
+ backpack = WEAKREF(equipped_item)
+
+/// Signal handler for when the quirk_holder unequips an equipped backpack. Removes the back_pain mood event.
+/datum/quirk/badback/proc/on_unequipped_backpack(obj/item/source, force, atom/newloc, no_move, invdrop, silent)
+ SIGNAL_HANDLER
+
+ UnregisterSignal(source, COMSIG_ITEM_POST_UNEQUIP)
+ quirk_holder.clear_mood_event("back_pain")
+ backpack = null
+ RegisterSignal(quirk_holder, COMSIG_MOB_EQUIPPED_ITEM, PROC_REF(on_equipped_item))
diff --git a/code/datums/quirks/negative_quirks/bad_touch.dm b/code/datums/quirks/negative_quirks/bad_touch.dm
new file mode 100644
index 00000000000..f3a5d967a01
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/bad_touch.dm
@@ -0,0 +1,31 @@
+/datum/quirk/bad_touch
+ name = "Bad Touch"
+ desc = "You don't like hugs. You'd really prefer if people just left you alone."
+ icon = "tg-bad-touch"
+ mob_trait = TRAIT_BADTOUCH
+ value = -1
+ gain_text = span_danger("You just want people to leave you alone.")
+ lose_text = span_notice("You could use a big hug.")
+ medical_record_text = "Patient has disdain for being touched. Potentially has undiagnosed haphephobia."
+ quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_MOODLET_BASED
+ hardcore_value = 1
+ mail_goodies = list(/obj/item/reagent_containers/spray/pepper) // show me on the doll where the bad man touched you
+
+/datum/quirk/bad_touch/add(client/client_source)
+ RegisterSignals(quirk_holder, list(COMSIG_LIVING_GET_PULLED, COMSIG_CARBON_HELP_ACT), PROC_REF(uncomfortable_touch))
+
+/datum/quirk/bad_touch/remove()
+ UnregisterSignal(quirk_holder, list(COMSIG_LIVING_GET_PULLED, COMSIG_CARBON_HELP_ACT))
+
+/// Causes a negative moodlet to our quirk holder on signal
+/datum/quirk/bad_touch/proc/uncomfortable_touch(datum/source)
+ SIGNAL_HANDLER
+
+ if(quirk_holder.stat == DEAD)
+ return
+
+ new /obj/effect/temp_visual/annoyed(quirk_holder.loc)
+ if(quirk_holder.mob_mood.sanity <= SANITY_NEUTRAL)
+ quirk_holder.add_mood_event("bad_touch", /datum/mood_event/very_bad_touch)
+ else
+ quirk_holder.add_mood_event("bad_touch", /datum/mood_event/bad_touch)
diff --git a/code/datums/quirks/negative_quirks/big_hands.dm b/code/datums/quirks/negative_quirks/big_hands.dm
new file mode 100644
index 00000000000..778ea6af8c3
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/big_hands.dm
@@ -0,0 +1,10 @@
+/datum/quirk/bighands
+ name = "Big Hands"
+ desc = "You have big hands, it sure does make it hard to use a lot of things."
+ icon = FA_ICON_HAND_DOTS
+ value = -6
+ mob_trait = TRAIT_CHUNKYFINGERS
+ gain_text = span_danger("Your hands are huge! You can't use small things anymore!")
+ lose_text = span_notice("Your hands are back to normal.")
+ medical_record_text = "Patient has unusually large hands. Made me question my masculinity..."
+ hardcore_value = 5
diff --git a/code/datums/quirks/negative_quirks/blindness.dm b/code/datums/quirks/negative_quirks/blindness.dm
new file mode 100644
index 00000000000..ce57e946fe9
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/blindness.dm
@@ -0,0 +1,20 @@
+/datum/quirk/item_quirk/blindness
+ name = "Blind"
+ desc = "You are completely blind, nothing can counteract this."
+ icon = FA_ICON_EYE_SLASH
+ value = -16
+ gain_text = span_danger("You can't see anything.")
+ lose_text = span_notice("You miraculously gain back your vision.")
+ medical_record_text = "Patient has permanent blindness."
+ hardcore_value = 15
+ quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE
+ mail_goodies = list(/obj/item/clothing/glasses/sunglasses, /obj/item/cane/white)
+
+/datum/quirk/item_quirk/blindness/add_unique(client/client_source)
+ give_item_to_holder(/obj/item/clothing/glasses/blindfold/white, list(LOCATION_EYES = ITEM_SLOT_EYES, LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
+
+/datum/quirk/item_quirk/blindness/add(client/client_source)
+ quirk_holder.become_blind(QUIRK_TRAIT)
+
+/datum/quirk/item_quirk/blindness/remove()
+ quirk_holder.cure_blind(QUIRK_TRAIT)
diff --git a/code/datums/quirks/negative_quirks/blood_deficiency.dm b/code/datums/quirks/negative_quirks/blood_deficiency.dm
new file mode 100644
index 00000000000..c75007bacc2
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/blood_deficiency.dm
@@ -0,0 +1,39 @@
+/datum/quirk/blooddeficiency
+ name = "Blood Deficiency"
+ desc = "Your body can't produce enough blood to sustain itself."
+ icon = FA_ICON_TINT
+ value = -8
+ mob_trait = TRAIT_BLOOD_DEFICIENCY
+ gain_text = span_danger("You feel your vigor slowly fading away.")
+ lose_text = span_notice("You feel vigorous again.")
+ medical_record_text = "Patient requires regular treatment for blood loss due to low production of blood."
+ hardcore_value = 8
+ mail_goodies = list(/obj/item/reagent_containers/blood/o_minus) // universal blood type that is safe for all
+ var/min_blood = BLOOD_VOLUME_SAFE - 25 // just barely survivable without treatment
+
+/datum/quirk/blooddeficiency/post_add()
+ if(!ishuman(quirk_holder))
+ return
+
+ // for making sure the roundstart species has the right blood pack sent to them
+ var/mob/living/carbon/human/carbon_target = quirk_holder
+ carbon_target.dna.species.update_quirk_mail_goodies(carbon_target, src)
+
+/**
+ * Makes the mob lose blood from having the blood deficiency quirk, if possible
+ *
+ * Arguments:
+ * * seconds_per_tick
+ */
+/datum/quirk/blooddeficiency/proc/lose_blood(seconds_per_tick)
+ if(quirk_holder.stat == DEAD)
+ return
+
+ var/mob/living/carbon/human/carbon_target = quirk_holder
+ if(HAS_TRAIT(carbon_target, TRAIT_NOBLOOD) && isnull(carbon_target.dna.species.exotic_blood)) //can't lose blood if your species doesn't have any
+ return
+
+ if (carbon_target.blood_volume <= min_blood)
+ return
+ // Ensures that we don't reduce total blood volume below min_blood.
+ carbon_target.blood_volume = max(min_blood, carbon_target.blood_volume - carbon_target.dna.species.blood_deficiency_drain_rate * seconds_per_tick)
diff --git a/code/datums/quirks/negative_quirks/body_purist.dm b/code/datums/quirks/negative_quirks/body_purist.dm
new file mode 100644
index 00000000000..6350a710882
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/body_purist.dm
@@ -0,0 +1,69 @@
+/datum/quirk/body_purist
+ name = "Body Purist"
+ desc = "You believe your body is a temple and its natural form is an embodiment of perfection. Accordingly, you despise the idea of ever augmenting it with unnatural parts, cybernetic, prosthetic, or anything like it."
+ icon = FA_ICON_PERSON_RAYS
+ value = -2
+ quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_MOODLET_BASED
+ gain_text = span_danger("You now begin to hate the idea of having cybernetic implants.")
+ lose_text = span_notice("Maybe cybernetics aren't so bad. You now feel okay with augmentations and prosthetics.")
+ medical_record_text = "This patient has disclosed an extreme hatred for unnatural bodyparts and augmentations."
+ hardcore_value = 3
+ mail_goodies = list(/obj/item/paper/pamphlet/cybernetics)
+ var/cybernetics_level = 0
+
+/datum/quirk/body_purist/add(client/client_source)
+ check_cybernetics()
+ RegisterSignal(quirk_holder, COMSIG_CARBON_GAIN_ORGAN, PROC_REF(on_organ_gain))
+ RegisterSignal(quirk_holder, COMSIG_CARBON_LOSE_ORGAN, PROC_REF(on_organ_lose))
+ RegisterSignal(quirk_holder, COMSIG_CARBON_ATTACH_LIMB, PROC_REF(on_limb_gain))
+ RegisterSignal(quirk_holder, COMSIG_CARBON_REMOVE_LIMB, PROC_REF(on_limb_lose))
+
+/datum/quirk/body_purist/remove()
+ UnregisterSignal(quirk_holder, list(
+ COMSIG_CARBON_GAIN_ORGAN,
+ COMSIG_CARBON_LOSE_ORGAN,
+ COMSIG_CARBON_ATTACH_LIMB,
+ COMSIG_CARBON_REMOVE_LIMB,
+ ))
+ quirk_holder.clear_mood_event("body_purist")
+
+/datum/quirk/body_purist/proc/check_cybernetics()
+ var/mob/living/carbon/owner = quirk_holder
+ if(!istype(owner))
+ return
+ for(var/obj/item/bodypart/limb as anything in owner.bodyparts)
+ if(IS_ROBOTIC_LIMB(limb))
+ cybernetics_level++
+ for(var/obj/item/organ/organ as anything in owner.organs)
+ if(IS_ROBOTIC_ORGAN(organ) && !(organ.organ_flags & ORGAN_HIDDEN))
+ cybernetics_level++
+ update_mood()
+
+/datum/quirk/body_purist/proc/update_mood()
+ quirk_holder.clear_mood_event("body_purist")
+ if(cybernetics_level)
+ quirk_holder.add_mood_event("body_purist", /datum/mood_event/body_purist, -cybernetics_level * 10)
+
+/datum/quirk/body_purist/proc/on_organ_gain(datum/source, obj/item/organ/new_organ, special)
+ SIGNAL_HANDLER
+ if(IS_ROBOTIC_ORGAN(new_organ) && !(new_organ.organ_flags & ORGAN_HIDDEN)) //why the fuck are there 2 of them
+ cybernetics_level++
+ update_mood()
+
+/datum/quirk/body_purist/proc/on_organ_lose(datum/source, obj/item/organ/old_organ, special)
+ SIGNAL_HANDLER
+ if(IS_ROBOTIC_ORGAN(old_organ) && !(old_organ.organ_flags & ORGAN_HIDDEN))
+ cybernetics_level--
+ update_mood()
+
+/datum/quirk/body_purist/proc/on_limb_gain(datum/source, obj/item/bodypart/new_limb, special)
+ SIGNAL_HANDLER
+ if(IS_ROBOTIC_LIMB(new_limb))
+ cybernetics_level++
+ update_mood()
+
+/datum/quirk/body_purist/proc/on_limb_lose(datum/source, obj/item/bodypart/old_limb, special)
+ SIGNAL_HANDLER
+ if(IS_ROBOTIC_LIMB(old_limb))
+ cybernetics_level--
+ update_mood()
diff --git a/code/datums/quirks/negative_quirks/brain_problems.dm b/code/datums/quirks/negative_quirks/brain_problems.dm
new file mode 100644
index 00000000000..15cc0128020
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/brain_problems.dm
@@ -0,0 +1,37 @@
+ /* A couple of brain tumor stats for anyone curious / looking at this quirk for balancing:
+ * - It takes less 16 minute 40 seconds to die from brain death due to a brain tumor.
+ * - It takes 1 minutes 40 seconds to take 10% (20 organ damage) brain damage.
+ * - 5u mannitol will heal 12.5% (25 organ damage) brain damage
+ */
+/datum/quirk/item_quirk/brainproblems
+ name = "Brain Tumor"
+ desc = "You have a little friend in your brain that is slowly destroying it. Better bring some mannitol!"
+ icon = FA_ICON_BRAIN
+ value = -12
+ gain_text = span_danger("You feel smooth.")
+ lose_text = span_notice("You feel wrinkled again.")
+ medical_record_text = "Patient has a tumor in their brain that is slowly driving them to brain death."
+ hardcore_value = 12
+ quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES
+ mail_goodies = list(/obj/item/storage/pill_bottle/mannitol/braintumor)
+
+/datum/quirk/item_quirk/brainproblems/add_unique(client/client_source)
+ give_item_to_holder(
+ /obj/item/storage/pill_bottle/mannitol/braintumor,
+ list(
+ LOCATION_LPOCKET = ITEM_SLOT_LPOCKET,
+ LOCATION_RPOCKET = ITEM_SLOT_RPOCKET,
+ LOCATION_BACKPACK = ITEM_SLOT_BACKPACK,
+ LOCATION_HANDS = ITEM_SLOT_HANDS,
+ ),
+ flavour_text = "These will keep you alive until you can secure a supply of medication. Don't rely on them too much!",
+ )
+
+/datum/quirk/item_quirk/brainproblems/process(seconds_per_tick)
+ if(quirk_holder.stat == DEAD)
+ return
+
+ if(HAS_TRAIT(quirk_holder, TRAIT_TUMOR_SUPPRESSED))
+ return
+
+ quirk_holder.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.2 * seconds_per_tick)
diff --git a/code/datums/quirks/negative_quirks/chronic_illness.dm b/code/datums/quirks/negative_quirks/chronic_illness.dm
new file mode 100644
index 00000000000..663d4138198
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/chronic_illness.dm
@@ -0,0 +1,16 @@
+/datum/quirk/item_quirk/chronic_illness
+ name = "Chronic Illness"
+ desc = "You have a chronic illness that requires constant medication to keep under control."
+ icon = FA_ICON_DISEASE
+ value = -12
+ gain_text = span_danger("You feel a bit off today.")
+ lose_text = span_notice("You feel a bit better today.")
+ medical_record_text = "Patient has a chronic illness that requires constant medication to keep under control."
+ hardcore_value = 12
+ mail_goodies = list(/obj/item/storage/pill_bottle/sansufentanyl)
+
+/datum/quirk/item_quirk/chronic_illness/add_unique(client/client_source)
+ var/datum/disease/chronic_illness/hms = new /datum/disease/chronic_illness()
+ quirk_holder.ForceContractDisease(hms)
+ give_item_to_holder(/obj/item/storage/pill_bottle/sansufentanyl, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK),flavour_text = "You've been provided with medication to help manage your condition. Take it regularly to avoid complications.")
+ give_item_to_holder(/obj/item/healthanalyzer/simple/disease, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK))
diff --git a/code/datums/quirks/negative_quirks/claustrophobia.dm b/code/datums/quirks/negative_quirks/claustrophobia.dm
new file mode 100644
index 00000000000..e0207d227dd
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/claustrophobia.dm
@@ -0,0 +1,54 @@
+/datum/quirk/claustrophobia
+ name = "Claustrophobia"
+ desc = "You are terrified of small spaces and certain jolly figures. If you are placed inside any container, locker, or machinery, a panic attack sets in and you struggle to breathe."
+ icon = FA_ICON_BOX_OPEN
+ value = -4
+ medical_record_text = "Patient demonstrates a fear of tight spaces."
+ hardcore_value = 5
+ quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES
+ mail_goodies = list(/obj/item/reagent_containers/syringe/convermol) // to help breathing
+
+/datum/quirk/claustrophobia/remove()
+ quirk_holder.clear_mood_event("claustrophobia")
+
+/datum/quirk/claustrophobia/process(seconds_per_tick)
+ if(quirk_holder.stat != CONSCIOUS || quirk_holder.IsSleeping() || quirk_holder.IsUnconscious())
+ return
+
+ if(HAS_TRAIT(quirk_holder, TRAIT_FEARLESS))
+ return
+
+ var/nick_spotted = FALSE
+
+ for(var/mob/living/carbon/human/possible_claus in view(5, quirk_holder))
+ if(evaluate_jolly_levels(possible_claus))
+ nick_spotted = TRUE
+ break
+
+ if(!nick_spotted && isturf(quirk_holder.loc))
+ quirk_holder.clear_mood_event("claustrophobia")
+ return
+
+ quirk_holder.add_mood_event("claustrophobia", /datum/mood_event/claustrophobia)
+ quirk_holder.losebreath += 0.25 // miss a breath one in four times
+ if(SPT_PROB(25, seconds_per_tick))
+ if(nick_spotted)
+ to_chat(quirk_holder, span_warning("Santa Claus is here! I gotta get out of here!"))
+ else
+ to_chat(quirk_holder, span_warning("You feel trapped! Must escape... can't breathe..."))
+
+///investigates whether possible_saint_nick possesses a high level of christmas cheer
+/datum/quirk/claustrophobia/proc/evaluate_jolly_levels(mob/living/carbon/human/possible_saint_nick)
+ if(!istype(possible_saint_nick))
+ return FALSE
+
+ if(istype(possible_saint_nick.back, /obj/item/storage/backpack/santabag))
+ return TRUE
+
+ if(istype(possible_saint_nick.head, /obj/item/clothing/head/costume/santa) || istype(possible_saint_nick.head, /obj/item/clothing/head/helmet/space/santahat))
+ return TRUE
+
+ if(istype(possible_saint_nick.wear_suit, /obj/item/clothing/suit/space/santa))
+ return TRUE
+
+ return FALSE
diff --git a/code/datums/quirks/negative_quirks/clumsy.dm b/code/datums/quirks/negative_quirks/clumsy.dm
new file mode 100644
index 00000000000..8cf363753d4
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/clumsy.dm
@@ -0,0 +1,9 @@
+/datum/quirk/clumsy
+ name = "Clumsy"
+ desc = "You're clumsy, a goofball, a silly dude. You big loveable himbo/bimbo you! Hope you weren't planning on using your hands for anything that takes even a LICK of dexterity."
+ icon = FA_ICON_FACE_DIZZY
+ value = -8
+ mob_trait = TRAIT_CLUMSY
+ gain_text = span_danger("You feel your IQ sink like your brain is liquid.")
+ lose_text = span_notice("You feel like your IQ went up to at least average.")
+ medical_record_text = "Patient has demonstrated an extreme difficulty with high motor skill paired with an inability to demonstrate critical thinking."
diff --git a/code/datums/quirks/negative_quirks/cursed.dm b/code/datums/quirks/negative_quirks/cursed.dm
new file mode 100644
index 00000000000..4b99ff850b8
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/cursed.dm
@@ -0,0 +1,17 @@
+/*
+// SKYRAT EDIT REMOVAL
+/datum/quirk/cursed
+ name = "Cursed"
+ desc = "You are cursed with bad luck. You are much more likely to suffer from accidents and mishaps. When it rains, it pours."
+ icon = FA_ICON_CLOUD_SHOWERS_HEAVY
+ value = -8
+ mob_trait = TRAIT_CURSED
+ gain_text = span_danger("You feel like you're going to have a bad day.")
+ lose_text = span_notice("You feel like you're going to have a good day.")
+ medical_record_text = "Patient is cursed with bad luck."
+ hardcore_value = 8
+
+/datum/quirk/cursed/add(client/client_source)
+ quirk_holder.AddComponent(/datum/component/omen/quirk)
+*/
+// SKYRAT EDIT REMOVAL END
diff --git a/code/datums/quirks/negative_quirks/deafness.dm b/code/datums/quirks/negative_quirks/deafness.dm
new file mode 100644
index 00000000000..077bbe72aa5
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/deafness.dm
@@ -0,0 +1,14 @@
+/datum/quirk/item_quirk/deafness
+ name = "Deaf"
+ desc = "You are incurably deaf."
+ icon = FA_ICON_DEAF
+ value = -8
+ mob_trait = TRAIT_DEAF
+ gain_text = span_danger("You can't hear anything.")
+ lose_text = span_notice("You're able to hear again!")
+ medical_record_text = "Patient's cochlear nerve is incurably damaged."
+ hardcore_value = 12
+ mail_goodies = list(/obj/item/clothing/mask/whistle)
+
+/datum/quirk/item_quirk/deafness/add_unique(client/client_source)
+ give_item_to_holder(/obj/item/clothing/accessory/deaf_pin, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
diff --git a/code/datums/quirks/negative_quirks/depression.dm b/code/datums/quirks/negative_quirks/depression.dm
new file mode 100644
index 00000000000..0bf15516105
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/depression.dm
@@ -0,0 +1,12 @@
+/datum/quirk/depression
+ name = "Depression"
+ desc = "You sometimes just hate life."
+ icon = FA_ICON_FROWN
+ mob_trait = TRAIT_DEPRESSION
+ value = -3
+ gain_text = span_danger("You start feeling depressed.")
+ lose_text = span_notice("You no longer feel depressed.") //if only it were that easy!
+ medical_record_text = "Patient has a mild mood disorder causing them to experience acute episodes of depression."
+ quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_MOODLET_BASED
+ hardcore_value = 2
+ mail_goodies = list(/obj/item/storage/pill_bottle/happinesspsych)
diff --git a/code/datums/quirks/negative_quirks/family_heirloom.dm b/code/datums/quirks/negative_quirks/family_heirloom.dm
new file mode 100644
index 00000000000..0fd08c68f21
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/family_heirloom.dm
@@ -0,0 +1,72 @@
+/datum/quirk/item_quirk/family_heirloom
+ name = "Family Heirloom"
+ desc = "You are the current owner of an heirloom, passed down for generations. You have to keep it safe!"
+ icon = FA_ICON_TOOLBOX
+ value = -2
+ medical_record_text = "Patient demonstrates an unnatural attachment to a family heirloom."
+ hardcore_value = 1
+ quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES|QUIRK_MOODLET_BASED
+ /// A weak reference to our heirloom.
+ var/datum/weakref/heirloom
+ mail_goodies = list(/obj/item/storage/secure/briefcase)
+
+/datum/quirk/item_quirk/family_heirloom/add_unique(client/client_source)
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ var/obj/item/heirloom_type
+
+ // The quirk holder's species - we have a 50% chance, if we have a species with a set heirloom, to choose a species heirloom.
+ var/datum/species/holder_species = human_holder.dna?.species
+ if(holder_species && LAZYLEN(holder_species.family_heirlooms) && prob(50))
+ heirloom_type = pick(holder_species.family_heirlooms)
+ else
+ // Our quirk holder's job
+ var/datum/job/holder_job = human_holder.last_mind?.assigned_role
+ if(holder_job && LAZYLEN(holder_job.family_heirlooms))
+ heirloom_type = pick(holder_job.family_heirlooms)
+
+ // If we didn't find an heirloom somehow, throw them a generic one
+ if(!heirloom_type)
+ heirloom_type = pick(/obj/item/toy/cards/deck, /obj/item/lighter, /obj/item/dice/d20)
+
+ var/obj/new_heirloom = new heirloom_type(get_turf(human_holder))
+ heirloom = WEAKREF(new_heirloom)
+
+ give_item_to_holder(
+ new_heirloom,
+ list(
+ LOCATION_LPOCKET = ITEM_SLOT_LPOCKET,
+ LOCATION_RPOCKET = ITEM_SLOT_RPOCKET,
+ LOCATION_BACKPACK = ITEM_SLOT_BACKPACK,
+ LOCATION_HANDS = ITEM_SLOT_HANDS,
+ ),
+ flavour_text = "This is a precious family heirloom, passed down from generation to generation. Keep it safe!",
+ )
+
+/datum/quirk/item_quirk/family_heirloom/post_add()
+ var/list/names = splittext(quirk_holder.real_name, " ")
+ var/family_name = names[names.len]
+
+ var/obj/family_heirloom = heirloom?.resolve()
+ if(!family_heirloom)
+ to_chat(quirk_holder, span_boldnotice("A wave of existential dread runs over you as you realize your precious family heirloom is missing. Perhaps the Gods will show mercy on your cursed soul?"))
+ return
+ family_heirloom.AddComponent(/datum/component/heirloom, quirk_holder.mind, family_name)
+
+ return ..()
+
+/datum/quirk/item_quirk/family_heirloom/process()
+ if(quirk_holder.stat == DEAD)
+ return
+
+ var/obj/family_heirloom = heirloom?.resolve()
+
+ if(family_heirloom && (family_heirloom in quirk_holder.get_all_contents()))
+ quirk_holder.clear_mood_event("family_heirloom_missing")
+ quirk_holder.add_mood_event("family_heirloom", /datum/mood_event/family_heirloom)
+ else
+ quirk_holder.clear_mood_event("family_heirloom")
+ quirk_holder.add_mood_event("family_heirloom_missing", /datum/mood_event/family_heirloom_missing)
+
+/datum/quirk/item_quirk/family_heirloom/remove()
+ quirk_holder.clear_mood_event("family_heirloom_missing")
+ quirk_holder.clear_mood_event("family_heirloom")
diff --git a/code/datums/quirks/negative_quirks/frail.dm b/code/datums/quirks/negative_quirks/frail.dm
new file mode 100644
index 00000000000..6b806875ea2
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/frail.dm
@@ -0,0 +1,11 @@
+/datum/quirk/frail
+ name = "Frail"
+ desc = "You have skin of paper and bones of glass! You suffer wounds much more easily than most."
+ icon = FA_ICON_SKULL
+ value = -6
+ mob_trait = TRAIT_EASILY_WOUNDED
+ gain_text = span_danger("You feel frail.")
+ lose_text = span_notice("You feel sturdy again.")
+ medical_record_text = "Patient is absurdly easy to injure. Please take all due diligence to avoid possible malpractice suits."
+ hardcore_value = 4
+ mail_goodies = list(/obj/effect/spawner/random/medical/minor_healing)
diff --git a/code/datums/quirks/negative_quirks/glass_jaw.dm b/code/datums/quirks/negative_quirks/glass_jaw.dm
new file mode 100644
index 00000000000..33ad19add6d
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/glass_jaw.dm
@@ -0,0 +1,52 @@
+/datum/quirk/glass_jaw
+ name = "Glass Jaw"
+ desc = "You have a very fragile jaw. Any sufficiently hard blow to your head might knock you out."
+ icon = FA_ICON_HAND_FIST
+ value = -4
+ gain_text = span_danger("Your jaw feels loose.")
+ lose_text = span_notice("Your jaw feels fitting again.")
+ medical_record_text = "Patient is absurdly easy to knock out. Do not allow them near a boxing ring."
+ hardcore_value = 4
+ mail_goodies = list(
+ /obj/item/clothing/gloves/boxing,
+ /obj/item/clothing/mask/luchador/rudos,
+ )
+
+/datum/quirk/glass_jaw/New()
+ . = ..()
+ //randomly picks between blue or red equipment for goodies
+ if(prob(50))
+ mail_goodies = list(
+ /obj/item/clothing/gloves/boxing,
+ /obj/item/clothing/mask/luchador/rudos,
+ )
+ else
+ mail_goodies = list(
+ /obj/item/clothing/gloves/boxing/blue,
+ /obj/item/clothing/mask/luchador/tecnicos,
+ )
+
+/datum/quirk/glass_jaw/add(client/client_source)
+ RegisterSignal(quirk_holder, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(punch_out))
+
+/datum/quirk/glass_jaw/remove()
+ UnregisterSignal(quirk_holder, COMSIG_MOB_APPLY_DAMAGE)
+
+/datum/quirk/glass_jaw/proc/punch_out(mob/living/carbon/source, damage, damagetype, def_zone, blocked, wound_bonus, bare_wound_bonus, sharpness, attack_direction, attacking_item)
+ SIGNAL_HANDLER
+ if((damagetype != BRUTE) || (def_zone != BODY_ZONE_HEAD))
+ return
+ var/actual_damage = damage - (damage * blocked/100)
+ //only roll for knockouts at 5 damage or more
+ if(actual_damage < 5)
+ return
+ //blunt items are more likely to knock out, but sharp ones are still capable of doing it
+ if(prob(CEILING(actual_damage * (sharpness & (SHARP_EDGED|SHARP_POINTY) ? 0.65 : 1), 1)))
+ //don't display the message if little mac is already KO'd
+ if(!source.IsUnconscious())
+ source.visible_message(
+ span_warning("[source] gets knocked out!"),
+ span_userdanger("You get knocked out!"),
+ vision_distance = COMBAT_MESSAGE_RANGE,
+ )
+ source.Unconscious(3 SECONDS)
diff --git a/code/datums/quirks/negative_quirks/heavy_sleeper.dm b/code/datums/quirks/negative_quirks/heavy_sleeper.dm
new file mode 100644
index 00000000000..dea79683915
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/heavy_sleeper.dm
@@ -0,0 +1,19 @@
+/datum/quirk/heavy_sleeper
+ name = "Heavy Sleeper"
+ desc = "You sleep like a rock! Whenever you're put to sleep or knocked unconscious, you take a little bit longer to wake up."
+ icon = FA_ICON_BED
+ value = -2
+ mob_trait = TRAIT_HEAVY_SLEEPER
+ gain_text = span_danger("You feel sleepy.")
+ lose_text = span_notice("You feel awake again.")
+ medical_record_text = "Patient has abnormal sleep study results and is difficult to wake up."
+ hardcore_value = 2
+ mail_goodies = list(
+ /obj/item/clothing/glasses/blindfold,
+ /obj/item/bedsheet/random,
+ /obj/item/clothing/under/misc/pj/red,
+ /obj/item/clothing/head/costume/nightcap/red,
+ /obj/item/clothing/under/misc/pj/blue,
+ /obj/item/clothing/head/costume/nightcap/blue,
+ /obj/item/pillow/random,
+ )
diff --git a/code/datums/quirks/negative_quirks/hemiplegic.dm b/code/datums/quirks/negative_quirks/hemiplegic.dm
new file mode 100644
index 00000000000..459b880fad2
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/hemiplegic.dm
@@ -0,0 +1,22 @@
+/datum/quirk/hemiplegic
+ name = "Hemiplegic"
+ desc = "Half of your body doesn't work. Nothing will ever fix this."
+ icon = FA_ICON_CIRCLE_HALF_STROKE
+ value = -10 // slightly more bearable than paraplegic but not by much
+ gain_text = null // Handled by trauma.
+ lose_text = null
+ medical_record_text = "Patient has an untreatable impairment in motor function on half of their body."
+ hardcore_value = 10
+ mail_goodies = list(
+ /obj/item/stack/sheet/mineral/uranium/half, //half a stack of a material that has a half life
+ /obj/item/reagent_containers/cup/glass/drinkingglass/filled/half_full,
+ )
+
+/datum/quirk/hemiplegic/add(client/client_source)
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ var/trauma_type = pick(/datum/brain_trauma/severe/paralysis/hemiplegic/left, /datum/brain_trauma/severe/paralysis/hemiplegic/right)
+ human_holder.gain_trauma(trauma_type, TRAUMA_RESILIENCE_ABSOLUTE)
+
+/datum/quirk/hemiplegic/remove()
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ human_holder.cure_trauma_type(/datum/brain_trauma/severe/paralysis/hemiplegic, TRAUMA_RESILIENCE_ABSOLUTE)
diff --git a/code/datums/quirks/negative_quirks/hypersensitive.dm b/code/datums/quirks/negative_quirks/hypersensitive.dm
new file mode 100644
index 00000000000..f51e72fc256
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/hypersensitive.dm
@@ -0,0 +1,18 @@
+/datum/quirk/hypersensitive
+ name = "Hypersensitive"
+ desc = "For better or worse, everything seems to affect your mood more than it should."
+ icon = FA_ICON_FLUSHED
+ value = -2
+ gain_text = span_danger("You seem to make a big deal out of everything.")
+ lose_text = span_notice("You don't seem to make a big deal out of everything anymore.")
+ medical_record_text = "Patient demonstrates a high level of emotional volatility."
+ hardcore_value = 3
+ mail_goodies = list(/obj/effect/spawner/random/entertainment/plushie_delux)
+
+/datum/quirk/hypersensitive/add(client/client_source)
+ if (quirk_holder.mob_mood)
+ quirk_holder.mob_mood.mood_modifier += 0.5
+
+/datum/quirk/hypersensitive/remove()
+ if (quirk_holder.mob_mood)
+ quirk_holder.mob_mood.mood_modifier -= 0.5
diff --git a/code/datums/quirks/negative_quirks/illiterate.dm b/code/datums/quirks/negative_quirks/illiterate.dm
new file mode 100644
index 00000000000..8101985f8f7
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/illiterate.dm
@@ -0,0 +1,9 @@
+/datum/quirk/illiterate
+ name = "Illiterate"
+ desc = "You dropped out of school and are unable to read or write. This affects reading, writing, using computers and other electronics."
+ icon = FA_ICON_GRADUATION_CAP
+ value = -8
+ mob_trait = TRAIT_ILLITERATE
+ medical_record_text = "Patient is not literate."
+ hardcore_value = 8
+ mail_goodies = list(/obj/item/pai_card) // can read things for you
diff --git a/code/datums/quirks/negative_quirks/indebted.dm b/code/datums/quirks/negative_quirks/indebted.dm
new file mode 100644
index 00000000000..1e30e7800d6
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/indebted.dm
@@ -0,0 +1,40 @@
+/datum/quirk/indebted
+ name = "Indebted"
+ desc = "Bad life decisions, medical bills, student loans, whatever it may be, you've incurred quite the debt. A portion of all you receive will go towards extinguishing it."
+ icon = FA_ICON_DOLLAR
+ quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_HIDE_FROM_SCAN
+ value = -2
+ medical_record_text = "Alas, the patient struggled to scrape together enough money to pay the checkup bill."
+ hardcore_value = 2
+
+/datum/quirk/indebted/add_unique(client/client_source)
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ if(!human_holder.account_id)
+ return
+ var/datum/bank_account/account = SSeconomy.bank_accounts_by_id["[human_holder.account_id]"]
+ var/debt = PAYCHECK_CREW * rand(275, 325)
+ account.account_debt += debt
+ RegisterSignal(account, COMSIG_BANK_ACCOUNT_DEBT_PAID, PROC_REF(on_debt_paid))
+ to_chat(client_source.mob, span_warning("You remember, you've a hefty, [debt] credits debt to pay..."))
+
+///Once the debt is extinguished, award an achievement and a pin for actually taking care of it.
+/datum/quirk/indebted/proc/on_debt_paid(datum/bank_account/source)
+ SIGNAL_HANDLER
+ if(source.account_debt)
+ return
+ UnregisterSignal(source, COMSIG_BANK_ACCOUNT_DEBT_PAID)
+ ///The debt was extinguished while the quirk holder was logged out, so let's kindly award it once they come back.
+ if(!quirk_holder.client)
+ RegisterSignal(quirk_holder, COMSIG_MOB_LOGIN, PROC_REF(award_on_login))
+ else
+ quirk_holder.client.give_award(/datum/award/achievement/misc/debt_extinguished, quirk_holder)
+ podspawn(list(
+ "target" = get_turf(quirk_holder),
+ "style" = STYLE_BLUESPACE,
+ "spawn" = /obj/item/clothing/accessory/debt_payer_pin,
+ ))
+
+/datum/quirk/indebted/proc/award_on_login(mob/source)
+ SIGNAL_HANDLER
+ quirk_holder.client.give_award(/datum/award/achievement/misc/debt_extinguished, quirk_holder)
+ UnregisterSignal(source, COMSIG_MOB_LOGIN)
diff --git a/code/datums/quirks/negative_quirks/insanity.dm b/code/datums/quirks/negative_quirks/insanity.dm
new file mode 100644
index 00000000000..56b56a53812
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/insanity.dm
@@ -0,0 +1,41 @@
+/datum/quirk/insanity
+ name = "Reality Dissociation Syndrome"
+ desc = "You suffer from a severe disorder that causes very vivid hallucinations. \
+ Mindbreaker toxin can suppress its effects, and you are immune to mindbreaker's hallucinogenic properties. \
+ THIS IS NOT A LICENSE TO GRIEF."
+ icon = FA_ICON_GRIN_TONGUE_WINK
+ value = -8
+ gain_text = span_userdanger("...")
+ lose_text = span_notice("You feel in tune with the world again.")
+ medical_record_text = "Patient suffers from acute Reality Dissociation Syndrome and experiences vivid hallucinations."
+ hardcore_value = 6
+ mail_goodies = list(/obj/item/storage/pill_bottle/lsdpsych)
+ /// Weakref to the trauma we give out
+ var/datum/weakref/added_trama_ref
+
+/datum/quirk/insanity/add(client/client_source)
+ if(!iscarbon(quirk_holder))
+ return
+ var/mob/living/carbon/carbon_quirk_holder = quirk_holder
+
+ // Setup our special RDS mild hallucination.
+ // Not a unique subtype so not to plague subtypesof,
+ // also as we inherit the names and values from our quirk.
+ var/datum/brain_trauma/mild/hallucinations/added_trauma = new()
+ added_trauma.resilience = TRAUMA_RESILIENCE_ABSOLUTE
+ added_trauma.name = name
+ added_trauma.desc = medical_record_text
+ added_trauma.scan_desc = lowertext(name)
+ added_trauma.gain_text = null
+ added_trauma.lose_text = null
+
+ carbon_quirk_holder.gain_trauma(added_trauma)
+ added_trama_ref = WEAKREF(added_trauma)
+
+/datum/quirk/insanity/post_add()
+ var/rds_policy = get_policy("[type]") || "Please note that your [lowertext(name)] does NOT give you any additional right to attack people or cause chaos."
+ // I don't /think/ we'll need this, but for newbies who think "roleplay as insane" = "license to kill", it's probably a good thing to have.
+ to_chat(quirk_holder, span_big(span_info(rds_policy)))
+
+/datum/quirk/insanity/remove()
+ QDEL_NULL(added_trama_ref)
diff --git a/code/datums/quirks/negative_quirks/junkie.dm b/code/datums/quirks/negative_quirks/junkie.dm
new file mode 100644
index 00000000000..269f6d2d96e
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/junkie.dm
@@ -0,0 +1,216 @@
+/datum/quirk/item_quirk/junkie
+ name = "Junkie"
+ desc = "You can't get enough of hard drugs."
+ icon = FA_ICON_PILLS
+ value = -6
+ gain_text = span_danger("You suddenly feel the craving for drugs.")
+ medical_record_text = "Patient has a history of hard drugs."
+ hardcore_value = 4
+ quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES
+ mail_goodies = list(/obj/effect/spawner/random/contraband/narcotics)
+ var/drug_list = list(/datum/reagent/drug/blastoff, /datum/reagent/drug/krokodil, /datum/reagent/medicine/morphine, /datum/reagent/drug/happiness, /datum/reagent/drug/methamphetamine) //List of possible IDs
+ var/datum/reagent/reagent_type //!If this is defined, reagent_id will be unused and the defined reagent type will be instead.
+ var/datum/reagent/reagent_instance //! actual instanced version of the reagent
+ var/where_drug //! Where the drug spawned
+ var/obj/item/drug_container_type //! If this is defined before pill generation, pill generation will be skipped. This is the type of the pill bottle.
+ var/where_accessory //! where the accessory spawned
+ var/obj/item/accessory_type //! If this is null, an accessory won't be spawned.
+ var/process_interval = 30 SECONDS //! how frequently the quirk processes
+ var/next_process = 0 //! ticker for processing
+ var/drug_flavour_text = "Better hope you don't run out..."
+
+/datum/quirk/item_quirk/junkie/add_unique(client/client_source)
+ var/mob/living/carbon/human/human_holder = quirk_holder
+
+ if(!reagent_type)
+ reagent_type = pick(drug_list)
+
+ reagent_instance = new reagent_type()
+
+ for(var/addiction in reagent_instance.addiction_types)
+ human_holder.last_mind?.add_addiction_points(addiction, 1000)
+
+ var/current_turf = get_turf(quirk_holder)
+
+ if(!drug_container_type)
+ drug_container_type = /obj/item/storage/pill_bottle
+
+ var/obj/item/drug_instance = new drug_container_type(current_turf)
+ if(istype(drug_instance, /obj/item/storage/pill_bottle))
+ var/pill_state = "pill[rand(1,20)]"
+ for(var/i in 1 to 7)
+ var/obj/item/reagent_containers/pill/pill = new(drug_instance)
+ pill.icon_state = pill_state
+ pill.reagents.add_reagent(reagent_type, 3)
+
+ give_item_to_holder(
+ drug_instance,
+ list(
+ LOCATION_LPOCKET = ITEM_SLOT_LPOCKET,
+ LOCATION_RPOCKET = ITEM_SLOT_RPOCKET,
+ LOCATION_BACKPACK = ITEM_SLOT_BACKPACK,
+ LOCATION_HANDS = ITEM_SLOT_HANDS,
+ ),
+ flavour_text = drug_flavour_text,
+ )
+
+ if(accessory_type)
+ give_item_to_holder(
+ accessory_type,
+ list(
+ LOCATION_LPOCKET = ITEM_SLOT_LPOCKET,
+ LOCATION_RPOCKET = ITEM_SLOT_RPOCKET,
+ LOCATION_BACKPACK = ITEM_SLOT_BACKPACK,
+ LOCATION_HANDS = ITEM_SLOT_HANDS,
+ )
+ )
+
+/datum/quirk/item_quirk/junkie/remove()
+ if(quirk_holder && reagent_instance)
+ for(var/addiction_type in subtypesof(/datum/addiction))
+ quirk_holder.mind.remove_addiction_points(addiction_type, MAX_ADDICTION_POINTS)
+
+/datum/quirk/item_quirk/junkie/process(seconds_per_tick)
+ if(HAS_TRAIT(quirk_holder, TRAIT_LIVERLESS_METABOLISM))
+ return
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ if(world.time > next_process)
+ next_process = world.time + process_interval
+ var/deleted = QDELETED(reagent_instance)
+ var/missing_addiction = FALSE
+ for(var/addiction_type in reagent_instance.addiction_types)
+ if(!LAZYACCESS(human_holder.last_mind?.active_addictions, addiction_type))
+ missing_addiction = TRUE
+ if(deleted || missing_addiction)
+ if(deleted)
+ reagent_instance = new reagent_type()
+ to_chat(quirk_holder, span_danger("You thought you kicked it, but you feel like you're falling back onto bad habits.."))
+ for(var/addiction in reagent_instance.addiction_types)
+ human_holder.last_mind?.add_addiction_points(addiction, 1000) ///Max that shit out
+
+/datum/quirk/item_quirk/junkie/smoker
+ name = "Smoker"
+ desc = "Sometimes you just really want a smoke. Probably not great for your lungs."
+ icon = FA_ICON_SMOKING
+ value = -4
+ gain_text = span_danger("You could really go for a smoke right about now.")
+ lose_text = span_notice("You don't feel nearly as hooked to nicotine anymore.")
+ medical_record_text = "Patient is a current smoker."
+ reagent_type = /datum/reagent/drug/nicotine
+ accessory_type = /obj/item/lighter/greyscale
+ mob_trait = TRAIT_SMOKER
+ hardcore_value = 1
+ drug_flavour_text = "Make sure you get your favorite brand when you run out."
+ mail_goodies = list(
+ /obj/effect/spawner/random/entertainment/cigarette_pack,
+ /obj/effect/spawner/random/entertainment/cigar,
+ /obj/effect/spawner/random/entertainment/lighter,
+ /obj/item/clothing/mask/cigarette/pipe,
+ )
+
+/datum/quirk/item_quirk/junkie/smoker/New()
+ drug_container_type = pick(/obj/item/storage/fancy/cigarettes,
+ /obj/item/storage/fancy/cigarettes/cigpack_midori,
+ /obj/item/storage/fancy/cigarettes/cigpack_uplift,
+ /obj/item/storage/fancy/cigarettes/cigpack_robust,
+ /obj/item/storage/fancy/cigarettes/cigpack_robustgold,
+ /obj/item/storage/fancy/cigarettes/cigpack_carp)
+
+ return ..()
+
+/datum/quirk/item_quirk/junkie/smoker/post_add()
+ . = ..()
+ quirk_holder.add_mob_memory(/datum/memory/key/quirk_smoker, protagonist = quirk_holder, preferred_brand = initial(drug_container_type.name))
+ // smoker lungs have 25% less health and healing
+ var/mob/living/carbon/carbon_holder = quirk_holder
+ var/obj/item/organ/internal/lungs/smoker_lungs = null
+ var/obj/item/organ/internal/lungs/old_lungs = carbon_holder.get_organ_slot(ORGAN_SLOT_LUNGS)
+ if(old_lungs && IS_ORGANIC_ORGAN(old_lungs))
+ if(isplasmaman(carbon_holder))
+ smoker_lungs = /obj/item/organ/internal/lungs/plasmaman/plasmaman_smoker
+ else if(isethereal(carbon_holder))
+ smoker_lungs = /obj/item/organ/internal/lungs/ethereal/ethereal_smoker
+ else
+ smoker_lungs = /obj/item/organ/internal/lungs/smoker_lungs
+ if(!isnull(smoker_lungs))
+ smoker_lungs = new smoker_lungs
+ smoker_lungs.Insert(carbon_holder, special = TRUE, drop_if_replaced = FALSE)
+
+/datum/quirk/item_quirk/junkie/smoker/process(seconds_per_tick)
+ . = ..()
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ var/obj/item/mask_item = human_holder.get_item_by_slot(ITEM_SLOT_MASK)
+ if(istype(mask_item, /obj/item/clothing/mask/cigarette))
+ var/obj/item/storage/fancy/cigarettes/cigarettes = drug_container_type
+ if(istype(mask_item, initial(cigarettes.spawn_type)))
+ quirk_holder.clear_mood_event("wrong_cigs")
+ else
+ quirk_holder.add_mood_event("wrong_cigs", /datum/mood_event/wrong_brand)
+
+/datum/quirk/item_quirk/junkie/alcoholic
+ name = "Alcoholic"
+ desc = "You just can't live without alcohol. Your liver is a machine that turns ethanol into acetaldehyde."
+ icon = FA_ICON_WINE_GLASS
+ value = -4
+ gain_text = span_danger("You really need a drink.")
+ lose_text = span_notice("Alcohol doesn't seem nearly as enticing anymore.")
+ medical_record_text = "Patient is an alcoholic."
+ reagent_type = /datum/reagent/consumable/ethanol
+ drug_container_type = /obj/item/reagent_containers/cup/glass/bottle/whiskey
+ mob_trait = TRAIT_HEAVY_DRINKER
+ hardcore_value = 1
+ drug_flavour_text = "Make sure you get your favorite type of drink when you run out."
+ mail_goodies = list(
+ /obj/effect/spawner/random/food_or_drink/booze,
+ /obj/item/book/bible/booze,
+ )
+ /// Cached typepath of the owner's favorite alcohol reagent
+ var/datum/reagent/consumable/ethanol/favorite_alcohol
+
+/datum/quirk/item_quirk/junkie/alcoholic/New()
+ drug_container_type = pick(
+ /obj/item/reagent_containers/cup/glass/bottle/whiskey,
+ /obj/item/reagent_containers/cup/glass/bottle/vodka,
+ /obj/item/reagent_containers/cup/glass/bottle/ale,
+ /obj/item/reagent_containers/cup/glass/bottle/beer,
+ /obj/item/reagent_containers/cup/glass/bottle/hcider,
+ /obj/item/reagent_containers/cup/glass/bottle/wine,
+ /obj/item/reagent_containers/cup/glass/bottle/sake,
+ )
+
+ return ..()
+
+/datum/quirk/item_quirk/junkie/alcoholic/post_add()
+ . = ..()
+ RegisterSignal(quirk_holder, COMSIG_MOB_REAGENT_CHECK, PROC_REF(check_brandy))
+
+ var/obj/item/reagent_containers/brandy_container = GLOB.alcohol_containers[drug_container_type]
+ if(isnull(brandy_container))
+ stack_trace("Alcoholic quirk added while the GLOB.alcohol_containers is (somehow) not initialized!")
+ brandy_container = new drug_container_type
+ favorite_alcohol = brandy_container.list_reagents[1]
+ qdel(brandy_container)
+ else
+ favorite_alcohol = brandy_container.list_reagents[1]
+
+ quirk_holder.add_mob_memory(/datum/memory/key/quirk_alcoholic, protagonist = quirk_holder, preferred_brandy = initial(favorite_alcohol.name))
+ // alcoholic livers have 25% less health and healing
+ var/obj/item/organ/internal/liver/alcohol_liver = quirk_holder.get_organ_slot(ORGAN_SLOT_LIVER)
+ if(alcohol_liver && IS_ORGANIC_ORGAN(alcohol_liver)) // robotic livers aren't affected
+ alcohol_liver.maxHealth = alcohol_liver.maxHealth * 0.75
+ alcohol_liver.healing_factor = alcohol_liver.healing_factor * 0.75
+
+/datum/quirk/item_quirk/junkie/alcoholic/remove()
+ UnregisterSignal(quirk_holder, COMSIG_MOB_REAGENT_CHECK)
+
+/datum/quirk/item_quirk/junkie/alcoholic/proc/check_brandy(mob/source, datum/reagent/booze)
+ SIGNAL_HANDLER
+
+ //we don't care if it is not alcohol
+ if(!istype(booze, /datum/reagent/consumable/ethanol))
+ return
+
+ if(istype(booze, favorite_alcohol))
+ quirk_holder.clear_mood_event("wrong_alcohol")
+ else
+ quirk_holder.add_mood_event("wrong_alcohol", /datum/mood_event/wrong_brandy)
diff --git a/code/datums/quirks/negative_quirks/light_drinker.dm b/code/datums/quirks/negative_quirks/light_drinker.dm
new file mode 100644
index 00000000000..5f82e2b9cd7
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/light_drinker.dm
@@ -0,0 +1,11 @@
+/datum/quirk/light_drinker
+ name = "Light Drinker"
+ desc = "You just can't handle your drinks and get drunk very quickly."
+ icon = FA_ICON_COCKTAIL
+ value = -2
+ mob_trait = TRAIT_LIGHT_DRINKER
+ gain_text = span_notice("Just the thought of drinking alcohol makes your head spin.")
+ lose_text = span_danger("You're no longer severely affected by alcohol.")
+ medical_record_text = "Patient demonstrates a low tolerance for alcohol. (Wimp)"
+ hardcore_value = 3
+ mail_goodies = list(/obj/item/reagent_containers/cup/glass/waterbottle)
diff --git a/code/datums/quirks/negative_quirks/mute.dm b/code/datums/quirks/negative_quirks/mute.dm
new file mode 100644
index 00000000000..44706c4d434
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/mute.dm
@@ -0,0 +1,10 @@
+/datum/quirk/mute
+ name = "Mute"
+ desc = "For some reason you are completely unable to speak."
+ icon = FA_ICON_VOLUME_XMARK
+ value = -4
+ mob_trait = TRAIT_MUTE
+ gain_text = span_danger("You find yourself unable to speak!")
+ lose_text = span_notice("You feel a growing strength in your vocal chords.")
+ medical_record_text = "The patient is unable to use their voice in any capacity."
+ hardcore_value = 4
diff --git a/code/datums/quirks/negative_quirks/nearsighted.dm b/code/datums/quirks/negative_quirks/nearsighted.dm
new file mode 100644
index 00000000000..6a5397b6504
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/nearsighted.dm
@@ -0,0 +1,30 @@
+/datum/quirk/item_quirk/nearsighted
+ name = "Nearsighted"
+ desc = "You are nearsighted without prescription glasses, but spawn with a pair."
+ icon = FA_ICON_GLASSES
+ value = -4
+ gain_text = span_danger("Things far away from you start looking blurry.")
+ lose_text = span_notice("You start seeing faraway things normally again.")
+ medical_record_text = "Patient requires prescription glasses in order to counteract nearsightedness."
+ hardcore_value = 5
+ quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE
+ mail_goodies = list(/obj/item/clothing/glasses/regular) // extra pair if orginal one gets broken by somebody mean
+
+/datum/quirk/item_quirk/nearsighted/add_unique(client/client_source)
+ var/glasses_name = client_source?.prefs.read_preference(/datum/preference/choiced/glasses) || "Regular"
+ var/obj/item/clothing/glasses/glasses_type
+
+ glasses_name = glasses_name == "Random" ? pick(GLOB.nearsighted_glasses) : glasses_name
+ glasses_type = GLOB.nearsighted_glasses[glasses_name]
+
+ give_item_to_holder(glasses_type, list(
+ LOCATION_EYES = ITEM_SLOT_EYES,
+ LOCATION_BACKPACK = ITEM_SLOT_BACKPACK,
+ LOCATION_HANDS = ITEM_SLOT_HANDS,
+ ))
+
+/datum/quirk/item_quirk/nearsighted/add(client/client_source)
+ quirk_holder.become_nearsighted(QUIRK_TRAIT)
+
+/datum/quirk/item_quirk/nearsighted/remove()
+ quirk_holder.cure_nearsighted(QUIRK_TRAIT)
diff --git a/code/datums/quirks/negative_quirks/negative_quirks.dm b/code/datums/quirks/negative_quirks/negative_quirks.dm
deleted file mode 100644
index 02b27a0a436..00000000000
--- a/code/datums/quirks/negative_quirks/negative_quirks.dm
+++ /dev/null
@@ -1,1541 +0,0 @@
-//predominantly negative traits
-/datum/quirk/badback
- name = "Bad Back"
- desc = "Thanks to your poor posture, backpacks and other bags never sit right on your back. More evenly weighted objects are fine, though."
- icon = FA_ICON_HIKING
- value = -8
- quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_MOODLET_BASED
- gain_text = span_danger("Your back REALLY hurts!")
- lose_text = span_notice("Your back feels better.")
- medical_record_text = "Patient scans indicate severe and chronic back pain."
- hardcore_value = 4
- mail_goodies = list(/obj/item/cane)
- var/datum/weakref/backpack
-
-/datum/quirk/badback/add(client/client_source)
- var/mob/living/carbon/human/human_holder = quirk_holder
- var/obj/item/storage/backpack/equipped_backpack = human_holder.back
- if(istype(equipped_backpack))
- quirk_holder.add_mood_event("back_pain", /datum/mood_event/back_pain)
- RegisterSignal(human_holder.back, COMSIG_ITEM_POST_UNEQUIP, PROC_REF(on_unequipped_backpack))
- else
- RegisterSignal(quirk_holder, COMSIG_MOB_EQUIPPED_ITEM, PROC_REF(on_equipped_item))
-
-/datum/quirk/badback/remove()
- UnregisterSignal(quirk_holder, COMSIG_MOB_EQUIPPED_ITEM)
-
- var/obj/item/storage/equipped_backpack = backpack?.resolve()
- if(equipped_backpack)
- UnregisterSignal(equipped_backpack, COMSIG_ITEM_POST_UNEQUIP)
- quirk_holder.clear_mood_event("back_pain")
-
-/// Signal handler for when the quirk_holder equips an item. If it's a backpack, adds the back_pain mood event.
-/datum/quirk/badback/proc/on_equipped_item(mob/living/source, obj/item/equipped_item, slot)
- SIGNAL_HANDLER
-
- if(!(slot & ITEM_SLOT_BACK) || !istype(equipped_item, /obj/item/storage/backpack))
- return
-
- quirk_holder.add_mood_event("back_pain", /datum/mood_event/back_pain)
- RegisterSignal(equipped_item, COMSIG_ITEM_POST_UNEQUIP, PROC_REF(on_unequipped_backpack))
- UnregisterSignal(quirk_holder, COMSIG_MOB_EQUIPPED_ITEM)
- backpack = WEAKREF(equipped_item)
-
-/// Signal handler for when the quirk_holder unequips an equipped backpack. Removes the back_pain mood event.
-/datum/quirk/badback/proc/on_unequipped_backpack(obj/item/source, force, atom/newloc, no_move, invdrop, silent)
- SIGNAL_HANDLER
-
- UnregisterSignal(source, COMSIG_ITEM_POST_UNEQUIP)
- quirk_holder.clear_mood_event("back_pain")
- backpack = null
- RegisterSignal(quirk_holder, COMSIG_MOB_EQUIPPED_ITEM, PROC_REF(on_equipped_item))
-
-/datum/quirk/blooddeficiency
- name = "Blood Deficiency"
- desc = "Your body can't produce enough blood to sustain itself."
- icon = FA_ICON_TINT
- value = -8
- mob_trait = TRAIT_BLOOD_DEFICIENCY
- gain_text = span_danger("You feel your vigor slowly fading away.")
- lose_text = span_notice("You feel vigorous again.")
- medical_record_text = "Patient requires regular treatment for blood loss due to low production of blood."
- hardcore_value = 8
- mail_goodies = list(/obj/item/reagent_containers/blood/o_minus) // universal blood type that is safe for all
- var/min_blood = BLOOD_VOLUME_SAFE - 25 // just barely survivable without treatment
-
-/datum/quirk/blooddeficiency/post_add()
- if(!ishuman(quirk_holder))
- return
-
- // for making sure the roundstart species has the right blood pack sent to them
- var/mob/living/carbon/human/carbon_target = quirk_holder
- carbon_target.dna.species.update_quirk_mail_goodies(carbon_target, src)
-
-/**
- * Makes the mob lose blood from having the blood deficiency quirk, if possible
- *
- * Arguments:
- * * seconds_per_tick
- */
-/datum/quirk/blooddeficiency/proc/lose_blood(seconds_per_tick)
- if(quirk_holder.stat == DEAD)
- return
-
- var/mob/living/carbon/human/carbon_target = quirk_holder
- if(HAS_TRAIT(carbon_target, TRAIT_NOBLOOD) && isnull(carbon_target.dna.species.exotic_blood)) //can't lose blood if your species doesn't have any
- return
-
- if (carbon_target.blood_volume <= min_blood)
- return
- // Ensures that we don't reduce total blood volume below min_blood.
- carbon_target.blood_volume = max(min_blood, carbon_target.blood_volume - carbon_target.dna.species.blood_deficiency_drain_rate * seconds_per_tick)
-
-/datum/quirk/item_quirk/blindness
- name = "Blind"
- desc = "You are completely blind, nothing can counteract this."
- icon = FA_ICON_EYE_SLASH
- value = -16
- gain_text = span_danger("You can't see anything.")
- lose_text = span_notice("You miraculously gain back your vision.")
- medical_record_text = "Patient has permanent blindness."
- hardcore_value = 15
- quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE
- mail_goodies = list(/obj/item/clothing/glasses/sunglasses, /obj/item/cane/white)
-
-/datum/quirk/item_quirk/blindness/add_unique(client/client_source)
- give_item_to_holder(/obj/item/clothing/glasses/blindfold/white, list(LOCATION_EYES = ITEM_SLOT_EYES, LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
-
-/datum/quirk/item_quirk/blindness/add(client/client_source)
- quirk_holder.become_blind(QUIRK_TRAIT)
-
-/datum/quirk/item_quirk/blindness/remove()
- quirk_holder.cure_blind(QUIRK_TRAIT)
-
- /* A couple of brain tumor stats for anyone curious / looking at this quirk for balancing:
- * - It takes less 16 minute 40 seconds to die from brain death due to a brain tumor.
- * - It takes 1 minutes 40 seconds to take 10% (20 organ damage) brain damage.
- * - 5u mannitol will heal 12.5% (25 organ damage) brain damage
- */
-/datum/quirk/item_quirk/brainproblems
- name = "Brain Tumor"
- desc = "You have a little friend in your brain that is slowly destroying it. Better bring some mannitol!"
- icon = FA_ICON_BRAIN
- value = -12
- gain_text = span_danger("You feel smooth.")
- lose_text = span_notice("You feel wrinkled again.")
- medical_record_text = "Patient has a tumor in their brain that is slowly driving them to brain death."
- hardcore_value = 12
- quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES
- mail_goodies = list(/obj/item/storage/pill_bottle/mannitol/braintumor)
-
-/datum/quirk/item_quirk/brainproblems/add_unique(client/client_source)
- give_item_to_holder(
- /obj/item/storage/pill_bottle/mannitol/braintumor,
- list(
- LOCATION_LPOCKET = ITEM_SLOT_LPOCKET,
- LOCATION_RPOCKET = ITEM_SLOT_RPOCKET,
- LOCATION_BACKPACK = ITEM_SLOT_BACKPACK,
- LOCATION_HANDS = ITEM_SLOT_HANDS,
- ),
- flavour_text = "These will keep you alive until you can secure a supply of medication. Don't rely on them too much!",
- )
-
-/datum/quirk/item_quirk/brainproblems/process(seconds_per_tick)
- if(quirk_holder.stat == DEAD)
- return
-
- if(HAS_TRAIT(quirk_holder, TRAIT_TUMOR_SUPPRESSED))
- return
-
- quirk_holder.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.2 * seconds_per_tick)
-
-/datum/quirk/item_quirk/deafness
- name = "Deaf"
- desc = "You are incurably deaf."
- icon = FA_ICON_DEAF
- value = -8
- mob_trait = TRAIT_DEAF
- gain_text = span_danger("You can't hear anything.")
- lose_text = span_notice("You're able to hear again!")
- medical_record_text = "Patient's cochlear nerve is incurably damaged."
- hardcore_value = 12
- mail_goodies = list(/obj/item/clothing/mask/whistle)
-
-/datum/quirk/item_quirk/deafness/add_unique(client/client_source)
- give_item_to_holder(/obj/item/clothing/accessory/deaf_pin, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
-
-/datum/quirk/depression
- name = "Depression"
- desc = "You sometimes just hate life."
- icon = FA_ICON_FROWN
- mob_trait = TRAIT_DEPRESSION
- value = -3
- gain_text = span_danger("You start feeling depressed.")
- lose_text = span_notice("You no longer feel depressed.") //if only it were that easy!
- medical_record_text = "Patient has a mild mood disorder causing them to experience acute episodes of depression."
- quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_MOODLET_BASED
- hardcore_value = 2
- mail_goodies = list(/obj/item/storage/pill_bottle/happinesspsych)
-
-/datum/quirk/item_quirk/family_heirloom
- name = "Family Heirloom"
- desc = "You are the current owner of an heirloom, passed down for generations. You have to keep it safe!"
- icon = FA_ICON_TOOLBOX
- value = -2
- medical_record_text = "Patient demonstrates an unnatural attachment to a family heirloom."
- hardcore_value = 1
- quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES|QUIRK_MOODLET_BASED
- /// A weak reference to our heirloom.
- var/datum/weakref/heirloom
- mail_goodies = list(/obj/item/storage/secure/briefcase)
-
-/datum/quirk/item_quirk/family_heirloom/add_unique(client/client_source)
- var/mob/living/carbon/human/human_holder = quirk_holder
- var/obj/item/heirloom_type
-
- // The quirk holder's species - we have a 50% chance, if we have a species with a set heirloom, to choose a species heirloom.
- var/datum/species/holder_species = human_holder.dna?.species
- if(holder_species && LAZYLEN(holder_species.family_heirlooms) && prob(50))
- heirloom_type = pick(holder_species.family_heirlooms)
- else
- // Our quirk holder's job
- var/datum/job/holder_job = human_holder.last_mind?.assigned_role
- if(holder_job && LAZYLEN(holder_job.family_heirlooms))
- heirloom_type = pick(holder_job.family_heirlooms)
-
- // If we didn't find an heirloom somehow, throw them a generic one
- if(!heirloom_type)
- heirloom_type = pick(/obj/item/toy/cards/deck, /obj/item/lighter, /obj/item/dice/d20)
-
- var/obj/new_heirloom = new heirloom_type(get_turf(human_holder))
- heirloom = WEAKREF(new_heirloom)
-
- give_item_to_holder(
- new_heirloom,
- list(
- LOCATION_LPOCKET = ITEM_SLOT_LPOCKET,
- LOCATION_RPOCKET = ITEM_SLOT_RPOCKET,
- LOCATION_BACKPACK = ITEM_SLOT_BACKPACK,
- LOCATION_HANDS = ITEM_SLOT_HANDS,
- ),
- flavour_text = "This is a precious family heirloom, passed down from generation to generation. Keep it safe!",
- )
-
-/datum/quirk/item_quirk/family_heirloom/post_add()
- var/list/names = splittext(quirk_holder.real_name, " ")
- var/family_name = names[names.len]
-
- var/obj/family_heirloom = heirloom?.resolve()
- if(!family_heirloom)
- to_chat(quirk_holder, span_boldnotice("A wave of existential dread runs over you as you realize your precious family heirloom is missing. Perhaps the Gods will show mercy on your cursed soul?"))
- return
- family_heirloom.AddComponent(/datum/component/heirloom, quirk_holder.mind, family_name)
-
- return ..()
-
-/datum/quirk/item_quirk/family_heirloom/process()
- if(quirk_holder.stat == DEAD)
- return
-
- var/obj/family_heirloom = heirloom?.resolve()
-
- if(family_heirloom && (family_heirloom in quirk_holder.get_all_contents()))
- quirk_holder.clear_mood_event("family_heirloom_missing")
- quirk_holder.add_mood_event("family_heirloom", /datum/mood_event/family_heirloom)
- else
- quirk_holder.clear_mood_event("family_heirloom")
- quirk_holder.add_mood_event("family_heirloom_missing", /datum/mood_event/family_heirloom_missing)
-
-/datum/quirk/item_quirk/family_heirloom/remove()
- quirk_holder.clear_mood_event("family_heirloom_missing")
- quirk_holder.clear_mood_event("family_heirloom")
-
-/datum/quirk/glass_jaw
- name = "Glass Jaw"
- desc = "You have a very fragile jaw. Any sufficiently hard blow to your head might knock you out."
- icon = FA_ICON_HAND_FIST
- value = -4
- gain_text = span_danger("Your jaw feels loose.")
- lose_text = span_notice("Your jaw feels fitting again.")
- medical_record_text = "Patient is absurdly easy to knock out. Do not allow them near a boxing ring."
- hardcore_value = 4
- mail_goodies = list(
- /obj/item/clothing/gloves/boxing,
- /obj/item/clothing/mask/luchador/rudos,
- )
-
-/datum/quirk/glass_jaw/New()
- . = ..()
- //randomly picks between blue or red equipment for goodies
- if(prob(50))
- mail_goodies = list(
- /obj/item/clothing/gloves/boxing,
- /obj/item/clothing/mask/luchador/rudos,
- )
- else
- mail_goodies = list(
- /obj/item/clothing/gloves/boxing/blue,
- /obj/item/clothing/mask/luchador/tecnicos,
- )
-
-/datum/quirk/glass_jaw/add(client/client_source)
- RegisterSignal(quirk_holder, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(punch_out))
-
-/datum/quirk/glass_jaw/remove()
- UnregisterSignal(quirk_holder, COMSIG_MOB_APPLY_DAMAGE)
-
-/datum/quirk/glass_jaw/proc/punch_out(mob/living/carbon/source, damage, damagetype, def_zone, blocked, wound_bonus, bare_wound_bonus, sharpness, attack_direction, attacking_item)
- SIGNAL_HANDLER
- if((damagetype != BRUTE) || (def_zone != BODY_ZONE_HEAD))
- return
- var/actual_damage = damage - (damage * blocked/100)
- //only roll for knockouts at 5 damage or more
- if(actual_damage < 5)
- return
- //blunt items are more likely to knock out, but sharp ones are still capable of doing it
- if(prob(CEILING(actual_damage * (sharpness & (SHARP_EDGED|SHARP_POINTY) ? 0.65 : 1), 1)))
- //don't display the message if little mac is already KO'd
- if(!source.IsUnconscious())
- source.visible_message(
- span_warning("[source] gets knocked out!"),
- span_userdanger("You get knocked out!"),
- vision_distance = COMBAT_MESSAGE_RANGE,
- )
- source.Unconscious(3 SECONDS)
-
-/datum/quirk/frail
- name = "Frail"
- desc = "You have skin of paper and bones of glass! You suffer wounds much more easily than most."
- icon = FA_ICON_SKULL
- value = -6
- mob_trait = TRAIT_EASILY_WOUNDED
- gain_text = span_danger("You feel frail.")
- lose_text = span_notice("You feel sturdy again.")
- medical_record_text = "Patient is absurdly easy to injure. Please take all due diligence to avoid possible malpractice suits."
- hardcore_value = 4
- mail_goodies = list(/obj/effect/spawner/random/medical/minor_healing)
-
-/datum/quirk/heavy_sleeper
- name = "Heavy Sleeper"
- desc = "You sleep like a rock! Whenever you're put to sleep or knocked unconscious, you take a little bit longer to wake up."
- icon = FA_ICON_BED
- value = -2
- mob_trait = TRAIT_HEAVY_SLEEPER
- gain_text = span_danger("You feel sleepy.")
- lose_text = span_notice("You feel awake again.")
- medical_record_text = "Patient has abnormal sleep study results and is difficult to wake up."
- hardcore_value = 2
- mail_goodies = list(
- /obj/item/clothing/glasses/blindfold,
- /obj/item/bedsheet/random,
- /obj/item/clothing/under/misc/pj/red,
- /obj/item/clothing/head/costume/nightcap/red,
- /obj/item/clothing/under/misc/pj/blue,
- /obj/item/clothing/head/costume/nightcap/blue,
- /obj/item/pillow/random,
- )
-
-/datum/quirk/hypersensitive
- name = "Hypersensitive"
- desc = "For better or worse, everything seems to affect your mood more than it should."
- icon = FA_ICON_FLUSHED
- value = -2
- gain_text = span_danger("You seem to make a big deal out of everything.")
- lose_text = span_notice("You don't seem to make a big deal out of everything anymore.")
- medical_record_text = "Patient demonstrates a high level of emotional volatility."
- hardcore_value = 3
- mail_goodies = list(/obj/effect/spawner/random/entertainment/plushie_delux)
-
-/datum/quirk/hypersensitive/add(client/client_source)
- if (quirk_holder.mob_mood)
- quirk_holder.mob_mood.mood_modifier += 0.5
-
-/datum/quirk/hypersensitive/remove()
- if (quirk_holder.mob_mood)
- quirk_holder.mob_mood.mood_modifier -= 0.5
-
-/datum/quirk/light_drinker
- name = "Light Drinker"
- desc = "You just can't handle your drinks and get drunk very quickly."
- icon = FA_ICON_COCKTAIL
- value = -2
- mob_trait = TRAIT_LIGHT_DRINKER
- gain_text = span_notice("Just the thought of drinking alcohol makes your head spin.")
- lose_text = span_danger("You're no longer severely affected by alcohol.")
- medical_record_text = "Patient demonstrates a low tolerance for alcohol. (Wimp)"
- hardcore_value = 3
- mail_goodies = list(/obj/item/reagent_containers/cup/glass/waterbottle)
-
-
-/datum/quirk/item_quirk/nearsighted
- name = "Nearsighted"
- desc = "You are nearsighted without prescription glasses, but spawn with a pair."
- icon = FA_ICON_GLASSES
- value = -4
- gain_text = span_danger("Things far away from you start looking blurry.")
- lose_text = span_notice("You start seeing faraway things normally again.")
- medical_record_text = "Patient requires prescription glasses in order to counteract nearsightedness."
- hardcore_value = 5
- quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE
- mail_goodies = list(/obj/item/clothing/glasses/regular) // extra pair if orginal one gets broken by somebody mean
-
-/datum/quirk/item_quirk/nearsighted/add_unique(client/client_source)
- var/glasses_name = client_source?.prefs.read_preference(/datum/preference/choiced/glasses) || "Regular"
- var/obj/item/clothing/glasses/glasses_type
-
- glasses_name = glasses_name == "Random" ? pick(GLOB.nearsighted_glasses) : glasses_name
- glasses_type = GLOB.nearsighted_glasses[glasses_name]
-
- give_item_to_holder(glasses_type, list(
- LOCATION_EYES = ITEM_SLOT_EYES,
- LOCATION_BACKPACK = ITEM_SLOT_BACKPACK,
- LOCATION_HANDS = ITEM_SLOT_HANDS,
- ))
-
-/datum/quirk/item_quirk/nearsighted/add(client/client_source)
- quirk_holder.become_nearsighted(QUIRK_TRAIT)
-
-/datum/quirk/item_quirk/nearsighted/remove()
- quirk_holder.cure_nearsighted(QUIRK_TRAIT)
-
-/datum/quirk/nyctophobia
- name = "Nyctophobia"
- desc = "As far as you can remember, you've always been afraid of the dark. While in the dark without a light source, you instinctively act careful, and constantly feel a sense of dread."
- icon = FA_ICON_LIGHTBULB
- value = -3
- medical_record_text = "Patient demonstrates a fear of the dark. (Seriously?)"
- hardcore_value = 5
- mail_goodies = list(/obj/effect/spawner/random/engineering/flashlight)
-
-/datum/quirk/nyctophobia/add(client/client_source)
- RegisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED, PROC_REF(on_holder_moved))
-
-/datum/quirk/nyctophobia/remove()
- UnregisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED)
- quirk_holder.clear_mood_event("nyctophobia")
-
-/// Called when the quirk holder moves. Updates the quirk holder's mood.
-/datum/quirk/nyctophobia/proc/on_holder_moved(mob/living/source, atom/old_loc, dir, forced)
- SIGNAL_HANDLER
-
- if(quirk_holder.stat != CONSCIOUS || quirk_holder.IsSleeping() || quirk_holder.IsUnconscious())
- return
-
- if(HAS_TRAIT(quirk_holder, TRAIT_FEARLESS))
- return
-
- var/mob/living/carbon/human/human_holder = quirk_holder
-
- if(human_holder.dna?.species.id in list(SPECIES_SHADOW, SPECIES_NIGHTMARE))
- return
-
- if((human_holder.sight & SEE_TURFS) == SEE_TURFS)
- return
-
- var/turf/holder_turf = get_turf(quirk_holder)
-
- var/lums = holder_turf.get_lumcount()
-
- if(lums > LIGHTING_TILE_IS_DARK)
- quirk_holder.clear_mood_event("nyctophobia")
- return
-
- if(quirk_holder.move_intent == MOVE_INTENT_RUN)
- to_chat(quirk_holder, span_warning("Easy, easy, take it slow... you're in the dark..."))
- quirk_holder.toggle_move_intent()
- quirk_holder.add_mood_event("nyctophobia", /datum/mood_event/nyctophobia)
-
-#define MOOD_CATEGORY_PHOTOPHOBIA "photophobia"
-
-/datum/quirk/photophobia
- name = "Photophobia"
- desc = "Bright lights seem to bother you more than others. Maybe it's a medical condition."
- icon = FA_ICON_ARROWS_TO_EYE
- value = -4
- gain_text = span_danger("The safety of light feels off...")
- lose_text = span_notice("Enlightening.")
- medical_record_text = "Patient has acute phobia of light, and insists it is physically harmful."
- hardcore_value = 4
- mail_goodies = list(
- /obj/item/flashlight/flashdark,
- /obj/item/food/grown/mushroom/glowshroom/shadowshroom,
- /obj/item/skillchip/light_remover,
- )
-
-/datum/quirk/photophobia/add(client/client_source)
- RegisterSignal(quirk_holder, COMSIG_CARBON_GAIN_ORGAN, PROC_REF(check_eyes))
- RegisterSignal(quirk_holder, COMSIG_CARBON_LOSE_ORGAN, PROC_REF(restore_eyes))
- RegisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED, PROC_REF(on_holder_moved))
- update_eyes(quirk_holder.get_organ_slot(ORGAN_SLOT_EYES))
-
-/datum/quirk/photophobia/remove()
- UnregisterSignal(quirk_holder, list(
- COMSIG_CARBON_GAIN_ORGAN,
- COMSIG_CARBON_LOSE_ORGAN,
- COMSIG_MOVABLE_MOVED,))
- quirk_holder.clear_mood_event(MOOD_CATEGORY_PHOTOPHOBIA)
- var/obj/item/organ/internal/eyes/normal_eyes = quirk_holder.get_organ_slot(ORGAN_SLOT_EYES)
- if(istype(normal_eyes))
- normal_eyes.flash_protect = initial(normal_eyes.flash_protect)
-
-/datum/quirk/photophobia/proc/check_eyes(obj/item/organ/internal/eyes/sensitive_eyes)
- SIGNAL_HANDLER
- if(!istype(sensitive_eyes))
- return
- update_eyes(sensitive_eyes)
-
-/datum/quirk/photophobia/proc/update_eyes(obj/item/organ/internal/eyes/target_eyes)
- if(!istype(target_eyes))
- return
- target_eyes.flash_protect = max(target_eyes.flash_protect - 1, FLASH_PROTECTION_HYPER_SENSITIVE)
-
-/datum/quirk/photophobia/proc/restore_eyes(obj/item/organ/internal/eyes/normal_eyes)
- SIGNAL_HANDLER
- if(!istype(normal_eyes))
- return
- normal_eyes.flash_protect = initial(normal_eyes.flash_protect)
-
-/datum/quirk/photophobia/proc/on_holder_moved(mob/living/source, atom/old_loc, dir, forced)
- SIGNAL_HANDLER
-
- if(quirk_holder.stat != CONSCIOUS || quirk_holder.IsSleeping() || quirk_holder.IsUnconscious())
- return
-
- if(HAS_TRAIT(quirk_holder, TRAIT_FEARLESS))
- return
-
- var/mob/living/carbon/human/human_holder = quirk_holder
-
- if(human_holder.sight & SEE_TURFS)
- return
-
- var/turf/holder_turf = get_turf(quirk_holder)
-
- var/lums = holder_turf.get_lumcount()
-
- var/eye_protection = quirk_holder.get_eye_protection()
- if(lums < LIGHTING_TILE_IS_DARK || eye_protection >= FLASH_PROTECTION_NONE)
- quirk_holder.clear_mood_event(MOOD_CATEGORY_PHOTOPHOBIA)
- return
- quirk_holder.add_mood_event(MOOD_CATEGORY_PHOTOPHOBIA, /datum/mood_event/photophobia)
-
- #undef MOOD_CATEGORY_PHOTOPHOBIA
-
-/datum/quirk/softspoken
- name = "Soft-Spoken"
- desc = "You are soft-spoken, and your voice is hard to hear."
- icon = FA_ICON_COMMENT
- value = -2
- mob_trait = TRAIT_SOFTSPOKEN
- gain_text = span_danger("You feel like you're speaking more quietly.")
- lose_text = span_notice("You feel like you're speaking louder.")
- medical_record_text = "Patient is soft-spoken and difficult to hear."
-
-/datum/quirk/clumsy
- name = "Clumsy"
- desc = "You're clumsy, a goofball, a silly dude. You big loveable himbo/bimbo you! Hope you weren't planning on using your hands for anything that takes even a LICK of dexterity."
- icon = FA_ICON_FACE_DIZZY
- value = -8
- mob_trait = TRAIT_CLUMSY
- gain_text = span_danger("You feel your IQ sink like your brain is liquid.")
- lose_text = span_notice("You feel like your IQ went up to at least average.")
- medical_record_text = "Patient has demonstrated an extreme difficulty with high motor skill paired with an inability to demonstrate critical thinking."
-
-/datum/quirk/nonviolent
- name = "Pacifist"
- desc = "The thought of violence makes you sick. So much so, in fact, that you can't hurt anyone."
- icon = FA_ICON_PEACE
- value = -8
- mob_trait = TRAIT_PACIFISM
- gain_text = span_danger("You feel repulsed by the thought of violence!")
- lose_text = span_notice("You think you can defend yourself again.")
- medical_record_text = "Patient is unusually pacifistic and cannot bring themselves to cause physical harm."
- hardcore_value = 6
- mail_goodies = list(/obj/effect/spawner/random/decoration/flower, /obj/effect/spawner/random/contraband/cannabis) // flower power
-
-/datum/quirk/bighands
- name = "Big Hands"
- desc = "You have big hands, it sure does make it hard to use a lot of things."
- icon = FA_ICON_HAND_DOTS
- value = -6
- mob_trait = TRAIT_CHUNKYFINGERS
- gain_text = span_danger("Your hands are huge! You can't use small things anymore!")
- lose_text = span_notice("Your hands are back to normal.")
- medical_record_text = "Patient has unusually large hands. Made me question my masculinity..."
- hardcore_value = 5
-
-/datum/quirk/paraplegic
- name = "Paraplegic"
- desc = "Your legs do not function. Nothing will ever fix this. But hey, free wheelchair!"
- icon = FA_ICON_WHEELCHAIR
- value = -12
- gain_text = null // Handled by trauma.
- lose_text = null
- medical_record_text = "Patient has an untreatable impairment in motor function in the lower extremities."
- hardcore_value = 15
- mail_goodies = list(/obj/vehicle/ridden/wheelchair/motorized) //yes a fullsized unfolded motorized wheelchair does fit
-
-/datum/quirk/paraplegic/add_unique(client/client_source)
- if(quirk_holder.buckled) // Handle late joins being buckled to arrival shuttle chairs.
- quirk_holder.buckled.unbuckle_mob(quirk_holder)
-
- var/turf/holder_turf = get_turf(quirk_holder)
- var/obj/structure/chair/spawn_chair = locate() in holder_turf
-
- var/obj/vehicle/ridden/wheelchair/wheels
- if(client_source?.get_award_status(/datum/award/score/hardcore_random) >= 5000) //More than 5k score? you unlock the gamer wheelchair.
- wheels = new /obj/vehicle/ridden/wheelchair/gold(holder_turf)
- else
- wheels = new(holder_turf)
- if(spawn_chair) // Makes spawning on the arrivals shuttle more consistent looking
- wheels.setDir(spawn_chair.dir)
-
- wheels.buckle_mob(quirk_holder)
-
- // During the spawning process, they may have dropped what they were holding, due to the paralysis
- // So put the things back in their hands.
- for(var/obj/item/dropped_item in holder_turf)
- if(dropped_item.fingerprintslast == quirk_holder.ckey)
- quirk_holder.put_in_hands(dropped_item)
-
-/datum/quirk/paraplegic/add(client/client_source)
- var/mob/living/carbon/human/human_holder = quirk_holder
- human_holder.gain_trauma(/datum/brain_trauma/severe/paralysis/paraplegic, TRAUMA_RESILIENCE_ABSOLUTE)
-
-/datum/quirk/paraplegic/remove()
- var/mob/living/carbon/human/human_holder = quirk_holder
- human_holder.cure_trauma_type(/datum/brain_trauma/severe/paralysis/paraplegic, TRAUMA_RESILIENCE_ABSOLUTE)
-
-/datum/quirk/hemiplegic
- name = "Hemiplegic"
- desc = "Half of your body doesn't work. Nothing will ever fix this."
- icon = FA_ICON_CIRCLE_HALF_STROKE
- value = -10 // slightly more bearable than paraplegic but not by much
- gain_text = null // Handled by trauma.
- lose_text = null
- medical_record_text = "Patient has an untreatable impairment in motor function on half of their body."
- hardcore_value = 10
- mail_goodies = list(
- /obj/item/stack/sheet/mineral/uranium/half, //half a stack of a material that has a half life
- /obj/item/reagent_containers/cup/glass/drinkingglass/filled/half_full,
- )
-
-/datum/quirk/hemiplegic/add(client/client_source)
- var/mob/living/carbon/human/human_holder = quirk_holder
- var/trauma_type = pick(/datum/brain_trauma/severe/paralysis/hemiplegic/left, /datum/brain_trauma/severe/paralysis/hemiplegic/right)
- human_holder.gain_trauma(trauma_type, TRAUMA_RESILIENCE_ABSOLUTE)
-
-/datum/quirk/hemiplegic/remove()
- var/mob/living/carbon/human/human_holder = quirk_holder
- human_holder.cure_trauma_type(/datum/brain_trauma/severe/paralysis/hemiplegic, TRAUMA_RESILIENCE_ABSOLUTE)
-
-/datum/quirk/poor_aim
- name = "Stormtrooper Aim"
- desc = "You've never hit anything you were aiming for in your life."
- icon = FA_ICON_BULLSEYE
- value = -4
- medical_record_text = "Patient possesses a strong tremor in both hands."
- hardcore_value = 3
- mail_goodies = list(/obj/item/cardboard_cutout) // for target practice
-
-/datum/quirk/poor_aim/add(client/client_source)
- RegisterSignal(quirk_holder, COMSIG_MOB_FIRED_GUN, PROC_REF(on_mob_fired_gun))
-
-/datum/quirk/poor_aim/remove(client/client_source)
- UnregisterSignal(quirk_holder, COMSIG_MOB_FIRED_GUN)
-
-/datum/quirk/poor_aim/proc/on_mob_fired_gun(mob/user, obj/item/gun/gun_fired, target, params, zone_override, list/bonus_spread_values)
- SIGNAL_HANDLER
- bonus_spread_values[MIN_BONUS_SPREAD_INDEX] += 10
- bonus_spread_values[MAX_BONUS_SPREAD_INDEX] += 35
-
-/datum/quirk/prosopagnosia
- name = "Prosopagnosia"
- desc = "You have a mental disorder that prevents you from being able to recognize faces at all."
- icon = FA_ICON_USER_SECRET
- value = -4
- mob_trait = TRAIT_PROSOPAGNOSIA
- medical_record_text = "Patient suffers from prosopagnosia and cannot recognize faces."
- hardcore_value = 5
- mail_goodies = list(/obj/item/skillchip/appraiser) // bad at recognizing faces but good at recognizing IDs
-
-/datum/quirk/prosthetic_limb
- name = "Prosthetic Limb"
- 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
- mail_goodies = list(/obj/item/weldingtool/mini, /obj/item/stack/cable_coil/five)
- /// The slot to replace, in string form
- var/slot_string = "limb"
- /// the original limb from before the prosthetic was applied
- 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/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)
-
-/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."))
-
-/datum/quirk/prosthetic_limb/remove()
- var/mob/living/carbon/human/human_holder = quirk_holder
- human_holder.del_and_replace_bodypart(old_limb, special = TRUE)
- old_limb = null
-
-/datum/quirk/quadruple_amputee
- name = "Quadruple Amputee"
- desc = "Oops! All Prosthetics! Due to some truly cruel cosmic punishment, all your limbs have been replaced with surplus prosthetics."
- icon = "tg-prosthetic-full"
- value = -6
- medical_record_text = "During physical examination, patient was found to have all low-budget prosthetic limbs."
- hardcore_value = 6
- quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE
- mail_goodies = list(/obj/item/weldingtool/mini, /obj/item/stack/cable_coil/five)
-
-/datum/quirk/quadruple_amputee/add_unique(client/client_source)
- var/mob/living/carbon/human/human_holder = quirk_holder
- human_holder.del_and_replace_bodypart(new /obj/item/bodypart/arm/left/robot/surplus, special = TRUE)
- human_holder.del_and_replace_bodypart(new /obj/item/bodypart/arm/right/robot/surplus, special = TRUE)
- human_holder.del_and_replace_bodypart(new /obj/item/bodypart/leg/left/robot/surplus, special = TRUE)
- human_holder.del_and_replace_bodypart(new /obj/item/bodypart/leg/right/robot/surplus, special = TRUE)
-
-/datum/quirk/quadruple_amputee/post_add()
- to_chat(quirk_holder, span_boldannounce("All your limbs have been replaced with surplus prosthetics. They are fragile and will easily come apart under duress. \
- Additionally, you need to use a welding tool and cables to repair them, instead of bruise packs and ointment."))
-
-/datum/quirk/prosthetic_organ
- name = "Prosthetic Organ"
- desc = "An accident caused you to lose one of your organs. Because of this, you now have a surplus prosthetic!"
- icon = FA_ICON_LUNGS
- value = -3
- medical_record_text = "During physical examination, patient was found to have a low-budget prosthetic organ. \
- Removal of these organs is known to be dangerous to the patient as well as the practitioner."
- hardcore_value = 3
- mail_goodies = list(/obj/item/storage/organbox)
- /// The slot to replace, in string form
- var/slot_string = "organ"
- /// The original organ from before the prosthetic was applied
- var/obj/item/organ/old_organ
-
-/datum/quirk/prosthetic_organ/add_unique(client/client_source)
- var/mob/living/carbon/human/human_holder = quirk_holder
- var/static/list/organ_slots = list(
- ORGAN_SLOT_HEART,
- ORGAN_SLOT_LUNGS,
- ORGAN_SLOT_LIVER,
- ORGAN_SLOT_STOMACH,
- )
- var/list/possible_organ_slots = organ_slots.Copy()
- if(HAS_TRAIT(human_holder, TRAIT_NOBLOOD))
- possible_organ_slots -= ORGAN_SLOT_HEART
- if(HAS_TRAIT(human_holder, TRAIT_NOBREATH))
- possible_organ_slots -= ORGAN_SLOT_LUNGS
- if(HAS_TRAIT(human_holder, TRAIT_LIVERLESS_METABOLISM))
- possible_organ_slots -= ORGAN_SLOT_LIVER
- if(HAS_TRAIT(human_holder, TRAIT_NOHUNGER))
- possible_organ_slots -= ORGAN_SLOT_STOMACH
- if(!length(organ_slots)) //what the hell
- return
- var/organ_slot = pick(possible_organ_slots)
- var/obj/item/organ/prosthetic
- switch(organ_slot)
- if(ORGAN_SLOT_HEART)
- prosthetic = new /obj/item/organ/internal/heart/cybernetic/surplus
- slot_string = "heart"
- if(ORGAN_SLOT_LUNGS)
- prosthetic = new /obj/item/organ/internal/lungs/cybernetic/surplus
- slot_string = "lungs"
- if(ORGAN_SLOT_LIVER)
- prosthetic = new /obj/item/organ/internal/liver/cybernetic/surplus
- slot_string = "liver"
- if(ORGAN_SLOT_STOMACH)
- prosthetic = new /obj/item/organ/internal/stomach/cybernetic/surplus
- slot_string = "stomach"
- medical_record_text = "During physical examination, patient was found to have a low-budget prosthetic [slot_string]. \
- Removal of these organs is known to be dangerous to the patient as well as the practitioner."
- old_organ = human_holder.get_organ_slot(organ_slot)
- if(prosthetic.Insert(human_holder, special = TRUE, drop_if_replaced = TRUE))
- old_organ.moveToNullspace()
- STOP_PROCESSING(SSobj, old_organ)
-
-/datum/quirk/prosthetic_organ/post_add()
- to_chat(quirk_holder, span_boldannounce("Your [slot_string] has been replaced with a surplus organ. It is fragile and will easily come apart under duress. \
- Additionally, any EMP will make it stop working entirely."))
-
-/datum/quirk/prosthetic_organ/remove()
- if(old_organ)
- old_organ.Insert(quirk_holder, special = TRUE)
- old_organ = null
-
-/datum/quirk/tin_man
- name = "Tin Man"
- desc = "Oops! All Prosthetics! Due to some truly cruel cosmic punishment, most of your internal organs have been replaced with surplus prosthetics."
- icon = FA_ICON_ROBOT
- value = -6
- medical_record_text = "During physical examination, patient was found to have numerous low-budget prosthetic internal organs. \
- Removal of these organs is known to be dangerous to the patient as well as the practitioner."
- hardcore_value = 6
- mail_goodies = list(/obj/item/storage/organbox)
-
-/datum/quirk/tin_man/add_unique(client/client_source)
- var/mob/living/carbon/human/human_holder = quirk_holder
- var/static/list/organ_slots = list(
- ORGAN_SLOT_HEART = /obj/item/organ/internal/heart/cybernetic/surplus,
- ORGAN_SLOT_LUNGS = /obj/item/organ/internal/lungs/cybernetic/surplus,
- ORGAN_SLOT_LIVER = /obj/item/organ/internal/liver/cybernetic/surplus,
- ORGAN_SLOT_STOMACH = /obj/item/organ/internal/stomach/cybernetic/surplus,
- )
- var/list/possible_organ_slots = organ_slots.Copy()
- if(HAS_TRAIT(human_holder, TRAIT_NOBLOOD))
- possible_organ_slots -= ORGAN_SLOT_HEART
- if(HAS_TRAIT(human_holder, TRAIT_NOBREATH))
- possible_organ_slots -= ORGAN_SLOT_LUNGS
- if(HAS_TRAIT(human_holder, TRAIT_LIVERLESS_METABOLISM))
- possible_organ_slots -= ORGAN_SLOT_LIVER
- if(HAS_TRAIT(human_holder, TRAIT_NOHUNGER))
- possible_organ_slots -= ORGAN_SLOT_STOMACH
- if(!length(organ_slots)) //what the hell
- return
- for(var/organ_slot in possible_organ_slots)
- var/organ_path = possible_organ_slots[organ_slot]
- var/obj/item/organ/new_organ = new organ_path()
- new_organ.Insert(human_holder, special = TRUE, drop_if_replaced = FALSE)
-
-/datum/quirk/tin_man/post_add()
- to_chat(quirk_holder, span_boldannounce("Most of your internal organs have been replaced with surplus prosthetics. They are fragile and will easily come apart under duress. \
- Additionally, any EMP will make them stop working entirely."))
-
-/datum/quirk/pushover
- name = "Pushover"
- desc = "Your first instinct is always to let people push you around. Resisting out of grabs will take conscious effort."
- icon = FA_ICON_HANDSHAKE
- value = -8
- mob_trait = TRAIT_GRABWEAKNESS
- gain_text = span_danger("You feel like a pushover.")
- lose_text = span_notice("You feel like standing up for yourself.")
- medical_record_text = "Patient presents a notably unassertive personality and is easy to manipulate."
- hardcore_value = 4
- mail_goodies = list(/obj/item/clothing/gloves/cargo_gauntlet)
-
-/datum/quirk/insanity
- name = "Reality Dissociation Syndrome"
- desc = "You suffer from a severe disorder that causes very vivid hallucinations. \
- Mindbreaker toxin can suppress its effects, and you are immune to mindbreaker's hallucinogenic properties. \
- THIS IS NOT A LICENSE TO GRIEF."
- icon = FA_ICON_GRIN_TONGUE_WINK
- value = -8
- gain_text = span_userdanger("...")
- lose_text = span_notice("You feel in tune with the world again.")
- medical_record_text = "Patient suffers from acute Reality Dissociation Syndrome and experiences vivid hallucinations."
- hardcore_value = 6
- mail_goodies = list(/obj/item/storage/pill_bottle/lsdpsych)
- /// Weakref to the trauma we give out
- var/datum/weakref/added_trama_ref
-
-/datum/quirk/insanity/add(client/client_source)
- if(!iscarbon(quirk_holder))
- return
- var/mob/living/carbon/carbon_quirk_holder = quirk_holder
-
- // Setup our special RDS mild hallucination.
- // Not a unique subtype so not to plague subtypesof,
- // also as we inherit the names and values from our quirk.
- var/datum/brain_trauma/mild/hallucinations/added_trauma = new()
- added_trauma.resilience = TRAUMA_RESILIENCE_ABSOLUTE
- added_trauma.name = name
- added_trauma.desc = medical_record_text
- added_trauma.scan_desc = lowertext(name)
- added_trauma.gain_text = null
- added_trauma.lose_text = null
-
- carbon_quirk_holder.gain_trauma(added_trauma)
- added_trama_ref = WEAKREF(added_trauma)
-
-/datum/quirk/insanity/post_add()
- var/rds_policy = get_policy("[type]") || "Please note that your [lowertext(name)] does NOT give you any additional right to attack people or cause chaos."
- // I don't /think/ we'll need this, but for newbies who think "roleplay as insane" = "license to kill", it's probably a good thing to have.
- to_chat(quirk_holder, span_big(span_info(rds_policy)))
-
-/datum/quirk/insanity/remove()
- QDEL_NULL(added_trama_ref)
-
-/datum/quirk/social_anxiety
- name = "Social Anxiety"
- desc = "Talking to people is very difficult for you, and you often stutter or even lock up."
- icon = FA_ICON_COMMENT_SLASH
- value = -3
- gain_text = span_danger("You start worrying about what you're saying.")
- lose_text = span_notice("You feel easier about talking again.") //if only it were that easy!
- medical_record_text = "Patient is usually anxious in social encounters and prefers to avoid them."
- hardcore_value = 4
- mob_trait = TRAIT_ANXIOUS
- mail_goodies = list(/obj/item/storage/pill_bottle/psicodine)
- var/dumb_thing = TRUE
-
-/datum/quirk/social_anxiety/add(client/client_source)
- RegisterSignal(quirk_holder, COMSIG_MOB_EYECONTACT, PROC_REF(eye_contact))
- RegisterSignal(quirk_holder, COMSIG_MOB_EXAMINATE, PROC_REF(looks_at_floor))
- RegisterSignal(quirk_holder, COMSIG_MOB_SAY, PROC_REF(handle_speech))
-
-/datum/quirk/social_anxiety/remove()
- UnregisterSignal(quirk_holder, list(COMSIG_MOB_EYECONTACT, COMSIG_MOB_EXAMINATE, COMSIG_MOB_SAY))
-
-/datum/quirk/social_anxiety/proc/handle_speech(datum/source, list/speech_args)
- SIGNAL_HANDLER
-
- if(HAS_TRAIT(quirk_holder, TRAIT_FEARLESS))
- return
-
- var/moodmod
- if(quirk_holder.mob_mood)
- moodmod = (1+0.02*(50-(max(50, quirk_holder.mob_mood.mood_level*(7-quirk_holder.mob_mood.sanity_level))))) //low sanity levels are better, they max at 6
- else
- moodmod = (1+0.02*(50-(max(50, 0.1*quirk_holder.nutrition))))
- var/nearby_people = 0
- for(var/mob/living/carbon/human/H in oview(3, quirk_holder))
- if(H.client)
- nearby_people++
- var/message = speech_args[SPEECH_MESSAGE]
- if(message)
- var/list/message_split = splittext(message, " ")
- var/list/new_message = list()
- var/mob/living/carbon/human/quirker = quirk_holder
- for(var/word in message_split)
- if(prob(max(5,(nearby_people*12.5*moodmod))) && word != message_split[1]) //Minimum 1/20 chance of filler
- new_message += pick("uh,","erm,","um,")
- if(prob(min(5,(0.05*(nearby_people*12.5)*moodmod)))) //Max 1 in 20 chance of cutoff after a successful filler roll, for 50% odds in a 15 word sentence
- quirker.set_silence_if_lower(6 SECONDS)
- to_chat(quirker, span_danger("You feel self-conscious and stop talking. You need a moment to recover!"))
- break
- if(prob(max(5,(nearby_people*12.5*moodmod)))) //Minimum 1/20 chance of stutter
- // Add a short stutter, THEN treat our word
- quirker.adjust_stutter(0.5 SECONDS)
- var/list/message_data = quirker.treat_message(word, capitalize_message = FALSE)
- new_message += message_data["message"]
- else
- new_message += word
-
- message = jointext(new_message, " ")
- var/mob/living/carbon/human/quirker = quirk_holder
- if(prob(min(50,(0.50*(nearby_people*12.5)*moodmod)))) //Max 50% chance of not talking
- if(dumb_thing)
- to_chat(quirker, span_userdanger("You think of a dumb thing you said a long time ago and scream internally."))
- dumb_thing = FALSE //only once per life
- if(prob(1))
- new/obj/item/food/spaghetti/pastatomato(get_turf(quirker)) //now that's what I call spaghetti code
- else
- to_chat(quirk_holder, span_warning("You think that wouldn't add much to the conversation and decide not to say it."))
- if(prob(min(25,(0.25*(nearby_people*12.75)*moodmod)))) //Max 25% chance of silence stacks after successful not talking roll
- to_chat(quirker, span_danger("You retreat into yourself. You really don't feel up to talking."))
- quirker.set_silence_if_lower(10 SECONDS)
-
- speech_args[SPEECH_MESSAGE] = pick("Uh.","Erm.","Um.")
- else
- speech_args[SPEECH_MESSAGE] = message
-
-// small chance to make eye contact with inanimate objects/mindless mobs because of nerves
-/datum/quirk/social_anxiety/proc/looks_at_floor(datum/source, atom/A)
- SIGNAL_HANDLER
-
- var/mob/living/mind_check = A
- if(prob(85) || (istype(mind_check) && mind_check.mind))
- return
-
- addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(to_chat), quirk_holder, span_smallnotice("You make eye contact with [A].")), 3)
-
-/datum/quirk/social_anxiety/proc/eye_contact(datum/source, mob/living/other_mob, triggering_examiner)
- SIGNAL_HANDLER
-
- if(prob(75))
- return
- var/msg
- if(triggering_examiner)
- msg = "You make eye contact with [other_mob], "
- else
- msg = "[other_mob] makes eye contact with you, "
-
- switch(rand(1,3))
- if(1)
- quirk_holder.set_jitter_if_lower(20 SECONDS)
- msg += "causing you to start fidgeting!"
- if(2)
- quirk_holder.set_stutter_if_lower(6 SECONDS)
- msg += "causing you to start stuttering!"
- if(3)
- quirk_holder.Stun(2 SECONDS)
- msg += "causing you to freeze up!"
-
- quirk_holder.add_mood_event("anxiety_eyecontact", /datum/mood_event/anxiety_eyecontact)
- addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(to_chat), quirk_holder, span_userdanger("[msg]")), 3) // so the examine signal has time to fire and this will print after
- return COMSIG_BLOCK_EYECONTACT
-
-/datum/mood_event/anxiety_eyecontact
- description = "Sometimes eye contact makes me so nervous..."
- mood_change = -5
- timeout = 3 MINUTES
-
-/datum/quirk/item_quirk/junkie
- name = "Junkie"
- desc = "You can't get enough of hard drugs."
- icon = FA_ICON_PILLS
- value = -6
- gain_text = span_danger("You suddenly feel the craving for drugs.")
- medical_record_text = "Patient has a history of hard drugs."
- hardcore_value = 4
- quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES
- mail_goodies = list(/obj/effect/spawner/random/contraband/narcotics)
- var/drug_list = list(/datum/reagent/drug/blastoff, /datum/reagent/drug/krokodil, /datum/reagent/medicine/morphine, /datum/reagent/drug/happiness, /datum/reagent/drug/methamphetamine) //List of possible IDs
- var/datum/reagent/reagent_type //!If this is defined, reagent_id will be unused and the defined reagent type will be instead.
- var/datum/reagent/reagent_instance //! actual instanced version of the reagent
- var/where_drug //! Where the drug spawned
- var/obj/item/drug_container_type //! If this is defined before pill generation, pill generation will be skipped. This is the type of the pill bottle.
- var/where_accessory //! where the accessory spawned
- var/obj/item/accessory_type //! If this is null, an accessory won't be spawned.
- var/process_interval = 30 SECONDS //! how frequently the quirk processes
- var/next_process = 0 //! ticker for processing
- var/drug_flavour_text = "Better hope you don't run out..."
-
-/datum/quirk/item_quirk/junkie/add_unique(client/client_source)
- var/mob/living/carbon/human/human_holder = quirk_holder
-
- if(!reagent_type)
- reagent_type = pick(drug_list)
-
- reagent_instance = new reagent_type()
-
- for(var/addiction in reagent_instance.addiction_types)
- human_holder.last_mind?.add_addiction_points(addiction, 1000)
-
- var/current_turf = get_turf(quirk_holder)
-
- if(!drug_container_type)
- drug_container_type = /obj/item/storage/pill_bottle
-
- var/obj/item/drug_instance = new drug_container_type(current_turf)
- if(istype(drug_instance, /obj/item/storage/pill_bottle))
- var/pill_state = "pill[rand(1,20)]"
- for(var/i in 1 to 7)
- var/obj/item/reagent_containers/pill/pill = new(drug_instance)
- pill.icon_state = pill_state
- pill.reagents.add_reagent(reagent_type, 3)
-
- give_item_to_holder(
- drug_instance,
- list(
- LOCATION_LPOCKET = ITEM_SLOT_LPOCKET,
- LOCATION_RPOCKET = ITEM_SLOT_RPOCKET,
- LOCATION_BACKPACK = ITEM_SLOT_BACKPACK,
- LOCATION_HANDS = ITEM_SLOT_HANDS,
- ),
- flavour_text = drug_flavour_text,
- )
-
- if(accessory_type)
- give_item_to_holder(
- accessory_type,
- list(
- LOCATION_LPOCKET = ITEM_SLOT_LPOCKET,
- LOCATION_RPOCKET = ITEM_SLOT_RPOCKET,
- LOCATION_BACKPACK = ITEM_SLOT_BACKPACK,
- LOCATION_HANDS = ITEM_SLOT_HANDS,
- )
- )
-
-/datum/quirk/item_quirk/junkie/remove()
- if(quirk_holder && reagent_instance)
- for(var/addiction_type in subtypesof(/datum/addiction))
- quirk_holder.mind.remove_addiction_points(addiction_type, MAX_ADDICTION_POINTS)
-
-/datum/quirk/item_quirk/junkie/process(seconds_per_tick)
- if(HAS_TRAIT(quirk_holder, TRAIT_LIVERLESS_METABOLISM))
- return
- var/mob/living/carbon/human/human_holder = quirk_holder
- if(world.time > next_process)
- next_process = world.time + process_interval
- var/deleted = QDELETED(reagent_instance)
- var/missing_addiction = FALSE
- for(var/addiction_type in reagent_instance.addiction_types)
- if(!LAZYACCESS(human_holder.last_mind?.active_addictions, addiction_type))
- missing_addiction = TRUE
- if(deleted || missing_addiction)
- if(deleted)
- reagent_instance = new reagent_type()
- to_chat(quirk_holder, span_danger("You thought you kicked it, but you feel like you're falling back onto bad habits.."))
- for(var/addiction in reagent_instance.addiction_types)
- human_holder.last_mind?.add_addiction_points(addiction, 1000) ///Max that shit out
-
-/datum/quirk/item_quirk/junkie/smoker
- name = "Smoker"
- desc = "Sometimes you just really want a smoke. Probably not great for your lungs."
- icon = FA_ICON_SMOKING
- value = -4
- gain_text = span_danger("You could really go for a smoke right about now.")
- lose_text = span_notice("You don't feel nearly as hooked to nicotine anymore.")
- medical_record_text = "Patient is a current smoker."
- reagent_type = /datum/reagent/drug/nicotine
- accessory_type = /obj/item/lighter/greyscale
- mob_trait = TRAIT_SMOKER
- hardcore_value = 1
- drug_flavour_text = "Make sure you get your favorite brand when you run out."
- mail_goodies = list(
- /obj/effect/spawner/random/entertainment/cigarette_pack,
- /obj/effect/spawner/random/entertainment/cigar,
- /obj/effect/spawner/random/entertainment/lighter,
- /obj/item/clothing/mask/cigarette/pipe,
- )
-
-/datum/quirk/item_quirk/junkie/smoker/New()
- drug_container_type = pick(/obj/item/storage/fancy/cigarettes,
- /obj/item/storage/fancy/cigarettes/cigpack_midori,
- /obj/item/storage/fancy/cigarettes/cigpack_uplift,
- /obj/item/storage/fancy/cigarettes/cigpack_robust,
- /obj/item/storage/fancy/cigarettes/cigpack_robustgold,
- /obj/item/storage/fancy/cigarettes/cigpack_carp)
-
- return ..()
-
-/datum/quirk/item_quirk/junkie/smoker/post_add()
- . = ..()
- quirk_holder.add_mob_memory(/datum/memory/key/quirk_smoker, protagonist = quirk_holder, preferred_brand = initial(drug_container_type.name))
- // smoker lungs have 25% less health and healing
- var/obj/item/organ/internal/lungs/smoker_lungs = quirk_holder.get_organ_slot(ORGAN_SLOT_LUNGS)
- if(smoker_lungs && IS_ORGANIC_ORGAN(smoker_lungs)) // robotic lungs aren't affected
- smoker_lungs.maxHealth = smoker_lungs.maxHealth * 0.75
- smoker_lungs.healing_factor = smoker_lungs.healing_factor * 0.75
-
-/datum/quirk/item_quirk/junkie/smoker/process(seconds_per_tick)
- . = ..()
- var/mob/living/carbon/human/human_holder = quirk_holder
- var/obj/item/mask_item = human_holder.get_item_by_slot(ITEM_SLOT_MASK)
- if(istype(mask_item, /obj/item/clothing/mask/cigarette))
- var/obj/item/storage/fancy/cigarettes/cigarettes = drug_container_type
- if(istype(mask_item, initial(cigarettes.spawn_type)))
- quirk_holder.clear_mood_event("wrong_cigs")
- else
- quirk_holder.add_mood_event("wrong_cigs", /datum/mood_event/wrong_brand)
-
-/datum/quirk/item_quirk/junkie/alcoholic
- name = "Alcoholic"
- desc = "You just can't live without alcohol. Your liver is a machine that turns ethanol into acetaldehyde."
- icon = FA_ICON_WINE_GLASS
- value = -4
- gain_text = span_danger("You really need a drink.")
- lose_text = span_notice("Alcohol doesn't seem nearly as enticing anymore.")
- medical_record_text = "Patient is an alcoholic."
- reagent_type = /datum/reagent/consumable/ethanol
- drug_container_type = /obj/item/reagent_containers/cup/glass/bottle/whiskey
- mob_trait = TRAIT_HEAVY_DRINKER
- hardcore_value = 1
- drug_flavour_text = "Make sure you get your favorite type of drink when you run out."
- mail_goodies = list(
- /obj/effect/spawner/random/food_or_drink/booze,
- /obj/item/book/bible/booze,
- )
- /// Cached typepath of the owner's favorite alcohol reagent
- var/datum/reagent/consumable/ethanol/favorite_alcohol
-
-/datum/quirk/item_quirk/junkie/alcoholic/New()
- drug_container_type = pick(
- /obj/item/reagent_containers/cup/glass/bottle/whiskey,
- /obj/item/reagent_containers/cup/glass/bottle/vodka,
- /obj/item/reagent_containers/cup/glass/bottle/ale,
- /obj/item/reagent_containers/cup/glass/bottle/beer,
- /obj/item/reagent_containers/cup/glass/bottle/hcider,
- /obj/item/reagent_containers/cup/glass/bottle/wine,
- /obj/item/reagent_containers/cup/glass/bottle/sake,
- )
-
- return ..()
-
-/datum/quirk/item_quirk/junkie/alcoholic/post_add()
- . = ..()
- RegisterSignal(quirk_holder, COMSIG_MOB_REAGENT_CHECK, PROC_REF(check_brandy))
-
- var/obj/item/reagent_containers/brandy_container = GLOB.alcohol_containers[drug_container_type]
- if(isnull(brandy_container))
- stack_trace("Alcoholic quirk added while the GLOB.alcohol_containers is (somehow) not initialized!")
- brandy_container = new drug_container_type
- favorite_alcohol = brandy_container.list_reagents[1]
- qdel(brandy_container)
- else
- favorite_alcohol = brandy_container.list_reagents[1]
-
- quirk_holder.add_mob_memory(/datum/memory/key/quirk_alcoholic, protagonist = quirk_holder, preferred_brandy = initial(favorite_alcohol.name))
- // alcoholic livers have 25% less health and healing
- var/obj/item/organ/internal/liver/alcohol_liver = quirk_holder.get_organ_slot(ORGAN_SLOT_LIVER)
- if(alcohol_liver && IS_ORGANIC_ORGAN(alcohol_liver)) // robotic livers aren't affected
- alcohol_liver.maxHealth = alcohol_liver.maxHealth * 0.75
- alcohol_liver.healing_factor = alcohol_liver.healing_factor * 0.75
-
-/datum/quirk/item_quirk/junkie/alcoholic/remove()
- UnregisterSignal(quirk_holder, COMSIG_MOB_REAGENT_CHECK)
-
-/datum/quirk/item_quirk/junkie/alcoholic/proc/check_brandy(mob/source, datum/reagent/booze)
- SIGNAL_HANDLER
-
- //we don't care if it is not alcohol
- if(!istype(booze, /datum/reagent/consumable/ethanol))
- return
-
- if(istype(booze, favorite_alcohol))
- quirk_holder.clear_mood_event("wrong_alcohol")
- else
- quirk_holder.add_mood_event("wrong_alcohol", /datum/mood_event/wrong_brandy)
-
-/datum/quirk/item_quirk/chronic_illness
- name = "Chronic Illness"
- desc = "You have a chronic illness that requires constant medication to keep under control."
- icon = FA_ICON_DISEASE
- value = -12
- gain_text = span_danger("You feel a bit off today.")
- lose_text = span_notice("You feel a bit better today.")
- medical_record_text = "Patient has a chronic illness that requires constant medication to keep under control."
- hardcore_value = 12
- mail_goodies = list(/obj/item/storage/pill_bottle/sansufentanyl)
-
-/datum/quirk/item_quirk/chronic_illness/add_unique(client/client_source)
- var/datum/disease/chronic_illness/hms = new /datum/disease/chronic_illness()
- quirk_holder.ForceContractDisease(hms)
- give_item_to_holder(/obj/item/storage/pill_bottle/sansufentanyl, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK),flavour_text = "You've been provided with medication to help manage your condition. Take it regularly to avoid complications.")
- give_item_to_holder(/obj/item/healthanalyzer/simple/disease, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK))
-
-/datum/quirk/unstable
- name = "Unstable"
- desc = "Due to past troubles, you are unable to recover your sanity if you lose it. Be very careful managing your mood!"
- icon = FA_ICON_ANGRY
- value = -10
- mob_trait = TRAIT_UNSTABLE
- gain_text = span_danger("There's a lot on your mind right now.")
- lose_text = span_notice("Your mind finally feels calm.")
- medical_record_text = "Patient's mind is in a vulnerable state, and cannot recover from traumatic events."
- hardcore_value = 9
- mail_goodies = list(/obj/effect/spawner/random/entertainment/plushie)
-
-/datum/quirk/item_quirk/allergic
- name = "Extreme Medicine Allergy"
- desc = "Ever since you were a kid, you've been allergic to certain chemicals..."
- icon = FA_ICON_PRESCRIPTION_BOTTLE
- value = -6
- gain_text = span_danger("You feel your immune system shift.")
- lose_text = span_notice("You feel your immune system phase back into perfect shape.")
- medical_record_text = "Patient's immune system responds violently to certain chemicals."
- hardcore_value = 3
- quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES
- mail_goodies = list(/obj/item/reagent_containers/hypospray/medipen) // epinephrine medipen stops allergic reactions
- var/list/allergies = list()
- var/list/blacklist = list(
- /datum/reagent/medicine/c2,
- /datum/reagent/medicine/epinephrine,
- /datum/reagent/medicine/adminordrazine,
- /datum/reagent/medicine/omnizine/godblood,
- /datum/reagent/medicine/cordiolis_hepatico,
- /datum/reagent/medicine/synaphydramine,
- /datum/reagent/medicine/diphenhydramine,
- /datum/reagent/medicine/sansufentanyl
- )
- var/allergy_string
-
-/datum/quirk/item_quirk/allergic/add_unique(client/client_source)
- var/list/chem_list = subtypesof(/datum/reagent/medicine) - blacklist
- var/list/allergy_chem_names = list()
- for(var/i in 0 to 5)
- var/datum/reagent/medicine/chem_type = pick_n_take(chem_list)
- allergies += chem_type
- allergy_chem_names += initial(chem_type.name)
-
- allergy_string = allergy_chem_names.Join(", ")
- //name = "Extreme [allergy_string] Allergies"
- medical_record_text = "Patient's immune system responds violently to [allergy_string]"
-
- var/mob/living/carbon/human/human_holder = quirk_holder
- var/obj/item/clothing/accessory/dogtag/allergy/dogtag = new(get_turf(human_holder), allergy_string)
-
- give_item_to_holder(dogtag, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS), flavour_text = "Make sure medical staff can see this...")
-
-/datum/quirk/item_quirk/allergic/post_add()
- quirk_holder.add_mob_memory(/datum/memory/key/quirk_allergy, allergy_string = allergy_string)
- to_chat(quirk_holder, span_boldnotice("You are allergic to [allergy_string], make sure not to consume any of these!"))
-
-/datum/quirk/item_quirk/allergic/process(seconds_per_tick)
- if(!iscarbon(quirk_holder))
- return
-
- if(IS_IN_STASIS(quirk_holder))
- return
-
- if(quirk_holder.stat == DEAD)
- return
-
- var/mob/living/carbon/carbon_quirk_holder = quirk_holder
- for(var/allergy in allergies)
- var/datum/reagent/instantiated_med = carbon_quirk_holder.reagents.has_reagent(allergy)
- if(!instantiated_med)
- continue
- //Just halts the progression, I'd suggest you run to medbay asap to get it fixed
- if(carbon_quirk_holder.reagents.has_reagent(/datum/reagent/medicine/epinephrine))
- instantiated_med.reagent_removal_skip_list |= ALLERGIC_REMOVAL_SKIP
- return //intentionally stops the entire proc so we avoid the organ damage after the loop
- instantiated_med.reagent_removal_skip_list -= ALLERGIC_REMOVAL_SKIP
- carbon_quirk_holder.adjustToxLoss(3 * seconds_per_tick)
- carbon_quirk_holder.reagents.add_reagent(/datum/reagent/toxin/histamine, 3 * seconds_per_tick)
- if(SPT_PROB(10, seconds_per_tick))
- carbon_quirk_holder.vomit()
- carbon_quirk_holder.adjustOrganLoss(pick(ORGAN_SLOT_BRAIN,ORGAN_SLOT_APPENDIX,ORGAN_SLOT_LUNGS,ORGAN_SLOT_HEART,ORGAN_SLOT_LIVER,ORGAN_SLOT_STOMACH),10)
-
-/datum/quirk/bad_touch
- name = "Bad Touch"
- desc = "You don't like hugs. You'd really prefer if people just left you alone."
- icon = "tg-bad-touch"
- mob_trait = TRAIT_BADTOUCH
- value = -1
- gain_text = span_danger("You just want people to leave you alone.")
- lose_text = span_notice("You could use a big hug.")
- medical_record_text = "Patient has disdain for being touched. Potentially has undiagnosed haphephobia."
- quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_MOODLET_BASED
- hardcore_value = 1
- mail_goodies = list(/obj/item/reagent_containers/spray/pepper) // show me on the doll where the bad man touched you
-
-/datum/quirk/bad_touch/add(client/client_source)
- RegisterSignals(quirk_holder, list(COMSIG_LIVING_GET_PULLED, COMSIG_CARBON_HELP_ACT), PROC_REF(uncomfortable_touch))
-
-/datum/quirk/bad_touch/remove()
- UnregisterSignal(quirk_holder, list(COMSIG_LIVING_GET_PULLED, COMSIG_CARBON_HELP_ACT))
-
-/// Causes a negative moodlet to our quirk holder on signal
-/datum/quirk/bad_touch/proc/uncomfortable_touch(datum/source)
- SIGNAL_HANDLER
-
- if(quirk_holder.stat == DEAD)
- return
-
- new /obj/effect/temp_visual/annoyed(quirk_holder.loc)
- if(quirk_holder.mob_mood.sanity <= SANITY_NEUTRAL)
- quirk_holder.add_mood_event("bad_touch", /datum/mood_event/very_bad_touch)
- else
- quirk_holder.add_mood_event("bad_touch", /datum/mood_event/bad_touch)
-
-/datum/quirk/claustrophobia
- name = "Claustrophobia"
- desc = "You are terrified of small spaces and certain jolly figures. If you are placed inside any container, locker, or machinery, a panic attack sets in and you struggle to breathe."
- icon = FA_ICON_BOX_OPEN
- value = -4
- medical_record_text = "Patient demonstrates a fear of tight spaces."
- hardcore_value = 5
- quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES
- mail_goodies = list(/obj/item/reagent_containers/syringe/convermol) // to help breathing
-
-/datum/quirk/claustrophobia/remove()
- quirk_holder.clear_mood_event("claustrophobia")
-
-/datum/quirk/claustrophobia/process(seconds_per_tick)
- if(quirk_holder.stat != CONSCIOUS || quirk_holder.IsSleeping() || quirk_holder.IsUnconscious())
- return
-
- if(HAS_TRAIT(quirk_holder, TRAIT_FEARLESS))
- return
-
- var/nick_spotted = FALSE
-
- for(var/mob/living/carbon/human/possible_claus in view(5, quirk_holder))
- if(evaluate_jolly_levels(possible_claus))
- nick_spotted = TRUE
- break
-
- if(!nick_spotted && isturf(quirk_holder.loc))
- quirk_holder.clear_mood_event("claustrophobia")
- return
-
- quirk_holder.add_mood_event("claustrophobia", /datum/mood_event/claustrophobia)
- quirk_holder.losebreath += 0.25 // miss a breath one in four times
- if(SPT_PROB(25, seconds_per_tick))
- if(nick_spotted)
- to_chat(quirk_holder, span_warning("Santa Claus is here! I gotta get out of here!"))
- else
- to_chat(quirk_holder, span_warning("You feel trapped! Must escape... can't breathe..."))
-
-///investigates whether possible_saint_nick possesses a high level of christmas cheer
-/datum/quirk/claustrophobia/proc/evaluate_jolly_levels(mob/living/carbon/human/possible_saint_nick)
- if(!istype(possible_saint_nick))
- return FALSE
-
- if(istype(possible_saint_nick.back, /obj/item/storage/backpack/santabag))
- return TRUE
-
- if(istype(possible_saint_nick.head, /obj/item/clothing/head/costume/santa) || istype(possible_saint_nick.head, /obj/item/clothing/head/helmet/space/santahat))
- return TRUE
-
- if(istype(possible_saint_nick.wear_suit, /obj/item/clothing/suit/space/santa))
- return TRUE
-
- return FALSE
-
-/datum/quirk/illiterate
- name = "Illiterate"
- desc = "You dropped out of school and are unable to read or write. This affects reading, writing, using computers and other electronics."
- icon = FA_ICON_GRADUATION_CAP
- value = -8
- mob_trait = TRAIT_ILLITERATE
- medical_record_text = "Patient is not literate."
- hardcore_value = 8
- mail_goodies = list(/obj/item/pai_card) // can read things for you
-
-
-/datum/quirk/mute
- name = "Mute"
- desc = "For some reason you are completely unable to speak."
- icon = FA_ICON_VOLUME_XMARK
- value = -4
- mob_trait = TRAIT_MUTE
- gain_text = span_danger("You find yourself unable to speak!")
- lose_text = span_notice("You feel a growing strength in your vocal chords.")
- medical_record_text = "The patient is unable to use their voice in any capacity."
- hardcore_value = 4
-
-/datum/quirk/body_purist
- name = "Body Purist"
- desc = "You believe your body is a temple and its natural form is an embodiment of perfection. Accordingly, you despise the idea of ever augmenting it with unnatural parts, cybernetic, prosthetic, or anything like it."
- icon = FA_ICON_PERSON_RAYS
- value = -2
- quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_MOODLET_BASED
- gain_text = span_danger("You now begin to hate the idea of having cybernetic implants.")
- lose_text = span_notice("Maybe cybernetics aren't so bad. You now feel okay with augmentations and prosthetics.")
- medical_record_text = "This patient has disclosed an extreme hatred for unnatural bodyparts and augmentations."
- hardcore_value = 3
- mail_goodies = list(/obj/item/paper/pamphlet/cybernetics)
- var/cybernetics_level = 0
-
-/datum/quirk/body_purist/add(client/client_source)
- check_cybernetics()
- RegisterSignal(quirk_holder, COMSIG_CARBON_GAIN_ORGAN, PROC_REF(on_organ_gain))
- RegisterSignal(quirk_holder, COMSIG_CARBON_LOSE_ORGAN, PROC_REF(on_organ_lose))
- RegisterSignal(quirk_holder, COMSIG_CARBON_ATTACH_LIMB, PROC_REF(on_limb_gain))
- RegisterSignal(quirk_holder, COMSIG_CARBON_REMOVE_LIMB, PROC_REF(on_limb_lose))
-
-/datum/quirk/body_purist/remove()
- UnregisterSignal(quirk_holder, list(
- COMSIG_CARBON_GAIN_ORGAN,
- COMSIG_CARBON_LOSE_ORGAN,
- COMSIG_CARBON_ATTACH_LIMB,
- COMSIG_CARBON_REMOVE_LIMB,
- ))
- quirk_holder.clear_mood_event("body_purist")
-
-/datum/quirk/body_purist/proc/check_cybernetics()
- var/mob/living/carbon/owner = quirk_holder
- if(!istype(owner))
- return
- for(var/obj/item/bodypart/limb as anything in owner.bodyparts)
- if(IS_ROBOTIC_LIMB(limb))
- cybernetics_level++
- for(var/obj/item/organ/organ as anything in owner.organs)
- if(IS_ROBOTIC_ORGAN(organ) && !(organ.organ_flags & ORGAN_HIDDEN))
- cybernetics_level++
- update_mood()
-
-/datum/quirk/body_purist/proc/update_mood()
- quirk_holder.clear_mood_event("body_purist")
- if(cybernetics_level)
- quirk_holder.add_mood_event("body_purist", /datum/mood_event/body_purist, -cybernetics_level * 10)
-
-/datum/quirk/body_purist/proc/on_organ_gain(datum/source, obj/item/organ/new_organ, special)
- SIGNAL_HANDLER
- if(IS_ROBOTIC_ORGAN(new_organ) && !(new_organ.organ_flags & ORGAN_HIDDEN)) //why the fuck are there 2 of them
- cybernetics_level++
- update_mood()
-
-/datum/quirk/body_purist/proc/on_organ_lose(datum/source, obj/item/organ/old_organ, special)
- SIGNAL_HANDLER
- if(IS_ROBOTIC_ORGAN(old_organ) && !(old_organ.organ_flags & ORGAN_HIDDEN))
- cybernetics_level--
- update_mood()
-
-/datum/quirk/body_purist/proc/on_limb_gain(datum/source, obj/item/bodypart/new_limb, special)
- SIGNAL_HANDLER
- if(IS_ROBOTIC_LIMB(new_limb))
- cybernetics_level++
- update_mood()
-
-/datum/quirk/body_purist/proc/on_limb_lose(datum/source, obj/item/bodypart/old_limb, special)
- SIGNAL_HANDLER
- if(IS_ROBOTIC_LIMB(old_limb))
- cybernetics_level--
- update_mood()
-
-// SKYRAT EDIT REMOVAL BEGIN
-/*
-/datum/quirk/cursed
- name = "Cursed"
- desc = "You are cursed with bad luck. You are much more likely to suffer from accidents and mishaps. When it rains, it pours."
- icon = FA_ICON_CLOUD_SHOWERS_HEAVY
- value = -8
- mob_trait = TRAIT_CURSED
- gain_text = span_danger("You feel like you're going to have a bad day.")
- lose_text = span_notice("You feel like you're going to have a good day.")
- medical_record_text = "Patient is cursed with bad luck."
- hardcore_value = 8
-
-/datum/quirk/cursed/add(client/client_source)
- quirk_holder.AddComponent(/datum/component/omen/quirk)
-*/
-// SKYRAT EDIT REMOVAL END
-
-/datum/quirk/indebted
- name = "Indebted"
- desc = "Bad life decisions, medical bills, student loans, whatever it may be, you've incurred quite the debt. A portion of all you receive will go towards extinguishing it."
- icon = FA_ICON_DOLLAR
- quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_HIDE_FROM_SCAN
- value = -2
- medical_record_text = "Alas, the patient struggled to scrape together enough money to pay the checkup bill."
- hardcore_value = 2
-
-/datum/quirk/indebted/add_unique(client/client_source)
- var/mob/living/carbon/human/human_holder = quirk_holder
- if(!human_holder.account_id)
- return
- var/datum/bank_account/account = SSeconomy.bank_accounts_by_id["[human_holder.account_id]"]
- var/debt = PAYCHECK_CREW * rand(275, 325)
- account.account_debt += debt
- RegisterSignal(account, COMSIG_BANK_ACCOUNT_DEBT_PAID, PROC_REF(on_debt_paid))
- to_chat(client_source.mob, span_warning("You remember, you've a hefty, [debt] credits debt to pay..."))
-
-///Once the debt is extinguished, award an achievement and a pin for actually taking care of it.
-/datum/quirk/indebted/proc/on_debt_paid(datum/bank_account/source)
- SIGNAL_HANDLER
- if(source.account_debt)
- return
- UnregisterSignal(source, COMSIG_BANK_ACCOUNT_DEBT_PAID)
- ///The debt was extinguished while the quirk holder was logged out, so let's kindly award it once they come back.
- if(!quirk_holder.client)
- RegisterSignal(quirk_holder, COMSIG_MOB_LOGIN, PROC_REF(award_on_login))
- else
- quirk_holder.client.give_award(/datum/award/achievement/misc/debt_extinguished, quirk_holder)
- podspawn(list(
- "target" = get_turf(quirk_holder),
- "style" = STYLE_BLUESPACE,
- "spawn" = /obj/item/clothing/accessory/debt_payer_pin,
- ))
-
-/datum/quirk/indebted/proc/award_on_login(mob/source)
- SIGNAL_HANDLER
- quirk_holder.client.give_award(/datum/award/achievement/misc/debt_extinguished, quirk_holder)
- UnregisterSignal(source, COMSIG_MOB_LOGIN)
diff --git a/code/datums/quirks/negative_quirks/non_violent.dm b/code/datums/quirks/negative_quirks/non_violent.dm
new file mode 100644
index 00000000000..e1dbb0e6480
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/non_violent.dm
@@ -0,0 +1,11 @@
+/datum/quirk/nonviolent
+ name = "Pacifist"
+ desc = "The thought of violence makes you sick. So much so, in fact, that you can't hurt anyone."
+ icon = FA_ICON_PEACE
+ value = -8
+ mob_trait = TRAIT_PACIFISM
+ gain_text = span_danger("You feel repulsed by the thought of violence!")
+ lose_text = span_notice("You think you can defend yourself again.")
+ medical_record_text = "Patient is unusually pacifistic and cannot bring themselves to cause physical harm."
+ hardcore_value = 6
+ mail_goodies = list(/obj/effect/spawner/random/decoration/flower, /obj/effect/spawner/random/contraband/cannabis) // flower power
diff --git a/code/datums/quirks/negative_quirks/numb.dm b/code/datums/quirks/negative_quirks/numb.dm
new file mode 100644
index 00000000000..cd4f28cb302
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/numb.dm
@@ -0,0 +1,15 @@
+/datum/quirk/numb
+ name = "Numb"
+ desc = "You can't feel pain at all."
+ icon = FA_ICON_STAR_OF_LIFE
+ value = -4
+ gain_text = "You feel your body becoming numb."
+ lose_text = "The numbness subsides."
+ medical_record_text = "The patient exhibits congenital hypoesthesia, making them insensitive to pain stimuli."
+ hardcore_value = 4
+
+/datum/quirk/numb/add(client/client_source)
+ quirk_holder.apply_status_effect(/datum/status_effect/grouped/screwy_hud/fake_healthy, type)
+
+/datum/quirk/numb/remove(client/client_source)
+ quirk_holder.remove_status_effect(/datum/status_effect/grouped/screwy_hud/fake_healthy, type)
diff --git a/code/datums/quirks/negative_quirks/nyctophobia.dm b/code/datums/quirks/negative_quirks/nyctophobia.dm
new file mode 100644
index 00000000000..af891a2058a
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/nyctophobia.dm
@@ -0,0 +1,46 @@
+/datum/quirk/nyctophobia
+ name = "Nyctophobia"
+ desc = "As far as you can remember, you've always been afraid of the dark. While in the dark without a light source, you instinctively act careful, and constantly feel a sense of dread."
+ icon = FA_ICON_LIGHTBULB
+ value = -3
+ medical_record_text = "Patient demonstrates a fear of the dark. (Seriously?)"
+ hardcore_value = 5
+ mail_goodies = list(/obj/effect/spawner/random/engineering/flashlight)
+
+/datum/quirk/nyctophobia/add(client/client_source)
+ RegisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED, PROC_REF(on_holder_moved))
+
+/datum/quirk/nyctophobia/remove()
+ UnregisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED)
+ quirk_holder.clear_mood_event("nyctophobia")
+
+/// Called when the quirk holder moves. Updates the quirk holder's mood.
+/datum/quirk/nyctophobia/proc/on_holder_moved(mob/living/source, atom/old_loc, dir, forced)
+ SIGNAL_HANDLER
+
+ if(quirk_holder.stat != CONSCIOUS || quirk_holder.IsSleeping() || quirk_holder.IsUnconscious())
+ return
+
+ if(HAS_TRAIT(quirk_holder, TRAIT_FEARLESS))
+ return
+
+ var/mob/living/carbon/human/human_holder = quirk_holder
+
+ if(human_holder.dna?.species.id in list(SPECIES_SHADOW, SPECIES_NIGHTMARE))
+ return
+
+ if((human_holder.sight & SEE_TURFS) == SEE_TURFS)
+ return
+
+ var/turf/holder_turf = get_turf(quirk_holder)
+
+ var/lums = holder_turf.get_lumcount()
+
+ if(lums > LIGHTING_TILE_IS_DARK)
+ quirk_holder.clear_mood_event("nyctophobia")
+ return
+
+ if(quirk_holder.move_intent == MOVE_INTENT_RUN)
+ to_chat(quirk_holder, span_warning("Easy, easy, take it slow... you're in the dark..."))
+ quirk_holder.toggle_move_intent()
+ quirk_holder.add_mood_event("nyctophobia", /datum/mood_event/nyctophobia)
diff --git a/code/datums/quirks/negative_quirks/paraplegic.dm b/code/datums/quirks/negative_quirks/paraplegic.dm
new file mode 100644
index 00000000000..58e1c4ba31e
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/paraplegic.dm
@@ -0,0 +1,41 @@
+/datum/quirk/paraplegic
+ name = "Paraplegic"
+ desc = "Your legs do not function. Nothing will ever fix this. But hey, free wheelchair!"
+ icon = FA_ICON_WHEELCHAIR
+ value = -12
+ gain_text = null // Handled by trauma.
+ lose_text = null
+ medical_record_text = "Patient has an untreatable impairment in motor function in the lower extremities."
+ hardcore_value = 15
+ mail_goodies = list(/obj/vehicle/ridden/wheelchair/motorized) //yes a fullsized unfolded motorized wheelchair does fit
+
+/datum/quirk/paraplegic/add_unique(client/client_source)
+ if(quirk_holder.buckled) // Handle late joins being buckled to arrival shuttle chairs.
+ quirk_holder.buckled.unbuckle_mob(quirk_holder)
+
+ var/turf/holder_turf = get_turf(quirk_holder)
+ var/obj/structure/chair/spawn_chair = locate() in holder_turf
+
+ var/obj/vehicle/ridden/wheelchair/wheels
+ if(client_source?.get_award_status(/datum/award/score/hardcore_random) >= 5000) //More than 5k score? you unlock the gamer wheelchair.
+ wheels = new /obj/vehicle/ridden/wheelchair/gold(holder_turf)
+ else
+ wheels = new(holder_turf)
+ if(spawn_chair) // Makes spawning on the arrivals shuttle more consistent looking
+ wheels.setDir(spawn_chair.dir)
+
+ wheels.buckle_mob(quirk_holder)
+
+ // During the spawning process, they may have dropped what they were holding, due to the paralysis
+ // So put the things back in their hands.
+ for(var/obj/item/dropped_item in holder_turf)
+ if(dropped_item.fingerprintslast == quirk_holder.ckey)
+ quirk_holder.put_in_hands(dropped_item)
+
+/datum/quirk/paraplegic/add(client/client_source)
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ human_holder.gain_trauma(/datum/brain_trauma/severe/paralysis/paraplegic, TRAUMA_RESILIENCE_ABSOLUTE)
+
+/datum/quirk/paraplegic/remove()
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ human_holder.cure_trauma_type(/datum/brain_trauma/severe/paralysis/paraplegic, TRAUMA_RESILIENCE_ABSOLUTE)
diff --git a/code/datums/quirks/negative_quirks/photophobia.dm b/code/datums/quirks/negative_quirks/photophobia.dm
new file mode 100644
index 00000000000..b543aeda076
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/photophobia.dm
@@ -0,0 +1,75 @@
+#define MOOD_CATEGORY_PHOTOPHOBIA "photophobia"
+
+/datum/quirk/photophobia
+ name = "Photophobia"
+ desc = "Bright lights seem to bother you more than others. Maybe it's a medical condition."
+ icon = FA_ICON_ARROWS_TO_EYE
+ value = -4
+ gain_text = span_danger("The safety of light feels off...")
+ lose_text = span_notice("Enlightening.")
+ medical_record_text = "Patient has acute phobia of light, and insists it is physically harmful."
+ hardcore_value = 4
+ mail_goodies = list(
+ /obj/item/flashlight/flashdark,
+ /obj/item/food/grown/mushroom/glowshroom/shadowshroom,
+ /obj/item/skillchip/light_remover,
+ )
+
+/datum/quirk/photophobia/add(client/client_source)
+ RegisterSignal(quirk_holder, COMSIG_CARBON_GAIN_ORGAN, PROC_REF(check_eyes))
+ RegisterSignal(quirk_holder, COMSIG_CARBON_LOSE_ORGAN, PROC_REF(restore_eyes))
+ RegisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED, PROC_REF(on_holder_moved))
+ update_eyes(quirk_holder.get_organ_slot(ORGAN_SLOT_EYES))
+
+/datum/quirk/photophobia/remove()
+ UnregisterSignal(quirk_holder, list(
+ COMSIG_CARBON_GAIN_ORGAN,
+ COMSIG_CARBON_LOSE_ORGAN,
+ COMSIG_MOVABLE_MOVED,))
+ quirk_holder.clear_mood_event(MOOD_CATEGORY_PHOTOPHOBIA)
+ var/obj/item/organ/internal/eyes/normal_eyes = quirk_holder.get_organ_slot(ORGAN_SLOT_EYES)
+ if(istype(normal_eyes))
+ normal_eyes.flash_protect = initial(normal_eyes.flash_protect)
+
+/datum/quirk/photophobia/proc/check_eyes(obj/item/organ/internal/eyes/sensitive_eyes)
+ SIGNAL_HANDLER
+ if(!istype(sensitive_eyes))
+ return
+ update_eyes(sensitive_eyes)
+
+/datum/quirk/photophobia/proc/update_eyes(obj/item/organ/internal/eyes/target_eyes)
+ if(!istype(target_eyes))
+ return
+ target_eyes.flash_protect = max(target_eyes.flash_protect - 1, FLASH_PROTECTION_HYPER_SENSITIVE)
+
+/datum/quirk/photophobia/proc/restore_eyes(obj/item/organ/internal/eyes/normal_eyes)
+ SIGNAL_HANDLER
+ if(!istype(normal_eyes))
+ return
+ normal_eyes.flash_protect = initial(normal_eyes.flash_protect)
+
+/datum/quirk/photophobia/proc/on_holder_moved(mob/living/source, atom/old_loc, dir, forced)
+ SIGNAL_HANDLER
+
+ if(quirk_holder.stat != CONSCIOUS || quirk_holder.IsSleeping() || quirk_holder.IsUnconscious())
+ return
+
+ if(HAS_TRAIT(quirk_holder, TRAIT_FEARLESS))
+ return
+
+ var/mob/living/carbon/human/human_holder = quirk_holder
+
+ if(human_holder.sight & SEE_TURFS)
+ return
+
+ var/turf/holder_turf = get_turf(quirk_holder)
+
+ var/lums = holder_turf.get_lumcount()
+
+ var/eye_protection = quirk_holder.get_eye_protection()
+ if(lums < LIGHTING_TILE_IS_DARK || eye_protection >= FLASH_PROTECTION_NONE)
+ quirk_holder.clear_mood_event(MOOD_CATEGORY_PHOTOPHOBIA)
+ return
+ quirk_holder.add_mood_event(MOOD_CATEGORY_PHOTOPHOBIA, /datum/mood_event/photophobia)
+
+ #undef MOOD_CATEGORY_PHOTOPHOBIA
diff --git a/code/datums/quirks/negative_quirks/poor_aim.dm b/code/datums/quirks/negative_quirks/poor_aim.dm
new file mode 100644
index 00000000000..d86feb809b0
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/poor_aim.dm
@@ -0,0 +1,19 @@
+/datum/quirk/poor_aim
+ name = "Stormtrooper Aim"
+ desc = "You've never hit anything you were aiming for in your life."
+ icon = FA_ICON_BULLSEYE
+ value = -4
+ medical_record_text = "Patient possesses a strong tremor in both hands."
+ hardcore_value = 3
+ mail_goodies = list(/obj/item/cardboard_cutout) // for target practice
+
+/datum/quirk/poor_aim/add(client/client_source)
+ RegisterSignal(quirk_holder, COMSIG_MOB_FIRED_GUN, PROC_REF(on_mob_fired_gun))
+
+/datum/quirk/poor_aim/remove(client/client_source)
+ UnregisterSignal(quirk_holder, COMSIG_MOB_FIRED_GUN)
+
+/datum/quirk/poor_aim/proc/on_mob_fired_gun(mob/user, obj/item/gun/gun_fired, target, params, zone_override, list/bonus_spread_values)
+ SIGNAL_HANDLER
+ bonus_spread_values[MIN_BONUS_SPREAD_INDEX] += 10
+ bonus_spread_values[MAX_BONUS_SPREAD_INDEX] += 35
diff --git a/code/datums/quirks/negative_quirks/prosopagnosia.dm b/code/datums/quirks/negative_quirks/prosopagnosia.dm
new file mode 100644
index 00000000000..8634e13bf63
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/prosopagnosia.dm
@@ -0,0 +1,9 @@
+/datum/quirk/prosopagnosia
+ name = "Prosopagnosia"
+ desc = "You have a mental disorder that prevents you from being able to recognize faces at all."
+ icon = FA_ICON_USER_SECRET
+ value = -4
+ mob_trait = TRAIT_PROSOPAGNOSIA
+ medical_record_text = "Patient suffers from prosopagnosia and cannot recognize faces."
+ hardcore_value = 5
+ mail_goodies = list(/obj/item/skillchip/appraiser) // bad at recognizing faces but good at recognizing IDs
diff --git a/code/datums/quirks/negative_quirks/prosthetic_limb.dm b/code/datums/quirks/negative_quirks/prosthetic_limb.dm
new file mode 100644
index 00000000000..f6f0e304a6d
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/prosthetic_limb.dm
@@ -0,0 +1,42 @@
+/datum/quirk/prosthetic_limb
+ name = "Prosthetic Limb"
+ 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
+ mail_goodies = list(/obj/item/weldingtool/mini, /obj/item/stack/cable_coil/five)
+ /// The slot to replace, in string form
+ var/slot_string = "limb"
+ /// the original limb from before the prosthetic was applied
+ 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/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)
+
+/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."))
+
+/datum/quirk/prosthetic_limb/remove()
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ human_holder.del_and_replace_bodypart(old_limb, special = TRUE)
+ old_limb = null
diff --git a/code/datums/quirks/negative_quirks/prosthetic_organ.dm b/code/datums/quirks/negative_quirks/prosthetic_organ.dm
new file mode 100644
index 00000000000..6330035b5a7
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/prosthetic_organ.dm
@@ -0,0 +1,63 @@
+/datum/quirk/prosthetic_organ
+ name = "Prosthetic Organ"
+ desc = "An accident caused you to lose one of your organs. Because of this, you now have a surplus prosthetic!"
+ icon = FA_ICON_LUNGS
+ value = -3
+ medical_record_text = "During physical examination, patient was found to have a low-budget prosthetic organ. \
+ Removal of these organs is known to be dangerous to the patient as well as the practitioner."
+ hardcore_value = 3
+ mail_goodies = list(/obj/item/storage/organbox)
+ /// The slot to replace, in string form
+ var/slot_string = "organ"
+ /// The original organ from before the prosthetic was applied
+ var/obj/item/organ/old_organ
+
+/datum/quirk/prosthetic_organ/add_unique(client/client_source)
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ var/static/list/organ_slots = list(
+ ORGAN_SLOT_HEART,
+ ORGAN_SLOT_LUNGS,
+ ORGAN_SLOT_LIVER,
+ ORGAN_SLOT_STOMACH,
+ )
+ var/list/possible_organ_slots = organ_slots.Copy()
+ if(HAS_TRAIT(human_holder, TRAIT_NOBLOOD))
+ possible_organ_slots -= ORGAN_SLOT_HEART
+ if(HAS_TRAIT(human_holder, TRAIT_NOBREATH))
+ possible_organ_slots -= ORGAN_SLOT_LUNGS
+ if(HAS_TRAIT(human_holder, TRAIT_LIVERLESS_METABOLISM))
+ possible_organ_slots -= ORGAN_SLOT_LIVER
+ if(HAS_TRAIT(human_holder, TRAIT_NOHUNGER))
+ possible_organ_slots -= ORGAN_SLOT_STOMACH
+ if(!length(organ_slots)) //what the hell
+ return
+ var/organ_slot = pick(possible_organ_slots)
+ var/obj/item/organ/prosthetic
+ switch(organ_slot)
+ if(ORGAN_SLOT_HEART)
+ prosthetic = new /obj/item/organ/internal/heart/cybernetic/surplus
+ slot_string = "heart"
+ if(ORGAN_SLOT_LUNGS)
+ prosthetic = new /obj/item/organ/internal/lungs/cybernetic/surplus
+ slot_string = "lungs"
+ if(ORGAN_SLOT_LIVER)
+ prosthetic = new /obj/item/organ/internal/liver/cybernetic/surplus
+ slot_string = "liver"
+ if(ORGAN_SLOT_STOMACH)
+ prosthetic = new /obj/item/organ/internal/stomach/cybernetic/surplus
+ slot_string = "stomach"
+ medical_record_text = "During physical examination, patient was found to have a low-budget prosthetic [slot_string]. \
+ Removal of these organs is known to be dangerous to the patient as well as the practitioner."
+ old_organ = human_holder.get_organ_slot(organ_slot)
+ if(prosthetic.Insert(human_holder, special = TRUE, drop_if_replaced = TRUE))
+ old_organ.moveToNullspace()
+ STOP_PROCESSING(SSobj, old_organ)
+
+/datum/quirk/prosthetic_organ/post_add()
+ to_chat(quirk_holder, span_boldannounce("Your [slot_string] has been replaced with a surplus organ. It is fragile and will easily come apart under duress. \
+ Additionally, any EMP will make it stop working entirely."))
+
+/datum/quirk/prosthetic_organ/remove()
+ if(old_organ)
+ old_organ.Insert(quirk_holder, special = TRUE)
+ old_organ = null
diff --git a/code/datums/quirks/negative_quirks/pushover.dm b/code/datums/quirks/negative_quirks/pushover.dm
new file mode 100644
index 00000000000..663d8173759
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/pushover.dm
@@ -0,0 +1,11 @@
+/datum/quirk/pushover
+ name = "Pushover"
+ desc = "Your first instinct is always to let people push you around. Resisting out of grabs will take conscious effort."
+ icon = FA_ICON_HANDSHAKE
+ value = -8
+ mob_trait = TRAIT_GRABWEAKNESS
+ gain_text = span_danger("You feel like a pushover.")
+ lose_text = span_notice("You feel like standing up for yourself.")
+ medical_record_text = "Patient presents a notably unassertive personality and is easy to manipulate."
+ hardcore_value = 4
+ mail_goodies = list(/obj/item/clothing/gloves/cargo_gauntlet)
diff --git a/code/datums/quirks/negative_quirks/quadruple_amputee.dm b/code/datums/quirks/negative_quirks/quadruple_amputee.dm
new file mode 100644
index 00000000000..493cdf0b71c
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/quadruple_amputee.dm
@@ -0,0 +1,20 @@
+/datum/quirk/quadruple_amputee
+ name = "Quadruple Amputee"
+ desc = "Oops! All Prosthetics! Due to some truly cruel cosmic punishment, all your limbs have been replaced with surplus prosthetics."
+ icon = "tg-prosthetic-full"
+ value = -6
+ medical_record_text = "During physical examination, patient was found to have all low-budget prosthetic limbs."
+ hardcore_value = 6
+ quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE
+ mail_goodies = list(/obj/item/weldingtool/mini, /obj/item/stack/cable_coil/five)
+
+/datum/quirk/quadruple_amputee/add_unique(client/client_source)
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ human_holder.del_and_replace_bodypart(new /obj/item/bodypart/arm/left/robot/surplus, special = TRUE)
+ human_holder.del_and_replace_bodypart(new /obj/item/bodypart/arm/right/robot/surplus, special = TRUE)
+ human_holder.del_and_replace_bodypart(new /obj/item/bodypart/leg/left/robot/surplus, special = TRUE)
+ human_holder.del_and_replace_bodypart(new /obj/item/bodypart/leg/right/robot/surplus, special = TRUE)
+
+/datum/quirk/quadruple_amputee/post_add()
+ to_chat(quirk_holder, span_boldannounce("All your limbs have been replaced with surplus prosthetics. They are fragile and will easily come apart under duress. \
+ Additionally, you need to use a welding tool and cables to repair them, instead of bruise packs and ointment."))
diff --git a/code/datums/quirks/negative_quirks/social_anxiety.dm b/code/datums/quirks/negative_quirks/social_anxiety.dm
new file mode 100644
index 00000000000..3d140bd80a0
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/social_anxiety.dm
@@ -0,0 +1,114 @@
+/datum/quirk/social_anxiety
+ name = "Social Anxiety"
+ desc = "Talking to people is very difficult for you, and you often stutter or even lock up."
+ icon = FA_ICON_COMMENT_SLASH
+ value = -3
+ gain_text = span_danger("You start worrying about what you're saying.")
+ lose_text = span_notice("You feel easier about talking again.") //if only it were that easy!
+ medical_record_text = "Patient is usually anxious in social encounters and prefers to avoid them."
+ hardcore_value = 4
+ mob_trait = TRAIT_ANXIOUS
+ mail_goodies = list(/obj/item/storage/pill_bottle/psicodine)
+ var/dumb_thing = TRUE
+
+/datum/quirk/social_anxiety/add(client/client_source)
+ RegisterSignal(quirk_holder, COMSIG_MOB_EYECONTACT, PROC_REF(eye_contact))
+ RegisterSignal(quirk_holder, COMSIG_MOB_EXAMINATE, PROC_REF(looks_at_floor))
+ RegisterSignal(quirk_holder, COMSIG_MOB_SAY, PROC_REF(handle_speech))
+
+/datum/quirk/social_anxiety/remove()
+ UnregisterSignal(quirk_holder, list(COMSIG_MOB_EYECONTACT, COMSIG_MOB_EXAMINATE, COMSIG_MOB_SAY))
+
+/datum/quirk/social_anxiety/proc/handle_speech(datum/source, list/speech_args)
+ SIGNAL_HANDLER
+
+ if(HAS_TRAIT(quirk_holder, TRAIT_FEARLESS))
+ return
+
+ var/moodmod
+ if(quirk_holder.mob_mood)
+ moodmod = (1+0.02*(50-(max(50, quirk_holder.mob_mood.mood_level*(7-quirk_holder.mob_mood.sanity_level))))) //low sanity levels are better, they max at 6
+ else
+ moodmod = (1+0.02*(50-(max(50, 0.1*quirk_holder.nutrition))))
+ var/nearby_people = 0
+ for(var/mob/living/carbon/human/H in oview(3, quirk_holder))
+ if(H.client)
+ nearby_people++
+ var/message = speech_args[SPEECH_MESSAGE]
+ if(message)
+ var/list/message_split = splittext(message, " ")
+ var/list/new_message = list()
+ var/mob/living/carbon/human/quirker = quirk_holder
+ for(var/word in message_split)
+ if(prob(max(5,(nearby_people*12.5*moodmod))) && word != message_split[1]) //Minimum 1/20 chance of filler
+ new_message += pick("uh,","erm,","um,")
+ if(prob(min(5,(0.05*(nearby_people*12.5)*moodmod)))) //Max 1 in 20 chance of cutoff after a successful filler roll, for 50% odds in a 15 word sentence
+ quirker.set_silence_if_lower(6 SECONDS)
+ to_chat(quirker, span_danger("You feel self-conscious and stop talking. You need a moment to recover!"))
+ break
+ if(prob(max(5,(nearby_people*12.5*moodmod)))) //Minimum 1/20 chance of stutter
+ // Add a short stutter, THEN treat our word
+ quirker.adjust_stutter(0.5 SECONDS)
+ var/list/message_data = quirker.treat_message(word, capitalize_message = FALSE)
+ new_message += message_data["message"]
+ else
+ new_message += word
+
+ message = jointext(new_message, " ")
+ var/mob/living/carbon/human/quirker = quirk_holder
+ if(prob(min(50,(0.50*(nearby_people*12.5)*moodmod)))) //Max 50% chance of not talking
+ if(dumb_thing)
+ to_chat(quirker, span_userdanger("You think of a dumb thing you said a long time ago and scream internally."))
+ dumb_thing = FALSE //only once per life
+ if(prob(1))
+ new/obj/item/food/spaghetti/pastatomato(get_turf(quirker)) //now that's what I call spaghetti code
+ else
+ to_chat(quirk_holder, span_warning("You think that wouldn't add much to the conversation and decide not to say it."))
+ if(prob(min(25,(0.25*(nearby_people*12.75)*moodmod)))) //Max 25% chance of silence stacks after successful not talking roll
+ to_chat(quirker, span_danger("You retreat into yourself. You really don't feel up to talking."))
+ quirker.set_silence_if_lower(10 SECONDS)
+
+ speech_args[SPEECH_MESSAGE] = pick("Uh.","Erm.","Um.")
+ else
+ speech_args[SPEECH_MESSAGE] = message
+
+// small chance to make eye contact with inanimate objects/mindless mobs because of nerves
+/datum/quirk/social_anxiety/proc/looks_at_floor(datum/source, atom/A)
+ SIGNAL_HANDLER
+
+ var/mob/living/mind_check = A
+ if(prob(85) || (istype(mind_check) && mind_check.mind))
+ return
+
+ addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(to_chat), quirk_holder, span_smallnotice("You make eye contact with [A].")), 3)
+
+/datum/quirk/social_anxiety/proc/eye_contact(datum/source, mob/living/other_mob, triggering_examiner)
+ SIGNAL_HANDLER
+
+ if(prob(75))
+ return
+ var/msg
+ if(triggering_examiner)
+ msg = "You make eye contact with [other_mob], "
+ else
+ msg = "[other_mob] makes eye contact with you, "
+
+ switch(rand(1,3))
+ if(1)
+ quirk_holder.set_jitter_if_lower(20 SECONDS)
+ msg += "causing you to start fidgeting!"
+ if(2)
+ quirk_holder.set_stutter_if_lower(6 SECONDS)
+ msg += "causing you to start stuttering!"
+ if(3)
+ quirk_holder.Stun(2 SECONDS)
+ msg += "causing you to freeze up!"
+
+ quirk_holder.add_mood_event("anxiety_eyecontact", /datum/mood_event/anxiety_eyecontact)
+ addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(to_chat), quirk_holder, span_userdanger("[msg]")), 3) // so the examine signal has time to fire and this will print after
+ return COMSIG_BLOCK_EYECONTACT
+
+/datum/mood_event/anxiety_eyecontact
+ description = "Sometimes eye contact makes me so nervous..."
+ mood_change = -5
+ timeout = 3 MINUTES
diff --git a/code/datums/quirks/negative_quirks/softspoken.dm b/code/datums/quirks/negative_quirks/softspoken.dm
new file mode 100644
index 00000000000..41be5f1aca0
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/softspoken.dm
@@ -0,0 +1,9 @@
+/datum/quirk/softspoken
+ name = "Soft-Spoken"
+ desc = "You are soft-spoken, and your voice is hard to hear."
+ icon = FA_ICON_COMMENT
+ value = -2
+ mob_trait = TRAIT_SOFTSPOKEN
+ gain_text = span_danger("You feel like you're speaking more quietly.")
+ lose_text = span_notice("You feel like you're speaking louder.")
+ medical_record_text = "Patient is soft-spoken and difficult to hear."
diff --git a/code/datums/quirks/negative_quirks/tin_man.dm b/code/datums/quirks/negative_quirks/tin_man.dm
new file mode 100644
index 00000000000..5a4ab4b1357
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/tin_man.dm
@@ -0,0 +1,37 @@
+/datum/quirk/tin_man
+ name = "Tin Man"
+ desc = "Oops! All Prosthetics! Due to some truly cruel cosmic punishment, most of your internal organs have been replaced with surplus prosthetics."
+ icon = FA_ICON_ROBOT
+ value = -6
+ medical_record_text = "During physical examination, patient was found to have numerous low-budget prosthetic internal organs. \
+ Removal of these organs is known to be dangerous to the patient as well as the practitioner."
+ hardcore_value = 6
+ mail_goodies = list(/obj/item/storage/organbox)
+
+/datum/quirk/tin_man/add_unique(client/client_source)
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ var/static/list/organ_slots = list(
+ ORGAN_SLOT_HEART = /obj/item/organ/internal/heart/cybernetic/surplus,
+ ORGAN_SLOT_LUNGS = /obj/item/organ/internal/lungs/cybernetic/surplus,
+ ORGAN_SLOT_LIVER = /obj/item/organ/internal/liver/cybernetic/surplus,
+ ORGAN_SLOT_STOMACH = /obj/item/organ/internal/stomach/cybernetic/surplus,
+ )
+ var/list/possible_organ_slots = organ_slots.Copy()
+ if(HAS_TRAIT(human_holder, TRAIT_NOBLOOD))
+ possible_organ_slots -= ORGAN_SLOT_HEART
+ if(HAS_TRAIT(human_holder, TRAIT_NOBREATH))
+ possible_organ_slots -= ORGAN_SLOT_LUNGS
+ if(HAS_TRAIT(human_holder, TRAIT_LIVERLESS_METABOLISM))
+ possible_organ_slots -= ORGAN_SLOT_LIVER
+ if(HAS_TRAIT(human_holder, TRAIT_NOHUNGER))
+ possible_organ_slots -= ORGAN_SLOT_STOMACH
+ if(!length(organ_slots)) //what the hell
+ return
+ for(var/organ_slot in possible_organ_slots)
+ var/organ_path = possible_organ_slots[organ_slot]
+ var/obj/item/organ/new_organ = new organ_path()
+ new_organ.Insert(human_holder, special = TRUE, drop_if_replaced = FALSE)
+
+/datum/quirk/tin_man/post_add()
+ to_chat(quirk_holder, span_boldannounce("Most of your internal organs have been replaced with surplus prosthetics. They are fragile and will easily come apart under duress. \
+ Additionally, any EMP will make them stop working entirely."))
diff --git a/code/datums/quirks/negative_quirks/unstable.dm b/code/datums/quirks/negative_quirks/unstable.dm
new file mode 100644
index 00000000000..5d39776eeba
--- /dev/null
+++ b/code/datums/quirks/negative_quirks/unstable.dm
@@ -0,0 +1,11 @@
+/datum/quirk/unstable
+ name = "Unstable"
+ desc = "Due to past troubles, you are unable to recover your sanity if you lose it. Be very careful managing your mood!"
+ icon = FA_ICON_ANGRY
+ value = -10
+ mob_trait = TRAIT_UNSTABLE
+ gain_text = span_danger("There's a lot on your mind right now.")
+ lose_text = span_notice("Your mind finally feels calm.")
+ medical_record_text = "Patient's mind is in a vulnerable state, and cannot recover from traumatic events."
+ hardcore_value = 9
+ mail_goodies = list(/obj/effect/spawner/random/entertainment/plushie)
diff --git a/code/datums/quirks/neutral_quirks/bald.dm b/code/datums/quirks/neutral_quirks/bald.dm
new file mode 100644
index 00000000000..8a760f6ceef
--- /dev/null
+++ b/code/datums/quirks/neutral_quirks/bald.dm
@@ -0,0 +1,53 @@
+/datum/quirk/item_quirk/bald
+ name = "Smooth-Headed"
+ desc = "You have no hair and are quite insecure about it! Keep your wig on, or at least your head covered up."
+ icon = FA_ICON_EGG
+ value = 0
+ mob_trait = TRAIT_BALD
+ gain_text = span_notice("Your head is as smooth as can be, it's terrible.")
+ lose_text = span_notice("Your head itches, could it be... growing hair?!")
+ medical_record_text = "Patient starkly refused to take off headwear during examination."
+ mail_goodies = list(/obj/item/clothing/head/wig/random)
+ /// The user's starting hairstyle
+ var/old_hair
+
+/datum/quirk/item_quirk/bald/add(client/client_source)
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ old_hair = human_holder.hairstyle
+ human_holder.set_hairstyle("Bald", update = TRUE)
+ RegisterSignal(human_holder, COMSIG_CARBON_EQUIP_HAT, PROC_REF(equip_hat))
+ RegisterSignal(human_holder, COMSIG_CARBON_UNEQUIP_HAT, PROC_REF(unequip_hat))
+
+/datum/quirk/item_quirk/bald/add_unique(client/client_source)
+ var/obj/item/clothing/head/wig/natural/baldie_wig = new(get_turf(quirk_holder))
+ if(old_hair == "Bald")
+ baldie_wig.hairstyle = pick(GLOB.hairstyles_list - "Bald")
+ else
+ baldie_wig.hairstyle = old_hair
+
+ baldie_wig.update_appearance()
+
+ give_item_to_holder(baldie_wig, list(LOCATION_HEAD = ITEM_SLOT_HEAD, LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
+
+/datum/quirk/item_quirk/bald/remove()
+ . = ..()
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ human_holder.hairstyle = old_hair
+ human_holder.update_body_parts()
+ UnregisterSignal(human_holder, list(COMSIG_CARBON_EQUIP_HAT, COMSIG_CARBON_UNEQUIP_HAT))
+ human_holder.clear_mood_event("bad_hair_day")
+
+///Checks if the headgear equipped is a wig and sets the mood event accordingly
+/datum/quirk/item_quirk/bald/proc/equip_hat(mob/user, obj/item/hat)
+ SIGNAL_HANDLER
+
+ if(istype(hat, /obj/item/clothing/head/wig))
+ quirk_holder.add_mood_event("bad_hair_day", /datum/mood_event/confident_mane) //Our head is covered, but also by a wig so we're happy.
+ else
+ quirk_holder.clear_mood_event("bad_hair_day") //Our head is covered
+
+///Applies a bad moodlet for having an uncovered head
+/datum/quirk/item_quirk/bald/proc/unequip_hat(mob/user, obj/item/clothing, force, newloc, no_move, invdrop, silent)
+ SIGNAL_HANDLER
+
+ quirk_holder.add_mood_event("bad_hair_day", /datum/mood_event/bald)
diff --git a/code/datums/quirks/neutral_quirks/colorist.dm b/code/datums/quirks/neutral_quirks/colorist.dm
new file mode 100644
index 00000000000..f82fd5bf6fe
--- /dev/null
+++ b/code/datums/quirks/neutral_quirks/colorist.dm
@@ -0,0 +1,13 @@
+/* SKYRAT EDIT REMOVAL
+/datum/quirk/item_quirk/colorist
+ name = "Colorist"
+ desc = "You like carrying around a hair dye spray to quickly apply color patterns to your hair."
+ icon = FA_ICON_FILL_DRIP
+ value = 0
+ medical_record_text = "Patient enjoys dyeing their hair with pretty colors."
+ mail_goodies = list(/obj/item/dyespray)
+
+/datum/quirk/item_quirk/colorist/add_unique(client/client_source)
+ give_item_to_holder(/obj/item/dyespray, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
+*/
+//SKYRAT EDIT REMOVAL
diff --git a/code/datums/quirks/neutral_quirks/deviant_tastes.dm b/code/datums/quirks/neutral_quirks/deviant_tastes.dm
new file mode 100644
index 00000000000..566b469c7a7
--- /dev/null
+++ b/code/datums/quirks/neutral_quirks/deviant_tastes.dm
@@ -0,0 +1,24 @@
+/datum/quirk/deviant_tastes
+ name = "Deviant Tastes"
+ desc = "You dislike food that most people enjoy, and find delicious what they don't."
+ icon = FA_ICON_GRIN_TONGUE_SQUINT
+ value = 0
+ gain_text = span_notice("You start craving something that tastes strange.")
+ lose_text = span_notice("You feel like eating normal food again.")
+ medical_record_text = "Patient demonstrates irregular nutrition preferences."
+ mail_goodies = list(/obj/item/food/urinalcake, /obj/item/food/badrecipe) // Mhhhmmm yummy
+
+/datum/quirk/deviant_tastes/add(client/client_source)
+ var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE)
+ if(!tongue)
+ return
+ var/liked_foodtypes = tongue.liked_foodtypes
+ tongue.liked_foodtypes = tongue.disliked_foodtypes
+ tongue.disliked_foodtypes = liked_foodtypes
+
+/datum/quirk/deviant_tastes/remove()
+ var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE)
+ if(!tongue)
+ return
+ tongue.liked_foodtypes = initial(tongue.liked_foodtypes)
+ tongue.disliked_foodtypes = initial(tongue.disliked_foodtypes)
diff --git a/code/datums/quirks/neutral_quirks/extrovert.dm b/code/datums/quirks/neutral_quirks/extrovert.dm
new file mode 100644
index 00000000000..5622956ba5b
--- /dev/null
+++ b/code/datums/quirks/neutral_quirks/extrovert.dm
@@ -0,0 +1,10 @@
+/datum/quirk/extrovert
+ name = "Extrovert"
+ desc = "You are energized by talking to others, and enjoy spending your free time in the bar."
+ icon = FA_ICON_USERS
+ value = 0
+ mob_trait = TRAIT_EXTROVERT
+ gain_text = span_notice("You feel like hanging out with other people.")
+ lose_text = span_danger("You feel like you're over the bar scene.")
+ medical_record_text = "Patient will not shut the hell up."
+ mail_goodies = list(/obj/item/reagent_containers/cup/glass/flask)
diff --git a/code/datums/quirks/neutral_quirks/foreigner.dm b/code/datums/quirks/neutral_quirks/foreigner.dm
new file mode 100644
index 00000000000..da317a7e66a
--- /dev/null
+++ b/code/datums/quirks/neutral_quirks/foreigner.dm
@@ -0,0 +1,21 @@
+/datum/quirk/foreigner
+ name = "Foreigner"
+ desc = "You're not from around here. You don't know Galactic Common!"
+ icon = FA_ICON_LANGUAGE
+ value = 0
+ gain_text = span_notice("The words being spoken around you don't make any sense.")
+ lose_text = span_notice("You've developed fluency in Galactic Common.")
+ medical_record_text = "Patient does not speak Galactic Common and may require an interpreter."
+ mail_goodies = list(/obj/item/taperecorder) // for translation
+
+/datum/quirk/foreigner/add(client/client_source)
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ human_holder.add_blocked_language(/datum/language/common)
+ if(ishumanbasic(human_holder))
+ human_holder.grant_language(/datum/language/uncommon, source = LANGUAGE_QUIRK)
+
+/datum/quirk/foreigner/remove()
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ human_holder.remove_blocked_language(/datum/language/common)
+ if(ishumanbasic(human_holder))
+ human_holder.remove_language(/datum/language/uncommon)
diff --git a/code/datums/quirks/neutral_quirks/gamer.dm b/code/datums/quirks/neutral_quirks/gamer.dm
new file mode 100644
index 00000000000..0ab2e780480
--- /dev/null
+++ b/code/datums/quirks/neutral_quirks/gamer.dm
@@ -0,0 +1,90 @@
+#define GAMING_WITHDRAWAL_TIME (15 MINUTES)
+/datum/quirk/gamer
+ name = "Gamer"
+ desc = "You are a hardcore gamer, and you have a need to game. You love winning and hate losing. You only like gamer food."
+ icon = FA_ICON_GAMEPAD
+ value = 0
+ gain_text = span_notice("You feel the sudden urge to game.")
+ lose_text = span_notice("You've lost all interest in gaming.")
+ medical_record_text = "Patient has a severe video game addiction."
+ mob_trait = TRAIT_GAMER
+ mail_goodies = list(/obj/item/toy/intento, /obj/item/clothing/head/fedora)
+ /// Timer for gaming withdrawal to kick in
+ var/gaming_withdrawal_timer = TIMER_ID_NULL
+
+/datum/quirk/gamer/add(client/client_source)
+ var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE)
+ if(tongue)
+ // Gamer diet
+ tongue.liked_foodtypes = JUNKFOOD
+ RegisterSignal(quirk_holder, COMSIG_MOB_WON_VIDEOGAME, PROC_REF(won_game))
+ RegisterSignal(quirk_holder, COMSIG_MOB_LOST_VIDEOGAME, PROC_REF(lost_game))
+ RegisterSignal(quirk_holder, COMSIG_MOB_PLAYED_VIDEOGAME, PROC_REF(gamed))
+
+/datum/quirk/gamer/add_unique(client/client_source)
+ // The gamer starts off quelled
+ gaming_withdrawal_timer = addtimer(CALLBACK(src, PROC_REF(enter_withdrawal)), GAMING_WITHDRAWAL_TIME, TIMER_STOPPABLE)
+
+/datum/quirk/gamer/remove()
+ var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE)
+ if(tongue)
+ tongue.liked_foodtypes = initial(tongue.liked_foodtypes)
+ UnregisterSignal(quirk_holder, COMSIG_MOB_WON_VIDEOGAME)
+ UnregisterSignal(quirk_holder, COMSIG_MOB_LOST_VIDEOGAME)
+ UnregisterSignal(quirk_holder, COMSIG_MOB_PLAYED_VIDEOGAME)
+
+/**
+ * Gamer won a game
+ *
+ * Executed on the COMSIG_MOB_WON_VIDEOGAME signal
+ * This signal should be called whenever a player has won a video game.
+ * (E.g. Orion Trail)
+ */
+/datum/quirk/gamer/proc/won_game()
+ SIGNAL_HANDLER
+ // Epic gamer victory
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ human_holder.add_mood_event("gamer_won", /datum/mood_event/gamer_won)
+
+/**
+ * Gamer lost a game
+ *
+ * Executed on the COMSIG_MOB_LOST_VIDEOGAME signal
+ * This signal should be called whenever a player has lost a video game.
+ * (E.g. Orion Trail)
+ */
+/datum/quirk/gamer/proc/lost_game()
+ SIGNAL_HANDLER
+ // Executed when a gamer has lost
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ human_holder.add_mood_event("gamer_lost", /datum/mood_event/gamer_lost)
+ // Executed asynchronously due to say()
+ INVOKE_ASYNC(src, PROC_REF(gamer_moment))
+/**
+ * Gamer is playing a game
+ *
+ * Executed on the COMSIG_MOB_PLAYED_VIDEOGAME signal
+ * This signal should be called whenever a player interacts with a video game.
+ */
+/datum/quirk/gamer/proc/gamed()
+ SIGNAL_HANDLER
+
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ // Remove withdrawal malus
+ human_holder.clear_mood_event("gamer_withdrawal")
+ // Reset withdrawal timer
+ if (gaming_withdrawal_timer)
+ deltimer(gaming_withdrawal_timer)
+ gaming_withdrawal_timer = addtimer(CALLBACK(src, PROC_REF(enter_withdrawal)), GAMING_WITHDRAWAL_TIME, TIMER_STOPPABLE)
+
+
+/datum/quirk/gamer/proc/gamer_moment()
+ // It was a heated gamer moment...
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ human_holder.say(";[pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER")]!!", forced = name)
+
+/datum/quirk/gamer/proc/enter_withdrawal()
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ human_holder.add_mood_event("gamer_withdrawal", /datum/mood_event/gamer_withdrawal)
+
+#undef GAMING_WITHDRAWAL_TIME
diff --git a/code/datums/quirks/neutral_quirks/heretochromatic.dm b/code/datums/quirks/neutral_quirks/heretochromatic.dm
new file mode 100644
index 00000000000..1df079c0e45
--- /dev/null
+++ b/code/datums/quirks/neutral_quirks/heretochromatic.dm
@@ -0,0 +1,54 @@
+/datum/quirk/heterochromatic
+ name = "Heterochromatic"
+ desc = "One of your eyes is a different color than the other!"
+ icon = FA_ICON_EYE_LOW_VISION // Ignore the icon name, its actually a fairly good representation of different color eyes
+ quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE
+ value = 0
+ mail_goodies = list(/obj/item/clothing/glasses/eyepatch)
+
+// Only your first eyes are heterochromatic
+// If someone comes and says "well mr coder you can have DNA bound heterochromia so it's not unrealistic
+// to allow all inserted replacement eyes to become heterochromatic or for it to transfer between mobs"
+// Then just change this to [proc/add] I really don't care
+/datum/quirk/heterochromatic/add_unique(client/client_source)
+ var/color = client_source?.prefs.read_preference(/datum/preference/color/heterochromatic)
+ if(!color)
+ return
+
+ apply_heterochromatic_eyes(color)
+
+/// Applies the passed color to this mob's eyes
+/datum/quirk/heterochromatic/proc/apply_heterochromatic_eyes(color)
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ var/was_not_hetero = !human_holder.eye_color_heterochromatic
+ human_holder.eye_color_heterochromatic = TRUE
+ human_holder.eye_color_right = color
+
+ var/obj/item/organ/internal/eyes/eyes_of_the_holder = quirk_holder.get_organ_by_type(/obj/item/organ/internal/eyes)
+ if(!eyes_of_the_holder)
+ return
+
+ eyes_of_the_holder.eye_color_right = color
+ eyes_of_the_holder.old_eye_color_right = color
+ eyes_of_the_holder.refresh()
+
+ if(was_not_hetero)
+ RegisterSignal(human_holder, COMSIG_CARBON_LOSE_ORGAN, PROC_REF(check_eye_removal))
+
+/datum/quirk/heterochromatic/remove()
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ human_holder.eye_color_heterochromatic = FALSE
+ human_holder.eye_color_right = human_holder.eye_color_left
+ UnregisterSignal(human_holder, COMSIG_CARBON_LOSE_ORGAN)
+
+/datum/quirk/heterochromatic/proc/check_eye_removal(datum/source, obj/item/organ/internal/eyes/removed)
+ SIGNAL_HANDLER
+
+ if(!istype(removed))
+ return
+
+ // Eyes were removed, remove heterochromia from the human holder and bid them adieu
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ human_holder.eye_color_heterochromatic = FALSE
+ human_holder.eye_color_right = human_holder.eye_color_left
+ UnregisterSignal(human_holder, COMSIG_CARBON_LOSE_ORGAN)
diff --git a/code/datums/quirks/neutral_quirks/introvert.dm b/code/datums/quirks/neutral_quirks/introvert.dm
new file mode 100644
index 00000000000..51f6f3e785e
--- /dev/null
+++ b/code/datums/quirks/neutral_quirks/introvert.dm
@@ -0,0 +1,10 @@
+/datum/quirk/introvert
+ name = "Introvert"
+ desc = "You are energized by having time to yourself, and enjoy spending your free time in the library."
+ icon = FA_ICON_BOOK_READER
+ value = 0
+ mob_trait = TRAIT_INTROVERT
+ gain_text = span_notice("You feel like reading a good book quietly.")
+ lose_text = span_danger("You feel like libraries are boring.")
+ medical_record_text = "Patient doesn't seem to say much."
+ mail_goodies = list(/obj/item/book/random)
diff --git a/code/datums/quirks/neutral_quirks/monochromatic.dm b/code/datums/quirks/neutral_quirks/monochromatic.dm
new file mode 100644
index 00000000000..dd66220cb56
--- /dev/null
+++ b/code/datums/quirks/neutral_quirks/monochromatic.dm
@@ -0,0 +1,23 @@
+/datum/quirk/monochromatic
+ name = "Monochromacy"
+ desc = "You suffer from full colorblindness, and perceive nearly the entire world in blacks and whites."
+ icon = FA_ICON_ADJUST
+ value = 0
+ medical_record_text = "Patient is afflicted with almost complete color blindness."
+ mail_goodies = list( // Noir detective wannabe
+ /obj/item/clothing/suit/jacket/det_suit/noir,
+ /obj/item/clothing/suit/jacket/det_suit/dark,
+ /obj/item/clothing/head/fedora/beige,
+ /obj/item/clothing/head/fedora/white,
+ )
+
+/datum/quirk/monochromatic/add(client/client_source)
+ quirk_holder.add_client_colour(/datum/client_colour/monochrome)
+
+/datum/quirk/monochromatic/post_add()
+ if(is_detective_job(quirk_holder.mind.assigned_role))
+ to_chat(quirk_holder, span_boldannounce("Mmm. Nothing's ever clear on this station. It's all shades of gray..."))
+ quirk_holder.playsound_local(quirk_holder, 'sound/ambience/ambidet1.ogg', 50, FALSE)
+
+/datum/quirk/monochromatic/remove()
+ quirk_holder.remove_client_colour(/datum/client_colour/monochrome)
diff --git a/code/datums/quirks/neutral_quirks/neutral_quirks.dm b/code/datums/quirks/neutral_quirks/neutral_quirks.dm
deleted file mode 100644
index b835f44985c..00000000000
--- a/code/datums/quirks/neutral_quirks/neutral_quirks.dm
+++ /dev/null
@@ -1,483 +0,0 @@
-//traits with no real impact that can be taken freely
-//MAKE SURE THESE DO NOT MAJORLY IMPACT GAMEPLAY. those should be positive or negative traits.
-
-/datum/quirk/extrovert
- name = "Extrovert"
- desc = "You are energized by talking to others, and enjoy spending your free time in the bar."
- icon = FA_ICON_USERS
- value = 0
- mob_trait = TRAIT_EXTROVERT
- gain_text = span_notice("You feel like hanging out with other people.")
- lose_text = span_danger("You feel like you're over the bar scene.")
- medical_record_text = "Patient will not shut the hell up."
- mail_goodies = list(/obj/item/reagent_containers/cup/glass/flask)
-
-/datum/quirk/introvert
- name = "Introvert"
- desc = "You are energized by having time to yourself, and enjoy spending your free time in the library."
- icon = FA_ICON_BOOK_READER
- value = 0
- mob_trait = TRAIT_INTROVERT
- gain_text = span_notice("You feel like reading a good book quietly.")
- lose_text = span_danger("You feel like libraries are boring.")
- medical_record_text = "Patient doesn't seem to say much."
- mail_goodies = list(/obj/item/book/random)
-
-/datum/quirk/no_taste
- name = "Ageusia"
- desc = "You can't taste anything! Toxic food will still poison you."
- icon = FA_ICON_MEH_BLANK
- value = 0
- mob_trait = TRAIT_AGEUSIA
- gain_text = span_notice("You can't taste anything!")
- lose_text = span_notice("You can taste again!")
- medical_record_text = "Patient suffers from ageusia and is incapable of tasting food or reagents."
- mail_goodies = list(/obj/effect/spawner/random/food_or_drink/condiment) // but can you taste the salt? CAN YOU?!
-
-/datum/quirk/foreigner
- name = "Foreigner"
- desc = "You're not from around here. You don't know Galactic Common!"
- icon = FA_ICON_LANGUAGE
- value = 0
- gain_text = span_notice("The words being spoken around you don't make any sense.")
- lose_text = span_notice("You've developed fluency in Galactic Common.")
- medical_record_text = "Patient does not speak Galactic Common and may require an interpreter."
- mail_goodies = list(/obj/item/taperecorder) // for translation
-
-/datum/quirk/foreigner/add(client/client_source)
- var/mob/living/carbon/human/human_holder = quirk_holder
- human_holder.add_blocked_language(/datum/language/common)
- if(ishumanbasic(human_holder))
- human_holder.grant_language(/datum/language/uncommon, source = LANGUAGE_QUIRK)
-
-/datum/quirk/foreigner/remove()
- var/mob/living/carbon/human/human_holder = quirk_holder
- human_holder.remove_blocked_language(/datum/language/common)
- if(ishumanbasic(human_holder))
- human_holder.remove_language(/datum/language/uncommon)
-
-/datum/quirk/vegetarian
- name = "Vegetarian"
- desc = "You find the idea of eating meat morally and physically repulsive."
- icon = FA_ICON_CARROT
- value = 0
- gain_text = span_notice("You feel repulsion at the idea of eating meat.")
- lose_text = span_notice("You feel like eating meat isn't that bad.")
- medical_record_text = "Patient reports a vegetarian diet."
- mail_goodies = list(/obj/effect/spawner/random/food_or_drink/salad)
-
-/datum/quirk/vegetarian/add(client/client_source)
- var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE)
- if(!tongue)
- return
- tongue.liked_foodtypes &= ~MEAT
- tongue.disliked_foodtypes |= MEAT
-
-/datum/quirk/vegetarian/remove()
- var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE)
- if(!tongue)
- return
- tongue.liked_foodtypes = initial(tongue.liked_foodtypes)
- tongue.disliked_foodtypes = initial(tongue.disliked_foodtypes)
-
-/datum/quirk/snob
- name = "Snob"
- desc = "You care about the finer things, if a room doesn't look nice its just not really worth it, is it?"
- icon = FA_ICON_USER_TIE
- value = 0
- gain_text = span_notice("You feel like you understand what things should look like.")
- lose_text = span_notice("Well who cares about deco anyways?")
- medical_record_text = "Patient seems to be rather stuck up."
- mob_trait = TRAIT_SNOB
- mail_goodies = list(/obj/item/chisel, /obj/item/paint_palette)
-
-/datum/quirk/pineapple_liker
- name = "Ananas Affinity"
- desc = "You find yourself greatly enjoying fruits of the ananas genus. You can't seem to ever get enough of their sweet goodness!"
- icon = FA_ICON_THUMBS_UP
- value = 0
- gain_text = span_notice("You feel an intense craving for pineapple.")
- lose_text = span_notice("Your feelings towards pineapples seem to return to a lukewarm state.")
- medical_record_text = "Patient demonstrates a pathological love of pineapple."
- mail_goodies = list(/obj/item/food/pizzaslice/pineapple)
-
-/datum/quirk/pineapple_liker/add(client/client_source)
- var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE)
- if(!tongue)
- return
- tongue.liked_foodtypes |= PINEAPPLE
-
-/datum/quirk/pineapple_liker/remove()
- var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE)
- if(!tongue)
- return
- tongue.liked_foodtypes = initial(tongue.liked_foodtypes)
-
-/datum/quirk/pineapple_hater
- name = "Ananas Aversion"
- desc = "You find yourself greatly detesting fruits of the ananas genus. Serious, how the hell can anyone say these things are good? And what kind of madman would even dare putting it on a pizza!?"
- icon = FA_ICON_THUMBS_DOWN
- value = 0
- gain_text = span_notice("You find yourself pondering what kind of idiot actually enjoys pineapples...")
- lose_text = span_notice("Your feelings towards pineapples seem to return to a lukewarm state.")
- medical_record_text = "Patient is correct to think that pineapple is disgusting."
- mail_goodies = list( // basic pizza slices
- /obj/item/food/pizzaslice/margherita,
- /obj/item/food/pizzaslice/meat,
- /obj/item/food/pizzaslice/mushroom,
- /obj/item/food/pizzaslice/vegetable,
- /obj/item/food/pizzaslice/sassysage,
- )
-
-/datum/quirk/pineapple_hater/add(client/client_source)
- var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE)
- if(!tongue)
- return
- tongue.disliked_foodtypes |= PINEAPPLE
-
-/datum/quirk/pineapple_hater/remove()
- var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE)
- if(!tongue)
- return
- tongue.disliked_foodtypes = initial(tongue.disliked_foodtypes)
-
-/datum/quirk/deviant_tastes
- name = "Deviant Tastes"
- desc = "You dislike food that most people enjoy, and find delicious what they don't."
- icon = FA_ICON_GRIN_TONGUE_SQUINT
- value = 0
- gain_text = span_notice("You start craving something that tastes strange.")
- lose_text = span_notice("You feel like eating normal food again.")
- medical_record_text = "Patient demonstrates irregular nutrition preferences."
- mail_goodies = list(/obj/item/food/urinalcake, /obj/item/food/badrecipe) // Mhhhmmm yummy
-
-/datum/quirk/deviant_tastes/add(client/client_source)
- var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE)
- if(!tongue)
- return
- var/liked_foodtypes = tongue.liked_foodtypes
- tongue.liked_foodtypes = tongue.disliked_foodtypes
- tongue.disliked_foodtypes = liked_foodtypes
-
-/datum/quirk/deviant_tastes/remove()
- var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE)
- if(!tongue)
- return
- tongue.liked_foodtypes = initial(tongue.liked_foodtypes)
- tongue.disliked_foodtypes = initial(tongue.disliked_foodtypes)
-
-/datum/quirk/heterochromatic
- name = "Heterochromatic"
- desc = "One of your eyes is a different color than the other!"
- icon = FA_ICON_EYE_LOW_VISION // Ignore the icon name, its actually a fairly good representation of different color eyes
- quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE
- value = 0
- mail_goodies = list(/obj/item/clothing/glasses/eyepatch)
-
-// Only your first eyes are heterochromatic
-// If someone comes and says "well mr coder you can have DNA bound heterochromia so it's not unrealistic
-// to allow all inserted replacement eyes to become heterochromatic or for it to transfer between mobs"
-// Then just change this to [proc/add] I really don't care
-/datum/quirk/heterochromatic/add_unique(client/client_source)
- var/color = client_source?.prefs.read_preference(/datum/preference/color/heterochromatic)
- if(!color)
- return
-
- apply_heterochromatic_eyes(color)
-
-/// Applies the passed color to this mob's eyes
-/datum/quirk/heterochromatic/proc/apply_heterochromatic_eyes(color)
- var/mob/living/carbon/human/human_holder = quirk_holder
- var/was_not_hetero = !human_holder.eye_color_heterochromatic
- human_holder.eye_color_heterochromatic = TRUE
- human_holder.eye_color_right = color
-
- var/obj/item/organ/internal/eyes/eyes_of_the_holder = quirk_holder.get_organ_by_type(/obj/item/organ/internal/eyes)
- if(!eyes_of_the_holder)
- return
-
- eyes_of_the_holder.eye_color_right = color
- eyes_of_the_holder.old_eye_color_right = color
- eyes_of_the_holder.refresh()
-
- if(was_not_hetero)
- RegisterSignal(human_holder, COMSIG_CARBON_LOSE_ORGAN, PROC_REF(check_eye_removal))
-
-/datum/quirk/heterochromatic/remove()
- var/mob/living/carbon/human/human_holder = quirk_holder
- human_holder.eye_color_heterochromatic = FALSE
- human_holder.eye_color_right = human_holder.eye_color_left
- UnregisterSignal(human_holder, COMSIG_CARBON_LOSE_ORGAN)
-
-/datum/quirk/heterochromatic/proc/check_eye_removal(datum/source, obj/item/organ/internal/eyes/removed)
- SIGNAL_HANDLER
-
- if(!istype(removed))
- return
-
- // Eyes were removed, remove heterochromia from the human holder and bid them adieu
- var/mob/living/carbon/human/human_holder = quirk_holder
- human_holder.eye_color_heterochromatic = FALSE
- human_holder.eye_color_right = human_holder.eye_color_left
- UnregisterSignal(human_holder, COMSIG_CARBON_LOSE_ORGAN)
-
-/datum/quirk/monochromatic
- name = "Monochromacy"
- desc = "You suffer from full colorblindness, and perceive nearly the entire world in blacks and whites."
- icon = FA_ICON_ADJUST
- value = 0
- medical_record_text = "Patient is afflicted with almost complete color blindness."
- mail_goodies = list( // Noir detective wannabe
- /obj/item/clothing/suit/jacket/det_suit/noir,
- /obj/item/clothing/suit/jacket/det_suit/dark,
- /obj/item/clothing/head/fedora/beige,
- /obj/item/clothing/head/fedora/white,
- )
-
-/datum/quirk/monochromatic/add(client/client_source)
- quirk_holder.add_client_colour(/datum/client_colour/monochrome)
-
-/datum/quirk/monochromatic/post_add()
- if(is_detective_job(quirk_holder.mind.assigned_role))
- to_chat(quirk_holder, span_boldannounce("Mmm. Nothing's ever clear on this station. It's all shades of gray..."))
- quirk_holder.playsound_local(quirk_holder, 'sound/ambience/ambidet1.ogg', 50, FALSE)
-
-/datum/quirk/monochromatic/remove()
- quirk_holder.remove_client_colour(/datum/client_colour/monochrome)
-
-/datum/quirk/phobia
- name = "Phobia"
- desc = "You are irrationally afraid of something."
- icon = FA_ICON_SPIDER
- value = 0
- medical_record_text = "Patient has an irrational fear of something."
- mail_goodies = list(/obj/item/clothing/glasses/blindfold, /obj/item/storage/pill_bottle/psicodine)
-
-// Phobia will follow you between transfers
-/datum/quirk/phobia/add(client/client_source)
- var/phobia = client_source?.prefs.read_preference(/datum/preference/choiced/phobia)
- if(!phobia)
- return
-
- var/mob/living/carbon/human/human_holder = quirk_holder
- human_holder.gain_trauma(new /datum/brain_trauma/mild/phobia(phobia), TRAUMA_RESILIENCE_ABSOLUTE)
-
-/datum/quirk/phobia/remove()
- var/mob/living/carbon/human/human_holder = quirk_holder
- human_holder.cure_trauma_type(/datum/brain_trauma/mild/phobia, TRAUMA_RESILIENCE_ABSOLUTE)
-
-/datum/quirk/shifty_eyes
- name = "Shifty Eyes"
- desc = "Your eyes tend to wander all over the place, whether you mean to or not, causing people to sometimes think you're looking directly at them when you aren't."
- icon = FA_ICON_EYE
- value = 0
- medical_record_text = "Fucking creep kept staring at me the whole damn checkup. I'm only diagnosing this because it's less awkward than thinking it was on purpose."
- mob_trait = TRAIT_SHIFTY_EYES
- mail_goodies = list(/obj/item/clothing/head/costume/papersack, /obj/item/clothing/head/costume/papersack/smiley)
-
-/datum/quirk/item_quirk/bald
- name = "Smooth-Headed"
- desc = "You have no hair and are quite insecure about it! Keep your wig on, or at least your head covered up."
- icon = FA_ICON_EGG
- value = 0
- mob_trait = TRAIT_BALD
- gain_text = span_notice("Your head is as smooth as can be, it's terrible.")
- lose_text = span_notice("Your head itches, could it be... growing hair?!")
- medical_record_text = "Patient starkly refused to take off headwear during examination."
- mail_goodies = list(/obj/item/clothing/head/wig/random)
- /// The user's starting hairstyle
- var/old_hair
-
-/datum/quirk/item_quirk/bald/add(client/client_source)
- var/mob/living/carbon/human/human_holder = quirk_holder
- old_hair = human_holder.hairstyle
- human_holder.set_hairstyle("Bald", update = TRUE)
- RegisterSignal(human_holder, COMSIG_CARBON_EQUIP_HAT, PROC_REF(equip_hat))
- RegisterSignal(human_holder, COMSIG_CARBON_UNEQUIP_HAT, PROC_REF(unequip_hat))
-
-/datum/quirk/item_quirk/bald/add_unique(client/client_source)
- var/obj/item/clothing/head/wig/natural/baldie_wig = new(get_turf(quirk_holder))
- if(old_hair == "Bald")
- baldie_wig.hairstyle = pick(GLOB.hairstyles_list - "Bald")
- else
- baldie_wig.hairstyle = old_hair
-
- baldie_wig.update_appearance()
-
- give_item_to_holder(baldie_wig, list(LOCATION_HEAD = ITEM_SLOT_HEAD, LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
-
-/datum/quirk/item_quirk/bald/remove()
- . = ..()
- var/mob/living/carbon/human/human_holder = quirk_holder
- human_holder.hairstyle = old_hair
- human_holder.update_body_parts()
- UnregisterSignal(human_holder, list(COMSIG_CARBON_EQUIP_HAT, COMSIG_CARBON_UNEQUIP_HAT))
- human_holder.clear_mood_event("bad_hair_day")
-
-///Checks if the headgear equipped is a wig and sets the mood event accordingly
-/datum/quirk/item_quirk/bald/proc/equip_hat(mob/user, obj/item/hat)
- SIGNAL_HANDLER
-
- if(istype(hat, /obj/item/clothing/head/wig))
- quirk_holder.add_mood_event("bad_hair_day", /datum/mood_event/confident_mane) //Our head is covered, but also by a wig so we're happy.
- else
- quirk_holder.clear_mood_event("bad_hair_day") //Our head is covered
-
-///Applies a bad moodlet for having an uncovered head
-/datum/quirk/item_quirk/bald/proc/unequip_hat(mob/user, obj/item/clothing, force, newloc, no_move, invdrop, silent)
- SIGNAL_HANDLER
-
- quirk_holder.add_mood_event("bad_hair_day", /datum/mood_event/bald)
-
-/datum/quirk/item_quirk/photographer
- name = "Photographer"
- desc = "You carry your camera and personal photo album everywhere you go, and your scrapbooks are legendary among your coworkers."
- icon = FA_ICON_CAMERA
- value = 0
- mob_trait = TRAIT_PHOTOGRAPHER
- gain_text = span_notice("You know everything about photography.")
- lose_text = span_danger("You forget how photo cameras work.")
- medical_record_text = "Patient mentions photography as a stress-relieving hobby."
- mail_goodies = list(/obj/item/camera_film)
-
-/datum/quirk/item_quirk/photographer/add_unique(client/client_source)
- var/mob/living/carbon/human/human_holder = quirk_holder
- var/obj/item/storage/photo_album/personal/photo_album = new(get_turf(human_holder))
- photo_album.persistence_id = "personal_[human_holder.last_mind?.key]" // this is a persistent album, the ID is tied to the account's key to avoid tampering
- photo_album.persistence_load()
- photo_album.name = "[human_holder.real_name]'s photo album"
-
- give_item_to_holder(photo_album, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
- give_item_to_holder(
- /obj/item/camera,
- list(
- LOCATION_NECK = ITEM_SLOT_NECK,
- LOCATION_LPOCKET = ITEM_SLOT_LPOCKET,
- LOCATION_RPOCKET = ITEM_SLOT_RPOCKET,
- LOCATION_BACKPACK = ITEM_SLOT_BACKPACK,
- LOCATION_HANDS = ITEM_SLOT_HANDS
- )
- )
-
-/datum/quirk/item_quirk/colorist
- name = "Colorist"
- desc = "You like carrying around a hair dye spray to quickly apply color patterns to your hair."
- icon = FA_ICON_FILL_DRIP
- value = 0
- medical_record_text = "Patient enjoys dyeing their hair with pretty colors."
- mail_goodies = list(/obj/item/dyespray)
-
-/datum/quirk/item_quirk/colorist/add_unique(client/client_source)
- give_item_to_holder(/obj/item/dyespray, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
-
-#define GAMING_WITHDRAWAL_TIME (15 MINUTES)
-/datum/quirk/gamer
- name = "Gamer"
- desc = "You are a hardcore gamer, and you have a need to game. You love winning and hate losing. You only like gamer food."
- icon = FA_ICON_GAMEPAD
- value = 0
- gain_text = span_notice("You feel the sudden urge to game.")
- lose_text = span_notice("You've lost all interest in gaming.")
- medical_record_text = "Patient has a severe video game addiction."
- mob_trait = TRAIT_GAMER
- mail_goodies = list(/obj/item/toy/intento, /obj/item/clothing/head/fedora)
- /// Timer for gaming withdrawal to kick in
- var/gaming_withdrawal_timer = TIMER_ID_NULL
-
-/datum/quirk/gamer/add(client/client_source)
- var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE)
- if(tongue)
- // Gamer diet
- tongue.liked_foodtypes = JUNKFOOD
- RegisterSignal(quirk_holder, COMSIG_MOB_WON_VIDEOGAME, PROC_REF(won_game))
- RegisterSignal(quirk_holder, COMSIG_MOB_LOST_VIDEOGAME, PROC_REF(lost_game))
- RegisterSignal(quirk_holder, COMSIG_MOB_PLAYED_VIDEOGAME, PROC_REF(gamed))
-
-/datum/quirk/gamer/add_unique(client/client_source)
- // The gamer starts off quelled
- gaming_withdrawal_timer = addtimer(CALLBACK(src, PROC_REF(enter_withdrawal)), GAMING_WITHDRAWAL_TIME, TIMER_STOPPABLE)
-
-/datum/quirk/gamer/remove()
- var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE)
- if(tongue)
- tongue.liked_foodtypes = initial(tongue.liked_foodtypes)
- UnregisterSignal(quirk_holder, COMSIG_MOB_WON_VIDEOGAME)
- UnregisterSignal(quirk_holder, COMSIG_MOB_LOST_VIDEOGAME)
- UnregisterSignal(quirk_holder, COMSIG_MOB_PLAYED_VIDEOGAME)
-
-/**
- * Gamer won a game
- *
- * Executed on the COMSIG_MOB_WON_VIDEOGAME signal
- * This signal should be called whenever a player has won a video game.
- * (E.g. Orion Trail)
- */
-/datum/quirk/gamer/proc/won_game()
- SIGNAL_HANDLER
- // Epic gamer victory
- var/mob/living/carbon/human/human_holder = quirk_holder
- human_holder.add_mood_event("gamer_won", /datum/mood_event/gamer_won)
-
-/**
- * Gamer lost a game
- *
- * Executed on the COMSIG_MOB_LOST_VIDEOGAME signal
- * This signal should be called whenever a player has lost a video game.
- * (E.g. Orion Trail)
- */
-/datum/quirk/gamer/proc/lost_game()
- SIGNAL_HANDLER
- // Executed when a gamer has lost
- var/mob/living/carbon/human/human_holder = quirk_holder
- human_holder.add_mood_event("gamer_lost", /datum/mood_event/gamer_lost)
- // Executed asynchronously due to say()
- INVOKE_ASYNC(src, PROC_REF(gamer_moment))
-/**
- * Gamer is playing a game
- *
- * Executed on the COMSIG_MOB_PLAYED_VIDEOGAME signal
- * This signal should be called whenever a player interacts with a video game.
- */
-/datum/quirk/gamer/proc/gamed()
- SIGNAL_HANDLER
-
- var/mob/living/carbon/human/human_holder = quirk_holder
- // Remove withdrawal malus
- human_holder.clear_mood_event("gamer_withdrawal")
- // Reset withdrawal timer
- if (gaming_withdrawal_timer)
- deltimer(gaming_withdrawal_timer)
- gaming_withdrawal_timer = addtimer(CALLBACK(src, PROC_REF(enter_withdrawal)), GAMING_WITHDRAWAL_TIME, TIMER_STOPPABLE)
-
-
-/datum/quirk/gamer/proc/gamer_moment()
- // It was a heated gamer moment...
- var/mob/living/carbon/human/human_holder = quirk_holder
- human_holder.say(";[pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER")]!!", forced = name)
-
-/datum/quirk/gamer/proc/enter_withdrawal()
- var/mob/living/carbon/human/human_holder = quirk_holder
- human_holder.add_mood_event("gamer_withdrawal", /datum/mood_event/gamer_withdrawal)
-
-#undef GAMING_WITHDRAWAL_TIME
-
-
-/datum/quirk/item_quirk/pride_pin
- name = "Pride Pin"
- desc = "Show off your pride with this changing pride pin!"
- icon = FA_ICON_RAINBOW
- value = 0
- gain_text = span_notice("You feel fruity.")
- lose_text = span_danger("You feel only slightly less fruity than before.")
- medical_record_text = "Patient appears to be fruity."
-
-/datum/quirk/item_quirk/pride_pin/add_unique(client/client_source)
- var/obj/item/clothing/accessory/pride/pin = new(get_turf(quirk_holder))
-
- var/pride_choice = client_source?.prefs?.read_preference(/datum/preference/choiced/pride_pin) || assoc_to_keys(GLOB.pride_pin_reskins)[1]
- var/pride_reskin = GLOB.pride_pin_reskins[pride_choice]
-
- pin.current_skin = pride_choice
- pin.icon_state = pride_reskin
-
- give_item_to_holder(pin, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
diff --git a/code/datums/quirks/neutral_quirks/no_taste.dm b/code/datums/quirks/neutral_quirks/no_taste.dm
new file mode 100644
index 00000000000..664aaf1d9de
--- /dev/null
+++ b/code/datums/quirks/neutral_quirks/no_taste.dm
@@ -0,0 +1,10 @@
+/datum/quirk/no_taste
+ name = "Ageusia"
+ desc = "You can't taste anything! Toxic food will still poison you."
+ icon = FA_ICON_MEH_BLANK
+ value = 0
+ mob_trait = TRAIT_AGEUSIA
+ gain_text = span_notice("You can't taste anything!")
+ lose_text = span_notice("You can taste again!")
+ medical_record_text = "Patient suffers from ageusia and is incapable of tasting food or reagents."
+ mail_goodies = list(/obj/effect/spawner/random/food_or_drink/condiment) // but can you taste the salt? CAN YOU?!
diff --git a/code/datums/quirks/neutral_quirks/phobia.dm b/code/datums/quirks/neutral_quirks/phobia.dm
new file mode 100644
index 00000000000..224401f0670
--- /dev/null
+++ b/code/datums/quirks/neutral_quirks/phobia.dm
@@ -0,0 +1,20 @@
+/datum/quirk/phobia
+ name = "Phobia"
+ desc = "You are irrationally afraid of something."
+ icon = FA_ICON_SPIDER
+ value = 0
+ medical_record_text = "Patient has an irrational fear of something."
+ mail_goodies = list(/obj/item/clothing/glasses/blindfold, /obj/item/storage/pill_bottle/psicodine)
+
+// Phobia will follow you between transfers
+/datum/quirk/phobia/add(client/client_source)
+ var/phobia = client_source?.prefs.read_preference(/datum/preference/choiced/phobia)
+ if(!phobia)
+ return
+
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ human_holder.gain_trauma(new /datum/brain_trauma/mild/phobia(phobia), TRAUMA_RESILIENCE_ABSOLUTE)
+
+/datum/quirk/phobia/remove()
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ human_holder.cure_trauma_type(/datum/brain_trauma/mild/phobia, TRAUMA_RESILIENCE_ABSOLUTE)
diff --git a/code/datums/quirks/neutral_quirks/photographer.dm b/code/datums/quirks/neutral_quirks/photographer.dm
new file mode 100644
index 00000000000..d2284df240c
--- /dev/null
+++ b/code/datums/quirks/neutral_quirks/photographer.dm
@@ -0,0 +1,29 @@
+/datum/quirk/item_quirk/photographer
+ name = "Photographer"
+ desc = "You carry your camera and personal photo album everywhere you go, and your scrapbooks are legendary among your coworkers."
+ icon = FA_ICON_CAMERA
+ value = 0
+ mob_trait = TRAIT_PHOTOGRAPHER
+ gain_text = span_notice("You know everything about photography.")
+ lose_text = span_danger("You forget how photo cameras work.")
+ medical_record_text = "Patient mentions photography as a stress-relieving hobby."
+ mail_goodies = list(/obj/item/camera_film)
+
+/datum/quirk/item_quirk/photographer/add_unique(client/client_source)
+ var/mob/living/carbon/human/human_holder = quirk_holder
+ var/obj/item/storage/photo_album/personal/photo_album = new(get_turf(human_holder))
+ photo_album.persistence_id = "personal_[human_holder.last_mind?.key]" // this is a persistent album, the ID is tied to the account's key to avoid tampering
+ photo_album.persistence_load()
+ photo_album.name = "[human_holder.real_name]'s photo album"
+
+ give_item_to_holder(photo_album, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
+ give_item_to_holder(
+ /obj/item/camera,
+ list(
+ LOCATION_NECK = ITEM_SLOT_NECK,
+ LOCATION_LPOCKET = ITEM_SLOT_LPOCKET,
+ LOCATION_RPOCKET = ITEM_SLOT_RPOCKET,
+ LOCATION_BACKPACK = ITEM_SLOT_BACKPACK,
+ LOCATION_HANDS = ITEM_SLOT_HANDS
+ )
+ )
diff --git a/code/datums/quirks/neutral_quirks/pineapple_hater.dm b/code/datums/quirks/neutral_quirks/pineapple_hater.dm
new file mode 100644
index 00000000000..f17eb4224ec
--- /dev/null
+++ b/code/datums/quirks/neutral_quirks/pineapple_hater.dm
@@ -0,0 +1,27 @@
+/datum/quirk/pineapple_hater
+ name = "Ananas Aversion"
+ desc = "You find yourself greatly detesting fruits of the ananas genus. Serious, how the hell can anyone say these things are good? And what kind of madman would even dare putting it on a pizza!?"
+ icon = FA_ICON_THUMBS_DOWN
+ value = 0
+ gain_text = span_notice("You find yourself pondering what kind of idiot actually enjoys pineapples...")
+ lose_text = span_notice("Your feelings towards pineapples seem to return to a lukewarm state.")
+ medical_record_text = "Patient is correct to think that pineapple is disgusting."
+ mail_goodies = list( // basic pizza slices
+ /obj/item/food/pizzaslice/margherita,
+ /obj/item/food/pizzaslice/meat,
+ /obj/item/food/pizzaslice/mushroom,
+ /obj/item/food/pizzaslice/vegetable,
+ /obj/item/food/pizzaslice/sassysage,
+ )
+
+/datum/quirk/pineapple_hater/add(client/client_source)
+ var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE)
+ if(!tongue)
+ return
+ tongue.disliked_foodtypes |= PINEAPPLE
+
+/datum/quirk/pineapple_hater/remove()
+ var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE)
+ if(!tongue)
+ return
+ tongue.disliked_foodtypes = initial(tongue.disliked_foodtypes)
diff --git a/code/datums/quirks/neutral_quirks/pineapple_liker.dm b/code/datums/quirks/neutral_quirks/pineapple_liker.dm
new file mode 100644
index 00000000000..c342e14769c
--- /dev/null
+++ b/code/datums/quirks/neutral_quirks/pineapple_liker.dm
@@ -0,0 +1,21 @@
+/datum/quirk/pineapple_liker
+ name = "Ananas Affinity"
+ desc = "You find yourself greatly enjoying fruits of the ananas genus. You can't seem to ever get enough of their sweet goodness!"
+ icon = FA_ICON_THUMBS_UP
+ value = 0
+ gain_text = span_notice("You feel an intense craving for pineapple.")
+ lose_text = span_notice("Your feelings towards pineapples seem to return to a lukewarm state.")
+ medical_record_text = "Patient demonstrates a pathological love of pineapple."
+ mail_goodies = list(/obj/item/food/pizzaslice/pineapple)
+
+/datum/quirk/pineapple_liker/add(client/client_source)
+ var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE)
+ if(!tongue)
+ return
+ tongue.liked_foodtypes |= PINEAPPLE
+
+/datum/quirk/pineapple_liker/remove()
+ var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE)
+ if(!tongue)
+ return
+ tongue.liked_foodtypes = initial(tongue.liked_foodtypes)
diff --git a/code/datums/quirks/neutral_quirks/pride_pin.dm b/code/datums/quirks/neutral_quirks/pride_pin.dm
new file mode 100644
index 00000000000..488c0a2bccb
--- /dev/null
+++ b/code/datums/quirks/neutral_quirks/pride_pin.dm
@@ -0,0 +1,19 @@
+/datum/quirk/item_quirk/pride_pin
+ name = "Pride Pin"
+ desc = "Show off your pride with this changing pride pin!"
+ icon = FA_ICON_RAINBOW
+ value = 0
+ gain_text = span_notice("You feel fruity.")
+ lose_text = span_danger("You feel only slightly less fruity than before.")
+ medical_record_text = "Patient appears to be fruity."
+
+/datum/quirk/item_quirk/pride_pin/add_unique(client/client_source)
+ var/obj/item/clothing/accessory/pride/pin = new(get_turf(quirk_holder))
+
+ var/pride_choice = client_source?.prefs?.read_preference(/datum/preference/choiced/pride_pin) || assoc_to_keys(GLOB.pride_pin_reskins)[1]
+ var/pride_reskin = GLOB.pride_pin_reskins[pride_choice]
+
+ pin.current_skin = pride_choice
+ pin.icon_state = pride_reskin
+
+ give_item_to_holder(pin, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
diff --git a/code/datums/quirks/neutral_quirks/shifty_eyes.dm b/code/datums/quirks/neutral_quirks/shifty_eyes.dm
new file mode 100644
index 00000000000..29f1def3761
--- /dev/null
+++ b/code/datums/quirks/neutral_quirks/shifty_eyes.dm
@@ -0,0 +1,8 @@
+/datum/quirk/shifty_eyes
+ name = "Shifty Eyes"
+ desc = "Your eyes tend to wander all over the place, whether you mean to or not, causing people to sometimes think you're looking directly at them when you aren't."
+ icon = FA_ICON_EYE
+ value = 0
+ medical_record_text = "Fucking creep kept staring at me the whole damn checkup. I'm only diagnosing this because it's less awkward than thinking it was on purpose."
+ mob_trait = TRAIT_SHIFTY_EYES
+ mail_goodies = list(/obj/item/clothing/head/costume/papersack, /obj/item/clothing/head/costume/papersack/smiley)
diff --git a/code/datums/quirks/neutral_quirks/snob.dm b/code/datums/quirks/neutral_quirks/snob.dm
new file mode 100644
index 00000000000..ab273f1ae53
--- /dev/null
+++ b/code/datums/quirks/neutral_quirks/snob.dm
@@ -0,0 +1,10 @@
+/datum/quirk/snob
+ name = "Snob"
+ desc = "You care about the finer things, if a room doesn't look nice its just not really worth it, is it?"
+ icon = FA_ICON_USER_TIE
+ value = 0
+ gain_text = span_notice("You feel like you understand what things should look like.")
+ lose_text = span_notice("Well who cares about deco anyways?")
+ medical_record_text = "Patient seems to be rather stuck up."
+ mob_trait = TRAIT_SNOB
+ mail_goodies = list(/obj/item/chisel, /obj/item/paint_palette)
diff --git a/code/datums/quirks/neutral_quirks/vegetarian.dm b/code/datums/quirks/neutral_quirks/vegetarian.dm
new file mode 100644
index 00000000000..0ade72acafe
--- /dev/null
+++ b/code/datums/quirks/neutral_quirks/vegetarian.dm
@@ -0,0 +1,23 @@
+/datum/quirk/vegetarian
+ name = "Vegetarian"
+ desc = "You find the idea of eating meat morally and physically repulsive."
+ icon = FA_ICON_CARROT
+ value = 0
+ gain_text = span_notice("You feel repulsion at the idea of eating meat.")
+ lose_text = span_notice("You feel like eating meat isn't that bad.")
+ medical_record_text = "Patient reports a vegetarian diet."
+ mail_goodies = list(/obj/effect/spawner/random/food_or_drink/salad)
+
+/datum/quirk/vegetarian/add(client/client_source)
+ var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE)
+ if(!tongue)
+ return
+ tongue.liked_foodtypes &= ~MEAT
+ tongue.disliked_foodtypes |= MEAT
+
+/datum/quirk/vegetarian/remove()
+ var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE)
+ if(!tongue)
+ return
+ tongue.liked_foodtypes = initial(tongue.liked_foodtypes)
+ tongue.disliked_foodtypes = initial(tongue.disliked_foodtypes)
diff --git a/code/datums/quirks/positive_quirks/alcohol_tolerance.dm b/code/datums/quirks/positive_quirks/alcohol_tolerance.dm
new file mode 100644
index 00000000000..6458513007d
--- /dev/null
+++ b/code/datums/quirks/positive_quirks/alcohol_tolerance.dm
@@ -0,0 +1,10 @@
+/datum/quirk/alcohol_tolerance
+ name = "Alcohol Tolerance"
+ desc = "You become drunk more slowly and suffer fewer drawbacks from alcohol."
+ icon = FA_ICON_BEER
+ value = 4
+ mob_trait = TRAIT_ALCOHOL_TOLERANCE
+ gain_text = span_notice("You feel like you could drink a whole keg!")
+ lose_text = span_danger("You don't feel as resistant to alcohol anymore. Somehow.")
+ medical_record_text = "Patient demonstrates a high tolerance for alcohol."
+ mail_goodies = list(/obj/item/skillchip/wine_taster)
diff --git a/code/datums/quirks/positive_quirks/apathetic.dm b/code/datums/quirks/positive_quirks/apathetic.dm
new file mode 100644
index 00000000000..170cb6f5d44
--- /dev/null
+++ b/code/datums/quirks/positive_quirks/apathetic.dm
@@ -0,0 +1,14 @@
+/datum/quirk/apathetic
+ name = "Apathetic"
+ desc = "You just don't care as much as other people. That's nice to have in a place like this, I guess."
+ icon = FA_ICON_MEH
+ value = 4
+ quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_MOODLET_BASED
+ medical_record_text = "Patient was administered the Apathy Evaluation Scale but did not bother to complete it."
+ mail_goodies = list(/obj/item/hourglass)
+
+/datum/quirk/apathetic/add(client/client_source)
+ quirk_holder.mob_mood?.mood_modifier -= 0.2
+
+/datum/quirk/apathetic/remove()
+ quirk_holder.mob_mood?.mood_modifier += 0.2
diff --git a/code/datums/quirks/positive_quirks/bilingual.dm b/code/datums/quirks/positive_quirks/bilingual.dm
new file mode 100644
index 00000000000..324054198b8
--- /dev/null
+++ b/code/datums/quirks/positive_quirks/bilingual.dm
@@ -0,0 +1,24 @@
+/datum/quirk/bilingual
+ name = "Bilingual"
+ desc = "Over the years you've picked up an extra language!"
+ icon = FA_ICON_GLOBE
+ value = 4
+ gain_text = span_notice("Some of the words of the people around you certainly aren't common. Good thing you studied for this.")
+ lose_text = span_notice("You seem to have forgotten your second language.")
+ medical_record_text = "Patient speaks multiple languages."
+ mail_goodies = list(/obj/item/taperecorder, /obj/item/clothing/head/frenchberet, /obj/item/clothing/mask/fakemoustache/italian)
+
+/datum/quirk/bilingual/add_unique(client/client_source)
+ var/wanted_language = client_source?.prefs.read_preference(/datum/preference/choiced/language)
+ var/datum/language/language_type
+ if(wanted_language == "Random")
+ language_type = pick(GLOB.uncommon_roundstart_languages)
+ else
+ language_type = GLOB.language_types_by_name[wanted_language]
+ if(quirk_holder.has_language(language_type))
+ language_type = /datum/language/uncommon
+ if(quirk_holder.has_language(language_type))
+ to_chat(quirk_holder, span_boldnotice("You are already familiar with the quirk in your preferences, so you did not learn one."))
+ return
+ to_chat(quirk_holder, span_boldnotice("You are already familiar with the quirk in your preferences, so you learned Galactic Uncommon instead."))
+ quirk_holder.grant_language(language_type, source = LANGUAGE_QUIRK)
diff --git a/code/datums/quirks/positive_quirks/clown_enjoyer.dm b/code/datums/quirks/positive_quirks/clown_enjoyer.dm
new file mode 100644
index 00000000000..984b0f7a6e4
--- /dev/null
+++ b/code/datums/quirks/positive_quirks/clown_enjoyer.dm
@@ -0,0 +1,31 @@
+/datum/quirk/item_quirk/clown_enjoyer
+ name = "Clown Enjoyer"
+ desc = "You enjoy clown antics and get a mood boost from wearing your clown pin."
+ icon = FA_ICON_MAP_PIN
+ value = 2
+ mob_trait = TRAIT_CLOWN_ENJOYER
+ gain_text = span_notice("You are a big enjoyer of clowns.")
+ lose_text = span_danger("The clown doesn't seem so great.")
+ medical_record_text = "Patient reports being a big enjoyer of clowns."
+ mail_goodies = list(
+ /obj/item/bikehorn,
+ /obj/item/stamp/clown,
+ /obj/item/megaphone/clown,
+ /obj/item/clothing/shoes/clown_shoes,
+ /obj/item/bedsheet/clown,
+ /obj/item/clothing/mask/gas/clown_hat,
+ /obj/item/storage/backpack/clown,
+ /obj/item/storage/backpack/duffelbag/clown,
+ /obj/item/toy/crayon/rainbow,
+ /obj/item/toy/figure/clown,
+ /obj/item/tank/internals/emergency_oxygen/engi/clown/n2o,
+ /obj/item/tank/internals/emergency_oxygen/engi/clown/bz,
+ /obj/item/tank/internals/emergency_oxygen/engi/clown/helium,
+ )
+
+/datum/quirk/item_quirk/clown_enjoyer/add_unique(client/client_source)
+ give_item_to_holder(/obj/item/clothing/accessory/clown_enjoyer_pin, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
+
+/datum/quirk/item_quirk/clown_enjoyer/add(client/client_source)
+ var/datum/atom_hud/fan = GLOB.huds[DATA_HUD_FAN]
+ fan.show_to(quirk_holder)
diff --git a/code/datums/quirks/positive_quirks/drunk_healing.dm b/code/datums/quirks/positive_quirks/drunk_healing.dm
new file mode 100644
index 00000000000..fbab2503b4e
--- /dev/null
+++ b/code/datums/quirks/positive_quirks/drunk_healing.dm
@@ -0,0 +1,22 @@
+/datum/quirk/drunkhealing
+ name = "Drunken Resilience"
+ desc = "Nothing like a good drink to make you feel on top of the world. Whenever you're drunk, you slowly recover from injuries."
+ icon = FA_ICON_WINE_BOTTLE
+ value = 8
+ gain_text = span_notice("You feel like a drink would do you good.")
+ lose_text = span_danger("You no longer feel like drinking would ease your pain.")
+ medical_record_text = "Patient has unusually efficient liver metabolism and can slowly regenerate wounds by drinking alcoholic beverages."
+ quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES
+ mail_goodies = list(/obj/effect/spawner/random/food_or_drink/booze)
+
+/datum/quirk/drunkhealing/process(seconds_per_tick)
+ switch(quirk_holder.get_drunk_amount())
+ if (6 to 40)
+ quirk_holder.adjustBruteLoss(-0.1 * seconds_per_tick, FALSE, required_bodytype = BODYTYPE_ORGANIC)
+ quirk_holder.adjustFireLoss(-0.05 * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC)
+ if (41 to 60)
+ quirk_holder.adjustBruteLoss(-0.4 * seconds_per_tick, FALSE, required_bodytype = BODYTYPE_ORGANIC)
+ quirk_holder.adjustFireLoss(-0.2 * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC)
+ if (61 to INFINITY)
+ quirk_holder.adjustBruteLoss(-0.8 * seconds_per_tick, FALSE, required_bodytype = BODYTYPE_ORGANIC)
+ quirk_holder.adjustFireLoss(-0.4 * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC)
diff --git a/code/datums/quirks/positive_quirks/empath.dm b/code/datums/quirks/positive_quirks/empath.dm
new file mode 100644
index 00000000000..3379f8a97c4
--- /dev/null
+++ b/code/datums/quirks/positive_quirks/empath.dm
@@ -0,0 +1,10 @@
+/datum/quirk/empath
+ name = "Empath"
+ desc = "Whether it's a sixth sense or careful study of body language, it only takes you a quick glance at someone to understand how they feel."
+ icon = FA_ICON_SMILE_BEAM
+ value = 6 // SKYRAT EDIT CHANGE - Quirk Rebalance - Original: value = 8
+ mob_trait = TRAIT_EMPATH
+ gain_text = span_notice("You feel in tune with those around you.")
+ lose_text = span_danger("You feel isolated from others.")
+ medical_record_text = "Patient is highly perceptive of and sensitive to social cues, or may possibly have ESP. Further testing needed."
+ mail_goodies = list(/obj/item/toy/foamfinger)
diff --git a/code/datums/quirks/positive_quirks/freerunning.dm b/code/datums/quirks/positive_quirks/freerunning.dm
new file mode 100644
index 00000000000..541d2b1cc44
--- /dev/null
+++ b/code/datums/quirks/positive_quirks/freerunning.dm
@@ -0,0 +1,10 @@
+/datum/quirk/freerunning
+ name = "Freerunning"
+ desc = "You're great at quick moves! You can climb tables more quickly and take no damage from short falls."
+ icon = FA_ICON_RUNNING
+ value = 8
+ mob_trait = TRAIT_FREERUNNING
+ gain_text = span_notice("You feel lithe on your feet!")
+ lose_text = span_danger("You feel clumsy again.")
+ medical_record_text = "Patient scored highly on cardio tests."
+ mail_goodies = list(/obj/item/melee/skateboard, /obj/item/clothing/shoes/wheelys/rollerskates)
diff --git a/code/datums/quirks/positive_quirks/friendly.dm b/code/datums/quirks/positive_quirks/friendly.dm
new file mode 100644
index 00000000000..8ab0003639b
--- /dev/null
+++ b/code/datums/quirks/positive_quirks/friendly.dm
@@ -0,0 +1,11 @@
+/datum/quirk/friendly
+ name = "Friendly"
+ desc = "You give the best hugs, especially when you're in the right mood."
+ icon = FA_ICON_HANDS_HELPING
+ value = 2
+ mob_trait = TRAIT_FRIENDLY
+ gain_text = span_notice("You want to hug someone.")
+ lose_text = span_danger("You no longer feel compelled to hug others.")
+ quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_MOODLET_BASED
+ medical_record_text = "Patient demonstrates low-inhibitions for physical contact and well-developed arms. Requesting another doctor take over this case."
+ mail_goodies = list(/obj/item/storage/box/hug)
diff --git a/code/datums/quirks/positive_quirks/jolly.dm b/code/datums/quirks/positive_quirks/jolly.dm
new file mode 100644
index 00000000000..7f6c334ba9d
--- /dev/null
+++ b/code/datums/quirks/positive_quirks/jolly.dm
@@ -0,0 +1,9 @@
+/datum/quirk/jolly
+ name = "Jolly"
+ desc = "You sometimes just feel happy, for no reason at all."
+ icon = FA_ICON_GRIN
+ value = 4
+ mob_trait = TRAIT_JOLLY
+ quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_MOODLET_BASED
+ medical_record_text = "Patient demonstrates constant euthymia irregular for environment. It's a bit much, to be honest."
+ mail_goodies = list(/obj/item/clothing/mask/joy)
diff --git a/code/datums/quirks/positive_quirks/light_step.dm b/code/datums/quirks/positive_quirks/light_step.dm
new file mode 100644
index 00000000000..80418b79b9d
--- /dev/null
+++ b/code/datums/quirks/positive_quirks/light_step.dm
@@ -0,0 +1,10 @@
+/datum/quirk/light_step
+ name = "Light Step"
+ desc = "You walk with a gentle step; footsteps and stepping on sharp objects is quieter and less painful. Also, your hands and clothes will not get messed in case of stepping in blood."
+ icon = FA_ICON_SHOE_PRINTS
+ value = 4
+ mob_trait = TRAIT_LIGHT_STEP
+ gain_text = span_notice("You walk with a little more litheness.")
+ lose_text = span_danger("You start tromping around like a barbarian.")
+ medical_record_text = "Patient's dexterity belies a strong capacity for stealth."
+ mail_goodies = list(/obj/item/clothing/shoes/sandal)
diff --git a/code/datums/quirks/positive_quirks/mime_fan.dm b/code/datums/quirks/positive_quirks/mime_fan.dm
new file mode 100644
index 00000000000..5145b4a2240
--- /dev/null
+++ b/code/datums/quirks/positive_quirks/mime_fan.dm
@@ -0,0 +1,29 @@
+/datum/quirk/item_quirk/mime_fan
+ name = "Mime Fan"
+ desc = "You're a fan of mime antics and get a mood boost from wearing your mime pin."
+ icon = FA_ICON_THUMBTACK
+ value = 2
+ mob_trait = TRAIT_MIME_FAN
+ gain_text = span_notice("You are a big fan of the Mime.")
+ lose_text = span_danger("The mime doesn't seem so great.")
+ medical_record_text = "Patient reports being a big fan of mimes."
+ mail_goodies = list(
+ /obj/item/toy/crayon/mime,
+ /obj/item/clothing/mask/gas/mime,
+ /obj/item/storage/backpack/mime,
+ /obj/item/clothing/under/rank/civilian/mime,
+ /obj/item/reagent_containers/cup/glass/bottle/bottleofnothing,
+ /obj/item/stamp/mime,
+ /obj/item/storage/box/survival/hug/black,
+ /obj/item/bedsheet/mime,
+ /obj/item/clothing/shoes/sneakers/mime,
+ /obj/item/toy/figure/mime,
+ /obj/item/toy/crayon/spraycan/mimecan,
+ )
+
+/datum/quirk/item_quirk/mime_fan/add_unique(client/client_source)
+ give_item_to_holder(/obj/item/clothing/accessory/mime_fan_pin, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
+
+/datum/quirk/item_quirk/mime_fan/add(client/client_source)
+ var/datum/atom_hud/fan = GLOB.huds[DATA_HUD_FAN]
+ fan.show_to(quirk_holder)
diff --git a/code/datums/quirks/positive_quirks/musician.dm b/code/datums/quirks/positive_quirks/musician.dm
new file mode 100644
index 00000000000..9d5e10f5f82
--- /dev/null
+++ b/code/datums/quirks/positive_quirks/musician.dm
@@ -0,0 +1,13 @@
+/datum/quirk/item_quirk/musician
+ name = "Musician"
+ desc = "You can tune handheld musical instruments to play melodies that clear certain negative effects and soothe the soul."
+ icon = FA_ICON_GUITAR
+ value = 2
+ mob_trait = TRAIT_MUSICIAN
+ gain_text = span_notice("You know everything about musical instruments.")
+ lose_text = span_danger("You forget how musical instruments work.")
+ medical_record_text = "Patient brain scans show a highly-developed auditory pathway."
+ mail_goodies = list(/obj/effect/spawner/random/entertainment/musical_instrument, /obj/item/instrument/piano_synth/headphones)
+
+/datum/quirk/item_quirk/musician/add_unique(client/client_source)
+ give_item_to_holder(/obj/item/choice_beacon/music, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
diff --git a/code/datums/quirks/positive_quirks/night_vision.dm b/code/datums/quirks/positive_quirks/night_vision.dm
new file mode 100644
index 00000000000..808a213db51
--- /dev/null
+++ b/code/datums/quirks/positive_quirks/night_vision.dm
@@ -0,0 +1,28 @@
+/datum/quirk/night_vision
+ name = "Night Vision"
+ desc = "You can see slightly more clearly in full darkness than most people."
+ icon = FA_ICON_MOON
+ value = 4
+ mob_trait = TRAIT_NIGHT_VISION
+ gain_text = span_notice("The shadows seem a little less dark.")
+ lose_text = span_danger("Everything seems a little darker.")
+ medical_record_text = "Patient's eyes show above-average acclimation to darkness."
+ mail_goodies = list(
+ /obj/item/flashlight/flashdark,
+ /obj/item/food/grown/mushroom/glowshroom/shadowshroom,
+ /obj/item/skillchip/light_remover,
+ )
+
+/datum/quirk/night_vision/add(client/client_source)
+ refresh_quirk_holder_eyes()
+
+/datum/quirk/night_vision/remove()
+ refresh_quirk_holder_eyes()
+
+/datum/quirk/night_vision/proc/refresh_quirk_holder_eyes()
+ var/mob/living/carbon/human/human_quirk_holder = quirk_holder
+ var/obj/item/organ/internal/eyes/eyes = human_quirk_holder.get_organ_by_type(/obj/item/organ/internal/eyes)
+ if(!eyes || eyes.lighting_cutoff)
+ return
+ // We've either added or removed TRAIT_NIGHT_VISION before calling this proc. Just refresh the eyes.
+ eyes.refresh()
diff --git a/code/datums/quirks/positive_quirks/positive_quirks.dm b/code/datums/quirks/positive_quirks/positive_quirks.dm
deleted file mode 100644
index e49aed64ee6..00000000000
--- a/code/datums/quirks/positive_quirks/positive_quirks.dm
+++ /dev/null
@@ -1,397 +0,0 @@
-//predominantly positive traits
-//this file is named weirdly so that positive traits are listed above negative ones
-
-/datum/quirk/alcohol_tolerance
- name = "Alcohol Tolerance"
- desc = "You become drunk more slowly and suffer fewer drawbacks from alcohol."
- icon = FA_ICON_BEER
- value = 4
- mob_trait = TRAIT_ALCOHOL_TOLERANCE
- gain_text = span_notice("You feel like you could drink a whole keg!")
- lose_text = span_danger("You don't feel as resistant to alcohol anymore. Somehow.")
- medical_record_text = "Patient demonstrates a high tolerance for alcohol."
- mail_goodies = list(/obj/item/skillchip/wine_taster)
-
-/datum/quirk/apathetic
- name = "Apathetic"
- desc = "You just don't care as much as other people. That's nice to have in a place like this, I guess."
- icon = FA_ICON_MEH
- value = 4
- quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_MOODLET_BASED
- medical_record_text = "Patient was administered the Apathy Evaluation Scale but did not bother to complete it."
- mail_goodies = list(/obj/item/hourglass)
-
-/datum/quirk/apathetic/add(client/client_source)
- quirk_holder.mob_mood?.mood_modifier -= 0.2
-
-/datum/quirk/apathetic/remove()
- quirk_holder.mob_mood?.mood_modifier += 0.2
-
-/datum/quirk/drunkhealing
- name = "Drunken Resilience"
- desc = "Nothing like a good drink to make you feel on top of the world. Whenever you're drunk, you slowly recover from injuries."
- icon = FA_ICON_WINE_BOTTLE
- value = 8
- gain_text = span_notice("You feel like a drink would do you good.")
- lose_text = span_danger("You no longer feel like drinking would ease your pain.")
- medical_record_text = "Patient has unusually efficient liver metabolism and can slowly regenerate wounds by drinking alcoholic beverages."
- quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES
- mail_goodies = list(/obj/effect/spawner/random/food_or_drink/booze)
-
-/datum/quirk/drunkhealing/process(seconds_per_tick)
- switch(quirk_holder.get_drunk_amount())
- if (6 to 40)
- quirk_holder.adjustBruteLoss(-0.1 * seconds_per_tick, FALSE, required_bodytype = BODYTYPE_ORGANIC)
- quirk_holder.adjustFireLoss(-0.05 * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC)
- if (41 to 60)
- quirk_holder.adjustBruteLoss(-0.4 * seconds_per_tick, FALSE, required_bodytype = BODYTYPE_ORGANIC)
- quirk_holder.adjustFireLoss(-0.2 * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC)
- if (61 to INFINITY)
- quirk_holder.adjustBruteLoss(-0.8 * seconds_per_tick, FALSE, required_bodytype = BODYTYPE_ORGANIC)
- quirk_holder.adjustFireLoss(-0.4 * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC)
-
-/datum/quirk/empath
- name = "Empath"
- desc = "Whether it's a sixth sense or careful study of body language, it only takes you a quick glance at someone to understand how they feel."
- icon = FA_ICON_SMILE_BEAM
- value = 6 /// SKYRAT EDIT - Quirk Rebalance - Original: value = 8
- mob_trait = TRAIT_EMPATH
- gain_text = span_notice("You feel in tune with those around you.")
- lose_text = span_danger("You feel isolated from others.")
- medical_record_text = "Patient is highly perceptive of and sensitive to social cues, or may possibly have ESP. Further testing needed."
- mail_goodies = list(/obj/item/toy/foamfinger)
-
-/datum/quirk/item_quirk/clown_enjoyer
- name = "Clown Enjoyer"
- desc = "You enjoy clown antics and get a mood boost from wearing your clown pin."
- icon = FA_ICON_MAP_PIN
- value = 2
- mob_trait = TRAIT_CLOWN_ENJOYER
- gain_text = span_notice("You are a big enjoyer of clowns.")
- lose_text = span_danger("The clown doesn't seem so great.")
- medical_record_text = "Patient reports being a big enjoyer of clowns."
- mail_goodies = list(
- /obj/item/bikehorn,
- /obj/item/stamp/clown,
- /obj/item/megaphone/clown,
- /obj/item/clothing/shoes/clown_shoes,
- /obj/item/bedsheet/clown,
- /obj/item/clothing/mask/gas/clown_hat,
- /obj/item/storage/backpack/clown,
- /obj/item/storage/backpack/duffelbag/clown,
- /obj/item/toy/crayon/rainbow,
- /obj/item/toy/figure/clown,
- )
-
-/datum/quirk/item_quirk/clown_enjoyer/add_unique(client/client_source)
- give_item_to_holder(/obj/item/clothing/accessory/clown_enjoyer_pin, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
-
-/datum/quirk/item_quirk/clown_enjoyer/add(client/client_source)
- var/datum/atom_hud/fan = GLOB.huds[DATA_HUD_FAN]
- fan.show_to(quirk_holder)
-
-/datum/quirk/item_quirk/mime_fan
- name = "Mime Fan"
- desc = "You're a fan of mime antics and get a mood boost from wearing your mime pin."
- icon = FA_ICON_THUMBTACK
- value = 2
- mob_trait = TRAIT_MIME_FAN
- gain_text = span_notice("You are a big fan of the Mime.")
- lose_text = span_danger("The mime doesn't seem so great.")
- medical_record_text = "Patient reports being a big fan of mimes."
- mail_goodies = list(
- /obj/item/toy/crayon/mime,
- /obj/item/clothing/mask/gas/mime,
- /obj/item/storage/backpack/mime,
- /obj/item/clothing/under/rank/civilian/mime,
- /obj/item/reagent_containers/cup/glass/bottle/bottleofnothing,
- /obj/item/stamp/mime,
- /obj/item/storage/box/survival/hug/black,
- /obj/item/bedsheet/mime,
- /obj/item/clothing/shoes/sneakers/mime,
- /obj/item/toy/figure/mime,
- /obj/item/toy/crayon/spraycan/mimecan,
- )
-
-/datum/quirk/item_quirk/mime_fan/add_unique(client/client_source)
- give_item_to_holder(/obj/item/clothing/accessory/mime_fan_pin, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
-
-/datum/quirk/item_quirk/mime_fan/add(client/client_source)
- var/datum/atom_hud/fan = GLOB.huds[DATA_HUD_FAN]
- fan.show_to(quirk_holder)
-
-/datum/quirk/freerunning
- name = "Freerunning"
- desc = "You're great at quick moves! You can climb tables more quickly and take no damage from short falls."
- icon = FA_ICON_RUNNING
- value = 8
- mob_trait = TRAIT_FREERUNNING
- gain_text = span_notice("You feel lithe on your feet!")
- lose_text = span_danger("You feel clumsy again.")
- medical_record_text = "Patient scored highly on cardio tests."
- mail_goodies = list(/obj/item/melee/skateboard, /obj/item/clothing/shoes/wheelys/rollerskates)
-
-/datum/quirk/friendly
- name = "Friendly"
- desc = "You give the best hugs, especially when you're in the right mood."
- icon = FA_ICON_HANDS_HELPING
- value = 2
- mob_trait = TRAIT_FRIENDLY
- gain_text = span_notice("You want to hug someone.")
- lose_text = span_danger("You no longer feel compelled to hug others.")
- quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_MOODLET_BASED
- medical_record_text = "Patient demonstrates low-inhibitions for physical contact and well-developed arms. Requesting another doctor take over this case."
- mail_goodies = list(/obj/item/storage/box/hug)
-
-/datum/quirk/jolly
- name = "Jolly"
- desc = "You sometimes just feel happy, for no reason at all."
- icon = FA_ICON_GRIN
- value = 4
- mob_trait = TRAIT_JOLLY
- quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_MOODLET_BASED
- medical_record_text = "Patient demonstrates constant euthymia irregular for environment. It's a bit much, to be honest."
- mail_goodies = list(/obj/item/clothing/mask/joy)
-
-/datum/quirk/light_step
- name = "Light Step"
- desc = "You walk with a gentle step; footsteps and stepping on sharp objects is quieter and less painful. Also, your hands and clothes will not get messed in case of stepping in blood."
- icon = FA_ICON_SHOE_PRINTS
- value = 4
- mob_trait = TRAIT_LIGHT_STEP
- gain_text = span_notice("You walk with a little more litheness.")
- lose_text = span_danger("You start tromping around like a barbarian.")
- medical_record_text = "Patient's dexterity belies a strong capacity for stealth."
- mail_goodies = list(/obj/item/clothing/shoes/sandal)
-
-/datum/quirk/item_quirk/musician
- name = "Musician"
- desc = "You can tune handheld musical instruments to play melodies that clear certain negative effects and soothe the soul."
- icon = FA_ICON_GUITAR
- value = 2
- mob_trait = TRAIT_MUSICIAN
- gain_text = span_notice("You know everything about musical instruments.")
- lose_text = span_danger("You forget how musical instruments work.")
- medical_record_text = "Patient brain scans show a highly-developed auditory pathway."
- mail_goodies = list(/obj/effect/spawner/random/entertainment/musical_instrument, /obj/item/instrument/piano_synth/headphones)
-
-/datum/quirk/item_quirk/musician/add_unique(client/client_source)
- give_item_to_holder(/obj/item/choice_beacon/music, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
-
-/datum/quirk/night_vision
- name = "Night Vision"
- desc = "You can see slightly more clearly in full darkness than most people."
- icon = FA_ICON_MOON
- value = 4
- mob_trait = TRAIT_NIGHT_VISION
- gain_text = span_notice("The shadows seem a little less dark.")
- lose_text = span_danger("Everything seems a little darker.")
- medical_record_text = "Patient's eyes show above-average acclimation to darkness."
- mail_goodies = list(
- /obj/item/flashlight/flashdark,
- /obj/item/food/grown/mushroom/glowshroom/shadowshroom,
- /obj/item/skillchip/light_remover,
- )
-
-/datum/quirk/night_vision/add(client/client_source)
- refresh_quirk_holder_eyes()
-
-/datum/quirk/night_vision/remove()
- refresh_quirk_holder_eyes()
-
-/datum/quirk/night_vision/proc/refresh_quirk_holder_eyes()
- var/mob/living/carbon/human/human_quirk_holder = quirk_holder
- var/obj/item/organ/internal/eyes/eyes = human_quirk_holder.get_organ_by_type(/obj/item/organ/internal/eyes)
- if(!eyes || eyes.lighting_cutoff)
- return
- // We've either added or removed TRAIT_NIGHT_VISION before calling this proc. Just refresh the eyes.
- eyes.refresh()
-
-/datum/quirk/bilingual
- name = "Bilingual"
- desc = "Over the years you've picked up an extra language!"
- icon = FA_ICON_GLOBE
- value = 4
- gain_text = span_notice("Some of the words of the people around you certainly aren't common. Good thing you studied for this.")
- lose_text = span_notice("You seem to have forgotten your second language.")
- medical_record_text = "Patient speaks multiple languages."
- mail_goodies = list(/obj/item/taperecorder, /obj/item/clothing/head/frenchberet, /obj/item/clothing/mask/fakemoustache/italian)
-
-/datum/quirk/bilingual/add_unique(client/client_source)
- var/wanted_language = client_source?.prefs.read_preference(/datum/preference/choiced/language)
- var/datum/language/language_type
- if(wanted_language == "Random")
- language_type = pick(GLOB.uncommon_roundstart_languages)
- else
- language_type = GLOB.language_types_by_name[wanted_language]
- if(quirk_holder.has_language(language_type))
- language_type = /datum/language/uncommon
- if(quirk_holder.has_language(language_type))
- to_chat(quirk_holder, span_boldnotice("You are already familiar with the quirk in your preferences, so you did not learn one."))
- return
- to_chat(quirk_holder, span_boldnotice("You are already familiar with the quirk in your preferences, so you learned Galactic Uncommon instead."))
- quirk_holder.grant_language(language_type, source = LANGUAGE_QUIRK)
-
-/datum/quirk/item_quirk/poster_boy
- name = "Poster Boy"
- desc = "You have some great posters! Hang them up and make everyone have a great time."
- icon = FA_ICON_TAPE
- value = 4
- mob_trait = TRAIT_POSTERBOY
- medical_record_text = "Patient reports a desire to cover walls with homemade objects."
- mail_goodies = list(/obj/item/poster/random_official)
-
-/datum/quirk/item_quirk/poster_boy/add_unique()
- var/mob/living/carbon/human/posterboy = quirk_holder
- var/obj/item/storage/box/posterbox/newbox = new()
- newbox.add_quirk_posters(posterboy.mind)
- give_item_to_holder(newbox, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
-
-/obj/item/storage/box/posterbox
- name = "Box of Posters"
- desc = "You made them yourself!"
-
-/// fills box of posters based on job, one neutral poster and 2 department posters
-/obj/item/storage/box/posterbox/proc/add_quirk_posters(datum/mind/posterboy)
- new /obj/item/poster/quirk/crew/random(src)
- var/department = posterboy.assigned_role.paycheck_department
- if(department == ACCOUNT_CIV) //if you are not part of a department you instead get 3 neutral posters
- for(var/i in 1 to 2)
- new /obj/item/poster/quirk/crew/random(src)
- return
- for(var/obj/item/poster/quirk/potential_poster as anything in subtypesof(/obj/item/poster/quirk))
- if(initial(potential_poster.quirk_poster_department) != department)
- continue
- new potential_poster(src)
-
-/datum/quirk/selfaware
- name = "Self-Aware"
- desc = "You know your body well, and can accurately assess the extent of your wounds."
- icon = FA_ICON_BONE
- value = 8
- mob_trait = TRAIT_SELF_AWARE
- medical_record_text = "Patient demonstrates an uncanny knack for self-diagnosis."
- mail_goodies = list(/obj/item/clothing/neck/stethoscope, /obj/item/skillchip/entrails_reader)
-
-/datum/quirk/skittish
- name = "Skittish"
- desc = "You're easy to startle, and hide frequently. Run into a closed locker to jump into it, as long as you have access. You can walk to avoid this."
- icon = FA_ICON_TRASH
- value = 8
- mob_trait = TRAIT_SKITTISH
- medical_record_text = "Patient demonstrates a high aversion to danger and has described hiding in containers out of fear."
- mail_goodies = list(/obj/structure/closet/cardboard)
-
-/datum/quirk/item_quirk/spiritual
- name = "Spiritual"
- desc = "You hold a spiritual belief, whether in God, nature or the arcane rules of the universe. You gain comfort from the presence of holy people, and believe that your prayers are more special than others. Being in the chapel makes you happy."
- icon = FA_ICON_BIBLE
- value = 2 /// SKYRAT EDIT - Quirk Rebalance - Original: value = 4
- mob_trait = TRAIT_SPIRITUAL
- gain_text = span_notice("You have faith in a higher power.")
- lose_text = span_danger("You lose faith!")
- medical_record_text = "Patient reports a belief in a higher power."
- mail_goodies = list(
- /obj/item/book/bible/booze,
- /obj/item/reagent_containers/cup/glass/bottle/holywater,
- /obj/item/bedsheet/chaplain,
- /obj/item/toy/cards/deck/tarot,
- /obj/item/storage/fancy/candle_box,
- )
-
-/datum/quirk/item_quirk/spiritual/add_unique(client/client_source)
- give_item_to_holder(/obj/item/storage/fancy/candle_box, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
- give_item_to_holder(/obj/item/storage/box/matches, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
-
-/datum/quirk/item_quirk/tagger
- name = "Tagger"
- desc = "You're an experienced artist. People will actually be impressed by your graffiti, and you can get twice as many uses out of drawing supplies."
- icon = FA_ICON_SPRAY_CAN
- value = 4
- mob_trait = TRAIT_TAGGER
- gain_text = span_notice("You know how to tag walls efficiently.")
- lose_text = span_danger("You forget how to tag walls properly.")
- medical_record_text = "Patient was recently seen for possible paint huffing incident."
- mail_goodies = list(
- /obj/item/toy/crayon/spraycan,
- /obj/item/canvas/nineteen_nineteen,
- /obj/item/canvas/twentythree_nineteen,
- /obj/item/canvas/twentythree_twentythree
- )
-
-/datum/quirk/item_quirk/tagger/add_unique(client/client_source)
- var/obj/item/toy/crayon/spraycan/can = new
- can.set_painting_tool_color(client_source?.prefs.read_preference(/datum/preference/color/paint_color))
- give_item_to_holder(can, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
-
-/datum/quirk/throwingarm
- name = "Throwing Arm"
- desc = "Your arms have a lot of heft to them! Objects that you throw just always seem to fly further than everyone elses, and you never miss a toss."
- icon = FA_ICON_BASEBALL
- value = 7
- mob_trait = TRAIT_THROWINGARM
- gain_text = span_notice("Your arms are full of energy!")
- lose_text = span_danger("Your arms ache a bit.")
- medical_record_text = "Patient displays mastery over throwing balls."
- mail_goodies = list(/obj/item/toy/beach_ball/baseball, /obj/item/toy/basketball, /obj/item/toy/dodgeball)
-
-/datum/quirk/voracious
- name = "Voracious"
- desc = "Nothing gets between you and your food. You eat faster and can binge on junk food! Being fat suits you just fine."
- icon = FA_ICON_DRUMSTICK_BITE
- value = 4
- mob_trait = TRAIT_VORACIOUS
- gain_text = span_notice("You feel HONGRY.")
- lose_text = span_danger("You no longer feel HONGRY.")
- mail_goodies = list(/obj/effect/spawner/random/food_or_drink/dinner)
-
-/datum/quirk/item_quirk/signer
- name = "Signer"
- desc = "You possess excellent communication skills in sign language."
- icon = FA_ICON_HANDS
- value = 4
- quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE
- mail_goodies = list(/obj/item/clothing/gloves/radio)
-
-/datum/quirk/item_quirk/signer/add_unique(client/client_source)
- quirk_holder.AddComponent(/datum/component/sign_language)
- var/obj/item/clothing/gloves/gloves_type = /obj/item/clothing/gloves/radio
- if(isplasmaman(quirk_holder))
- gloves_type = /obj/item/clothing/gloves/color/plasmaman/radio
- give_item_to_holder(gloves_type, list(LOCATION_GLOVES = ITEM_SLOT_GLOVES, LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
-
-/datum/quirk/item_quirk/signer/remove()
- qdel(quirk_holder.GetComponent(/datum/component/sign_language))
-
-/datum/quirk/item_quirk/settler
- name = "Settler"
- desc = "You are from a lineage of the earliest space settlers! While your family's generational exposure to varying gravity \
- has resulted in a ... smaller height than is typical for your species, you make up for it by being much better at outdoorsmanship and \
- carrying heavy equipment. You also get along great with animals. However, you are a bit on the slow side due to your small legs."
- gain_text = span_bold("You feel like the world is your oyster!")
- lose_text = span_danger("You think you might stay home today.")
- icon = FA_ICON_HOUSE
- value = 4
- mob_trait = TRAIT_SETTLER
- quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE
- medical_record_text = "Patient appears to be abnormally stout."
- mail_goodies = list(
- /obj/item/clothing/shoes/workboots/mining,
- /obj/item/gps,
- )
-
-/datum/quirk/item_quirk/settler/add_unique(client/client_source)
- give_item_to_holder(/obj/item/storage/box/papersack/wheat, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
- give_item_to_holder(/obj/item/storage/toolbox/fishing/small, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
- var/mob/living/carbon/human/human_quirkholder = quirk_holder
- human_quirkholder.set_mob_height(HUMAN_HEIGHT_SHORTEST)
- human_quirkholder.add_movespeed_modifier(/datum/movespeed_modifier/settler)
- human_quirkholder.physiology.hunger_mod *= 0.5 //good for you, shortass, you don't get hungry nearly as often
-
-/datum/quirk/item_quirk/settler/remove()
- if(QDELING(quirk_holder))
- return
- var/mob/living/carbon/human/human_quirkholder = quirk_holder
- human_quirkholder.set_mob_height(HUMAN_HEIGHT_MEDIUM)
- human_quirkholder.remove_movespeed_modifier(/datum/movespeed_modifier/settler)
- human_quirkholder.physiology.hunger_mod *= 2
diff --git a/code/datums/quirks/positive_quirks/poster_boy.dm b/code/datums/quirks/positive_quirks/poster_boy.dm
new file mode 100644
index 00000000000..4991ebc540b
--- /dev/null
+++ b/code/datums/quirks/positive_quirks/poster_boy.dm
@@ -0,0 +1,31 @@
+/datum/quirk/item_quirk/poster_boy
+ name = "Poster Boy"
+ desc = "You have some great posters! Hang them up and make everyone have a great time."
+ icon = FA_ICON_TAPE
+ value = 4
+ mob_trait = TRAIT_POSTERBOY
+ medical_record_text = "Patient reports a desire to cover walls with homemade objects."
+ mail_goodies = list(/obj/item/poster/random_official)
+
+/datum/quirk/item_quirk/poster_boy/add_unique()
+ var/mob/living/carbon/human/posterboy = quirk_holder
+ var/obj/item/storage/box/posterbox/newbox = new()
+ newbox.add_quirk_posters(posterboy.mind)
+ give_item_to_holder(newbox, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
+
+/obj/item/storage/box/posterbox
+ name = "Box of Posters"
+ desc = "You made them yourself!"
+
+/// fills box of posters based on job, one neutral poster and 2 department posters
+/obj/item/storage/box/posterbox/proc/add_quirk_posters(datum/mind/posterboy)
+ new /obj/item/poster/quirk/crew/random(src)
+ var/department = posterboy.assigned_role.paycheck_department
+ if(department == ACCOUNT_CIV) //if you are not part of a department you instead get 3 neutral posters
+ for(var/i in 1 to 2)
+ new /obj/item/poster/quirk/crew/random(src)
+ return
+ for(var/obj/item/poster/quirk/potential_poster as anything in subtypesof(/obj/item/poster/quirk))
+ if(initial(potential_poster.quirk_poster_department) != department)
+ continue
+ new potential_poster(src)
diff --git a/code/datums/quirks/positive_quirks/self_aware.dm b/code/datums/quirks/positive_quirks/self_aware.dm
new file mode 100644
index 00000000000..022d08659ef
--- /dev/null
+++ b/code/datums/quirks/positive_quirks/self_aware.dm
@@ -0,0 +1,8 @@
+/datum/quirk/selfaware
+ name = "Self-Aware"
+ desc = "You know your body well, and can accurately assess the extent of your wounds."
+ icon = FA_ICON_BONE
+ value = 8
+ mob_trait = TRAIT_SELF_AWARE
+ medical_record_text = "Patient demonstrates an uncanny knack for self-diagnosis."
+ mail_goodies = list(/obj/item/clothing/neck/stethoscope, /obj/item/skillchip/entrails_reader)
diff --git a/code/datums/quirks/positive_quirks/settler.dm b/code/datums/quirks/positive_quirks/settler.dm
new file mode 100644
index 00000000000..81402c050cd
--- /dev/null
+++ b/code/datums/quirks/positive_quirks/settler.dm
@@ -0,0 +1,32 @@
+/datum/quirk/item_quirk/settler
+ name = "Settler"
+ desc = "You are from a lineage of the earliest space settlers! While your family's generational exposure to varying gravity \
+ has resulted in a ... smaller height than is typical for your species, you make up for it by being much better at outdoorsmanship and \
+ carrying heavy equipment. You also get along great with animals. However, you are a bit on the slow side due to your small legs."
+ gain_text = span_bold("You feel like the world is your oyster!")
+ lose_text = span_danger("You think you might stay home today.")
+ icon = FA_ICON_HOUSE
+ value = 4
+ mob_trait = TRAIT_SETTLER
+ quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE
+ medical_record_text = "Patient appears to be abnormally stout."
+ mail_goodies = list(
+ /obj/item/clothing/shoes/workboots/mining,
+ /obj/item/gps,
+ )
+
+/datum/quirk/item_quirk/settler/add_unique(client/client_source)
+ give_item_to_holder(/obj/item/storage/box/papersack/wheat, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
+ give_item_to_holder(/obj/item/storage/toolbox/fishing/small, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
+ var/mob/living/carbon/human/human_quirkholder = quirk_holder
+ human_quirkholder.set_mob_height(HUMAN_HEIGHT_SHORTEST)
+ human_quirkholder.add_movespeed_modifier(/datum/movespeed_modifier/settler)
+ human_quirkholder.physiology.hunger_mod *= 0.5 //good for you, shortass, you don't get hungry nearly as often
+
+/datum/quirk/item_quirk/settler/remove()
+ if(QDELING(quirk_holder))
+ return
+ var/mob/living/carbon/human/human_quirkholder = quirk_holder
+ human_quirkholder.set_mob_height(HUMAN_HEIGHT_MEDIUM)
+ human_quirkholder.remove_movespeed_modifier(/datum/movespeed_modifier/settler)
+ human_quirkholder.physiology.hunger_mod *= 2
diff --git a/code/datums/quirks/positive_quirks/signer.dm b/code/datums/quirks/positive_quirks/signer.dm
new file mode 100644
index 00000000000..df0a2f34c5d
--- /dev/null
+++ b/code/datums/quirks/positive_quirks/signer.dm
@@ -0,0 +1,17 @@
+/datum/quirk/item_quirk/signer
+ name = "Signer"
+ desc = "You possess excellent communication skills in sign language."
+ icon = FA_ICON_HANDS
+ value = 4
+ quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE
+ mail_goodies = list(/obj/item/clothing/gloves/radio)
+
+/datum/quirk/item_quirk/signer/add_unique(client/client_source)
+ quirk_holder.AddComponent(/datum/component/sign_language)
+ var/obj/item/clothing/gloves/gloves_type = /obj/item/clothing/gloves/radio
+ if(isplasmaman(quirk_holder))
+ gloves_type = /obj/item/clothing/gloves/color/plasmaman/radio
+ give_item_to_holder(gloves_type, list(LOCATION_GLOVES = ITEM_SLOT_GLOVES, LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
+
+/datum/quirk/item_quirk/signer/remove()
+ qdel(quirk_holder.GetComponent(/datum/component/sign_language))
diff --git a/code/datums/quirks/positive_quirks/skittish.dm b/code/datums/quirks/positive_quirks/skittish.dm
new file mode 100644
index 00000000000..24bbac8e556
--- /dev/null
+++ b/code/datums/quirks/positive_quirks/skittish.dm
@@ -0,0 +1,8 @@
+/datum/quirk/skittish
+ name = "Skittish"
+ desc = "You're easy to startle, and hide frequently. Run into a closed locker to jump into it, as long as you have access. You can walk to avoid this."
+ icon = FA_ICON_TRASH
+ value = 8
+ mob_trait = TRAIT_SKITTISH
+ medical_record_text = "Patient demonstrates a high aversion to danger and has described hiding in containers out of fear."
+ mail_goodies = list(/obj/structure/closet/cardboard)
diff --git a/code/datums/quirks/positive_quirks/spacer.dm b/code/datums/quirks/positive_quirks/spacer.dm
index 4e0adcf73cd..24dc91fa627 100644
--- a/code/datums/quirks/positive_quirks/spacer.dm
+++ b/code/datums/quirks/positive_quirks/spacer.dm
@@ -15,6 +15,8 @@
/obj/item/storage/pill_bottle/ondansetron,
/obj/item/reagent_containers/pill/gravitum,
)
+ /// How high spacers get bumped up to
+ var/modded_height = HUMAN_HEIGHT_TALLER
/// How long on a planet before we get averse effects
var/planet_period = 3 MINUTES
/// TimerID for time spend on a planet
@@ -44,7 +46,7 @@
quirk_holder.inertia_move_delay *= 0.8
var/mob/living/carbon/human/human_quirker = quirk_holder
- human_quirker.set_mob_height(HUMAN_HEIGHT_TALLEST)
+ human_quirker.set_mob_height(modded_height)
human_quirker.physiology.pressure_mod *= 0.8
human_quirker.physiology.cold_mod *= 0.8
diff --git a/code/datums/quirks/positive_quirks/spiritual.dm b/code/datums/quirks/positive_quirks/spiritual.dm
new file mode 100644
index 00000000000..b08fe8b60c6
--- /dev/null
+++ b/code/datums/quirks/positive_quirks/spiritual.dm
@@ -0,0 +1,20 @@
+/datum/quirk/item_quirk/spiritual
+ name = "Spiritual"
+ desc = "You hold a spiritual belief, whether in God, nature or the arcane rules of the universe. You gain comfort from the presence of holy people, and believe that your prayers are more special than others. Being in the chapel makes you happy."
+ icon = FA_ICON_BIBLE
+ value = 2 /// SKYRAT EDIT - Quirk Rebalance - Original: value = 4
+ mob_trait = TRAIT_SPIRITUAL
+ gain_text = span_notice("You have faith in a higher power.")
+ lose_text = span_danger("You lose faith!")
+ medical_record_text = "Patient reports a belief in a higher power."
+ mail_goodies = list(
+ /obj/item/book/bible/booze,
+ /obj/item/reagent_containers/cup/glass/bottle/holywater,
+ /obj/item/bedsheet/chaplain,
+ /obj/item/toy/cards/deck/tarot,
+ /obj/item/storage/fancy/candle_box,
+ )
+
+/datum/quirk/item_quirk/spiritual/add_unique(client/client_source)
+ give_item_to_holder(/obj/item/storage/fancy/candle_box, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
+ give_item_to_holder(/obj/item/storage/box/matches, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
diff --git a/code/datums/quirks/positive_quirks/tagger.dm b/code/datums/quirks/positive_quirks/tagger.dm
new file mode 100644
index 00000000000..5aba24d850a
--- /dev/null
+++ b/code/datums/quirks/positive_quirks/tagger.dm
@@ -0,0 +1,20 @@
+/datum/quirk/item_quirk/tagger
+ name = "Tagger"
+ desc = "You're an experienced artist. People will actually be impressed by your graffiti, and you can get twice as many uses out of drawing supplies."
+ icon = FA_ICON_SPRAY_CAN
+ value = 4
+ mob_trait = TRAIT_TAGGER
+ gain_text = span_notice("You know how to tag walls efficiently.")
+ lose_text = span_danger("You forget how to tag walls properly.")
+ medical_record_text = "Patient was recently seen for possible paint huffing incident."
+ mail_goodies = list(
+ /obj/item/toy/crayon/spraycan,
+ /obj/item/canvas/nineteen_nineteen,
+ /obj/item/canvas/twentythree_nineteen,
+ /obj/item/canvas/twentythree_twentythree
+ )
+
+/datum/quirk/item_quirk/tagger/add_unique(client/client_source)
+ var/obj/item/toy/crayon/spraycan/can = new
+ can.set_painting_tool_color(client_source?.prefs.read_preference(/datum/preference/color/paint_color))
+ give_item_to_holder(can, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
diff --git a/code/datums/quirks/positive_quirks/throwing_arm.dm b/code/datums/quirks/positive_quirks/throwing_arm.dm
new file mode 100644
index 00000000000..5157b399009
--- /dev/null
+++ b/code/datums/quirks/positive_quirks/throwing_arm.dm
@@ -0,0 +1,10 @@
+/datum/quirk/throwingarm
+ name = "Throwing Arm"
+ desc = "Your arms have a lot of heft to them! Objects that you throw just always seem to fly further than everyone elses, and you never miss a toss."
+ icon = FA_ICON_BASEBALL
+ value = 7
+ mob_trait = TRAIT_THROWINGARM
+ gain_text = span_notice("Your arms are full of energy!")
+ lose_text = span_danger("Your arms ache a bit.")
+ medical_record_text = "Patient displays mastery over throwing balls."
+ mail_goodies = list(/obj/item/toy/beach_ball/baseball, /obj/item/toy/basketball, /obj/item/toy/dodgeball)
diff --git a/code/datums/quirks/positive_quirks/voracious.dm b/code/datums/quirks/positive_quirks/voracious.dm
new file mode 100644
index 00000000000..68073304f0d
--- /dev/null
+++ b/code/datums/quirks/positive_quirks/voracious.dm
@@ -0,0 +1,9 @@
+/datum/quirk/voracious
+ name = "Voracious"
+ desc = "Nothing gets between you and your food. You eat faster and can binge on junk food! Being fat suits you just fine."
+ icon = FA_ICON_DRUMSTICK_BITE
+ value = 4
+ mob_trait = TRAIT_VORACIOUS
+ gain_text = span_notice("You feel HONGRY.")
+ lose_text = span_danger("You no longer feel HONGRY.")
+ mail_goodies = list(/obj/effect/spawner/random/food_or_drink/dinner)
diff --git a/code/datums/ruins/lavaland.dm b/code/datums/ruins/lavaland.dm
index 69e2d10a67f..968e6df544e 100644
--- a/code/datums/ruins/lavaland.dm
+++ b/code/datums/ruins/lavaland.dm
@@ -278,3 +278,11 @@
suffix = "lavaland_surface_phonebooth.dmm"
allow_duplicates = FALSE
cost = 5
+
+/datum/map_template/ruin/lavaland/battle_site
+ name = "Battle Site"
+ id = "battle_site"
+ description = "The long past site of a battle between beast and humanoids. The victor is unknown, but the losers are clear."
+ suffix = "lavaland_battle_site.dmm"
+ allow_duplicates = TRUE
+ cost = 3
diff --git a/code/datums/ruins/space.dm b/code/datums/ruins/space.dm
index 8e28c164340..022b0d72504 100644
--- a/code/datums/ruins/space.dm
+++ b/code/datums/ruins/space.dm
@@ -126,6 +126,12 @@
name = "Derelict 8"
description = "An auxiliary storage bay might be the least respected room on any functional station, but studies show they are the least likely to be hit in an artillery strike."
+/datum/map_template/ruin/space/derelict9
+ id = "derelict9"
+ suffix = "derelict9.dmm"
+ name = "Derelict 9"
+ description = "Someone already found this high-security supply cache already, but were unable to get inside. Perhaps the next visitor will have more luck."
+
/datum/map_template/ruin/space/empty_shell
id = "empty-shell"
suffix = "emptyshell.dmm"
diff --git a/code/datums/shuttles/emergency.dm b/code/datums/shuttles/emergency.dm
index af87dc641d8..5e8553c69ee 100644
--- a/code/datums/shuttles/emergency.dm
+++ b/code/datums/shuttles/emergency.dm
@@ -3,12 +3,42 @@
/datum/map_template/shuttle/emergency // SKYRAT EDIT OVERRIDE - OVERRIDEN IN ADVANCED_SHUTTLES - shuttles.dm
port_id = "emergency"
name = "Base Shuttle Template (Emergency)"
+ ///assoc list of shuttle events to add to this shuttle on spawn (typepath = weight)
+ var/list/events
+ ///pick all events instead of random
+ var/use_all_events = FALSE
+ ///how many do we pick
+ var/event_amount = 1
+ ///do we empty the event list before adding our events
+ var/events_override = FALSE
/datum/map_template/shuttle/emergency/New()
. = ..()
if(!occupancy_limit && who_can_purchase)
CRASH("The [name] needs an occupancy limit!")
+ if(HAS_TRAIT(SSstation, STATION_TRAIT_SHUTTLE_SALE) && credit_cost > 0 && prob(15))
+ var/discount_amount = round(rand(25, 80), 5)
+ name += " ([discount_amount]% Discount!)"
+ var/discount_multiplier = 100 - discount_amount
+ credit_cost = ((credit_cost * discount_multiplier) / 100)
+///on post_load use our variables to change shuttle events
+/datum/map_template/shuttle/emergency/post_load(obj/docking_port/mobile/mobile)
+ . = ..()
+ if(!events)
+ return
+ if(events_override)
+ mobile.event_list.Cut()
+ if(use_all_events)
+ for(var/path in events)
+ mobile.event_list.Add(new path(mobile))
+ events -= path
+ else
+ for(var/i in 1 to event_amount)
+ var/path = pick_weight(events)
+ events -= path
+ mobile.event_list.Add(new path(mobile))
+
/datum/map_template/shuttle/emergency/backup
prefix = "_maps/shuttles/"
suffix = "backup"
@@ -44,6 +74,19 @@
credit_cost = CARGO_CRATE_VALUE * 10
occupancy_limit = "45"
+/datum/map_template/shuttle/emergency/humpback
+ suffix = "humpback"
+ name = "Humpback Emergency Shuttle"
+ description = "A repurposed cargo hauling and salvaging ship, for sightseeing and tourism. Has a bar. Complete with a 2 minute vacation plan to carp territory."
+ credit_cost = CARGO_CRATE_VALUE * 12
+ occupancy_limit = "30"
+ events = list(
+ /datum/shuttle_event/simple_spawner/carp/friendly = 10,
+ /datum/shuttle_event/simple_spawner/carp/friendly_but_no_personal_space = 2,
+ /datum/shuttle_event/simple_spawner/carp = 2,
+ /datum/shuttle_event/simple_spawner/carp/magic = 1,
+ )
+
/datum/map_template/shuttle/emergency/bar
suffix = "bar"
name = "The Emergency Escape Bar"
diff --git a/code/datums/shuttles/pirate.dm b/code/datums/shuttles/pirate.dm
index 27360a92cf4..c6f94b5684b 100644
--- a/code/datums/shuttles/pirate.dm
+++ b/code/datums/shuttles/pirate.dm
@@ -15,7 +15,7 @@
name = "pirate ship (Flying Dutchman)"
/datum/map_template/shuttle/pirate/interdyne
- suffix = "interdyne"
+ suffix = "ex_interdyne"
name = "pirate ship (Pharmaceutics Biocraft)"
/datum/map_template/shuttle/pirate/grey
diff --git a/code/datums/sprite_accessories.dm b/code/datums/sprite_accessories.dm
index 22e2473f2e4..16ce537b840 100644
--- a/code/datums/sprite_accessories.dm
+++ b/code/datums/sprite_accessories.dm
@@ -1162,6 +1162,8 @@
use_static = TRUE
+
+/* SKYRAT EDIT REMOVAL START - Underwear and bra split
//FEMALE UNDERWEAR
/datum/sprite_accessory/underwear/female_bikini
name = "Bikini"
@@ -1263,6 +1265,7 @@
icon_state = "female_kinky"
gender = FEMALE
use_static = TRUE
+*/ // SKYRAT EDIT END
////////////////////////////
// Undershirt Definitions //
@@ -1458,7 +1461,7 @@
name = "Short-sleeved Shirt (White)"
icon_state = "whiteshortsleeve"
gender = NEUTER
-
+/* SKYRAT EDIT REMOVAL START - Underwear and bra split
/datum/sprite_accessory/undershirt/sports_bra
name = "Sports Bra"
icon_state = "sports_bra"
@@ -1468,7 +1471,7 @@
name = "Sports Bra (Alt)"
icon_state = "sports_bra_alt"
gender = NEUTER
-
+*/ // SKYRAT EDIT END
/datum/sprite_accessory/undershirt/blueshirtsport
name = "Sports Shirt (Blue)"
icon_state = "blueshirtsport"
diff --git a/code/datums/station_traits/_station_trait.dm b/code/datums/station_traits/_station_trait.dm
index e42ce87f3e5..1205673c565 100644
--- a/code/datums/station_traits/_station_trait.dm
+++ b/code/datums/station_traits/_station_trait.dm
@@ -52,7 +52,7 @@
///type of info the centcom report has on this trait, if any.
/datum/station_trait/proc/get_report()
- return "[name] - [report_message]"
+ return "[name] - [report_message]"
/// Will attempt to revert the station trait, used by admins.
/datum/station_trait/proc/revert()
diff --git a/code/datums/station_traits/negative_traits.dm b/code/datums/station_traits/negative_traits.dm
index 86724170a96..f6e3ffbdd51 100644
--- a/code/datums/station_traits/negative_traits.dm
+++ b/code/datums/station_traits/negative_traits.dm
@@ -509,9 +509,6 @@
nebula.add_shielder(shielder, shielding_proc)
-/// Name of the glow we use for the radioation effect outside
-#define GLOW_NEBULA "glow_nebula"
-
///The station will be inside a radioactive nebula! Space is radioactive and the station needs to start setting up nebula shielding
/datum/station_trait/nebula/hostile/radiation
name = "Radioactive Nebula"
@@ -549,7 +546,7 @@
. = ..()
for(var/area/target as anything in get_areas(radioactive_areas))
- RegisterSignals(target, list(COMSIG_AREA_ENTERED, COMSIG_AREA_INITIALIZED_IN), PROC_REF(on_entered))
+ RegisterSignal(target, COMSIG_AREA_ENTERED, PROC_REF(on_entered))
RegisterSignal(target, COMSIG_AREA_EXITED, PROC_REF(on_exited))
/datum/station_trait/nebula/hostile/radiation/on_round_start()
@@ -581,27 +578,18 @@
/datum/station_trait/nebula/hostile/radiation/proc/on_entered(area/space, atom/movable/enterer, area/old_area)
SIGNAL_HANDLER
- if(iscarbon(enterer))//Don't actually make EVERY. SINGLE. THING. RADIOACTIVE. Just irradiate people
- if(!istype(old_area, radioactive_areas)) //old area wasnt radioactive
- enterer.AddComponent( \
- /datum/component/radioactive_exposure, \
- minimum_exposure_time = NEBULA_RADIATION_MINIMUM_EXPOSURE_TIME, \
- irradiation_chance_base = RADIATION_EXPOSURE_NEBULA_BASE_CHANCE, \
- irradiation_chance_increment = RADIATION_EXPOSURE_NEBULA_CHANCE_INCREMENT, \
- irradiation_interval = RADIATION_EXPOSURE_NEBULA_CHECK_INTERVAL, \
- source = src, \
- radioactive_areas = radioactive_areas, \
- )
+ // Old area was radioactive, so what's the point. nothing changes. nothing ever does. also make sure the subsystem is alive before we give it food
+ if (istype(old_area, radioactive_areas) || !SSradioactive_nebula.initialized)
+ return
- else if(isobj(enterer)) //and fake the rest
- //outline clashes too much with other outlines and creates pretty ugly lines
- enterer.add_filter(GLOW_NEBULA, 2, list("type" = "drop_shadow", "color" = nebula_radglow, "size" = 2))
+ SSradioactive_nebula.fake_irradiate(enterer)
///Called when an atom leaves space, so we can remove the radiation effect
/datum/station_trait/nebula/hostile/radiation/proc/on_exited(area/space, atom/movable/exiter, direction)
SIGNAL_HANDLER
- exiter.remove_filter(GLOW_NEBULA)
+ SSradioactive_nebula.fake_unirradiate(exiter)
+
// The component handles its own removal
/datum/station_trait/nebula/hostile/radiation/apply_nebula_effect(effect_strength = 0)
diff --git a/code/datums/station_traits/positive_traits.dm b/code/datums/station_traits/positive_traits.dm
index 0b5a2df246c..165cc4c2ad4 100644
--- a/code/datums/station_traits/positive_traits.dm
+++ b/code/datums/station_traits/positive_traits.dm
@@ -355,5 +355,79 @@
trait_to_give = STATION_TRAIT_BIGGER_PODS
blacklist = list(/datum/station_trait/cramped_escape_pods)
+/datum/station_trait/medbot_mania
+ name = "Advanced Medbots"
+ trait_type = STATION_TRAIT_POSITIVE
+ weight = 5
+ show_in_report = TRUE
+ report_message = "Your station's medibots have recieved a hardware upgrade, enabling expanded healing capabilities."
+ trait_to_give = STATION_TRAIT_MEDBOT_MANIA
+
+/datum/station_trait/random_event_weight_modifier/shuttle_loans
+ name = "Loaner Shuttle"
+ report_message = "Due to an uptick in pirate attacks around your sector, there are few supply vessels in nearby space willing to assist with special requests. Expect to recieve more shuttle loan opportunities, with slightly higher payouts."
+ trait_type = STATION_TRAIT_POSITIVE
+ weight = 4
+ event_control_path = /datum/round_event_control/shuttle_loan
+ weight_multiplier = 2.5
+ max_occurrences_modifier = 5 //All but one loan event will occur over the course of a round.
+ trait_to_give = STATION_TRAIT_LOANER_SHUTTLE
+
+/datum/station_trait/random_event_weight_modifier/wise_cows
+ name = "Wise Cow Invasion"
+ report_message = "Bluespace harmonic readings show unusual interpolative signals between your sector and agricultural sector MMF-D-02. Expect an increase in cow encounters. Encownters, if you will."
+ trait_type = STATION_TRAIT_POSITIVE
+ weight = 1
+ event_control_path = /datum/round_event_control/wisdomcow
+ weight_multiplier = 3
+ max_occurrences_modifier = 10 //lotta cows
+
+/datum/station_trait/shuttle_sale
+ name = "Shuttle Firesale"
+ report_message = "The Nanotrasen Emergency Dispatch team is celebrating a record number of shuttle calls in the recent quarter. Some of your emergency shuttle options have been discounted!"
+ trait_type = STATION_TRAIT_POSITIVE
+ weight = 4
+ trait_to_give = STATION_TRAIT_SHUTTLE_SALE
+ show_in_report = TRUE
+
+/datum/station_trait/missing_wallet
+ name = "Misplaced Wallet"
+ report_message = "A repair technician left their wallet in a locker somewhere. They would greatly appreciate if you could locate and return it to them when the shift has ended."
+ trait_type = STATION_TRAIT_POSITIVE
+ weight = 5
+ show_in_report = TRUE
+
+/datum/station_trait/missing_wallet/on_round_start()
+ . = ..()
+
+ var/obj/structure/closet/locker_to_fill = pick(GLOB.roundstart_station_closets)
+
+ var/obj/item/storage/wallet/new_wallet = new(locker_to_fill)
+
+ new /obj/item/stack/spacecash/c500(new_wallet)
+ if(prob(25)) //Jackpot!
+ new /obj/item/stack/spacecash/c1000(new_wallet)
+
+ new /obj/item/card/id/advanced/technician_id(new_wallet)
+ new_wallet.refreshID()
+
+ if(prob(35))
+ report_message += " The technician reports they last remember having their wallet around [get_area_name(new_wallet)]."
+
+ message_admins("A missing wallet has been placed in the [locker_to_fill] locker, in the [get_area_name(locker_to_fill)] area.")
+
+/obj/item/card/id/advanced/technician_id
+ name = "Repair Technician ID"
+ desc = "Repair Technician? We don't have those in this sector, just a bunch of lazy engineers! This must have been from the between-shift crew..."
+ registered_name = "Pluoxium LXVII"
+ registered_age = 67
+ trim = /datum/id_trim/technician_id
+
+/datum/id_trim/technician_id
+ access = list(ACCESS_EXTERNAL_AIRLOCKS, ACCESS_MAINT_TUNNELS)
+ assignment = "Repair Technician"
+ trim_state = "trim_stationengineer"
+ department_color = COLOR_ASSISTANT_GRAY
+
#undef PARTY_COOLDOWN_LENGTH_MIN
#undef PARTY_COOLDOWN_LENGTH_MAX
diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm
index ba54c1b7604..b9747d54acc 100644
--- a/code/datums/status_effects/buffs.dm
+++ b/code/datums/status_effects/buffs.dm
@@ -455,3 +455,65 @@
name = "Nest Vitalization"
desc = "The resin seems to pulsate around you. It seems to be sustaining your vital functions. You feel ill..."
icon_state = "nest_life"
+
+/**
+ * Granted to wizards upon satisfying the cheese sacrifice during grand rituals.
+ * Halves incoming damage and makes the owner stun immune, damage slow immune, levitating(even in space and hyperspace!) and glowing.
+ */
+/datum/status_effect/blessing_of_insanity
+ id = "blessing_of_insanity"
+ duration = -1
+ tick_interval = -1
+ alert_type = /atom/movable/screen/alert/status_effect/blessing_of_insanity
+
+/atom/movable/screen/alert/status_effect/blessing_of_insanity
+ name = "Blessing of Insanity"
+ desc = "Your devotion to madness has improved your resilience to all damage and you gain the power to levitate!"
+ //no screen alert - the gravity already throws one
+
+/datum/status_effect/blessing_of_insanity/on_apply()
+ if(ishuman(owner))
+ var/mob/living/carbon/human/human_owner = owner
+ var/datum/physiology/owner_physiology = human_owner.physiology
+ owner_physiology.brute_mod *= 0.5
+ owner_physiology.burn_mod *= 0.5
+ owner_physiology.tox_mod *= 0.5
+ owner_physiology.oxy_mod *= 0.5
+ owner_physiology.clone_mod *= 0.5
+ owner_physiology.stamina_mod *= 0.5
+ owner.add_filter("mad_glow", 2, list("type" = "outline", "color" = "#eed811c9", "size" = 2))
+ owner.AddElement(/datum/element/forced_gravity, 0)
+ owner.AddElement(/datum/element/simple_flying)
+ owner.add_stun_absorption(source = id, priority = 4)
+ add_traits(list(TRAIT_IGNOREDAMAGESLOWDOWN, TRAIT_FREE_HYPERSPACE_MOVEMENT), MAD_WIZARD_TRAIT)
+ owner.playsound_local(get_turf(owner), 'sound/chemistry/ahaha.ogg', vol = 100, vary = TRUE, use_reverb = TRUE)
+ return TRUE
+
+/datum/status_effect/blessing_of_insanity/on_remove()
+ if(ishuman(owner))
+ var/mob/living/carbon/human/human_owner = owner
+ var/datum/physiology/owner_physiology = human_owner.physiology
+ owner_physiology.brute_mod *= 2
+ owner_physiology.burn_mod *= 2
+ owner_physiology.tox_mod *= 2
+ owner_physiology.oxy_mod *= 2
+ owner_physiology.clone_mod *= 2
+ owner_physiology.stamina_mod *= 2
+ owner.remove_filter("mad_glow")
+ owner.RemoveElement(/datum/element/forced_gravity, 0)
+ owner.RemoveElement(/datum/element/simple_flying)
+ owner.remove_stun_absorption(id)
+ remove_traits(list(TRAIT_IGNOREDAMAGESLOWDOWN, TRAIT_FREE_HYPERSPACE_MOVEMENT), MAD_WIZARD_TRAIT)
+
+/// Gives you a brief period of anti-gravity
+/datum/status_effect/jump_jet
+ id = "jump_jet"
+ alert_type = null
+ duration = 5 SECONDS
+
+/datum/status_effect/jump_jet/on_apply()
+ owner.AddElement(/datum/element/forced_gravity, 0)
+ return TRUE
+
+/datum/status_effect/jump_jet/on_remove()
+ owner.RemoveElement(/datum/element/forced_gravity, 0)
diff --git a/code/datums/status_effects/buffs/food_haste.dm b/code/datums/status_effects/buffs/food_haste.dm
new file mode 100644
index 00000000000..9daf859fb19
--- /dev/null
+++ b/code/datums/status_effects/buffs/food_haste.dm
@@ -0,0 +1,20 @@
+/// Haste makes the eater move faster
+/datum/status_effect/food/haste
+ var/datum/movespeed_modifier/food_haste/modifier
+
+/datum/status_effect/food/haste/on_apply()
+ modifier = new()
+ modifier.multiplicative_slowdown = -0.04 * strength
+ owner.add_movespeed_modifier(modifier, update = TRUE)
+ return ..()
+
+/datum/status_effect/food/haste/be_replaced()
+ owner.remove_movespeed_modifier(modifier, update = TRUE)
+ return ..()
+
+/datum/status_effect/food/haste/on_remove()
+ owner.remove_movespeed_modifier(modifier, update = TRUE)
+ return ..()
+
+/datum/movespeed_modifier/food_haste
+ multiplicative_slowdown = -0.1
diff --git a/code/datums/status_effects/buffs/food_traits.dm b/code/datums/status_effects/buffs/food_traits.dm
new file mode 100644
index 00000000000..ebe22116dd0
--- /dev/null
+++ b/code/datums/status_effects/buffs/food_traits.dm
@@ -0,0 +1,8 @@
+/datum/status_effect/food/trait/shockimmune
+ alert_type = /atom/movable/screen/alert/status_effect/food_trait_shockimmune
+ trait = TRAIT_SHOCKIMMUNE
+
+/atom/movable/screen/alert/status_effect/food_trait_shockimmune
+ name = "Grounded"
+ desc = "That meal made me feel like a superconductor..."
+ icon_state = "food_buff_4"
diff --git a/code/datums/status_effects/buffs/stun_absorption.dm b/code/datums/status_effects/buffs/stun_absorption.dm
index e69908467db..9532d79c4f5 100644
--- a/code/datums/status_effects/buffs/stun_absorption.dm
+++ b/code/datums/status_effects/buffs/stun_absorption.dm
@@ -28,6 +28,11 @@
var/self_message
/// Message shown on anyone examining the owner.
var/examine_message
+ /// If TRUE, after passing the max seconds of stuns blocked, we will delete ourself.
+ /// If FALSE, we will instead recharge after some time.
+ var/delete_after_passing_max
+ /// If [delete_after_passing_max] is FALSE, this is how long we will wait before recharging.
+ var/recharge_time
/// Static list of all generic "stun received " signals that we will react to and block.
/// These all have the same arguments sent, so we can handle them all via the same signal handler.
@@ -49,6 +54,8 @@
self_message,
examine_message,
max_seconds_of_stuns_blocked = INFINITY,
+ delete_after_passing_max = TRUE,
+ recharge_time = 1 MINUTES,
)
if(isnum(duration))
@@ -60,6 +67,8 @@
src.self_message = self_message
src.examine_message = examine_message
src.max_seconds_of_stuns_blocked = max_seconds_of_stuns_blocked
+ src.delete_after_passing_max = delete_after_passing_max
+ src.recharge_time = recharge_time
return ..()
@@ -79,7 +88,9 @@
UnregisterSignal(owner, COMSIG_LIVING_GENERIC_STUN_CHECK)
/datum/status_effect/stun_absorption/get_examine_text()
- return replacetext(examine_message, "%EFFECT_OWNER_THEYRE", owner.p_Theyre())
+ if(can_absorb_stun())
+ return replacetext(examine_message, "%EFFECT_OWNER_THEYRE", owner.p_Theyre())
+ return null // no message if we can't absorb stuns, duh.
/**
* Signal proc for generic stun signals being sent, such as [COMSIG_LIVING_STATUS_STUN] or [COMSIG_LIVING_STATUS_KNOCKDOWN].
@@ -120,6 +131,14 @@
return COMPONENT_NO_STUN
+/// Simply checks if the owner of the effect is in a valid state to absorb stuns.
+/datum/status_effect/stun_absorption/proc/can_absorb_stun()
+ if(owner.stat != CONSCIOUS)
+ return FALSE
+ if(seconds_of_stuns_absorbed > max_seconds_of_stuns_blocked)
+ return FALSE
+ return TRUE
+
/**
* Absorb a number of seconds of stuns.
* If we hit the max amount of absorption, we will qdel ourself in this proc.
@@ -129,7 +148,7 @@
* Returns TRUE on successful absorption, or FALSE otherwise.
*/
/datum/status_effect/stun_absorption/proc/absorb_stun(amount)
- if(owner.stat != CONSCIOUS)
+ if(!can_absorb_stun())
return FALSE
// Now we gotta check that no other stun absorption we have is blocking us
@@ -161,11 +180,19 @@
// Count seconds absorbed
seconds_of_stuns_absorbed += amount
- if(seconds_of_stuns_absorbed >= max_seconds_of_stuns_blocked)
- qdel(src)
+ if(delete_after_passing_max)
+ if(seconds_of_stuns_absorbed >= max_seconds_of_stuns_blocked)
+ qdel(src)
+
+ else if(recharge_time > 0 SECONDS)
+ addtimer(CALLBACK(src, PROC_REF(recharge_absorption), amount), recharge_time)
return TRUE
+/// Used in callbacks to "recharge" the effect after passing the max seconds of stuns blocked.
+/datum/status_effect/stun_absorption/proc/recharge_absorption(amount)
+ seconds_of_stuns_absorbed = max(seconds_of_stuns_absorbed - amount, 0)
+
/**
* [proc/apply_status_effect] wrapper specifically for [/datum/status_effect/stun_absorption],
* specifically so that it's easier to apply stun absorptions with named arguments.
@@ -175,12 +202,16 @@
*
* Arguments
* * source - the source of the stun absorption.
- * * duration - how long does the stun absorption last before it ends? -1 or null = infinite duration
+ * * duration - how long does the stun absorption last before it ends? -1 or null (or infinity) = infinite duration
* * priority - what is this effect's priority to other stun absorptions? higher = more priority
* * message - optional, "other message" arg of visible message, shown on trigger. Use %EFFECT_OWNER if you want the owner's name to be inserted.
* * self_message - optional, "self message" arg of visible message, shown on trigger
* * examine_message - optional, what is shown on examine of the mob.
* * max_seconds_of_stuns_blocked - optional, how many seconds of stuns can it block before deleting? the stun that breaks over this number is still blocked, even if it is much higher.
+ * * delete_after_passing_max - optional, if TRUE, after passing the max seconds of stuns blocked, we will delete ourself.
+ * If FALSE, we will instead recharge after some time.
+ * * recharge_time - optional, if [delete_after_passing_max] is FALSE, this is how long we will wait before recharging.
+ * does nothing if [delete_after_passing_max] is TRUE.
*
* Returns an instance of a stun absorption effect, or NULL if failure
*/
@@ -192,6 +223,9 @@
self_message,
examine_message,
max_seconds_of_stuns_blocked = INFINITY,
+ delete_after_passing_max = TRUE,
+ recharge_time,
+ recharge_alert,
)
// Handle duplicate sources
@@ -216,6 +250,8 @@
self_message,
examine_message,
max_seconds_of_stuns_blocked,
+ delete_after_passing_max,
+ recharge_time,
)
/**
diff --git a/code/datums/status_effects/debuffs/choke.dm b/code/datums/status_effects/debuffs/choke.dm
index 4fb668b5fe0..c16b946aa02 100644
--- a/code/datums/status_effects/debuffs/choke.dm
+++ b/code/datums/status_effects/debuffs/choke.dm
@@ -110,7 +110,7 @@
if(choking_on && iscarbon(owner))
var/mob/living/carbon/carbon_owner = owner
// This will yeet the thing we're choking on out of us
- carbon_owner.vomit(lost_nutrition = 20, force = TRUE, distance = 2)
+ carbon_owner.vomit(vomit_flags = (VOMIT_CATEGORY_DEFAULT | MOB_VOMIT_FORCE), lost_nutrition = 20, distance = 2)
/datum/status_effect/choke/proc/on_vomit(mob/source, distance, force)
SIGNAL_HANDLER
@@ -215,8 +215,8 @@
if(iscarbon(victim))
var/mob/living/carbon/carbon_victim = victim
var/obj/item/bodypart/chest = carbon_victim.get_bodypart(BODY_ZONE_CHEST)
- if(chest)
- chest.force_wound_upwards(/datum/wound/blunt/severe, wound_source = "human force to the chest")
+ carbon_victim.cause_wound_of_type_and_severity(WOUND_BLUNT, chest, WOUND_SEVERITY_SEVERE, wound_source = "human force to the chest")
+
playsound(owner, 'sound/creatures/crack_vomit.ogg', 120, extrarange = 5, falloff_exponent = 4)
vomit_up()
diff --git a/code/datums/status_effects/debuffs/confusion.dm b/code/datums/status_effects/debuffs/confusion.dm
index 0f8f0ef3187..881eb6a5c36 100644
--- a/code/datums/status_effects/debuffs/confusion.dm
+++ b/code/datums/status_effects/debuffs/confusion.dm
@@ -31,7 +31,7 @@
var/direction = move_args[MOVE_ARG_DIRECTION]
var/new_dir
- if(time_left > CONFUSION_FULL_THRESHOLD)
+ if(time_left > CONFUSION_FULL_THRESHOLD && !owner.resting)
new_dir = pick(GLOB.alldirs)
else if(prob(time_left * CONFUSION_SIDEWAYS_MOVE_PROB_PER_SECOND))
diff --git a/code/datums/status_effects/debuffs/cursed.dm b/code/datums/status_effects/debuffs/cursed.dm
index 2ee7266f7b9..285fb86348e 100644
--- a/code/datums/status_effects/debuffs/cursed.dm
+++ b/code/datums/status_effects/debuffs/cursed.dm
@@ -5,6 +5,8 @@
/datum/status_effect/grouped/cursed
id = "cursed"
alert_type = /atom/movable/screen/alert/status_effect/cursed
+ remove_on_fullheal = TRUE
+ heal_flag_necessary = HEAL_ADMIN
/// The max number of curses a target can incur with this status effect.
var/max_curse_count = DEFAULT_MAX_CURSE_COUNT
/// The amount of times we have been "applied" to the target.
@@ -32,7 +34,7 @@
return ..()
/// Checks the number of curses we have and returns information back to the slot machine. `max_curse_amount` is set by the slot machine itself.
-/datum/status_effect/grouped/cursed/proc/check_curses(max_curse_amount)
+/datum/status_effect/grouped/cursed/proc/check_curses(mob/user, max_curse_amount)
SIGNAL_HANDLER
if(curse_count >= max_curse_amount)
return SLOT_MACHINE_USE_CANCEL
@@ -64,7 +66,7 @@
playsound(human_owner, SFX_SEAR, 50, TRUE)
var/obj/item/bodypart/affecting = human_owner.get_active_hand()
branded_hand = affecting
- affecting.force_wound_upwards(/datum/wound/burn/severe/cursed_brand, wound_source = "curse of the slot machine")
+ affecting.force_wound_upwards(/datum/wound/burn/flesh/severe/cursed_brand, wound_source = "curse of the slot machine")
messages += span_boldwarning("Your hand burns, and you quickly let go of the lever! You feel a little sick as the nerves deaden in your hand...")
messages += span_boldwarning("Some smoke appears to be coming out of your hand now, but it's not too bad...")
@@ -114,7 +116,7 @@
SIGNAL_HANDLER
if(!isnull(branded_hand))
- var/datum/wound/brand = branded_hand.get_wound_type(/datum/wound/burn/severe/cursed_brand)
+ var/datum/wound/brand = branded_hand.get_wound_type(/datum/wound/burn/flesh/severe/cursed_brand)
brand?.remove_wound()
owner.visible_message(
diff --git a/code/datums/status_effects/debuffs/debuffs.dm b/code/datums/status_effects/debuffs/debuffs.dm
index 50fe9690b41..8c8f910fd57 100644
--- a/code/datums/status_effects/debuffs/debuffs.dm
+++ b/code/datums/status_effects/debuffs/debuffs.dm
@@ -411,7 +411,9 @@
var/still_bleeding = FALSE
for(var/datum/wound/bleeding_thing as anything in throat.wounds)
- if(bleeding_thing.wound_type == WOUND_SLASH && bleeding_thing.severity > WOUND_SEVERITY_MODERATE)
+ var/datum/wound_pregen_data/pregen_data = GLOB.all_wound_pregen_data[bleeding_thing.type]
+
+ if(pregen_data.wounding_types_valid(list(WOUND_SLASH)) && bleeding_thing.severity > WOUND_SEVERITY_MODERATE && bleeding_thing.blood_flow > 0)
still_bleeding = TRUE
break
if(!still_bleeding)
diff --git a/code/datums/status_effects/debuffs/drunk.dm b/code/datums/status_effects/debuffs/drunk.dm
index 2e844a61b19..705fcc60eeb 100644
--- a/code/datums/status_effects/debuffs/drunk.dm
+++ b/code/datums/status_effects/debuffs/drunk.dm
@@ -170,7 +170,7 @@
owner.adjust_confusion(15 SECONDS)
if(iscarbon(owner))
var/mob/living/carbon/carbon_owner = owner
- carbon_owner.vomit() // Vomiting clears toxloss - consider this a blessing
+ carbon_owner.vomit(VOMIT_CATEGORY_DEFAULT) // Vomiting clears toxloss - consider this a blessing
// Over 71, we will constantly have blurry eyes
if(drunk_value >= 71)
diff --git a/code/datums/status_effects/debuffs/screen_blur.dm b/code/datums/status_effects/debuffs/screen_blur.dm
index f893a1d379f..abdd07d3cd5 100644
--- a/code/datums/status_effects/debuffs/screen_blur.dm
+++ b/code/datums/status_effects/debuffs/screen_blur.dm
@@ -14,7 +14,7 @@
return ..()
/datum/status_effect/eye_blur/on_apply()
- if(owner.mob_biotypes & (MOB_ROBOTIC|MOB_SPIRIT|MOB_EPIC))
+ if(owner.mob_biotypes & (MOB_ROBOTIC|MOB_SPIRIT|MOB_SPECIAL))
return FALSE
// Refresh the blur when a client jumps into the mob, in case we get put on a clientless mob with no hud
diff --git a/code/datums/status_effects/food_effects.dm b/code/datums/status_effects/food_effects.dm
new file mode 100644
index 00000000000..e41ef67ad10
--- /dev/null
+++ b/code/datums/status_effects/food_effects.dm
@@ -0,0 +1,52 @@
+/// Buffs given by eating hand-crafted food. The duration scales with consumable reagents purity.
+/datum/status_effect/food
+ id = "food_buff"
+ duration = 5 MINUTES // Same as food mood buffs
+ status_type = STATUS_EFFECT_REPLACE // Only one food buff allowed
+ /// Buff power
+ var/strength
+
+/datum/status_effect/food/on_creation(mob/living/new_owner, timeout_mod = 1, strength = 1)
+ src.strength = strength
+ //Generate alert when not specified
+ if(alert_type == /atom/movable/screen/alert/status_effect)
+ alert_type = "/atom/movable/screen/alert/status_effect/food/buff_[strength]"
+ if(isnum(timeout_mod))
+ duration *= timeout_mod
+ . = ..()
+
+/atom/movable/screen/alert/status_effect/food
+ name = "Hand-crafted meal"
+ desc = "Eating it made me feel better."
+ icon_state = "food_buff_1"
+
+/atom/movable/screen/alert/status_effect/food/buff_1
+ icon_state = "food_buff_1"
+
+/atom/movable/screen/alert/status_effect/food/buff_2
+ icon_state = "food_buff_2"
+
+/atom/movable/screen/alert/status_effect/food/buff_3
+ icon_state = "food_buff_3"
+
+/atom/movable/screen/alert/status_effect/food/buff_4
+ icon_state = "food_buff_4"
+
+/atom/movable/screen/alert/status_effect/food/buff_5
+ icon_state = "food_buff_5"
+
+/// Makes you gain a trait
+/datum/status_effect/food/trait
+ var/trait = TRAIT_DUMB // You need to override this
+
+/datum/status_effect/food/trait/on_apply()
+ ADD_TRAIT(owner, trait, type)
+ return ..()
+
+/datum/status_effect/food/trait/be_replaced()
+ REMOVE_TRAIT(owner, trait, type)
+ return ..()
+
+/datum/status_effect/food/trait/on_remove()
+ REMOVE_TRAIT(owner, trait, type)
+ return ..()
diff --git a/code/datums/status_effects/neutral.dm b/code/datums/status_effects/neutral.dm
index bd80df2a0f3..7161946c9ff 100644
--- a/code/datums/status_effects/neutral.dm
+++ b/code/datums/status_effects/neutral.dm
@@ -541,3 +541,20 @@
/datum/status_effect/tinlux_light/on_remove()
QDEL_NULL(mob_light_obj)
+
+/datum/status_effect/gutted
+ id = "gutted"
+ alert_type = null
+ duration = -1
+ tick_interval = -1
+
+/datum/status_effect/gutted/on_apply()
+ RegisterSignal(owner, COMSIG_MOB_STATCHANGE, PROC_REF(stop_gutting))
+ return TRUE
+
+/datum/status_effect/gutted/on_remove()
+ UnregisterSignal(owner, COMSIG_MOB_STATCHANGE)
+
+/datum/status_effect/gutted/proc/stop_gutting()
+ SIGNAL_HANDLER
+ qdel(src)
diff --git a/code/datums/status_effects/wound_effects.dm b/code/datums/status_effects/wound_effects.dm
index dfee1c2ee2c..6ec793c5672 100644
--- a/code/datums/status_effects/wound_effects.dm
+++ b/code/datums/status_effects/wound_effects.dm
@@ -54,11 +54,11 @@
right = C.get_bodypart(BODY_ZONE_R_LEG)
update_limp()
RegisterSignal(C, COMSIG_MOVABLE_MOVED, PROC_REF(check_step))
- RegisterSignals(C, list(COMSIG_CARBON_GAIN_WOUND, COMSIG_CARBON_LOSE_WOUND, COMSIG_CARBON_ATTACH_LIMB, COMSIG_CARBON_REMOVE_LIMB), PROC_REF(update_limp))
+ RegisterSignals(C, list(COMSIG_CARBON_GAIN_WOUND, COMSIG_CARBON_POST_LOSE_WOUND, COMSIG_CARBON_ATTACH_LIMB, COMSIG_CARBON_REMOVE_LIMB), PROC_REF(update_limp))
return TRUE
/datum/status_effect/limp/on_remove()
- UnregisterSignal(owner, list(COMSIG_MOVABLE_MOVED, COMSIG_CARBON_GAIN_WOUND, COMSIG_CARBON_LOSE_WOUND, COMSIG_CARBON_ATTACH_LIMB, COMSIG_CARBON_REMOVE_LIMB))
+ UnregisterSignal(owner, list(COMSIG_MOVABLE_MOVED, COMSIG_CARBON_GAIN_WOUND, COMSIG_CARBON_POST_LOSE_WOUND, COMSIG_CARBON_ATTACH_LIMB, COMSIG_CARBON_REMOVE_LIMB))
/atom/movable/screen/alert/status_effect/limp
name = "Limping"
@@ -165,51 +165,41 @@
if(W == linked_wound)
qdel(src)
-
-// bones
-/datum/status_effect/wound/blunt
-
-/datum/status_effect/wound/blunt/on_apply()
- . = ..()
- RegisterSignal(owner, COMSIG_MOB_SWAP_HANDS, PROC_REF(on_swap_hands))
- on_swap_hands()
-
-/datum/status_effect/wound/blunt/on_remove()
- . = ..()
- UnregisterSignal(owner, COMSIG_MOB_SWAP_HANDS)
- var/mob/living/carbon/wound_owner = owner
- wound_owner.remove_actionspeed_modifier(/datum/actionspeed_modifier/blunt_wound)
-
-/datum/status_effect/wound/blunt/proc/on_swap_hands()
- SIGNAL_HANDLER
-
- var/mob/living/carbon/wound_owner = owner
- if(wound_owner.get_active_hand() == linked_limb)
- wound_owner.add_actionspeed_modifier(/datum/actionspeed_modifier/blunt_wound, (linked_wound.interaction_efficiency_penalty - 1))
- else
- wound_owner.remove_actionspeed_modifier(/datum/actionspeed_modifier/blunt_wound)
-
-/datum/status_effect/wound/blunt/nextmove_modifier()
+/datum/status_effect/wound/nextmove_modifier()
var/mob/living/carbon/C = owner
if(C.get_active_hand() == linked_limb)
- return linked_wound.interaction_efficiency_penalty
+ return linked_wound.get_action_delay_mult()
- return 1
+ return ..()
+
+/datum/status_effect/wound/nextmove_adjust()
+ var/mob/living/carbon/C = owner
+
+ if(C.get_active_hand() == linked_limb)
+ return linked_wound.get_action_delay_increment()
+
+ return ..()
+
+
+// bones
+/datum/status_effect/wound/blunt/bone
// blunt
-/datum/status_effect/wound/blunt/moderate
+/datum/status_effect/wound/blunt/bone/moderate
id = "disjoint"
-/datum/status_effect/wound/blunt/severe
+/datum/status_effect/wound/blunt/bone/severe
id = "hairline"
-/datum/status_effect/wound/blunt/critical
+/datum/status_effect/wound/blunt/bone/critical
id = "compound"
+
// slash
-/datum/status_effect/wound/slash/moderate
+
+/datum/status_effect/wound/slash/flesh/moderate
id = "abrasion"
-/datum/status_effect/wound/slash/severe
+/datum/status_effect/wound/slash/flesh/severe
id = "laceration"
-/datum/status_effect/wound/slash/critical
+/datum/status_effect/wound/slash/flesh/critical
id = "avulsion"
// pierce
/datum/status_effect/wound/pierce/moderate
@@ -219,9 +209,9 @@
/datum/status_effect/wound/pierce/critical
id = "rupture"
// burns
-/datum/status_effect/wound/burn/moderate
+/datum/status_effect/wound/burn/flesh/moderate
id = "seconddeg"
-/datum/status_effect/wound/burn/severe
+/datum/status_effect/wound/burn/flesh/severe
id = "thirddeg"
-/datum/status_effect/wound/burn/critical
+/datum/status_effect/wound/burn/flesh/critical
id = "fourthdeg"
diff --git a/code/datums/storage/subtypes/surgery_tray.dm b/code/datums/storage/subtypes/surgery_tray.dm
new file mode 100644
index 00000000000..35886581318
--- /dev/null
+++ b/code/datums/storage/subtypes/surgery_tray.dm
@@ -0,0 +1,22 @@
+/datum/storage/surgery_tray
+ max_total_storage = 30
+ max_specific_storage = WEIGHT_CLASS_NORMAL
+ max_slots = 14
+
+/datum/storage/surgery_tray/New()
+ . = ..()
+ set_holdable(list(
+ /obj/item/blood_filter,
+ /obj/item/bonesetter,
+ /obj/item/cautery,
+ /obj/item/circular_saw,
+ /obj/item/clothing/mask/surgical,
+ /obj/item/hemostat,
+ /obj/item/razor,
+ /obj/item/retractor,
+ /obj/item/scalpel,
+ /obj/item/stack/medical/bone_gel,
+ /obj/item/stack/sticky_tape/surgical,
+ /obj/item/surgical_drapes,
+ /obj/item/surgicaldrill,
+ ))
diff --git a/code/datums/voice_of_god_command.dm b/code/datums/voice_of_god_command.dm
index f1ce13f9fa5..1be31c33d2a 100644
--- a/code/datums/voice_of_god_command.dm
+++ b/code/datums/voice_of_god_command.dm
@@ -144,7 +144,7 @@ GLOBAL_LIST_INIT(voice_of_god_commands, init_voice_of_god_commands())
/datum/voice_of_god_command/vomit/execute(list/listeners, mob/living/user, power_multiplier = 1, message)
for(var/mob/living/carbon/target in listeners)
- target.vomit(10 * power_multiplier, distance = power_multiplier, stun = FALSE)
+ target.vomit(vomit_flags = (MOB_VOMIT_MESSAGE | MOB_VOMIT_HARM), lost_nutrition = (power_multiplier * 10), distance = power_multiplier)
/// This command silences the listeners. Thrice as effective is the user is a mime or curator.
/datum/voice_of_god_command/silence
diff --git a/code/datums/wires/conveyor.dm b/code/datums/wires/conveyor.dm
index 53175eb00fb..dd0ac811bc2 100644
--- a/code/datums/wires/conveyor.dm
+++ b/code/datums/wires/conveyor.dm
@@ -1,7 +1,7 @@
/datum/wires/conveyor
holder_type = /obj/machinery/conveyor_switch
proper_name = "Conveyor"
- /// var holder that logs who put the assembly inside and gets transfered to the switch on pulse
+ /// var holder that logs who put the assembly inside and gets transferred to the switch on pulse
var/datum/weakref/fingerman_ref
/datum/wires/conveyor/New(atom/holder)
diff --git a/code/datums/wires/mass_driver.dm b/code/datums/wires/mass_driver.dm
new file mode 100644
index 00000000000..329da73c2dc
--- /dev/null
+++ b/code/datums/wires/mass_driver.dm
@@ -0,0 +1,25 @@
+/datum/wires/mass_driver
+ holder_type = /obj/machinery/mass_driver
+ proper_name = "Mass Driver"
+
+/datum/wires/mass_driver/New(atom/holder)
+ wires = list(WIRE_LAUNCH, WIRE_SAFETIES)
+ ..()
+
+/datum/wires/mass_driver/on_pulse(wire)
+ var/obj/machinery/mass_driver/the_mass_driver = holder
+ switch(wire)
+ if(WIRE_LAUNCH)
+ the_mass_driver.drive()
+ holder.visible_message(span_notice("The drive mechanism activates."))
+ if(WIRE_SAFETIES)
+ the_mass_driver.power = 3
+ holder.visible_message(span_notice("You hear a worrying whirring noise emitting from the mass driver."))
+
+/datum/wires/mass_driver/on_cut(wire, mend, source)
+ var/obj/machinery/mass_driver/the_mass_driver = holder
+ switch(wire)
+ if(WIRE_SAFETIES)
+ if(the_mass_driver.power > 1)
+ the_mass_driver.power = 1
+ holder.visible_message(span_notice("The whirring noise emitting from the mass driver stops."))
diff --git a/code/datums/wounds/_wound_static_data.dm b/code/datums/wounds/_wound_static_data.dm
new file mode 100644
index 00000000000..7a59ea57413
--- /dev/null
+++ b/code/datums/wounds/_wound_static_data.dm
@@ -0,0 +1,199 @@
+// This datum is merely a singleton instance that allows for custom "can be applied" behaviors without instantiating a wound instance.
+// For example: You can make a pregen_data subtype for your wound that overrides can_be_applied_to to only apply to specifically slimeperson limbs.
+// Without this, youre stuck with very static initial variables.
+
+/// A singleton datum that holds pre-gen and static data about a wound. Each wound datum should have a corresponding wound_pregen_data.
+/datum/wound_pregen_data
+ /// The typepath of the wound we will be handling and storing data of. NECESSARY IF THIS IS A NON-ABSTRACT TYPE!
+ var/datum/wound/wound_path_to_generate
+
+ /// Will this be instantiated?
+ var/abstract = FALSE
+
+ /// If true, our wound can be selected in ordinary wound rolling. If this is set to false, our wound can only be directly instantiated by use of specific typepath.
+ var/can_be_randomly_generated = TRUE
+
+ /// A list of biostates a limb must have to receive our wound, in wounds.dm.
+ var/required_limb_biostate
+ /// If false, we will check if the limb has all of our required biostates instead of just any.
+ var/require_any_biostate = FALSE
+
+ /// If false, we will iterate through wounds on a given limb, and if any match our type, we wont add our wound.
+ var/duplicates_allowed = FALSE
+
+ /// If we require BIO_BLOODED, we will not add our wound if this is true and the limb cannot bleed.
+ var/ignore_cannot_bleed = TRUE // a lot of bleed wounds should still be applied for purposes of mangling flesh
+
+ /// A list of bodyzones we are applicable to.
+ var/list/viable_zones = list(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
+ /// The types of attack that can generate this wound. E.g. WOUND_SLASH = A sharp attack can cause this, WOUND_BLUNT = an attack with no sharpness/an attack with sharpness against a limb with mangled exterior can cause this.
+ var/list/required_wounding_types
+ /// If true, this wound can only be generated by all [required_wounding_types] at once, not just any.
+ var/match_all_wounding_types = FALSE
+
+ /// The weight that will be used if, by the end of wound selection, there are multiple valid wounds. This will be inserted into pick_weight, so use integers.
+ var/weight = WOUND_DEFAULT_WEIGHT
+
+ /// The minimum injury roll a attack must get to generate us. Affected by our wound's threshold_penalty and series_threshold_penalty, as well as the attack's wound_bonus. See check_wounding_mods().
+ var/threshold_minimum
+
+ /// The series of wounds this is in. See wounds.dm (the defines file) for a more detailed explanation - but tldr is that no 2 wounds of the same series can be on a limb.
+ var/wound_series
+
+ /// If true, we will attempt to, during a random wound roll, overpower and remove other wound typepaths from the possible wounds list using [competition_mode] and [overpower_wounds_of_even_severity].
+ var/compete_for_wounding = TRUE
+ /// The competition mode with which we will remove other wounds from a possible wound roll assuming [compete_for_wounding] is TRUE. See wounds.dm, the defines file, for more information on what these do.
+ var/competition_mode = WOUND_COMPETITION_OVERPOWER_LESSERS
+ /// If this and [compete_for_wounding] is true, we will remove wounds of an even severity to us during a random wound roll.
+ var/overpower_wounds_of_even_severity = FALSE
+
+ /// A list of BIO_ defines that will be iterated over in order to determine the scar file our wound will generate.
+ /// Use generate_scar_priorities to create a custom list.
+ var/list/scar_priorities
+
+/datum/wound_pregen_data/New()
+ . = ..()
+
+ if (!abstract)
+ if (required_limb_biostate == null)
+ stack_trace("required_limb_biostate null - please set it! occured on: [src.type]")
+ if (wound_path_to_generate == null)
+ stack_trace("wound_path_to_generate null - please set it! occured on: [src.type]")
+
+ scar_priorities = generate_scar_priorities()
+
+/// Should return a list of BIO_ biostate priorities, in order. See [scar_priorities] for further documentation.
+/datum/wound_pregen_data/proc/generate_scar_priorities()
+ RETURN_TYPE(/list)
+
+ var/list/priorities = list(
+ "[BIO_FLESH]",
+ "[BIO_BONE]",
+ )
+
+ return priorities
+
+// this proc is the primary reason this datum exists - a singleton instance so we can always run this proc even without the wound existing
+/**
+ * Args:
+ * * obj/item/bodypart/limb: The limb we are considering.
+ * * list/suggested_wounding_types: The wounding types to be checked against the wounding types we require. Defaults to required_wounding_types.
+ * * datum/wound/old_wound: If we would replace a wound, this would be said wound. Nullable.
+ * * random_roll = FALSE: If this is in the context of a random wound generation, and this wound wasn't specifically checked.
+ *
+ * Returns:
+ * FALSE if the limb cannot be wounded, if the wounding types dont match ours (via wounding_types_valid()), if we have a higher severity wound already in our series,
+ * if we have a biotype mismatch, if the limb isnt in a viable zone, or if theres any duplicate wound types.
+ * TRUE otherwise.
+ */
+/datum/wound_pregen_data/proc/can_be_applied_to(obj/item/bodypart/limb, list/suggested_wounding_types = required_wounding_types, datum/wound/old_wound, random_roll = FALSE, duplicates_allowed = src.duplicates_allowed, care_about_existing_wounds = TRUE)
+ SHOULD_BE_PURE(TRUE)
+
+ if (!istype(limb) || !limb.owner)
+ return FALSE
+
+ if (random_roll && !can_be_randomly_generated)
+ return FALSE
+
+ if (HAS_TRAIT(limb.owner, TRAIT_NEVER_WOUNDED) || (limb.owner.status_flags & GODMODE))
+ return FALSE
+
+ if (!wounding_types_valid(suggested_wounding_types))
+ return FALSE
+
+ if (care_about_existing_wounds)
+ for (var/datum/wound/preexisting_wound as anything in limb.wounds)
+ var/datum/wound_pregen_data/pregen_data = GLOB.all_wound_pregen_data[preexisting_wound.type]
+ if (pregen_data.wound_series == wound_series)
+ if (preexisting_wound.severity >= initial(wound_path_to_generate.severity))
+ return FALSE
+
+ if (!ignore_cannot_bleed && ((required_limb_biostate & BIO_BLOODED) && !limb.can_bleed()))
+ return FALSE
+
+ if (!biostate_valid(limb.biological_state))
+ return FALSE
+
+ if (!(limb.body_zone in viable_zones))
+ return FALSE
+
+ // we accept promotions and demotions, but no point in redundancy. This should have already been checked wherever the wound was rolled and applied for (see: bodypart damage code), but we do an extra check
+ // in case we ever directly add wounds
+ if (!duplicates_allowed)
+ for (var/datum/wound/preexisting_wound as anything in limb.wounds)
+ if (preexisting_wound.type == wound_path_to_generate && (preexisting_wound != old_wound))
+ return FALSE
+ return TRUE
+
+/// Returns true if we have the given biostates, or any biostate in it if check_for_any is true. False otherwise.
+/datum/wound_pregen_data/proc/biostate_valid(biostate)
+ if (require_any_biostate)
+ if (!(biostate & required_limb_biostate))
+ return FALSE
+ else if (!((biostate & required_limb_biostate) == required_limb_biostate)) // check for all
+ return FALSE
+
+ return TRUE
+
+/**
+ * A simple getter for [weight], with arguments supplied to allow custom behavior.
+ *
+ * Args:
+ * * obj/item/bodypart/limb: The limb we are contemplating being added to. Nullable.
+ * * woundtype: The woundtype of the assumed attack that would generate us. Nullable.
+ * * damage: The raw damage that would cause us. Nullable.
+ * * attack_direction: The direction of the attack that'd cause us. Nullable.
+ * * damage_source: The entity that would cause us. Nullable.
+ *
+ * Returns:
+ * Our weight.
+ */
+/datum/wound_pregen_data/proc/get_weight(obj/item/bodypart/limb, woundtype, damage, attack_direction, damage_source)
+ return weight
+
+/// Returns TRUE if we use WOUND_ALL, or we require all types and have all/if we require any and have any, FALSE otherwise.
+/datum/wound_pregen_data/proc/wounding_types_valid(list/suggested_wounding_types)
+ if (WOUND_ALL in required_wounding_types)
+ return TRUE
+ if (!length(suggested_wounding_types))
+ return FALSE
+
+ for (var/iter_wounding_type as anything in suggested_wounding_types)
+ if (!(iter_wounding_type in required_wounding_types))
+ if (match_all_wounding_types)
+ return FALSE
+ else
+ if (!match_all_wounding_types)
+ return TRUE
+
+ return match_all_wounding_types // if we get here, we've matched everything
+
+/**
+ * A simple getter for [threshold_minimum], with arguments supplied to allow custom behavior.
+ *
+ * Args:
+ * * obj/item/bodypart/part: The limb we are contemplating being added to.
+ * * attack_direction: The direction of the attack that'd generate us. Nullable.
+ * * damage_source: The source of the damage that'd cause us. Nullable.
+ */
+/datum/wound_pregen_data/proc/get_threshold_for(obj/item/bodypart/part, attack_direction, damage_source)
+ return threshold_minimum
+
+/// Returns a new instance of our wound datum.
+/datum/wound_pregen_data/proc/generate_instance(obj/item/bodypart/limb, ...)
+ RETURN_TYPE(/datum/wound)
+
+ return new wound_path_to_generate
+
+/datum/wound_pregen_data/Destroy(force, ...)
+ var/error_message = "[src], a singleton wound pregen data instance, was destroyed! This should not happen!"
+ if (force)
+ error_message += " NOTE: This Destroy() was called with force == TRUE. This instance will be deleted and replaced with a new one."
+ stack_trace(error_message)
+
+ if (!force)
+ return QDEL_HINT_LETMELIVE
+
+ . = ..()
+
+ GLOB.all_wound_pregen_data[wound_path_to_generate] = new src.type //recover
diff --git a/code/datums/wounds/_wounds.dm b/code/datums/wounds/_wounds.dm
index 33686d6bc24..faf1ef87057 100644
--- a/code/datums/wounds/_wounds.dm
+++ b/code/datums/wounds/_wounds.dm
@@ -14,6 +14,13 @@
deciding what specific wound will be applied. I'd like to have a few different types of wounds for at least some of the choices, but I'm just doing rough generals for now. Expect polishing
*/
+#define WOUND_CRITICAL_BLUNT_DISMEMBER_BONUS 15
+
+// Applied into wounds when they're scanned with the wound analyzer, halves time to treat them manually.
+#define TRAIT_WOUND_SCANNED "wound_scanned"
+// I dunno lol
+#define ANALYZER_TRAIT "analyzer_trait"
+
/datum/wound
/// What it's named
var/name = "Wound"
@@ -24,51 +31,61 @@
/// What the limb looks like on a cursory examine
var/examine_desc = "is badly hurt"
+ /// Simple description, shortened for clarity if defined. Otherwise just takes the normal desc in the analyzer proc.
+ var/simple_desc
+ /// Simple analyzer's wound description, which focuses less on the clinical aspect of the wound and more on easily readable treatment instructions.
+ var/simple_treat_text = "Go to medbay idiot"
+ /// Improvised remedies indicated by the first aid analyzer only.
+ var/homemade_treat_text = "Remember to drink lots of water!"
+
+
+ /// If this wound can generate a scar.
+ var/can_scar = TRUE
+
+ /// The default file we take our scar descriptions from, if we fail to get the ideal file.
+ var/default_scar_file
+
/// needed for "your arm has a compound fracture" vs "your arm has some third degree burns"
var/a_or_from = "a"
/// The visible message when this happens
var/occur_text = ""
/// This sound will be played upon the wound being applied
var/sound_effect
+ /// The volume of [sound_effect]
+ var/sound_volume = 70
/// Either WOUND_SEVERITY_TRIVIAL (meme wounds like stubbed toe), WOUND_SEVERITY_MODERATE, WOUND_SEVERITY_SEVERE, or WOUND_SEVERITY_CRITICAL (or maybe WOUND_SEVERITY_LOSS)
var/severity = WOUND_SEVERITY_MODERATE
- /// The list of wounds it belongs in, WOUND_LIST_BLUNT, WOUND_LIST_SLASH, or WOUND_LIST_BURN
- var/wound_type
- /// What body zones can we affect
- var/list/viable_zones = list(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
/// Who owns the body part that we're wounding
var/mob/living/carbon/victim = null
- /// The bodypart we're parented to
+ /// The bodypart we're parented to. Not guaranteed to be non-null, especially after/during removal or if we haven't been applied
var/obj/item/bodypart/limb = null
/// Specific items such as bandages or sutures that can try directly treating this wound
var/list/treatable_by
/// Specific items such as bandages or sutures that can try directly treating this wound only if the user has the victim in an aggressive grab or higher
var/list/treatable_by_grabbed
- /// Tools with the specified tool flag will also be able to try directly treating this wound
- var/treatable_tool
+ /// Any tools with any of the flags in this list will be usable to try directly treating this wound
+ var/list/treatable_tools
/// How long it will take to treat this wound with a standard effective tool, assuming it doesn't need surgery
var/base_treat_time = 5 SECONDS
/// Using this limb in a do_after interaction will multiply the length by this duration (arms)
var/interaction_efficiency_penalty = 1
/// Incoming damage on this limb will be multiplied by this, to simulate tenderness and vulnerability (mostly burns).
- var/damage_mulitplier_penalty = 1
+ var/damage_multiplier_penalty = 1
/// If set and this wound is applied to a leg, we take this many deciseconds extra per step on this leg
var/limp_slowdown
/// If this wound has a limp_slowdown and is applied to a leg, it has this chance to limp each step
var/limp_chance
/// How much we're contributing to this limb's bleed_rate
var/blood_flow
- /// Essentially, keeps track of whether or not this wound is capable of bleeding (in case the owner has the NOBLOOD species trait)
- var/no_bleeding = FALSE
- /// The minimum we need to roll on [/obj/item/bodypart/proc/check_wounding] to begin suffering this wound, see check_wounding_mods() for more
- var/threshold_minimum
/// How much having this wound will add to all future check_wounding() rolls on this limb, to allow progression to worse injuries with repeated damage
var/threshold_penalty
+ /// How much having this wound will add to all future check_wounding() rolls on this limb, but only for wounds of its own series
+ var/series_threshold_penalty = 0
/// If we need to process each life tick
var/processes = FALSE
@@ -79,9 +96,12 @@
var/status_effect_type
/// If we're operating on this wound and it gets healed, we'll nix the surgery too
var/datum/surgery/attached_surgery
- /// if you're a lazy git and just throw them in cryo, the wound will go away after accumulating severity * 25 power
+ /// if you're a lazy git and just throw them in cryo, the wound will go away after accumulating severity * [base_xadone_progress_to_qdel] power
var/cryo_progress
+ /// The base amount of [cryo_progress] required to have ourselves fully healed by cryo. Multiplied against severity.
+ var/base_xadone_progress_to_qdel = 33
+
/// What kind of scars this wound will create description wise once healed
var/scar_keyword = "generic"
/// If we've already tried scarring while removing (remove_wound can be called twice in a del chain, let's be nice to our code yeah?) TODO: make this cleaner
@@ -90,20 +110,68 @@
var/wound_source
/// What flags apply to this wound
- var/wound_flags = (FLESH_WOUND | BONE_WOUND | ACCEPTS_GAUZE)
+ var/wound_flags = (ACCEPTS_GAUZE)
+
+ /// The unique ID of our wound for use with [actionspeed_mod]. Defaults to REF(src).
+ var/unique_id
+ /// The actionspeed modifier we will use in case we are on the arms and have a interaction penalty. Qdelled on destroy.
+ var/datum/actionspeed_modifier/wound_interaction_inefficiency/actionspeed_mod
+
+/datum/wound/New()
+ . = ..()
+
+ unique_id = generate_unique_id()
+ update_actionspeed_modifier()
/datum/wound/Destroy()
- if(attached_surgery)
- QDEL_NULL(attached_surgery)
- remove_wound()
- set_limb(null)
- victim = null
+ QDEL_NULL(attached_surgery)
+ if (limb)
+ remove_wound()
+
+ QDEL_NULL(actionspeed_mod)
+
return ..()
-// Applied into wounds when they're scanned with the wound analyzer, halves time to treat them manually.
-#define TRAIT_WOUND_SCANNED "wound_scanned"
-// I dunno lol
-#define ANALYZER_TRAIT "analyzer_trait"
+/// If we should have an actionspeed_mod, ensures we do and updates its slowdown. Otherwise, ensures we dont have one
+/// by qdeleting any existing modifier.
+/datum/wound/proc/update_actionspeed_modifier()
+ if (should_have_actionspeed_modifier())
+ if (!actionspeed_mod)
+ generate_actionspeed_modifier()
+ actionspeed_mod.multiplicative_slowdown = get_effective_actionspeed_modifier()
+ victim?.update_actionspeed()
+ else
+ remove_actionspeed_modifier()
+
+/// Returns TRUE if we have an interaction_efficiency_penalty, and if we are on the arms, FALSE otherwise.
+/datum/wound/proc/should_have_actionspeed_modifier()
+ return (limb && victim && (limb.body_zone == BODY_ZONE_L_ARM || limb.body_zone == BODY_ZONE_R_ARM) && interaction_efficiency_penalty != 0)
+
+/// If we have no actionspeed_mod, generates a new one with our unique ID, sets actionspeed_mod to it, then returns it.
+/datum/wound/proc/generate_actionspeed_modifier()
+ RETURN_TYPE(/datum/actionspeed_modifier)
+
+ if (actionspeed_mod)
+ return actionspeed_mod
+
+ var/datum/actionspeed_modifier/wound_interaction_inefficiency/new_modifier = new /datum/actionspeed_modifier/wound_interaction_inefficiency(unique_id, src)
+ new_modifier.multiplicative_slowdown = get_effective_actionspeed_modifier()
+ victim?.add_actionspeed_modifier(new_modifier)
+
+ actionspeed_mod = new_modifier
+ return actionspeed_mod
+
+/// If we have an actionspeed_mod, qdels it and sets our ref of it to null.
+/datum/wound/proc/remove_actionspeed_modifier()
+ if (!actionspeed_mod)
+ return
+
+ victim?.remove_actionspeed_modifier(actionspeed_mod)
+ QDEL_NULL(actionspeed_mod)
+
+/// Generates the ID we use for [unique_id], which is also set as our actionspeed mod's ID
+/datum/wound/proc/generate_unique_id()
+ return REF(src) // unique, cannot change, a perfect id
/**
* apply_wound() is used once a wound type is instantiated to assign it to a bodypart, and actually come into play.
@@ -118,22 +186,10 @@
* * wound_source: The source of the wound, such as a weapon.
*/
/datum/wound/proc/apply_wound(obj/item/bodypart/L, silent = FALSE, datum/wound/old_wound = null, smited = FALSE, attack_direction = null, wound_source = "Unknown")
- if(!istype(L) || !L.owner || !(L.body_zone in viable_zones) || !IS_ORGANIC_LIMB(L) || HAS_TRAIT(L.owner, TRAIT_NEVER_WOUNDED) || (L.owner.status_flags & GODMODE))
- qdel(src)
- return
- // Checks for biological state, to ensure only valid wounds are applied on the limb
- if(((wound_flags & BONE_WOUND) && !(L.biological_state & BIO_BONE)) || ((wound_flags & FLESH_WOUND) && !(L.biological_state & BIO_FLESH)))
+ if (!can_be_applied_to(L, old_wound))
qdel(src)
- return
-
- // we accept promotions and demotions, but no point in redundancy. This should have already been checked wherever the wound was rolled and applied for (see: bodypart damage code), but we do an extra check
- // in case we ever directly add wounds
- for(var/i in L.wounds)
- var/datum/wound/preexisting_wound = i
- if((preexisting_wound.type == type) && (preexisting_wound != old_wound))
- qdel(src)
- return
+ return FALSE
if(isitem(wound_source))
var/obj/item/wound_item = wound_source
@@ -145,7 +201,6 @@
set_limb(L)
LAZYADD(victim.all_wounds, src)
LAZYADD(limb.wounds, src)
- no_bleeding = HAS_TRAIT(victim, TRAIT_NOBLOOD)
update_descriptions()
limb.update_wounds()
if(status_effect_type)
@@ -165,18 +220,41 @@
var/msg = span_danger("[victim]'s [limb.plaintext_zone] [occur_text]!")
var/vis_dist = COMBAT_MESSAGE_RANGE
- if(severity != WOUND_SEVERITY_MODERATE)
+ if(severity > WOUND_SEVERITY_MODERATE)
msg = "[msg]"
vis_dist = DEFAULT_MESSAGE_RANGE
victim.visible_message(msg, span_userdanger("Your [limb.plaintext_zone] [occur_text]!"), vision_distance = vis_dist)
if(sound_effect)
- playsound(L.owner, sound_effect, 70 + 20 * severity, TRUE)
+ playsound(L.owner, sound_effect, sound_volume + (20 * severity), TRUE)
wound_injury(old_wound, attack_direction = attack_direction)
if(!demoted)
second_wind()
+ return TRUE
+
+/// Returns TRUE if we can be applied to the limb.
+/datum/wound/proc/can_be_applied_to(obj/item/bodypart/L, datum/wound/old_wound)
+ var/datum/wound_pregen_data/pregen_data = GLOB.all_wound_pregen_data[type]
+
+ // We assume we aren't being randomly applied - we have no reason to believe we are
+ // And, besides, if we were, you could just as easily check our pregen data rather than run this proc
+ // Generally speaking this proc is called in apply_wound, which is called when the caller is already confidant in its ability to be applied
+ return pregen_data.can_be_applied_to(L, old_wound = old_wound)
+
+/// Returns the zones we can be applied to.
+/datum/wound/proc/get_viable_zones()
+ var/datum/wound_pregen_data/pregen_data = GLOB.all_wound_pregen_data[type]
+
+ return pregen_data.viable_zones
+
+/// Returns the biostate we require to be applied.
+/datum/wound/proc/get_required_biostate()
+ var/datum/wound_pregen_data/pregen_data = GLOB.all_wound_pregen_data[type]
+
+ return pregen_data.required_limb_biostate
+
// Updates descriptive texts for the wound, in case it can get altered for whatever reason
/datum/wound/proc/update_descriptions()
return
@@ -185,13 +263,66 @@
SIGNAL_HANDLER
set_victim(null)
+/// Setter for [victim]. Should completely transfer signals, attributes, etc. To the new victim - if there is any, as it can be null.
/datum/wound/proc/set_victim(new_victim)
if(victim)
+ UnregisterSignal(victim, list(COMSIG_QDELETING, COMSIG_MOB_SWAP_HANDS, COMSIG_CARBON_POST_REMOVE_LIMB, COMSIG_CARBON_POST_ATTACH_LIMB))
UnregisterSignal(victim, COMSIG_QDELETING)
+ UnregisterSignal(victim, COMSIG_MOB_SWAP_HANDS)
+ UnregisterSignal(victim, COMSIG_CARBON_POST_REMOVE_LIMB)
+ if (actionspeed_mod)
+ victim.remove_actionspeed_modifier(actionspeed_mod) // no need to qdelete it, just remove it from our victim
+
remove_wound_from_victim()
victim = new_victim
if(victim)
RegisterSignal(victim, COMSIG_QDELETING, PROC_REF(null_victim))
+ RegisterSignals(victim, list(COMSIG_MOB_SWAP_HANDS, COMSIG_CARBON_POST_REMOVE_LIMB, COMSIG_CARBON_POST_ATTACH_LIMB), PROC_REF(add_or_remove_actionspeed_mod))
+
+ if (limb)
+ start_limping_if_we_should() // the status effect already handles removing itself
+ add_or_remove_actionspeed_mod()
+
+/// Proc called to change the variable `limb` and react to the event.
+/datum/wound/proc/set_limb(obj/item/bodypart/new_value, replaced = FALSE)
+ if(limb == new_value)
+ return FALSE //Limb can either be a reference to something or `null`. Returning the number variable makes it clear no change was made.
+ . = limb
+ if(limb) // if we're nulling limb, we're basically detaching from it, so we should remove ourselves in that case
+ UnregisterSignal(limb, COMSIG_QDELETING)
+ UnregisterSignal(limb, list(COMSIG_BODYPART_GAUZED, COMSIG_BODYPART_GAUZE_DESTROYED))
+ LAZYREMOVE(limb.wounds, src)
+ limb.update_wounds(replaced)
+ if (disabling)
+ limb.remove_traits(list(TRAIT_PARALYSIS, TRAIT_DISABLED_BY_WOUND), REF(src))
+
+ limb = new_value
+
+ // POST-CHANGE
+
+ if (limb)
+ RegisterSignal(limb, COMSIG_QDELETING, PROC_REF(source_died))
+ RegisterSignals(limb, list(COMSIG_BODYPART_GAUZED, COMSIG_BODYPART_GAUZE_DESTROYED), PROC_REF(gauze_state_changed))
+ if (disabling)
+ limb.add_traits(list(TRAIT_PARALYSIS, TRAIT_DISABLED_BY_WOUND), REF(src))
+
+ if (victim)
+ start_limping_if_we_should() // the status effect already handles removing itself
+ add_or_remove_actionspeed_mod()
+
+ update_inefficiencies(replaced)
+
+/datum/wound/proc/add_or_remove_actionspeed_mod()
+ update_actionspeed_modifier()
+ if (actionspeed_mod)
+ if(victim.get_active_hand() == limb)
+ victim.add_actionspeed_modifier(actionspeed_mod, TRUE)
+ else
+ victim.remove_actionspeed_modifier(actionspeed_mod)
+
+/datum/wound/proc/start_limping_if_we_should()
+ if ((limb.body_zone == BODY_ZONE_L_LEG || limb.body_zone == BODY_ZONE_R_LEG) && limp_slowdown > 0 && limp_chance > 0)
+ victim.apply_status_effect(/datum/status_effect/limp)
/datum/wound/proc/source_died()
SIGNAL_HANDLER
@@ -200,15 +331,26 @@
/// Remove the wound from whatever it's afflicting, and cleans up whateverstatus effects it had or modifiers it had on interaction times. ignore_limb is used for detachments where we only want to forget the victim
/datum/wound/proc/remove_wound(ignore_limb, replaced = FALSE)
//TODO: have better way to tell if we're getting removed without replacement (full heal) scar stuff
+ var/old_victim = victim
+ var/old_limb = limb
+
set_disabling(FALSE)
- if(limb && !already_scarred && !replaced)
+ if(limb && can_scar && !already_scarred && !replaced)
already_scarred = TRUE
var/datum/scar/new_scar = new
new_scar.generate(limb, src)
- remove_wound_from_victim()
+
+ remove_actionspeed_modifier()
+
+ null_victim() // we use the proc here because some behaviors may depend on changing victim to some new value
+
if(limb && !ignore_limb)
- LAZYREMOVE(limb.wounds, src)
- limb.update_wounds(replaced)
+ set_limb(null, replaced) // since we're removing limb's ref to us, we should do the same
+ // if you want to keep the ref, do it externally, theres no reason for us to remember it
+
+ if (ismob(old_victim))
+ var/mob/mob_victim = old_victim
+ SEND_SIGNAL(mob_victim, COMSIG_CARBON_POST_LOSE_WOUND, src, old_limb, ignore_limb, replaced)
/datum/wound/proc/remove_wound_from_victim()
if(!victim)
@@ -221,17 +363,15 @@
/**
* replace_wound() is used when you want to replace the current wound with a new wound, presumably of the same category, just of a different severity (either up or down counts)
*
- * This proc actually instantiates the new wound based off the specific type path passed, then returns the new instantiated wound datum.
- *
* Arguments:
- * * new_type- The TYPE PATH of the wound you want to replace this, like /datum/wound/slash/severe
+ * * new_wound- The wound instance you want to replace this
* * smited- If this is a smite, we don't care about this wound for stat tracking purposes (not yet implemented)
*/
-/datum/wound/proc/replace_wound(new_type, smited = FALSE, attack_direction = attack_direction)
- var/datum/wound/new_wound = new new_type
+/datum/wound/proc/replace_wound(datum/wound/new_wound, smited = FALSE, attack_direction = attack_direction)
already_scarred = TRUE
+ var/obj/item/bodypart/cached_limb = limb // remove_wound() nulls limb so we have to track it locally
remove_wound(replaced=TRUE)
- new_wound.apply_wound(limb, old_wound = src, smited = smited, attack_direction = attack_direction, wound_source = wound_source)
+ new_wound.apply_wound(cached_limb, old_wound = src, smited = smited, attack_direction = attack_direction, wound_source = wound_source)
. = new_wound
qdel(src)
@@ -239,24 +379,6 @@
/datum/wound/proc/wound_injury(datum/wound/old_wound = null, attack_direction = null)
return
-
-/// Proc called to change the variable `limb` and react to the event.
-/datum/wound/proc/set_limb(new_value)
- if(limb == new_value)
- return FALSE //Limb can either be a reference to something or `null`. Returning the number variable makes it clear no change was made.
- . = limb
- if(limb)
- UnregisterSignal(limb, COMSIG_QDELETING)
- limb = new_value
- RegisterSignal(new_value, COMSIG_QDELETING, PROC_REF(source_died))
- if(. && disabling)
- var/obj/item/bodypart/old_limb = .
- old_limb.remove_traits(list(TRAIT_PARALYSIS, TRAIT_DISABLED_BY_WOUND), REF(src))
- if(limb)
- if(disabling)
- limb.add_traits(list(TRAIT_PARALYSIS, TRAIT_DISABLED_BY_WOUND), REF(src))
-
-
/// Proc called to change the variable `disabling` and react to the event.
/datum/wound/proc/set_disabling(new_value)
if(disabling == new_value)
@@ -271,6 +393,60 @@
if(limb?.can_be_disabled)
limb.update_disabled()
+/// Setter for [interaction_efficiency_penalty]. Updates the actionspeed of our actionspeed mod.
+/datum/wound/proc/set_interaction_efficiency_penalty(new_value)
+ var/should_update = (new_value != interaction_efficiency_penalty)
+
+ interaction_efficiency_penalty = new_value
+
+ if (should_update)
+ update_actionspeed_modifier()
+
+/// Returns a "adjusted" interaction_efficiency_penalty that will be used for the actionspeed mod.
+/datum/wound/proc/get_effective_actionspeed_modifier()
+ return interaction_efficiency_penalty - 1
+
+/// Returns the decisecond multiplier of any click interactions, assuming our limb is being used.
+/datum/wound/proc/get_action_delay_mult()
+ SHOULD_BE_PURE(TRUE)
+
+ return interaction_efficiency_penalty
+
+/// Returns the decisecond increment of any click interactions, assuming our limb is being used.
+/datum/wound/proc/get_action_delay_increment()
+ SHOULD_BE_PURE(TRUE)
+
+ return 0
+
+/// Signal proc for if gauze has been applied or removed from our limb.
+/datum/wound/proc/gauze_state_changed()
+ SIGNAL_HANDLER
+
+ if (wound_flags & ACCEPTS_GAUZE)
+ update_inefficiencies()
+
+/// Updates our limping and interaction penalties in accordance with our gauze.
+/datum/wound/proc/update_inefficiencies(replaced_or_replacing = FALSE)
+ if (wound_flags & ACCEPTS_GAUZE)
+ if(limb.body_zone in list(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
+ if(limb.current_gauze?.splint_factor)
+ limp_slowdown = initial(limp_slowdown) * limb.current_gauze.splint_factor
+ limp_chance = initial(limp_chance) * limb.current_gauze.splint_factor
+ else
+ limp_slowdown = initial(limp_slowdown)
+ limp_chance = initial(limp_chance)
+ else if(limb.body_zone in list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM))
+ if(limb.current_gauze?.splint_factor)
+ set_interaction_efficiency_penalty(1 + ((get_effective_actionspeed_modifier()) * limb.current_gauze.splint_factor))
+ else
+ set_interaction_efficiency_penalty(initial(interaction_efficiency_penalty))
+
+ if(initial(disabling))
+ set_disabling(!limb.current_gauze)
+
+ limb.update_wounds(replaced_or_replacing)
+
+ start_limping_if_we_should()
/// Additional beneficial effects when the wound is gained, in case you want to give a temporary boost to allow the victim to try an escape or last stand
/datum/wound/proc/second_wind()
@@ -304,25 +480,7 @@
if(I.force && tendee.combat_mode)
return FALSE
- var/allowed = FALSE
-
- // check if we have a valid treatable tool
- if(I.tool_behaviour == treatable_tool)
- allowed = TRUE
- else if(treatable_tool == TOOL_CAUTERY && I.get_temperature() && user == victim) // allow improvised cauterization on yourself without an aggro grab
- allowed = TRUE
- // failing that, see if we're aggro grabbing them and if we have an item that works for aggro grabs only
- else if(user.pulling == victim && user.grab_state >= GRAB_AGGRESSIVE && check_grab_treatments(I, user))
- allowed = TRUE
- // failing THAT, we check if we have a generally allowed item
- else
- for(var/allowed_type in treatable_by)
- if(istype(I, allowed_type))
- allowed = TRUE
- break
-
- // if none of those apply, we return false to avoid interrupting
- if(!allowed)
+ if(!item_can_treat(I, user))
return FALSE
// now that we've determined we have a valid attempt at treating, we can stomp on their dreams if we're already interacting with the patient or if their part is obscured
@@ -338,8 +496,22 @@
return TRUE
// lastly, treat them
- treat(I, user)
- return TRUE
+ return treat(I, user) // we allow treat to return a value so it can control if the item does its normal interaction or not
+
+/// Returns TRUE if the item can be used to treat our wounds. Hooks into treat() - only things that return TRUE here may be used there.
+/datum/wound/proc/item_can_treat(obj/item/potential_treater, mob/user)
+ // check if we have a valid treatable tool
+ if(potential_treater.tool_behaviour in treatable_tools)
+ return TRUE
+ if(TOOL_CAUTERY in treatable_tools && potential_treater.get_temperature() && user == victim) // allow improvised cauterization on yourself without an aggro grab
+ return TRUE
+ // failing that, see if we're aggro grabbing them and if we have an item that works for aggro grabs only
+ if(user.pulling == victim && user.grab_state >= GRAB_AGGRESSIVE && check_grab_treatments(potential_treater, user))
+ return TRUE
+ // failing THAT, we check if we have a generally allowed item
+ for(var/allowed_type in treatable_by)
+ if(istype(potential_treater, allowed_type))
+ return TRUE
/// Return TRUE if we have an item that can only be used while aggro grabbed (unhanded aggro grab treatments go in [/datum/wound/proc/try_handling]). Treatment is still is handled in [/datum/wound/proc/treat]
/datum/wound/proc/check_grab_treatments(obj/item/I, mob/user)
@@ -361,18 +533,29 @@
/datum/wound/proc/still_exists()
return (!QDELETED(src) && limb)
-/// When our parent bodypart is hurt
-/datum/wound/proc/receive_damage(wounding_type, wounding_dmg, wound_bonus, attack_direction)
+/// When our parent bodypart is hurt.
+/datum/wound/proc/receive_damage(wounding_type, wounding_dmg, wound_bonus, attack_direction, damage_source)
return
/// Called from cryoxadone and pyroxadone when they're proc'ing. Wounds will slowly be fixed separately from other methods when these are in effect. crappy name but eh
/datum/wound/proc/on_xadone(power)
cryo_progress += power
- if(cryo_progress > 33 * severity)
+
+ return handle_xadone_progress()
+
+/// Does various actions based on [cryo_progress]. By default, qdeletes the wound past a certain threshold.
+/datum/wound/proc/handle_xadone_progress()
+ if(cryo_progress > get_xadone_progress_to_qdel())
qdel(src)
+/// Returns the amount of [cryo_progress] we need to be qdeleted.
+/datum/wound/proc/get_xadone_progress_to_qdel()
+ SHOULD_BE_PURE(TRUE)
+
+ return base_xadone_progress_to_qdel * severity
+
/// When synthflesh is applied to the victim, we call this. No sense in setting up an entire chem reaction system for wounds when we only care for a few chems. Probably will change in the future
-/datum/wound/proc/on_synthflesh(power)
+/datum/wound/proc/on_synthflesh(reac_volume)
return
/// Called when the patient is undergoing stasis, so that having fully treated a wound doesn't make you sit there helplessly until you think to unbuckle them
@@ -427,25 +610,104 @@
return .
/datum/wound/proc/get_wound_description(mob/user)
- . = "[victim.p_Their()] [limb.plaintext_zone] [examine_desc]"
- . = severity <= WOUND_SEVERITY_MODERATE ? "[.]." : "[.]!"
- return .
+ var/desc
+
+ if ((wound_flags & ACCEPTS_GAUZE) && limb.current_gauze)
+ var/sling_condition = get_gauze_condition()
+ desc = "[victim.p_Their()] [limb.plaintext_zone] is [sling_condition] fastened in a sling of [limb.current_gauze.name]"
+ else
+ desc = "[victim.p_Their()] [limb.plaintext_zone] [examine_desc]"
+
+ desc = modify_desc_before_span(desc, user)
+
+ return get_desc_intensity(desc)
+
+/// A hook proc used to modify desc before it is spanned via [get_desc_intensity]. Useful for inserting spans yourself.
+/datum/wound/proc/modify_desc_before_span(desc, mob/user)
+ return desc
+
+/datum/wound/proc/get_gauze_condition()
+ SHOULD_BE_PURE(TRUE)
+ if (!limb.current_gauze)
+ return null
+
+ switch(limb.current_gauze.absorption_capacity)
+ if(0 to 1.25)
+ return "just barely"
+ if(1.25 to 2.75)
+ return "loosely"
+ if(2.75 to 4)
+ return "mostly"
+ if(4 to INFINITY)
+ return "tightly"
+
+/// Spans [desc] based on our severity.
+/datum/wound/proc/get_desc_intensity(desc)
+ SHOULD_BE_PURE(TRUE)
+ if (severity > WOUND_SEVERITY_MODERATE)
+ return span_bold("[desc]!")
+ return "[desc]."
/datum/wound/proc/get_scanner_description(mob/user)
- return "Type: [name]\nSeverity: [severity_text()]\nDescription: [desc]\nRecommended Treatment: [treat_text]"
+ return "Type: [name]\nSeverity: [severity_text(simple = FALSE)]\nDescription: [desc]\nRecommended Treatment: [treat_text]"
-/datum/wound/proc/severity_text()
+/datum/wound/proc/get_simple_scanner_description(mob/user)
+ return "[name] detected!\nRisk: [severity_text(simple = TRUE)]\nDescription: [simple_desc ? simple_desc : desc]\nTreatment Guide: [simple_treat_text]\nHomemade Remedies: [homemade_treat_text]"
+
+/datum/wound/proc/severity_text(simple = FALSE)
switch(severity)
if(WOUND_SEVERITY_TRIVIAL)
return "Trivial"
if(WOUND_SEVERITY_MODERATE)
- return "Moderate"
+ return "Moderate" + (simple ? "!" : "")
if(WOUND_SEVERITY_SEVERE)
- return "Severe"
+ return "Severe" + (simple ? "!!" : "")
if(WOUND_SEVERITY_CRITICAL)
- return "Critical"
+ return "Critical" + (simple ? "!!!" : "")
+
+/// Returns TRUE if our limb is the head or chest, FALSE otherwise.
+/// Essential in the sense of "we cannot live without it".
+/datum/wound/proc/limb_essential()
+ return (limb.body_zone == BODY_ZONE_HEAD || limb.body_zone == BODY_ZONE_CHEST)
+
+/// Getter proc for our scar_keyword, in case we might have some custom scar gen logic.
+/datum/wound/proc/get_scar_keyword(obj/item/bodypart/scarred_limb, add_to_scars)
+ return scar_keyword
+
+/// Getter proc for our scar_file, in case we might have some custom scar gen logic.
+/datum/wound/proc/get_scar_file(obj/item/bodypart/scarred_limb, add_to_scars)
+ var/datum/wound_pregen_data/pregen_data = get_pregen_data()
+ // basically we iterate over biotypes until we find the one we want
+ // fleshy burns will look for flesh then bone
+ // dislocations will look for flesh, then bone, then metal
+ var/file = default_scar_file
+ for (var/biotype as anything in pregen_data.scar_priorities)
+ if (scarred_limb.biological_state & text2num(biotype))
+ file = GLOB.biotypes_to_scar_file[biotype]
+ break
+
+ return file
/// Returns what string is displayed when a limb that has sustained this wound is examined
/// (This is examining the LIMB ITSELF, when it's not attached to someone.)
/datum/wound/proc/get_limb_examine_description()
return
+
+/// Gets the flat percentage chance increment of a dismember occuring, if a dismember is attempted (requires mangled flesh and bone). returning 15 = +15%.
+/datum/wound/proc/get_dismember_chance_bonus(existing_chance)
+ SHOULD_BE_PURE(TRUE)
+
+ var/datum/wound_pregen_data/pregen_data = get_pregen_data()
+
+ if (WOUND_BLUNT in pregen_data.required_wounding_types && severity >= WOUND_SEVERITY_CRITICAL)
+ return WOUND_CRITICAL_BLUNT_DISMEMBER_BONUS // we only require mangled bone (T2 blunt), but if there's a critical blunt, we'll add 15% more
+
+/// Returns our pregen data, which is practically guaranteed to exist, so this proc can safely be used raw.
+/// In fact, since it's RETURN_TYPEd to wound_pregen_data, you can even directly access the variables without having to store the value of this proc in a typed variable.
+/// Ex. get_pregen_data().wound_series
+/datum/wound/proc/get_pregen_data()
+ RETURN_TYPE(/datum/wound_pregen_data)
+
+ return GLOB.all_wound_pregen_data[type]
+
+#undef WOUND_CRITICAL_BLUNT_DISMEMBER_BONUS
diff --git a/code/datums/wounds/blunt.dm b/code/datums/wounds/blunt.dm
new file mode 100644
index 00000000000..219b7dd8805
--- /dev/null
+++ b/code/datums/wounds/blunt.dm
@@ -0,0 +1,3 @@
+/datum/wound/blunt
+ name = "Blunt Wound"
+ sound_effect = 'sound/effects/wounds/crack1.ogg'
diff --git a/code/datums/wounds/bones.dm b/code/datums/wounds/bones.dm
index aa6cad87ed8..59e64db1ccf 100644
--- a/code/datums/wounds/bones.dm
+++ b/code/datums/wounds/bones.dm
@@ -1,16 +1,21 @@
-//SKYRAT EDIT REMOVAL - MOVED - MEDICINE
-/*
-
/*
Blunt/Bone wounds
*/
// TODO: well, a lot really, but i'd kill to get overlays and a bonebreaking effect like Blitz: The League, similar to electric shock skeletons
-/datum/wound/blunt
+/datum/wound_pregen_data/bone
+ abstract = TRUE
+ required_limb_biostate = BIO_BONE
+
+ required_wounding_types = list(WOUND_BLUNT)
+
+ wound_series = WOUND_SERIES_BONE_BLUNT_BASIC
+
+/datum/wound/blunt/bone
name = "Blunt (Bone) Wound"
- sound_effect = 'sound/effects/wounds/crack1.ogg'
- wound_type = WOUND_BLUNT
- wound_flags = (BONE_WOUND | ACCEPTS_GAUZE)
+ wound_flags = (ACCEPTS_GAUZE | SPLINT_OVERLAY) // SKYRAT EDIT: MEDICAL -- Makes bone wounds have a splint overlay
+
+ default_scar_file = BONE_SCAR_FILE
/// Have we been bone gel'd?
var/gelled
@@ -34,16 +39,13 @@
/*
Overwriting of base procs
*/
-/datum/wound/blunt/wound_injury(datum/wound/old_wound = null, attack_direction = null)
+/datum/wound/blunt/bone/wound_injury(datum/wound/old_wound = null, attack_direction = null)
// hook into gaining/losing gauze so crit bone wounds can re-enable/disable depending if they're slung or not
- RegisterSignals(limb, list(COMSIG_BODYPART_GAUZED, COMSIG_BODYPART_GAUZE_DESTROYED), PROC_REF(update_inefficiencies))
-
if(limb.body_zone == BODY_ZONE_HEAD && brain_trauma_group)
processes = TRUE
active_trauma = victim.gain_trauma_type(brain_trauma_group, TRAUMA_RESILIENCE_WOUND)
next_trauma_cycle = world.time + (rand(100-WOUND_BONE_HEAD_TIME_VARIANCE, 100+WOUND_BONE_HEAD_TIME_VARIANCE) * 0.01 * trauma_cycle_cooldown)
- RegisterSignal(victim, COMSIG_HUMAN_EARLY_UNARMED_ATTACK, PROC_REF(attack_with_hurt_hand))
if(limb.held_index && victim.get_item_for_held_index(limb.held_index) && (disabling || prob(30 * severity)))
var/obj/item/I = victim.get_item_for_held_index(limb.held_index)
if(istype(I, /obj/item/offhand))
@@ -53,19 +55,29 @@
victim.visible_message(span_danger("[victim] drops [I] in shock!"), span_warning("The force on your [limb.plaintext_zone] causes you to drop [I]!"), vision_distance=COMBAT_MESSAGE_RANGE)
update_inefficiencies()
+ return ..()
-/datum/wound/blunt/remove_wound(ignore_limb, replaced)
+/datum/wound/blunt/bone/set_victim(new_victim)
+
+ if (victim)
+ UnregisterSignal(victim, COMSIG_HUMAN_EARLY_UNARMED_ATTACK)
+ if (new_victim)
+ RegisterSignal(new_victim, COMSIG_HUMAN_EARLY_UNARMED_ATTACK, PROC_REF(attack_with_hurt_hand))
+
+ return ..()
+
+/datum/wound/blunt/bone/remove_wound(ignore_limb, replaced)
limp_slowdown = 0
limp_chance = 0
QDEL_NULL(active_trauma)
- if(limb)
- UnregisterSignal(limb, list(COMSIG_BODYPART_GAUZED, COMSIG_BODYPART_GAUZE_DESTROYED))
- if(victim)
- UnregisterSignal(victim, COMSIG_HUMAN_EARLY_UNARMED_ATTACK)
return ..()
-/datum/wound/blunt/handle_process(seconds_per_tick, times_fired)
+/datum/wound/blunt/bone/handle_process(seconds_per_tick, times_fired)
. = ..()
+
+ if (!victim || IS_IN_STASIS(victim))
+ return
+
if(limb.body_zone == BODY_ZONE_HEAD && brain_trauma_group && world.time > next_trauma_cycle)
if(active_trauma)
QDEL_NULL(active_trauma)
@@ -98,7 +110,7 @@
remove_wound()
/// If we're a human who's punching something with a broken arm, we might hurt ourselves doing so
-/datum/wound/blunt/proc/attack_with_hurt_hand(mob/M, atom/target, proximity)
+/datum/wound/blunt/bone/proc/attack_with_hurt_hand(mob/M, atom/target, proximity)
SIGNAL_HANDLER
if(victim.get_active_hand() != limb || !victim.combat_mode || !ismob(target) || severity <= WOUND_SEVERITY_MODERATE)
@@ -119,7 +131,7 @@
return COMPONENT_CANCEL_ATTACK_CHAIN
-/datum/wound/blunt/receive_damage(wounding_type, wounding_dmg, wound_bonus)
+/datum/wound/blunt/bone/receive_damage(wounding_type, wounding_dmg, wound_bonus)
if(!victim || wounding_dmg < WOUND_MINIMUM_DAMAGE)
return
if(ishuman(victim))
@@ -145,102 +157,81 @@
new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir)
victim.add_splatter_floor(get_step(victim.loc, victim.dir))
+/datum/wound/blunt/bone/modify_desc_before_span(desc)
+ . = ..()
-/datum/wound/blunt/get_wound_description(mob/user)
- if(!limb.current_gauze && !gelled && !taped)
- return ..()
-
- var/list/msg = list()
- if(!limb.current_gauze)
- msg += "[victim.p_Their()] [limb.plaintext_zone] [examine_desc]"
- else
- var/sling_condition = ""
- // how much life we have left in these bandages
- switch(limb.current_gauze.absorption_capacity)
- if(0 to 1.25)
- sling_condition = "just barely"
- if(1.25 to 2.75)
- sling_condition = "loosely"
- if(2.75 to 4)
- sling_condition = "mostly"
- if(4 to INFINITY)
- sling_condition = "tightly"
-
- msg += "[victim.p_Their()] [limb.plaintext_zone] is [sling_condition] fastened in a sling of [limb.current_gauze.name]"
-
- if(taped)
- msg += ", [span_notice("and appears to be reforming itself under some surgical tape!")]"
- else if(gelled)
- msg += ", [span_notice("with fizzing flecks of blue bone gel sparking off the bone!")]"
- else
- msg += "!"
- return "[msg.Join()]"
+ if (!limb.current_gauze)
+ if(taped)
+ . += ", [span_notice("and appears to be reforming itself under some surgical tape!")]"
+ else if(gelled)
+ . += ", [span_notice("with fizzing flecks of blue bone gel sparking off the bone!")]"
/datum/wound/blunt/get_limb_examine_description()
return span_warning("The bones in this limb appear badly cracked.")
/*
- New common procs for /datum/wound/blunt/
+ New common procs for /datum/wound/blunt/bone/
*/
-/datum/wound/blunt/proc/update_inefficiencies()
- SIGNAL_HANDLER
+/datum/wound/blunt/bone/get_scar_file(obj/item/bodypart/scarred_limb, add_to_scars)
+ if (scarred_limb.biological_state & BIO_BONE && (!(scarred_limb.biological_state & BIO_FLESH))) // only bone
+ return BONE_SCAR_FILE
+ else if (scarred_limb.biological_state & BIO_FLESH && (!(scarred_limb.biological_state & BIO_BONE)))
+ return FLESH_SCAR_FILE
- if(limb.body_zone in list(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
- if(limb.current_gauze?.splint_factor)
- limp_slowdown = initial(limp_slowdown) * limb.current_gauze.splint_factor
- limp_chance = initial(limp_chance) * limb.current_gauze.splint_factor
- else
- limp_slowdown = initial(limp_slowdown)
- limp_chance = initial(limp_chance)
- victim.apply_status_effect(/datum/status_effect/limp)
- else if(limb.body_zone in list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM))
- if(limb.current_gauze?.splint_factor)
- interaction_efficiency_penalty = 1 + ((interaction_efficiency_penalty - 1) * limb.current_gauze.splint_factor)
- else
- interaction_efficiency_penalty = initial(interaction_efficiency_penalty)
-
- if(initial(disabling))
- set_disabling(!limb.current_gauze)
-
- limb.update_wounds()
+ return ..()
/// Joint Dislocation (Moderate Blunt)
-/datum/wound/blunt/moderate
+/datum/wound/blunt/bone/moderate
name = "Joint Dislocation"
- desc = "Patient's bone has been unset from socket, causing pain and reduced motor function."
+ desc = "Patient's limb has been unset from socket, causing pain and reduced motor function."
treat_text = "Recommended application of bonesetter to affected limb, though manual relocation by applying an aggressive grab to the patient and helpfully interacting with afflicted limb may suffice."
examine_desc = "is awkwardly janked out of place"
occur_text = "janks violently and becomes unseated"
severity = WOUND_SEVERITY_MODERATE
- viable_zones = list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
interaction_efficiency_penalty = 1.3
limp_slowdown = 3
limp_chance = 50
- threshold_minimum = 35
threshold_penalty = 15
- treatable_tool = TOOL_BONESET
- wound_flags = (BONE_WOUND)
- status_effect_type = /datum/status_effect/wound/blunt/moderate
- scar_keyword = "bluntmoderate"
+ treatable_tools = list(TOOL_BONESET)
+ status_effect_type = /datum/status_effect/wound/blunt/bone/moderate
+ scar_keyword = "dislocate"
-/datum/wound/blunt/moderate/Destroy()
+ simple_desc = "Patient's bone has been dislocated, causing limping or reduced dexterity."
+ simple_treat_text = "Bandaging the wound will reduce its impact until treated with a bonesetter. Most commonly, it is treated by aggressively grabbing someone and helpfully wrenching the limb in place, though there's room for malfeasance when doing this."
+ homemade_treat_text = "Besides bandaging and wrenching, bone setters can be printed in lathes and utilized on oneself at the cost of great pain. As a last resort, crushing the patient with a firelock has sometimes been noted to fix their dislocated limb."
+
+/datum/wound_pregen_data/bone/dislocate
+ abstract = FALSE
+
+ wound_path_to_generate = /datum/wound/blunt/bone/moderate
+
+ required_limb_biostate = BIO_JOINTED
+
+ threshold_minimum = 35
+
+/datum/wound/blunt/bone/moderate/Destroy()
if(victim)
UnregisterSignal(victim, COMSIG_LIVING_DOORCRUSHED)
return ..()
-/datum/wound/blunt/moderate/wound_injury(datum/wound/old_wound, attack_direction = null)
- . = ..()
- RegisterSignal(victim, COMSIG_LIVING_DOORCRUSHED, PROC_REF(door_crush))
+/datum/wound/blunt/bone/moderate/set_victim(new_victim)
+
+ if (victim)
+ UnregisterSignal(victim, COMSIG_LIVING_DOORCRUSHED)
+ if (new_victim)
+ RegisterSignal(new_victim, COMSIG_LIVING_DOORCRUSHED, PROC_REF(door_crush))
+
+ return ..()
/// Getting smushed in an airlock/firelock is a last-ditch attempt to try relocating your limb
-/datum/wound/blunt/moderate/proc/door_crush()
+/datum/wound/blunt/bone/moderate/proc/door_crush()
SIGNAL_HANDLER
if(prob(40))
victim.visible_message(span_danger("[victim]'s dislocated [limb.plaintext_zone] pops back into place!"), span_userdanger("Your dislocated [limb.plaintext_zone] pops back into place! Ow!"))
remove_wound()
-/datum/wound/blunt/moderate/try_handling(mob/living/carbon/human/user)
+/datum/wound/blunt/bone/moderate/try_handling(mob/living/carbon/human/user)
if(user.pulling != victim || user.zone_selected != limb.body_zone)
return FALSE
@@ -258,7 +249,7 @@
return TRUE
/// If someone is snapping our dislocated joint back into place by hand with an aggro grab and help intent
-/datum/wound/blunt/moderate/proc/chiropractice(mob/living/carbon/human/user)
+/datum/wound/blunt/bone/moderate/proc/chiropractice(mob/living/carbon/human/user)
var/time = base_treat_time
if(!do_after(user, time, target=victim, extra_checks = CALLBACK(src, PROC_REF(still_exists))))
@@ -277,7 +268,7 @@
chiropractice(user)
/// If someone is snapping our dislocated joint into a fracture by hand with an aggro grab and harm or disarm intent
-/datum/wound/blunt/moderate/proc/malpractice(mob/living/carbon/human/user)
+/datum/wound/blunt/bone/moderate/proc/malpractice(mob/living/carbon/human/user)
var/time = base_treat_time
if(!do_after(user, time, target=victim, extra_checks = CALLBACK(src, PROC_REF(still_exists))))
@@ -295,7 +286,7 @@
malpractice(user)
-/datum/wound/blunt/moderate/treat(obj/item/I, mob/user)
+/datum/wound/blunt/bone/moderate/treat(obj/item/I, mob/user)
var/scanned = HAS_TRAIT(src, TRAIT_WOUND_SCANNED)
var/self_penalty_mult = user == victim ? 1.5 : 1
var/scanned_mult = scanned ? 0.5 : 1
@@ -324,7 +315,7 @@
Severe (Hairline Fracture)
*/
-/datum/wound/blunt/severe
+/datum/wound/blunt/bone/severe
name = "Hairline Fracture"
desc = "Patient's bone has suffered a crack in the foundation, causing serious pain and reduced limb functionality."
treat_text = "Recommended light surgical application of bone gel, though a sling of medical gauze will prevent worsening situation."
@@ -335,19 +326,30 @@
interaction_efficiency_penalty = 2
limp_slowdown = 6
limp_chance = 60
- threshold_minimum = 60
threshold_penalty = 30
treatable_by = list(/obj/item/stack/sticky_tape/surgical, /obj/item/stack/medical/bone_gel)
- status_effect_type = /datum/status_effect/wound/blunt/severe
+ status_effect_type = /datum/status_effect/wound/blunt/bone/severe
scar_keyword = "bluntsevere"
brain_trauma_group = BRAIN_TRAUMA_MILD
trauma_cycle_cooldown = 1.5 MINUTES
internal_bleeding_chance = 40
- wound_flags = (BONE_WOUND | ACCEPTS_GAUZE | MANGLES_BONE)
+ wound_flags = (ACCEPTS_GAUZE | MANGLES_INTERIOR | SPLINT_OVERLAY) // SKYRAT EDIT - MEDICAL (SPLINT_OVERLAY)
regen_ticks_needed = 120 // ticks every 2 seconds, 240 seconds, so roughly 4 minutes default
+ simple_desc = "Patient's bone has cracked in the middle, drastically reducing limb functionality."
+ simple_treat_text = "Bandaging the wound will reduce its impact until surgically treated with bone gel and surgical tape."
+ homemade_treat_text = "Bone gel and surgical tape may be applied directly to the wound, though this is quite difficult for most people to do so individually unless they've dosed themselves with one or more painkillers (Morphine and Miner's Salve have been known to help)"
+
+
+/datum/wound_pregen_data/bone/hairline
+ abstract = FALSE
+
+ wound_path_to_generate = /datum/wound/blunt/bone/severe
+
+ threshold_minimum = 60
+
/// Compound Fracture (Critical Blunt)
-/datum/wound/blunt/critical
+/datum/wound/blunt/bone/critical
name = "Compound Fracture"
desc = "Patient's bones have suffered multiple gruesome fractures, causing significant pain and near uselessness of limb."
treat_text = "Immediate binding of affected limb, followed by surgical intervention ASAP."
@@ -359,40 +361,49 @@
limp_slowdown = 7
limp_chance = 70
sound_effect = 'sound/effects/wounds/crack2.ogg'
- threshold_minimum = 115
threshold_penalty = 50
disabling = TRUE
treatable_by = list(/obj/item/stack/sticky_tape/surgical, /obj/item/stack/medical/bone_gel)
- status_effect_type = /datum/status_effect/wound/blunt/critical
+ status_effect_type = /datum/status_effect/wound/blunt/bone/critical
scar_keyword = "bluntcritical"
brain_trauma_group = BRAIN_TRAUMA_SEVERE
trauma_cycle_cooldown = 2.5 MINUTES
internal_bleeding_chance = 60
- wound_flags = (BONE_WOUND | ACCEPTS_GAUZE | MANGLES_BONE)
+ wound_flags = (ACCEPTS_GAUZE | MANGLES_INTERIOR | SPLINT_OVERLAY) // SKYRAT EDIT - MEDICAL (SPLINT_OVERLAY)
regen_ticks_needed = 240 // ticks every 2 seconds, 480 seconds, so roughly 8 minutes default
+ simple_desc = "Patient's bones have effectively shattered completely, causing total immobilization of the limb."
+ simple_treat_text = "Bandaging the wound will slightly reduce its impact until surgically treated with bone gel and surgical tape."
+ homemade_treat_text = "Although this is extremely difficult and slow to function, Bone gel and surgical tape may be applied directly to the wound, though this is nigh-impossible for most people to do so individually unless they've dosed themselves with one or more painkillers (Morphine and Miner's Salve have been known to help)"
+
+/datum/wound_pregen_data/bone/compound
+ abstract = FALSE
+
+ wound_path_to_generate = /datum/wound/blunt/bone/critical
+
+ threshold_minimum = 115
+
// doesn't make much sense for "a" bone to stick out of your head
-/datum/wound/blunt/critical/apply_wound(obj/item/bodypart/L, silent = FALSE, datum/wound/old_wound = null, smited = FALSE, attack_direction = null, wound_source = "Unknown")
+/datum/wound/blunt/bone/critical/apply_wound(obj/item/bodypart/L, silent = FALSE, datum/wound/old_wound = null, smited = FALSE, attack_direction = null, wound_source = "Unknown")
if(L.body_zone == BODY_ZONE_HEAD)
occur_text = "splits open, exposing a bare, cracked skull through the flesh and blood"
examine_desc = "has an unsettling indent, with bits of skull poking out"
. = ..()
/// if someone is using bone gel on our wound
-/datum/wound/blunt/proc/gel(obj/item/stack/medical/bone_gel/I, mob/user)
+/datum/wound/blunt/bone/proc/gel(obj/item/stack/medical/bone_gel/I, mob/user)
// skellies get treated nicer with bone gel since their "reattach dismembered limbs by hand" ability sucks when it's still critically wounded
if((limb.biological_state & BIO_BONE) && !(limb.biological_state & BIO_FLESH))
- skelly_gel(I, user)
- return
+ return skelly_gel(I, user)
if(gelled)
to_chat(user, span_warning("[user == victim ? "Your" : "[victim]'s"] [limb.plaintext_zone] is already coated with bone gel!"))
- return
+ return TRUE
user.visible_message(span_danger("[user] begins hastily applying [I] to [victim]'s' [limb.plaintext_zone]..."), span_warning("You begin hastily applying [I] to [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone], disregarding the warning label..."))
if(!do_after(user, base_treat_time * 1.5 * (user == victim ? 1.5 : 1), target = victim, extra_checks=CALLBACK(src, PROC_REF(still_exists))))
- return
+ return TRUE
I.use(1)
victim.emote("scream")
@@ -415,15 +426,16 @@
if(prob(25 + (20 * (severity - 2)) - painkiller_bonus)) // 25%/45% chance to fail self-applying with severe and critical wounds, modded by painkillers
victim.visible_message(span_danger("[victim] fails to finish applying [I] to [victim.p_their()] [limb.plaintext_zone], passing out from the pain!"), span_notice("You pass out from the pain of applying [I] to your [limb.plaintext_zone] before you can finish!"))
victim.AdjustUnconscious(5 SECONDS)
- return
+ return TRUE
victim.visible_message(span_notice("[victim] finishes applying [I] to [victim.p_their()] [limb.plaintext_zone], grimacing from the pain!"), span_notice("You finish applying [I] to your [limb.plaintext_zone], and your bones explode in pain!"))
limb.receive_damage(25, wound_bonus=CANT_WOUND)
victim.adjustStaminaLoss(100)
gelled = TRUE
+ return TRUE
/// skellies are less averse to bone gel, since they're literally all bone
-/datum/wound/blunt/proc/skelly_gel(obj/item/stack/medical/bone_gel/I, mob/user)
+/datum/wound/blunt/bone/proc/skelly_gel(obj/item/stack/medical/bone_gel/I, mob/user)
if(gelled)
to_chat(user, span_warning("[user == victim ? "Your" : "[victim]'s"] [limb.plaintext_zone] is already coated with bone gel!"))
return
@@ -442,20 +454,21 @@
gelled = TRUE
processes = TRUE
+ return TRUE
/// if someone is using surgical tape on our wound
-/datum/wound/blunt/proc/tape(obj/item/stack/sticky_tape/surgical/I, mob/user)
+/datum/wound/blunt/bone/proc/tape(obj/item/stack/sticky_tape/surgical/I, mob/user)
if(!gelled)
to_chat(user, span_warning("[user == victim ? "Your" : "[victim]'s"] [limb.plaintext_zone] must be coated with bone gel to perform this emergency operation!"))
- return
+ return TRUE
if(taped)
to_chat(user, span_warning("[user == victim ? "Your" : "[victim]'s"] [limb.plaintext_zone] is already wrapped in [I.name] and reforming!"))
- return
+ return TRUE
user.visible_message(span_danger("[user] begins applying [I] to [victim]'s' [limb.plaintext_zone]..."), span_warning("You begin applying [I] to [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone]..."))
if(!do_after(user, base_treat_time * (user == victim ? 1.5 : 1), target = victim, extra_checks=CALLBACK(src, PROC_REF(still_exists))))
- return
+ return TRUE
if(victim == user)
regen_ticks_needed *= 1.5
@@ -469,14 +482,15 @@
taped = TRUE
processes = TRUE
+ return TRUE
-/datum/wound/blunt/treat(obj/item/I, mob/user)
+/datum/wound/blunt/bone/treat(obj/item/I, mob/user)
if(istype(I, /obj/item/stack/medical/bone_gel))
- gel(I, user)
+ return gel(I, user)
else if(istype(I, /obj/item/stack/sticky_tape/surgical))
- tape(I, user)
+ return tape(I, user)
-/datum/wound/blunt/get_scanner_description(mob/user)
+/datum/wound/blunt/bone/get_scanner_description(mob/user)
. = ..()
. += "
"
@@ -500,4 +514,3 @@
else if(limb.body_zone == BODY_ZONE_CHEST && victim.blood_volume)
. += "Ribcage Trauma Detected: Further trauma to chest is likely to worsen internal bleeding until bone is repaired."
. += "
"
-*/
diff --git a/code/datums/wounds/burns.dm b/code/datums/wounds/burns.dm
index d3e7221d8f3..a97706c8e16 100644
--- a/code/datums/wounds/burns.dm
+++ b/code/datums/wounds/burns.dm
@@ -1,6 +1,3 @@
-//SKYRAT EDIT REMOVAL - MOVED - MEDICINE
-/*
-
/*
Burn wounds
*/
@@ -9,20 +6,24 @@
/datum/wound/burn
name = "Burn Wound"
a_or_from = "from"
- wound_type = WOUND_BURN
- processes = TRUE
sound_effect = 'sound/effects/wounds/sizzle1.ogg'
- wound_flags = (FLESH_WOUND | ACCEPTS_GAUZE)
+
+/datum/wound/burn/flesh
+ name = "Burn (Flesh) Wound"
+ a_or_from = "from"
+ processes = TRUE
+
+ default_scar_file = FLESH_SCAR_FILE
treatable_by = list(/obj/item/stack/medical/ointment, /obj/item/stack/medical/mesh) // sterilizer and alcohol will require reagent treatments, coming soon
- // Flesh damage vars
+ // Flesh damage vars
/// How much damage to our flesh we currently have. Once both this and infestation reach 0, the wound is considered healed
var/flesh_damage = 5
/// Our current counter for how much flesh regeneration we have stacked from regenerative mesh/synthflesh/whatever, decrements each tick and lowers flesh_damage
var/flesh_healing = 0
- // Infestation vars (only for severe and critical)
+ // Infestation vars (only for severe and critical)
/// How quickly infection breeds on this burn if we don't have disinfectant
var/infestation_rate = 0
/// Our current level of infection
@@ -33,8 +34,11 @@
/// Once we reach infestation beyond WOUND_INFESTATION_SEPSIS, we get this many warnings before the limb is completely paralyzed (you'd have to ignore a really bad burn for a really long time for this to happen)
var/strikes_to_lose_limb = 3
+/datum/wound/burn/flesh/handle_process(seconds_per_tick, times_fired)
+
+ if (!victim || IS_IN_STASIS(victim))
+ return
-/datum/wound/burn/handle_process(seconds_per_tick, times_fired)
. = ..()
if(strikes_to_lose_limb == 0) // we've already hit sepsis, nothing more to do
victim.adjustToxLoss(0.25 * seconds_per_tick)
@@ -42,14 +46,12 @@
victim.visible_message(span_danger("The infection on the remnants of [victim]'s [limb.plaintext_zone] shift and bubble nauseatingly!"), span_warning("You can feel the infection on the remnants of your [limb.plaintext_zone] coursing through your veins!"), vision_distance = COMBAT_MESSAGE_RANGE)
return
- if(victim.reagents)
- if(HAS_TRAIT(victim, TRAIT_VIRUS_RESISTANCE))
- sanitization += 0.9
- if(victim.reagents.has_reagent(/datum/reagent/space_cleaner/sterilizine/))
- sanitization += 0.9
- if(victim.reagents.has_reagent(/datum/reagent/medicine/mine_salve))
- sanitization += 0.3
- flesh_healing += 0.5
+ for(var/datum/reagent/reagent as anything in victim.reagents.reagent_list)
+ if(reagent.chemical_flags & REAGENT_AFFECTS_WOUNDS)
+ reagent.on_burn_wound_processing()
+
+ if(HAS_TRAIT(victim, TRAIT_VIRUS_RESISTANCE))
+ sanitization += 0.9
if(limb.current_gauze)
limb.seep_gauze(WOUND_BURN_SANITIZATION_RATE * seconds_per_tick)
@@ -130,7 +132,7 @@
var/datum/brain_trauma/severe/paralysis/sepsis = new (limb.body_zone)
victim.gain_trauma(sepsis)
-/datum/wound/burn/get_wound_description(mob/user)
+/datum/wound/burn/flesh/get_wound_description(mob/user)
if(strikes_to_lose_limb <= 0)
return span_deadsay("[victim.p_Their()] [limb.plaintext_zone] has locked up completely and is non-functional.")
@@ -163,7 +165,7 @@
return "[condition.Join()]"
-/datum/wound/burn/get_scanner_description(mob/user)
+/datum/wound/burn/flesh/get_scanner_description(mob/user)
if(strikes_to_lose_limb <= 0) // Unclear if it can go below 0, best to not take the chance
var/oopsie = "Type: [name]\nSeverity: [severity_text()]"
oopsie += "
Infection Level: [span_deadsay("The body part has suffered complete sepsis and must be removed. Amputate or augment limb immediately, or place the patient in a cryotube.")]
"
@@ -196,12 +198,12 @@
*/
/// if someone is using ointment or mesh on our burns
-/datum/wound/burn/proc/ointmentmesh(obj/item/stack/medical/I, mob/user)
+/datum/wound/burn/flesh/proc/ointmentmesh(obj/item/stack/medical/I, mob/user)
user.visible_message(span_notice("[user] begins applying [I] to [victim]'s [limb.plaintext_zone]..."), span_notice("You begin applying [I] to [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone]..."))
if (I.amount <= 0)
- return
+ return TRUE
if(!do_after(user, (user == victim ? I.self_delay : I.other_delay), extra_checks = CALLBACK(src, PROC_REF(still_exists))))
- return
+ return TRUE
limb.heal_damage(I.heal_brute, I.heal_burn)
user.visible_message(span_green("[user] applies [I] to [victim]."), span_green("You apply [I] to [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone]."))
@@ -211,36 +213,38 @@
if((infestation <= 0 || sanitization >= infestation) && (flesh_damage <= 0 || flesh_healing > flesh_damage))
to_chat(user, span_notice("You've done all you can with [I], now you must wait for the flesh on [victim]'s [limb.plaintext_zone] to recover."))
+ return TRUE
else
- try_treating(I, user)
+ return try_treating(I, user)
/// Paramedic UV penlights
-/datum/wound/burn/proc/uv(obj/item/flashlight/pen/paramedic/I, mob/user)
+/datum/wound/burn/flesh/proc/uv(obj/item/flashlight/pen/paramedic/I, mob/user)
if(!COOLDOWN_FINISHED(I, uv_cooldown))
to_chat(user, span_notice("[I] is still recharging!"))
- return
+ return TRUE
if(infestation <= 0 || infestation < sanitization)
to_chat(user, span_notice("There's no infection to treat on [victim]'s [limb.plaintext_zone]!"))
- return
+ return TRUE
user.visible_message(span_notice("[user] flashes the burns on [victim]'s [limb] with [I]."), span_notice("You flash the burns on [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone] with [I]."), vision_distance=COMBAT_MESSAGE_RANGE)
sanitization += I.uv_power
COOLDOWN_START(I, uv_cooldown, I.uv_cooldown_length)
+ return TRUE
-/datum/wound/burn/treat(obj/item/I, mob/user)
+/datum/wound/burn/flesh/treat(obj/item/I, mob/user)
if(istype(I, /obj/item/stack/medical/ointment))
- ointmentmesh(I, user)
+ return ointmentmesh(I, user)
else if(istype(I, /obj/item/stack/medical/mesh))
var/obj/item/stack/medical/mesh/mesh_check = I
if(!mesh_check.is_open)
to_chat(user, span_warning("You need to open [mesh_check] first."))
return
- ointmentmesh(mesh_check, user)
+ return ointmentmesh(mesh_check, user)
else if(istype(I, /obj/item/flashlight/pen/paramedic))
- uv(I, user)
+ return uv(I, user)
// people complained about burns not healing on stasis beds, so in addition to checking if it's cured, they also get the special ability to very slowly heal on stasis beds if they have the healing effects stored
-/datum/wound/burn/on_stasis(seconds_per_tick, times_fired)
+/datum/wound/burn/flesh/on_stasis(seconds_per_tick, times_fired)
. = ..()
if(strikes_to_lose_limb == 0) // we've already hit sepsis, nothing more to do
if(SPT_PROB(0.5, seconds_per_tick))
@@ -255,74 +259,124 @@
if(sanitization > 0)
infestation = max(infestation - (0.1 * WOUND_BURN_SANITIZATION_RATE * seconds_per_tick), 0)
-/datum/wound/burn/on_synthflesh(amount)
- flesh_healing += amount * 0.5 // 20u patch will heal 10 flesh standard
+/datum/wound/burn/flesh/on_synthflesh(reac_volume)
+ flesh_healing += reac_volume * 0.5 // 20u patch will heal 10 flesh standard
+
+/datum/wound_pregen_data/flesh_burn
+ abstract = TRUE
+
+ required_wounding_types = list(WOUND_BURN)
+ required_limb_biostate = BIO_FLESH
+
+ wound_series = WOUND_SERIES_FLESH_BURN_BASIC
/datum/wound/burn/get_limb_examine_description()
return span_warning("The flesh on this limb appears badly cooked.")
// we don't even care about first degree burns, straight to second
-/datum/wound/burn/moderate
+/datum/wound/burn/flesh/moderate
name = "Second Degree Burns"
desc = "Patient is suffering considerable burns with mild skin penetration, weakening limb integrity and increased burning sensations."
treat_text = "Recommended application of topical ointment or regenerative mesh to affected region."
examine_desc = "is badly burned and breaking out in blisters"
occur_text = "breaks out with violent red burns"
severity = WOUND_SEVERITY_MODERATE
- damage_mulitplier_penalty = 1.1
- threshold_minimum = 40
+ damage_multiplier_penalty = 1.1
threshold_penalty = 30 // burns cause significant decrease in limb integrity compared to other wounds
- status_effect_type = /datum/status_effect/wound/burn/moderate
+ status_effect_type = /datum/status_effect/wound/burn/flesh/moderate
flesh_damage = 5
scar_keyword = "burnmoderate"
-/datum/wound/burn/severe
+ simple_desc = "Patient's skin is burned, weakening the limb and multiplying percieved damage!"
+ simple_treat_text = "Ointment will speed up recovery, as will regenerative mesh. Risk of infection is negligible."
+ homemade_treat_text = "Healthy tea will speed up recovery. Salt, or preferably a salt-water mixture, will sanitize the wound, but the former will cause skin irritation, increasing the risk of infection."
+
+/datum/wound_pregen_data/flesh_burn/second_degree
+ abstract = FALSE
+
+ wound_path_to_generate = /datum/wound/burn/flesh/moderate
+
+ threshold_minimum = 40
+
+/datum/wound/burn/flesh/severe
name = "Third Degree Burns"
desc = "Patient is suffering extreme burns with full skin penetration, creating serious risk of infection and greatly reduced limb integrity."
treat_text = "Recommended immediate disinfection and excision of any infected skin, followed by bandaging and ointment. If the limb has locked up, it must be amputated, augmented or treated with cryogenics."
examine_desc = "appears seriously charred, with aggressive red splotches"
occur_text = "chars rapidly, exposing ruined tissue and spreading angry red burns"
severity = WOUND_SEVERITY_SEVERE
- damage_mulitplier_penalty = 1.2
- threshold_minimum = 80
+ damage_multiplier_penalty = 1.2
threshold_penalty = 40
- status_effect_type = /datum/status_effect/wound/burn/severe
+ status_effect_type = /datum/status_effect/wound/burn/flesh/severe
treatable_by = list(/obj/item/flashlight/pen/paramedic, /obj/item/stack/medical/ointment, /obj/item/stack/medical/mesh)
infestation_rate = 0.07 // appx 9 minutes to reach sepsis without any treatment
flesh_damage = 12.5
scar_keyword = "burnsevere"
-/datum/wound/burn/critical
+ simple_desc = "Patient's skin is badly burned, significantly weakening the limb and compounding further damage!!"
+ simple_treat_text = "Bandages will speed up recovery, as will ointment or regenerative mesh. Spaceacilin, sterilizine, and 'Miner's Salve' will help with infection."
+ homemade_treat_text = "Healthy tea will speed up recovery. Salt, or preferably a salt-water mixture, will sanitize the wound, but the former especially will cause skin irritation and dehydration, speeding up infection. Space Cleaner can be used as disinfectant in a pinch."
+
+/datum/wound_pregen_data/flesh_burn/third_degree
+ abstract = FALSE
+
+ wound_path_to_generate = /datum/wound/burn/flesh/severe
+
+ threshold_minimum = 80
+
+/datum/wound/burn/flesh/critical
name = "Catastrophic Burns"
desc = "Patient is suffering near complete loss of tissue and significantly charred muscle and bone, creating life-threatening risk of infection and negligible limb integrity."
treat_text = "Immediate surgical debriding of any infected skin, followed by potent tissue regeneration formula and bandaging. If the limb has locked up, it must be amputated, augmented or treated with cryogenics."
examine_desc = "is a ruined mess of blanched bone, melted fat, and charred tissue"
occur_text = "vaporizes as flesh, bone, and fat melt together in a horrifying mess"
severity = WOUND_SEVERITY_CRITICAL
- damage_mulitplier_penalty = 1.3
+ damage_multiplier_penalty = 1.3
sound_effect = 'sound/effects/wounds/sizzle2.ogg'
- threshold_minimum = 140
threshold_penalty = 80
- status_effect_type = /datum/status_effect/wound/burn/critical
+ status_effect_type = /datum/status_effect/wound/burn/flesh/critical
treatable_by = list(/obj/item/flashlight/pen/paramedic, /obj/item/stack/medical/ointment, /obj/item/stack/medical/mesh)
infestation_rate = 0.075 // appx 4.33 minutes to reach sepsis without any treatment
flesh_damage = 20
scar_keyword = "burncritical"
+ simple_desc = "Patient's skin is destroyed and tissue charred, leaving the limb with almost no integrity and a drastic chance of infection!!!"
+ simple_treat_text = "Immediately bandage the wound and treat it with ointment or regenerative mesh. Spaceacilin, sterilizine, or 'Miner's Salve' will stave off infection. Seek professional care immediately, before sepsis sets in and the wound becomes untreatable."
+ homemade_treat_text = "Healthy tea will help with recovery. A salt-water mixture, topically applied, might help stave off infection in the short term, but pure table salt is NOT recommended. Space Cleaner can be used as disinfectant in a pinch."
+
+/datum/wound_pregen_data/flesh_burn/fourth_degree
+ abstract = FALSE
+
+ wound_path_to_generate = /datum/wound/burn/flesh/critical
+
+ threshold_minimum = 140
+
///special severe wound caused by sparring interference or other god related punishments.
-/datum/wound/burn/severe/brand
+/datum/wound/burn/flesh/severe/brand
name = "Holy Brand"
desc = "Patient is suffering extreme burns from a strange brand marking, creating serious risk of infection and greatly reduced limb integrity."
examine_desc = "appears to have holy symbols painfully branded into their flesh, leaving severe burns."
occur_text = "chars rapidly into a strange pattern of holy symbols, burned into the flesh."
+ simple_desc = "Patient's skin has had strange markings burned onto it, significantly weakening the limb and compounding further damage!!"
+
+/datum/wound_pregen_data/flesh_burn/third_degree/holy
+ abstract = FALSE
+ can_be_randomly_generated = FALSE
+
+ wound_path_to_generate = /datum/wound/burn/flesh/severe/brand
/// special severe wound caused by the cursed slot machine.
-/datum/wound/burn/severe/cursed_brand
+/datum/wound/burn/flesh/severe/cursed_brand
name = "Ancient Brand"
- desc = "Patient is suffering extreme burns with oddly ornate brand markings, creating serious risk of infection and greatly reduced limb integrity."
+ desc = "Patient is suffering extreme burns with oddly ornate brand markings, creating serious risk of infection and greatly reduced limb integrity."
examine_desc = "appears to have ornate symbols painfully branded into their flesh, leaving severe burns"
occur_text = "chars rapidly into a pattern that can only be described as an agglomeration of several financial symbols, burned into the flesh"
-/datum/wound/burn/severe/cursed_brand/get_limb_examine_description()
+/datum/wound/burn/flesh/severe/cursed_brand/get_limb_examine_description()
return span_warning("The flesh on this limb has several ornate symbols burned into it, with pitting throughout.")
-*/
+
+/datum/wound_pregen_data/flesh_burn/third_degree/cursed_brand
+ abstract = FALSE
+ can_be_randomly_generated = FALSE
+
+ wound_path_to_generate = /datum/wound/burn/flesh/severe/cursed_brand
diff --git a/code/datums/wounds/loss.dm b/code/datums/wounds/loss.dm
index 66dddc99e1d..4fb5cad387f 100644
--- a/code/datums/wounds/loss.dm
+++ b/code/datums/wounds/loss.dm
@@ -1,3 +1,15 @@
+/datum/wound_pregen_data/loss
+ abstract = FALSE
+
+ wound_path_to_generate = /datum/wound/loss
+ required_limb_biostate = NONE
+ require_any_biostate = TRUE
+
+ required_wounding_types = list(WOUND_ALL)
+
+ wound_series = WOUND_SERIES_LOSS_BASIC
+
+ threshold_minimum = WOUND_DISMEMBER_OUTRIGHT_THRESH // not actually used since dismembering is handled differently, but may as well assign it since we got it
/datum/wound/loss
name = "Dismemberment Wound"
@@ -5,15 +17,17 @@
sound_effect = 'sound/effects/dismember.ogg'
severity = WOUND_SEVERITY_LOSS
- threshold_minimum = WOUND_DISMEMBER_OUTRIGHT_THRESH // not actually used since dismembering is handled differently, but may as well assign it since we got it
status_effect_type = null
scar_keyword = "dismember"
wound_flags = null
already_scarred = TRUE // We manually assign scars for dismembers through endround missing limbs and aheals
+ /// The wounding_type of the attack that caused us. Used to generate the description of our scar. Currently unused, but primarily exists in case non-biological wounds are added.
+ var/loss_wounding_type
+
/// Our special proc for our special dismembering, the wounding type only matters for what text we have
-/datum/wound/loss/proc/apply_dismember(obj/item/bodypart/dismembered_part, wounding_type=WOUND_SLASH, outright = FALSE, attack_direction)
- if(!istype(dismembered_part) || !dismembered_part.owner || !(dismembered_part.body_zone in viable_zones) || isalien(dismembered_part.owner) || !dismembered_part.can_dismember())
+/datum/wound/loss/proc/apply_dismember(obj/item/bodypart/dismembered_part, wounding_type = WOUND_SLASH, outright = FALSE, attack_direction)
+ if(!istype(dismembered_part) || !dismembered_part.owner || !(dismembered_part.body_zone in get_viable_zones()) || isalien(dismembered_part.owner) || !dismembered_part.can_dismember())
qdel(src)
return
@@ -23,7 +37,28 @@
if(dismembered_part.body_zone == BODY_ZONE_CHEST)
occur_text = "is split open, causing [victim.p_their()] internal organs to spill out!"
self_msg = "is split open, causing your internal organs to spill out!"
- else if(outright)
+ else
+ occur_text = dismembered_part.get_dismember_message(wounding_type, outright)
+
+ var/msg = span_bolddanger("[victim]'s [dismembered_part.plaintext_zone] [occur_text]")
+
+ victim.visible_message(msg, span_userdanger("Your [dismembered_part.plaintext_zone] [self_msg ? self_msg : occur_text]"))
+
+ loss_wounding_type = wounding_type
+
+ set_limb(dismembered_part)
+ second_wind()
+ log_wound(victim, src)
+ if(dismembered_part.can_bleed() && wounding_type != WOUND_BURN && victim.blood_volume)
+ victim.spray_blood(attack_direction, severity)
+ dismembered_part.dismember(wounding_type == WOUND_BURN ? BURN : BRUTE, wounding_type = wounding_type)
+ qdel(src)
+ return TRUE
+
+/obj/item/bodypart/proc/get_dismember_message(wounding_type, outright)
+ var/occur_text
+
+ if(outright)
switch(wounding_type)
if(WOUND_BLUNT)
occur_text = "is outright smashed to a gross pulp, severing it completely!"
@@ -34,25 +69,17 @@
if(WOUND_BURN)
occur_text = "is outright incinerated, falling to dust!"
else
+ var/bone_text = get_internal_description()
+ var/tissue_text = get_external_description()
+
switch(wounding_type)
if(WOUND_BLUNT)
- occur_text = "is shattered through the last bone holding it together, severing it completely!"
+ occur_text = "is shattered through the last [bone_text] holding it together, severing it completely!"
if(WOUND_SLASH)
- occur_text = "is slashed through the last tissue holding it together, severing it completely!"
+ occur_text = "is slashed through the last [tissue_text] holding it together, severing it completely!"
if(WOUND_PIERCE)
- occur_text = "is pierced through the last tissue holding it together, severing it completely!"
+ occur_text = "is pierced through the last [tissue_text] holding it together, severing it completely!"
if(WOUND_BURN)
occur_text = "is completely incinerated, falling to dust!"
- var/msg = span_bolddanger("[victim]'s [dismembered_part.plaintext_zone] [occur_text]")
-
- victim.visible_message(msg, span_userdanger("Your [dismembered_part.plaintext_zone] [self_msg ? self_msg : occur_text]"))
-
- set_limb(dismembered_part)
- second_wind()
- log_wound(victim, src)
- if(wounding_type != WOUND_BURN && victim.blood_volume)
- victim.spray_blood(attack_direction, severity)
- dismembered_part.dismember(wounding_type == WOUND_BURN ? BURN : BRUTE)
- qdel(src)
- return TRUE
+ return occur_text
diff --git a/code/datums/wounds/pierce.dm b/code/datums/wounds/pierce.dm
index 0f49496c91b..ec166584632 100644
--- a/code/datums/wounds/pierce.dm
+++ b/code/datums/wounds/pierce.dm
@@ -1,19 +1,18 @@
-//SKYRAT EDIT REMOVAL - MOVED - MEDICINE
-/*
-
/*
Piercing wounds
*/
-
/datum/wound/pierce
+
+/datum/wound/pierce/bleed
name = "Piercing Wound"
sound_effect = 'sound/weapons/slice.ogg'
processes = TRUE
- wound_type = WOUND_PIERCE
treatable_by = list(/obj/item/stack/medical/suture)
- treatable_tool = TOOL_CAUTERY
+ treatable_tools = list(TOOL_CAUTERY)
base_treat_time = 3 SECONDS
- wound_flags = (FLESH_WOUND | ACCEPTS_GAUZE)
+ wound_flags = (ACCEPTS_GAUZE | CAN_BE_GRASPED)
+
+ default_scar_file = FLESH_SCAR_FILE
/// How much blood we start losing when this wound is first applied
var/initial_flow
@@ -25,13 +24,15 @@
/// If we let off blood when hit, the max blood lost is this * the incoming damage
var/internal_bleeding_coefficient
-/datum/wound/pierce/wound_injury(datum/wound/old_wound = null, attack_direction = null)
+/datum/wound/pierce/bleed/wound_injury(datum/wound/old_wound = null, attack_direction = null)
set_blood_flow(initial_flow)
- if(!no_bleeding && attack_direction && victim.blood_volume > BLOOD_VOLUME_OKAY)
+ if(limb.can_bleed() && attack_direction && victim.blood_volume > BLOOD_VOLUME_OKAY)
victim.spray_blood(attack_direction, severity)
-/datum/wound/pierce/receive_damage(wounding_type, wounding_dmg, wound_bonus)
- if(victim.stat == DEAD || (wounding_dmg < 5) || no_bleeding || !victim.blood_volume || !prob(internal_bleeding_chance + wounding_dmg))
+ return ..()
+
+/datum/wound/pierce/bleed/receive_damage(wounding_type, wounding_dmg, wound_bonus)
+ if(victim.stat == DEAD || (wounding_dmg < 5) || !limb.can_bleed() || !victim.blood_volume || !prob(internal_bleeding_chance + wounding_dmg))
return
if(limb.current_gauze?.splint_factor)
wounding_dmg *= (1 - limb.current_gauze.splint_factor)
@@ -52,9 +53,9 @@
new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir)
victim.add_splatter_floor(get_step(victim.loc, victim.dir))
-/datum/wound/pierce/get_bleed_rate_of_change()
+/datum/wound/pierce/bleed/get_bleed_rate_of_change()
//basically if a species doesn't bleed, the wound is stagnant and will not heal on it's own (nor get worse)
- if(no_bleeding)
+ if(!limb.can_bleed())
return BLOOD_FLOW_STEADY
if(HAS_TRAIT(victim, TRAIT_BLOODY_MESS))
return BLOOD_FLOW_INCREASING
@@ -62,10 +63,13 @@
return BLOOD_FLOW_DECREASING
return BLOOD_FLOW_STEADY
-/datum/wound/pierce/handle_process(seconds_per_tick, times_fired)
+/datum/wound/pierce/bleed/handle_process(seconds_per_tick, times_fired)
+ if (!victim || IS_IN_STASIS(victim))
+ return
+
set_blood_flow(min(blood_flow, WOUND_SLASH_MAX_BLOODFLOW))
- if(!no_bleeding)
+ if(limb.can_bleed())
if(victim.bodytemperature < (BODYTEMP_NORMAL - 10))
adjust_blood_flow(-0.1 * seconds_per_tick)
if(SPT_PROB(2.5, seconds_per_tick))
@@ -81,31 +85,33 @@
if(blood_flow <= 0)
qdel(src)
-/datum/wound/pierce/on_stasis(seconds_per_tick, times_fired)
+/datum/wound/pierce/bleed/on_stasis(seconds_per_tick, times_fired)
. = ..()
if(blood_flow <= 0)
qdel(src)
-/datum/wound/pierce/check_grab_treatments(obj/item/I, mob/user)
+/datum/wound/pierce/bleed/check_grab_treatments(obj/item/I, mob/user)
if(I.get_temperature()) // if we're using something hot but not a cautery, we need to be aggro grabbing them first, so we don't try treating someone we're eswording
return TRUE
-/datum/wound/pierce/treat(obj/item/I, mob/user)
+/datum/wound/pierce/bleed/treat(obj/item/I, mob/user)
if(istype(I, /obj/item/stack/medical/suture))
- suture(I, user)
+ return suture(I, user)
else if(I.tool_behaviour == TOOL_CAUTERY || I.get_temperature())
- tool_cauterize(I, user)
+ return tool_cauterize(I, user)
-/datum/wound/pierce/on_xadone(power)
+/datum/wound/pierce/bleed/on_xadone(power)
. = ..()
- adjust_blood_flow(-0.03 * power) // i think it's like a minimum of 3 power, so .09 blood_flow reduction per tick is pretty good for 0 effort
-/datum/wound/pierce/on_synthflesh(power)
+ if (limb) // parent can cause us to be removed, so its reasonable to check if we're still applied
+ adjust_blood_flow(-0.03 * power) // i think it's like a minimum of 3 power, so .09 blood_flow reduction per tick is pretty good for 0 effort
+
+/datum/wound/pierce/bleed/on_synthflesh(reac_volume)
. = ..()
- adjust_blood_flow(-0.025 * power) // 20u * 0.05 = -1 blood flow, less than with slashes but still good considering smaller bleed rates
+ adjust_blood_flow(-0.025 * reac_volume) // 20u * 0.05 = -1 blood flow, less than with slashes but still good considering smaller bleed rates
/// If someone is using a suture to close this puncture
-/datum/wound/pierce/proc/suture(obj/item/stack/medical/suture/I, mob/user)
+/datum/wound/pierce/bleed/proc/suture(obj/item/stack/medical/suture/I, mob/user)
var/self_penalty_mult = (user == victim ? 1.4 : 1)
var/treatment_delay = base_treat_time * self_penalty_mult
@@ -116,8 +122,8 @@
user.visible_message(span_notice("[user] begins stitching [victim]'s [limb.plaintext_zone] with [I]..."), span_notice("You begin stitching [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone] with [I]..."))
if(!do_after(user, treatment_delay, target = victim, extra_checks = CALLBACK(src, PROC_REF(still_exists))))
- return
- var/bleeding_wording = (no_bleeding ? "holes" : "bleeding")
+ return TRUE
+ var/bleeding_wording = (!limb.can_bleed() ? "holes" : "bleeding")
user.visible_message(span_green("[user] stitches up some of the [bleeding_wording] on [victim]."), span_green("You stitch up some of the [bleeding_wording] on [user == victim ? "yourself" : "[victim]"]."))
var/blood_sutured = I.stop_bleeding / self_penalty_mult
adjust_blood_flow(-blood_sutured)
@@ -125,12 +131,13 @@
I.use(1)
if(blood_flow > 0)
- try_treating(I, user)
+ return try_treating(I, user)
else
to_chat(user, span_green("You successfully close the hole in [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone]."))
+ return TRUE
/// If someone is using either a cautery tool or something with heat to cauterize this pierce
-/datum/wound/pierce/proc/tool_cauterize(obj/item/I, mob/user)
+/datum/wound/pierce/bleed/proc/tool_cauterize(obj/item/I, mob/user)
var/improv_penalty_mult = (I.tool_behaviour == TOOL_CAUTERY ? 1 : 1.25) // 25% longer and less effective if you don't use a real cautery
var/self_penalty_mult = (user == victim ? 1.5 : 1) // 50% longer and less effective if you do it to yourself
@@ -144,9 +151,9 @@
user.visible_message(span_danger("[user] begins cauterizing [victim]'s [limb.plaintext_zone] with [I]..."), span_warning("You begin cauterizing [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone] with [I]..."))
if(!do_after(user, treatment_delay, target = victim, extra_checks = CALLBACK(src, PROC_REF(still_exists))))
- return
+ return TRUE
- var/bleeding_wording = (no_bleeding ? "holes" : "bleeding")
+ var/bleeding_wording = (!limb.can_bleed() ? "holes" : "bleeding")
user.visible_message(span_green("[user] cauterizes some of the [bleeding_wording] on [victim]."), span_green("You cauterize some of the [bleeding_wording] on [victim]."))
limb.receive_damage(burn = 2 + severity, wound_bonus = CANT_WOUND)
if(prob(30))
@@ -155,13 +162,22 @@
adjust_blood_flow(-blood_cauterized)
if(blood_flow > 0)
- try_treating(I, user)
+ return try_treating(I, user)
+ return TRUE
+
+/datum/wound_pregen_data/flesh_pierce
+ abstract = TRUE
+
+ required_limb_biostate = (BIO_FLESH)
+ required_wounding_types = list(WOUND_PIERCE)
+
+ wound_series = WOUND_SERIES_FLESH_PUNCTURE_BLEED
/datum/wound/pierce/get_limb_examine_description()
return span_warning("The flesh on this limb appears badly perforated.")
-/datum/wound/pierce/moderate
- name = "Minor Breakage"
+/datum/wound/pierce/bleed/moderate
+ name = "Minor Skin Breakage"
desc = "Patient's skin has been broken open, causing severe bruising and minor internal bleeding in affected area."
treat_text = "Treat affected site with bandaging or exposure to extreme cold. In dire cases, brief exposure to vacuum may suffice." // space is cold in ss13, so it's like an ice pack!
examine_desc = "has a small, circular hole, gently bleeding"
@@ -172,17 +188,26 @@
gauzed_clot_rate = 0.8
internal_bleeding_chance = 30
internal_bleeding_coefficient = 1.25
- threshold_minimum = 30
threshold_penalty = 20
status_effect_type = /datum/status_effect/wound/pierce/moderate
scar_keyword = "piercemoderate"
-/datum/wound/pierce/moderate/update_descriptions()
- if(no_bleeding)
+ simple_treat_text = "Bandaging the wound will reduce blood loss, help the wound close by itself quicker, and speed up the blood recovery period. The wound itself can be slowly sutured shut."
+ homemade_treat_text = "Tea stimulates the body's natural healing systems, slightly fastening clotting. The wound itself can be rinsed off on a sink or shower as well. Other remedies are unnecessary."
+
+/datum/wound_pregen_data/flesh_pierce/breakage
+ abstract = FALSE
+
+ wound_path_to_generate = /datum/wound/pierce/bleed/moderate
+
+ threshold_minimum = 30
+
+/datum/wound/pierce/bleed/moderate/update_descriptions()
+ if(!limb.can_bleed())
examine_desc = "has a small, circular hole"
occur_text = "splits a small hole open"
-/datum/wound/pierce/severe
+/datum/wound/pierce/bleed/severe
name = "Open Puncture"
desc = "Patient's internal tissue is penetrated, causing sizeable internal bleeding and reduced limb stability."
treat_text = "Repair punctures in skin by suture or cautery, extreme cold may also work."
@@ -194,16 +219,25 @@
gauzed_clot_rate = 0.6
internal_bleeding_chance = 60
internal_bleeding_coefficient = 1.5
- threshold_minimum = 50
threshold_penalty = 35
status_effect_type = /datum/status_effect/wound/pierce/severe
scar_keyword = "piercesevere"
-/datum/wound/pierce/severe/update_descriptions()
- if(no_bleeding)
+ simple_treat_text = "Bandaging the wound is essential, and will reduce blood loss. Afterwards, the wound can be sutured shut, preferably while the patient is resting and/or grasping their wound."
+ homemade_treat_text = "Bed sheets can be ripped up to make makeshift gauze. Flour, table salt, or salt mixed with water can be applied directly to stem the flow, though unmixed salt will irritate the skin and worsen natural healing. Resting and grabbing your wound will also reduce bleeding."
+
+/datum/wound_pregen_data/flesh_pierce/open_puncture
+ abstract = FALSE
+
+ wound_path_to_generate = /datum/wound/pierce/bleed/severe
+
+ threshold_minimum = 50
+
+/datum/wound/pierce/bleed/severe/update_descriptions()
+ if(!limb.can_bleed())
occur_text = "tears a hole open"
-/datum/wound/pierce/critical
+/datum/wound/pierce/bleed/critical
name = "Ruptured Cavity"
desc = "Patient's internal tissue and circulatory system is shredded, causing significant internal bleeding and damage to internal organs."
treat_text = "Surgical repair of puncture wound, followed by supervised resanguination."
@@ -215,9 +249,17 @@
gauzed_clot_rate = 0.4
internal_bleeding_chance = 80
internal_bleeding_coefficient = 1.75
- threshold_minimum = 100
threshold_penalty = 50
status_effect_type = /datum/status_effect/wound/pierce/critical
scar_keyword = "piercecritical"
- wound_flags = (FLESH_WOUND | ACCEPTS_GAUZE | MANGLES_FLESH)
-*/
+ wound_flags = (ACCEPTS_GAUZE | MANGLES_EXTERIOR | CAN_BE_GRASPED)
+
+ simple_treat_text = "Bandaging the wound is of utmost importance, as is seeking direct medical attention - Death will ensue if treatment is delayed whatsoever, with lack of oxygen killing the patient, thus Food, Iron, and saline solution is always recommended after treatment. This wound will not naturally seal itself."
+ homemade_treat_text = "Bed sheets can be ripped up to make makeshift gauze. Flour, salt, and saltwater topically applied will help. Dropping to the ground and grabbing your wound will reduce blood flow."
+
+/datum/wound_pregen_data/flesh_pierce/cavity
+ abstract = FALSE
+
+ wound_path_to_generate = /datum/wound/pierce/bleed/critical
+
+ threshold_minimum = 100
diff --git a/code/datums/wounds/scars/_scars.dm b/code/datums/wounds/scars/_scars.dm
index db6275ea62b..774d8cc5265 100644
--- a/code/datums/wounds/scars/_scars.dm
+++ b/code/datums/wounds/scars/_scars.dm
@@ -22,11 +22,14 @@
var/visibility = 2
/// Whether this scar can actually be covered up by clothing
var/coverable = TRUE
- /// Obviously, scars that describe damaged flesh wouldn't apply to a skeleton (in some cases like bone wounds, there can be different descriptions for skeletons and fleshy humanoids)
- var/biology = BIO_FLESH_BONE
/// If we're a persistent scar or may become one, we go in this character slot
var/persistent_character_slot = 0
+ /// The biostates we require from a limb to give them our scar.
+ var/required_limb_biostate
+ /// If false, we will only check to see if a limb has ALL our biostates, instead of just any.
+ var/check_any_biostates
+
/datum/scar/Destroy(force, ...)
if(limb)
LAZYREMOVE(limb.scars, src)
@@ -47,6 +50,19 @@
* * add_to_scars- Should always be TRUE unless you're just storing a scar for later usage, like how cuts want to store a scar for the highest severity of cut, rather than the severity when the wound is fully healed (probably demoted to moderate)
*/
/datum/scar/proc/generate(obj/item/bodypart/BP, datum/wound/W, add_to_scars=TRUE)
+
+ if (!W.can_scar)
+ qdel(src)
+ return
+
+ var/datum/wound_pregen_data/pregen_data = GLOB.all_wound_pregen_data[W.type]
+ if (!pregen_data)
+ qdel(src)
+ return
+
+ required_limb_biostate = pregen_data.required_limb_biostate
+ check_any_biostates = pregen_data.require_any_biostate
+
limb = BP
RegisterSignal(limb, COMSIG_QDELETING, PROC_REF(limb_gone))
@@ -59,12 +75,16 @@
if(victim)
LAZYADD(victim.all_scars, src)
- biology = limb?.biological_state || BIO_FLESH_BONE
+ var/scar_file = W.get_scar_file(BP, add_to_scars)
+ var/scar_keyword = W.get_scar_keyword(BP, add_to_scars)
+ if (!scar_file || !scar_keyword)
+ qdel(src)
+ return
- if((biology & BIO_BONE) && !(biology & BIO_FLESH))
- description = pick_list(BONE_SCAR_FILE, W.scar_keyword) || "general disfigurement"
- else // no specific support for flesh w/o bone scars since it's not really useful
- description = pick_list(FLESH_SCAR_FILE, W.scar_keyword) || "general disfigurement"
+ description = pick_list(scar_file, scar_keyword)
+ if (!description)
+ stack_trace("no valid description found for scar! file: [scar_file] keyword: [scar_keyword] wound: [W.type]")
+ description = "general disfigurement"
precise_location = pick_list_replacements(SCAR_LOC_FILE, limb.body_zone)
switch(W.severity)
@@ -86,22 +106,28 @@
LAZYADD(victim.all_scars, src)
/// Used to "load" a persistent scar
-/datum/scar/proc/load(obj/item/bodypart/BP, version, description, specific_location, severity=WOUND_SEVERITY_SEVERE, biology=BIO_FLESH_BONE, char_slot)
- if(!IS_ORGANIC_LIMB(BP))
+/datum/scar/proc/load(obj/item/bodypart/BP, version, description, specific_location, severity = WOUND_SEVERITY_SEVERE, required_limb_biostate = BIO_STANDARD_UNJOINTED, char_slot, check_any_biostates = FALSE)
+ if(!BP.scarrable)
qdel(src)
return
limb = BP
RegisterSignal(limb, COMSIG_QDELETING, PROC_REF(limb_gone))
- if(limb.owner)
- victim = limb.owner
- if(limb.biological_state != biology)
+ if (isnull(check_any_biostates)) // so we dont break old scars. NOTE: REMOVE AFTER VERSION NUMBER MOVES PAST 3
+ check_any_biostates = FALSE
+ if (check_any_biostates)
+ if (!(limb.biological_state & required_limb_biostate))
qdel(src)
return
+ else if (!((limb.biological_state & required_limb_biostate) == required_limb_biostate)) // check for all
+ qdel(src)
+ return
+ if(limb.owner)
+ victim = limb.owner
LAZYADD(victim.all_scars, src)
src.severity = severity
- src.biology = biology
+ src.required_limb_biostate = required_limb_biostate
persistent_character_slot = char_slot
LAZYADD(limb.scars, src)
@@ -163,9 +189,9 @@
/// Used to format a scar to save for either persistent scars, or for changeling disguises
/datum/scar/proc/format()
- return "[SCAR_CURRENT_VERSION]|[limb.body_zone]|[description]|[precise_location]|[severity]|[biology]|[persistent_character_slot]"
+ return "[SCAR_CURRENT_VERSION]|[limb.body_zone]|[description]|[precise_location]|[severity]|[required_limb_biostate]|[persistent_character_slot]|[check_any_biostates]"
/// Used to format a scar to save in preferences for persistent scars
-/datum/scar/proc/format_amputated(body_zone)
- description = pick_list(FLESH_SCAR_FILE, "dismember")
- return "[SCAR_CURRENT_VERSION]|[body_zone]|[description]|amputated|[WOUND_SEVERITY_LOSS]|[BIO_FLESH_BONE]|[persistent_character_slot]"
+/datum/scar/proc/format_amputated(body_zone, scar_file = FLESH_SCAR_FILE)
+ description = pick_list(scar_file, "dismember")
+ return "[SCAR_CURRENT_VERSION]|[body_zone]|[description]|amputated|[WOUND_SEVERITY_LOSS]|[required_limb_biostate]|[persistent_character_slot]|[check_any_biostates]"
diff --git a/code/datums/wounds/scars/_static_scar_data.dm b/code/datums/wounds/scars/_static_scar_data.dm
new file mode 100644
index 00000000000..942dcffff9c
--- /dev/null
+++ b/code/datums/wounds/scars/_static_scar_data.dm
@@ -0,0 +1,20 @@
+GLOBAL_LIST_INIT_TYPED(all_static_scar_data, /datum/static_scar_data, generate_static_scar_data())
+
+/proc/generate_static_scar_data()
+ RETURN_TYPE(/list/datum/static_scar_data)
+
+ var/list/datum/wound_pregen_data/data = list()
+
+ for (var/datum/wound_pregen_data/path as anything in typecacheof(path = /datum/static_scar_data, ignore_root_path = TRUE))
+ if (initial(path.abstract))
+ continue
+
+ var/datum/wound_pregen_data/pregen_data = new path
+ data[pregen_data.wound_path_to_generate] = pregen_data
+
+ return data
+
+/datum/static_scar_data
+ var/abstract = FALSE
+
+
diff --git a/code/datums/wounds/slash.dm b/code/datums/wounds/slash.dm
index 97fb744d3b3..4475d95f508 100644
--- a/code/datums/wounds/slash.dm
+++ b/code/datums/wounds/slash.dm
@@ -1,5 +1,3 @@
-//SKYRAT EDIT REMOVAL - MOVED - MEDICINE
-/*
/*
Slashing wounds
@@ -8,13 +6,25 @@
/datum/wound/slash
name = "Slashing (Cut) Wound"
sound_effect = 'sound/weapons/slice.ogg'
+
+/datum/wound_pregen_data/flesh_slash
+ abstract = TRUE
+
+ required_wounding_types = list(WOUND_SLASH)
+ required_limb_biostate = BIO_FLESH
+
+ wound_series = WOUND_SERIES_FLESH_SLASH_BLEED
+
+/datum/wound/slash/flesh
+ name = "Slashing (Cut) Flesh Wound"
processes = TRUE
- wound_type = WOUND_SLASH
treatable_by = list(/obj/item/stack/medical/suture)
treatable_by_grabbed = list(/obj/item/gun/energy/laser)
- treatable_tool = TOOL_CAUTERY
+ treatable_tools = list(TOOL_CAUTERY)
base_treat_time = 3 SECONDS
- wound_flags = (FLESH_WOUND | ACCEPTS_GAUZE)
+ wound_flags = (ACCEPTS_GAUZE|CAN_BE_GRASPED)
+
+ default_scar_file = FLESH_SCAR_FILE
/// How much blood we start losing when this wound is first applied
var/initial_flow
@@ -32,7 +42,12 @@
/// A bad system I'm using to track the worst scar we earned (since we can demote, we want the biggest our wound has been, not what it was when it was cured (probably moderate))
var/datum/scar/highest_scar
-/datum/wound/slash/wound_injury(datum/wound/slash/old_wound = null, attack_direction = null)
+/datum/wound/slash/flesh/Destroy()
+ highest_scar = null
+
+ return ..()
+
+/datum/wound/slash/flesh/wound_injury(datum/wound/slash/flesh/old_wound = null, attack_direction = null)
if(old_wound)
set_blood_flow(max(old_wound.blood_flow, initial_flow))
if(old_wound.severity > severity && old_wound.highest_scar)
@@ -40,7 +55,7 @@
old_wound.clear_highest_scar()
else
set_blood_flow(initial_flow)
- if(!no_bleeding && attack_direction && victim.blood_volume > BLOOD_VOLUME_OKAY)
+ if(limb.can_bleed() && attack_direction && victim.blood_volume > BLOOD_VOLUME_OKAY)
victim.spray_blood(attack_direction, severity)
if(!highest_scar)
@@ -48,24 +63,26 @@
set_highest_scar(new_scar)
new_scar.generate(limb, src, add_to_scars=FALSE)
-/datum/wound/slash/proc/set_highest_scar(datum/scar/new_scar)
+ return ..()
+
+/datum/wound/slash/flesh/proc/set_highest_scar(datum/scar/new_scar)
if(highest_scar)
UnregisterSignal(highest_scar, COMSIG_QDELETING)
if(new_scar)
RegisterSignal(new_scar, COMSIG_QDELETING, PROC_REF(clear_highest_scar))
highest_scar = new_scar
-/datum/wound/slash/proc/clear_highest_scar(datum/source)
+/datum/wound/slash/flesh/proc/clear_highest_scar(datum/source)
SIGNAL_HANDLER
set_highest_scar(null)
-/datum/wound/slash/remove_wound(ignore_limb, replaced)
+/datum/wound/slash/flesh/remove_wound(ignore_limb, replaced)
if(!replaced && highest_scar)
already_scarred = TRUE
highest_scar.lazy_attach(limb)
return ..()
-/datum/wound/slash/get_wound_description(mob/user)
+/datum/wound/slash/flesh/get_wound_description(mob/user)
if(!limb.current_gauze)
return ..()
@@ -84,11 +101,16 @@
return "[msg.Join()]"
-/datum/wound/slash/receive_damage(wounding_type, wounding_dmg, wound_bonus)
+/datum/wound/slash/flesh/receive_damage(wounding_type, wounding_dmg, wound_bonus)
+ if (!victim) // if we are dismembered, we can still take damage, its fine to check here
+ return
+
if(victim.stat != DEAD && wound_bonus != CANT_WOUND && wounding_type == WOUND_SLASH) // can't stab dead bodies to make it bleed faster this way
adjust_blood_flow(WOUND_SLASH_DAMAGE_FLOW_COEFF * wounding_dmg)
-/datum/wound/slash/drag_bleed_amount()
+ return ..()
+
+/datum/wound/slash/flesh/drag_bleed_amount()
// say we have 3 severe cuts with 3 blood flow each, pretty reasonable
// compare with being at 100 brute damage before, where you bled (brute/100 * 2), = 2 blood per tile
var/bleed_amt = min(blood_flow * 0.1, 1) // 3 * 3 * 0.1 = 0.9 blood total, less than before! the share here is .3 blood of course.
@@ -99,9 +121,9 @@
return bleed_amt
-/datum/wound/slash/get_bleed_rate_of_change()
+/datum/wound/slash/flesh/get_bleed_rate_of_change()
//basically if a species doesn't bleed, the wound is stagnant and will not heal on it's own (nor get worse)
- if(no_bleeding)
+ if(!limb.can_bleed())
return BLOOD_FLOW_STEADY
if(HAS_TRAIT(victim, TRAIT_BLOODY_MESS))
return BLOOD_FLOW_INCREASING
@@ -110,9 +132,13 @@
if(clot_rate < 0)
return BLOOD_FLOW_INCREASING
-/datum/wound/slash/handle_process(seconds_per_tick, times_fired)
+/datum/wound/slash/flesh/handle_process(seconds_per_tick, times_fired)
+
+ if (!victim || IS_IN_STASIS(victim))
+ return
+
// in case the victim has the NOBLOOD trait, the wound will simply not clot on it's own
- if(!no_bleeding)
+ if(limb.can_bleed())
set_blood_flow(min(blood_flow, WOUND_SLASH_MAX_BLOODFLOW))
if(HAS_TRAIT(victim, TRAIT_BLOODY_MESS))
@@ -125,7 +151,7 @@
adjust_blood_flow(-limb.current_gauze.absorption_rate * seconds_per_tick)
limb.seep_gauze(limb.current_gauze.absorption_rate * seconds_per_tick)
//otherwise, only clot if it's a bleeder
- else if(!no_bleeding)
+ else if(limb.can_bleed())
adjust_blood_flow(-clot_rate * seconds_per_tick)
if(blood_flow > highest_flow)
@@ -133,36 +159,36 @@
if(blood_flow < minimum_flow)
if(demotes_to)
- replace_wound(demotes_to)
+ replace_wound(new demotes_to)
else
- to_chat(victim, span_green("The cut on your [limb.plaintext_zone] has [no_bleeding ? "healed up" : "stopped bleeding"]!"))
+ to_chat(victim, span_green("The cut on your [limb.plaintext_zone] has [!limb.can_bleed() ? "healed up" : "stopped bleeding"]!"))
qdel(src)
-/datum/wound/slash/on_stasis(seconds_per_tick, times_fired)
+/datum/wound/slash/flesh/on_stasis(seconds_per_tick, times_fired)
if(blood_flow >= minimum_flow)
return
if(demotes_to)
- replace_wound(demotes_to)
+ replace_wound(new demotes_to)
return
qdel(src)
/* BEWARE, THE BELOW NONSENSE IS MADNESS. bones.dm looks more like what I have in mind and is sufficiently clean, don't pay attention to this messiness */
-/datum/wound/slash/check_grab_treatments(obj/item/I, mob/user)
+/datum/wound/slash/flesh/check_grab_treatments(obj/item/I, mob/user)
if(istype(I, /obj/item/gun/energy/laser))
return TRUE
if(I.get_temperature()) // if we're using something hot but not a cautery, we need to be aggro grabbing them first, so we don't try treating someone we're eswording
return TRUE
-/datum/wound/slash/treat(obj/item/I, mob/user)
+/datum/wound/slash/flesh/treat(obj/item/I, mob/user)
if(istype(I, /obj/item/gun/energy/laser))
- las_cauterize(I, user)
+ return las_cauterize(I, user)
else if(I.tool_behaviour == TOOL_CAUTERY || I.get_temperature())
- tool_cauterize(I, user)
+ return tool_cauterize(I, user)
else if(istype(I, /obj/item/stack/medical/suture))
- suture(I, user)
+ return suture(I, user)
-/datum/wound/slash/try_handling(mob/living/carbon/human/user)
+/datum/wound/slash/flesh/try_handling(mob/living/carbon/human/user)
if(user.pulling != victim || user.zone_selected != limb.body_zone || !isfelinid(user) || !victim.try_inject(user, injection_flags = INJECT_TRY_SHOW_ERROR_MESSAGE))
return FALSE
if(DOING_INTERACTION_WITH_TARGET(user, victim))
@@ -179,7 +205,7 @@
return TRUE
/// if a felinid is licking this cut to reduce bleeding
-/datum/wound/slash/proc/lick_wounds(mob/living/carbon/human/user)
+/datum/wound/slash/flesh/proc/lick_wounds(mob/living/carbon/human/user)
// transmission is one way patient -> felinid since google said cat saliva is antiseptic or whatever, and also because felinids are already risking getting beaten for this even without people suspecting they're spreading a deathvirus
for(var/i in victim.diseases)
var/datum/disease/iter_disease = i
@@ -201,16 +227,18 @@
else if(demotes_to)
to_chat(user, span_green("You successfully lower the severity of [victim]'s cuts."))
-/datum/wound/slash/on_xadone(power)
+/datum/wound/slash/flesh/on_xadone(power)
. = ..()
- adjust_blood_flow(-0.03 * power) // i think it's like a minimum of 3 power, so .09 blood_flow reduction per tick is pretty good for 0 effort
-/datum/wound/slash/on_synthflesh(power)
+ if (limb) // parent can cause us to be removed, so its reasonable to check if we're still applied
+ adjust_blood_flow(-0.03 * power) // i think it's like a minimum of 3 power, so .09 blood_flow reduction per tick is pretty good for 0 effort
+
+/datum/wound/slash/flesh/on_synthflesh(reac_volume)
. = ..()
- adjust_blood_flow(-0.075 * power) // 20u * 0.075 = -1.5 blood flow, pretty good for how little effort it is
+ adjust_blood_flow(-0.075 * reac_volume) // 20u * 0.075 = -1.5 blood flow, pretty good for how little effort it is
/// If someone's putting a laser gun up to our cut to cauterize it
-/datum/wound/slash/proc/las_cauterize(obj/item/gun/energy/laser/lasgun, mob/user)
+/datum/wound/slash/flesh/proc/las_cauterize(obj/item/gun/energy/laser/lasgun, mob/user)
var/self_penalty_mult = (user == victim ? 1.25 : 1)
user.visible_message(span_warning("[user] begins aiming [lasgun] directly at [victim]'s [limb.plaintext_zone]..."), span_userdanger("You begin aiming [lasgun] directly at [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone]..."))
if(!do_after(user, base_treat_time * self_penalty_mult, target=victim, extra_checks = CALLBACK(src, PROC_REF(still_exists))))
@@ -223,9 +251,10 @@
victim.emote("scream")
adjust_blood_flow(-1 * (damage / (5 * self_penalty_mult))) // 20 / 5 = 4 bloodflow removed, p good
victim.visible_message(span_warning("The cuts on [victim]'s [limb.plaintext_zone] scar over!"))
+ return TRUE
/// If someone is using either a cautery tool or something with heat to cauterize this cut
-/datum/wound/slash/proc/tool_cauterize(obj/item/I, mob/user)
+/datum/wound/slash/flesh/proc/tool_cauterize(obj/item/I, mob/user)
var/improv_penalty_mult = (I.tool_behaviour == TOOL_CAUTERY ? 1 : 1.25) // 25% longer and less effective if you don't use a real cautery
var/self_penalty_mult = (user == victim ? 1.5 : 1) // 50% longer and less effective if you do it to yourself
@@ -239,7 +268,7 @@
if(!do_after(user, treatment_delay, target = victim, extra_checks = CALLBACK(src, PROC_REF(still_exists))))
return
- var/bleeding_wording = (no_bleeding ? "cuts" : "bleeding")
+ var/bleeding_wording = (!limb.can_bleed() ? "cuts" : "bleeding")
user.visible_message(span_green("[user] cauterizes some of the [bleeding_wording] on [victim]."), span_green("You cauterize some of the [bleeding_wording] on [victim]."))
limb.receive_damage(burn = 2 + severity, wound_bonus = CANT_WOUND)
if(prob(30))
@@ -248,12 +277,14 @@
adjust_blood_flow(-blood_cauterized)
if(blood_flow > minimum_flow)
- try_treating(I, user)
+ return try_treating(I, user)
else if(demotes_to)
to_chat(user, span_green("You successfully lower the severity of [user == victim ? "your" : "[victim]'s"] cuts."))
+ return TRUE
+ return FALSE
/// If someone is using a suture to close this cut
-/datum/wound/slash/proc/suture(obj/item/stack/medical/suture/I, mob/user)
+/datum/wound/slash/flesh/proc/suture(obj/item/stack/medical/suture/I, mob/user)
var/self_penalty_mult = (user == victim ? 1.4 : 1)
var/treatment_delay = base_treat_time * self_penalty_mult
@@ -264,8 +295,8 @@
user.visible_message(span_notice("[user] begins stitching [victim]'s [limb.plaintext_zone] with [I]..."), span_notice("You begin stitching [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone] with [I]..."))
if(!do_after(user, treatment_delay, target = victim, extra_checks = CALLBACK(src, PROC_REF(still_exists))))
- return
- var/bleeding_wording = (no_bleeding ? "cuts" : "bleeding")
+ return TRUE
+ var/bleeding_wording = (!limb.can_bleed() ? "cuts" : "bleeding")
user.visible_message(span_green("[user] stitches up some of the [bleeding_wording] on [victim]."), span_green("You stitch up some of the [bleeding_wording] on [user == victim ? "yourself" : "[victim]"]."))
var/blood_sutured = I.stop_bleeding / self_penalty_mult
adjust_blood_flow(-blood_sutured)
@@ -273,14 +304,16 @@
I.use(1)
if(blood_flow > minimum_flow)
- try_treating(I, user)
+ return try_treating(I, user)
else if(demotes_to)
to_chat(user, span_green("You successfully lower the severity of [user == victim ? "your" : "[victim]'s"] cuts."))
+ return TRUE
+ return TRUE
/datum/wound/slash/get_limb_examine_description()
return span_warning("The flesh on this limb appears badly lacerated.")
-/datum/wound/slash/moderate
+/datum/wound/slash/flesh/moderate
name = "Rough Abrasion"
desc = "Patient's skin has been badly scraped, generating moderate blood loss."
treat_text = "Application of clean bandages or first-aid grade sutures, followed by food and rest."
@@ -291,16 +324,25 @@
initial_flow = 2
minimum_flow = 0.5
clot_rate = 0.05
- threshold_minimum = 20
threshold_penalty = 10
- status_effect_type = /datum/status_effect/wound/slash/moderate
+ status_effect_type = /datum/status_effect/wound/slash/flesh/moderate
scar_keyword = "slashmoderate"
-/datum/wound/slash/moderate/update_descriptions()
- if(no_bleeding)
+ simple_treat_text = "Bandaging the wound will reduce blood loss, help the wound close by itself quicker, and speed up the blood recovery period. The wound itself can be slowly sutured shut."
+ homemade_treat_text = "Tea stimulates the body's natural healing systems, slightly fastening clotting. The wound itself can be rinsed off on a sink or shower as well. Other remedies are unnecessary."
+
+/datum/wound/slash/flesh/moderate/update_descriptions()
+ if(!limb.can_bleed())
occur_text = "is cut open"
-/datum/wound/slash/severe
+/datum/wound_pregen_data/flesh_slash/abrasion
+ abstract = FALSE
+
+ wound_path_to_generate = /datum/wound/slash/flesh/moderate
+
+ threshold_minimum = 20
+
+/datum/wound/slash/flesh/severe
name = "Open Laceration"
desc = "Patient's skin is ripped clean open, allowing significant blood loss."
treat_text = "Speedy application of first-aid grade sutures and clean bandages, followed by vitals monitoring to ensure recovery."
@@ -311,50 +353,78 @@
initial_flow = 3.25
minimum_flow = 2.75
clot_rate = 0.03
- threshold_minimum = 50
threshold_penalty = 25
- demotes_to = /datum/wound/slash/moderate
- status_effect_type = /datum/status_effect/wound/slash/severe
+ demotes_to = /datum/wound/slash/flesh/moderate
+ status_effect_type = /datum/status_effect/wound/slash/flesh/severe
scar_keyword = "slashsevere"
-/datum/wound/slash/severe/update_descriptions()
- if(no_bleeding)
+ simple_treat_text = "Bandaging the wound is essential, and will reduce blood loss. Afterwards, the wound can be sutured shut, preferably while the patient is resting and/or grasping their wound."
+ homemade_treat_text = "Bed sheets can be ripped up to make makeshift gauze. Flour, table salt, or salt mixed with water can be applied directly to stem the flow, though unmixed salt will irritate the skin and worsen natural healing. Resting and grabbing your wound will also reduce bleeding."
+
+/datum/wound_pregen_data/flesh_slash/laceration
+ abstract = FALSE
+
+ wound_path_to_generate = /datum/wound/slash/flesh/severe
+
+ threshold_minimum = 50
+
+/datum/wound/slash/flesh/severe/update_descriptions()
+ if(!limb.can_bleed())
occur_text = "is ripped open"
-/datum/wound/slash/critical
+/datum/wound/slash/flesh/critical
name = "Weeping Avulsion"
desc = "Patient's skin is completely torn open, along with significant loss of tissue. Extreme blood loss will lead to quick death without intervention."
treat_text = "Immediate bandaging and either suturing or cauterization, followed by supervised resanguination."
examine_desc = "is carved down to the bone, spraying blood wildly"
- examine_desc = "is carved down to the bone"
occur_text = "is torn open, spraying blood wildly"
- occur_text = "is torn open"
sound_effect = 'sound/effects/wounds/blood3.ogg'
severity = WOUND_SEVERITY_CRITICAL
initial_flow = 4
minimum_flow = 3.85
clot_rate = -0.015 // critical cuts actively get worse instead of better
- threshold_minimum = 80
threshold_penalty = 40
- demotes_to = /datum/wound/slash/severe
- status_effect_type = /datum/status_effect/wound/slash/critical
+ demotes_to = /datum/wound/slash/flesh/severe
+ status_effect_type = /datum/status_effect/wound/slash/flesh/critical
scar_keyword = "slashcritical"
- wound_flags = (FLESH_WOUND | ACCEPTS_GAUZE | MANGLES_FLESH)
+ wound_flags = (ACCEPTS_GAUZE | MANGLES_EXTERIOR | CAN_BE_GRASPED)
+ simple_treat_text = "Bandaging the wound is of utmost importance, as is seeking direct medical attention - Death will ensue if treatment is delayed whatsoever, with lack of oxygen killing the patient, thus Food, Iron, and saline solution is always recommended after treatment. This wound will not naturally seal itself."
+ homemade_treat_text = "Bed sheets can be ripped up to make makeshift gauze. Flour, salt, and saltwater topically applied will help. Dropping to the ground and grabbing your wound will reduce blood flow."
-/datum/wound/slash/moderate/many_cuts
+/datum/wound/slash/flesh/critical/update_descriptions()
+ if (!limb.can_bleed())
+ occur_text = "is torn open"
+
+/datum/wound_pregen_data/flesh_slash/avulsion
+ abstract = FALSE
+
+ wound_path_to_generate = /datum/wound/slash/flesh/critical
+ threshold_minimum = 80
+
+/datum/wound/slash/flesh/moderate/many_cuts
name = "Numerous Small Slashes"
desc = "Patient's skin has numerous small slashes and cuts, generating moderate blood loss."
examine_desc = "has a ton of small cuts"
occur_text = "is cut numerous times, leaving many small slashes."
+/datum/wound_pregen_data/flesh_slash/abrasion/cuts
+ abstract = FALSE
+ can_be_randomly_generated = FALSE
+
+ wound_path_to_generate = /datum/wound/slash/flesh/moderate/many_cuts
+
// Subtype for cleave (heretic spell)
-/datum/wound/slash/critical/cleave
+/datum/wound/slash/flesh/critical/cleave
name = "Burning Avulsion"
examine_desc = "is ruptured, spraying blood wildly"
clot_rate = 0.01
-/datum/wound/slash/critical/cleave/update_descriptions()
- if(no_bleeding)
+/datum/wound/slash/flesh/critical/cleave/update_descriptions()
+ if(!limb.can_bleed())
occur_text = "is ruptured"
-*/
+/datum/wound_pregen_data/flesh_slash/avulsion/clear
+ abstract = FALSE
+ can_be_randomly_generated = FALSE
+
+ wound_path_to_generate = /datum/wound/slash/flesh/critical/cleave
diff --git a/code/game/area/areas/station/science.dm b/code/game/area/areas/station/science.dm
index fc968699df0..f63798aca62 100644
--- a/code/game/area/areas/station/science.dm
+++ b/code/game/area/areas/station/science.dm
@@ -73,7 +73,7 @@
icon_state = "ass_line"
/area/station/science/robotics/augments
- name = "improper Augmentation Theater"
+ name = "\improper Augmentation Theater"
icon_state = "robotics"
sound_environment = SOUND_AREA_TUNNEL_ENCLOSED
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 2e0352a05fa..29c5ea6e4df 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -541,6 +541,7 @@
SEND_SIGNAL(source, COMSIG_REAGENTS_EXPOSE_ATOM, src, reagents, methods, volume_modifier, show_message)
for(var/datum/reagent/current_reagent as anything in reagents)
. |= current_reagent.expose_atom(src, reagents[current_reagent])
+ SEND_SIGNAL(src, COMSIG_ATOM_AFTER_EXPOSE_REAGENTS, reagents, source, methods, volume_modifier, show_message)
/// Are you allowed to drop this atom
/atom/proc/AllowDrop()
@@ -851,8 +852,8 @@
if(SEND_SIGNAL(src, COMSIG_ATOM_RELAYMOVE, user, direction) & COMSIG_BLOCK_RELAYMOVE)
return
if(buckle_message_cooldown <= world.time)
- buckle_message_cooldown = world.time + 50
- to_chat(user, span_warning("You can't move while buckled to [src]!"))
+ buckle_message_cooldown = world.time + 25
+ balloon_alert(user, "can't move while buckled!")
return
/**
diff --git a/code/game/atoms_initializing_EXPENSIVE.dm b/code/game/atoms_initializing_EXPENSIVE.dm
index ae729ad1f48..1ecc6390edc 100644
--- a/code/game/atoms_initializing_EXPENSIVE.dm
+++ b/code/game/atoms_initializing_EXPENSIVE.dm
@@ -47,9 +47,6 @@
if(location)
/// Sends a signal that the new atom `src`, has been created at `loc`
SEND_SIGNAL(location, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON, A, arguments[1])
- var/area/atom_area = get_area(location)
- if(atom_area)
- SEND_SIGNAL(atom_area, COMSIG_AREA_INITIALIZED_IN, A)
if(created_atoms && from_template && ispath(the_type, /atom/movable))//we only want to populate the list with movables
created_atoms += A.get_all_contents()
diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm
index 1c394eaef5d..4fc3477b0a4 100644
--- a/code/game/gamemodes/dynamic/dynamic.dm
+++ b/code/game/gamemodes/dynamic/dynamic.dm
@@ -395,15 +395,17 @@ GLOBAL_LIST_EMPTY(dynamic_station_traits)
/// Generates the threat level using lorentz distribution and assigns peaceful_percentage.
/datum/game_mode/dynamic/proc/generate_threat()
- threat_level = lorentz_to_amount(threat_curve_centre, threat_curve_width, max_threat_level)
+ // At lower pop levels we run a Liner Interpolation against the max threat based proportionally on the number
+ // of players ready. This creates a balanced lorentz curve within a smaller range than 0 to max_threat_level.
+ var/calculated_max_threat = (SSticker.totalPlayersReady < low_pop_player_threshold) ? LERP(low_pop_maximum_threat, max_threat_level, SSticker.totalPlayersReady / low_pop_player_threshold) : max_threat_level
+ log_dynamic("Calculated maximum threat level based on player count of [SSticker.totalPlayersReady]: [calculated_max_threat]")
+
+ threat_level = lorentz_to_amount(threat_curve_centre, threat_curve_width, calculated_max_threat)
for(var/datum/station_trait/station_trait in GLOB.dynamic_station_traits)
threat_level = max(threat_level - GLOB.dynamic_station_traits[station_trait], 0)
log_dynamic("Threat reduced by [GLOB.dynamic_station_traits[station_trait]]. Source: [type].")
- if (SSticker.totalPlayersReady < low_pop_player_threshold)
- threat_level = min(threat_level, LERP(low_pop_maximum_threat, max_threat_level, SSticker.totalPlayersReady / low_pop_player_threshold))
-
peaceful_percentage = (threat_level/max_threat_level)*100
/// Generates the midround and roundstart budgets
@@ -457,11 +459,22 @@ GLOBAL_LIST_EMPTY(dynamic_station_traits)
//To new_player and such, and we want the datums to just free when the roundstart work is done
var/list/roundstart_rules = init_rulesets(/datum/dynamic_ruleset/roundstart)
+ SSjob.DivideOccupations(pure = TRUE, allow_all = TRUE)
for(var/i in GLOB.new_player_list)
var/mob/dead/new_player/player = i
if(player.ready == PLAYER_READY_TO_PLAY && player.mind && player.check_preferences())
- roundstart_pop_ready++
- candidates.Add(player)
+ if(is_unassigned_job(player.mind.assigned_role))
+ var/list/job_data = list()
+ var/job_prefs = player.client.prefs.job_preferences
+ 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(" | ")]")
+ else
+ roundstart_pop_ready++
+ candidates.Add(player)
+ SSjob.ResetOccupations()
log_dynamic("Listing [roundstart_rules.len] round start rulesets, and [candidates.len] players ready.")
if (candidates.len <= 0)
log_dynamic("[candidates.len] candidates.")
@@ -859,7 +872,7 @@ GLOBAL_LIST_EMPTY(dynamic_station_traits)
* rand() calls without arguments returns a value between 0 and 1, allowing for smaller intervals.
*/
/datum/game_mode/dynamic/proc/lorentz_to_amount(centre = 0, scale = 1.8, max_threat = 100, interval = 1)
- var/location = rand(-MAXIMUM_DYN_DISTANCE, MAXIMUM_DYN_DISTANCE) * rand()
+ var/location = RANDOM_DECIMAL(-MAXIMUM_DYN_DISTANCE, MAXIMUM_DYN_DISTANCE) * rand()
var/lorentz_result = LORENTZ_CUMULATIVE_DISTRIBUTION(centre, location, scale)
var/std_threat = lorentz_result * max_threat
///Without these, the amount won't come close to hitting 0% or 100% of the max threat.
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
index 34183d2f044..24da6df60a8 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
@@ -227,6 +227,7 @@ GLOBAL_VAR_INIT(revolutionary_win, FALSE)
scaling_cost = 9
requirements = list(101,101,60,30,30,25,20,15,10,10)
antag_cap = list("denominator" = 24)
+ ruleset_lazy_templates = list(LAZY_TEMPLATE_KEY_HERETIC_SACRIFICE)
/datum/dynamic_ruleset/roundstart/heretics/pre_execute(population)
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index e86940c7713..00488ba1dfb 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -97,6 +97,10 @@ GLOBAL_LIST_EMPTY(objectives) //SKYRAT EDIT ADDITION
/datum/objective/proc/check_completion()
return completed
+/// Provides a string describing what a good job you did or did not do
+/datum/objective/proc/get_roundend_success_suffix()
+ return check_completion() ? span_greentext("Success!") : span_redtext("Fail.")
+
/datum/objective/proc/is_unique_objective(possible_target, dupe_search_range)
if(!islist(dupe_search_range))
stack_trace("Non-list passed as duplicate objective search range")
@@ -588,12 +592,6 @@ GLOBAL_LIST_EMPTY(possible_items)
/datum/objective/steal/get_target()
return steal_target
-/datum/objective/steal/New()
- ..()
- if(!GLOB.possible_items.len)//Only need to fill the list when it's needed.
- for(var/I in subtypesof(/datum/objective_item/steal))
- new I
-
/datum/objective/steal/find_target(dupe_search_range, list/blacklist)
var/list/datum/mind/owners = get_owners()
if(!dupe_search_range)
@@ -959,6 +957,9 @@ GLOBAL_LIST_EMPTY(possible_items)
if(expl)
explanation_text = expl
+/datum/objective/custom/get_roundend_success_suffix()
+ return "" // Just print the objective with no success/fail evaluation, as it has no mechanical backing
+
//Ideally this would be all of them but laziness and unusual subtypes
/proc/generate_admin_objective_list()
GLOB.admin_objective_list = list()
diff --git a/code/game/gamemodes/objective_items.dm b/code/game/gamemodes/objective_items.dm
index c8c951a9fd4..2240f220e48 100644
--- a/code/game/gamemodes/objective_items.dm
+++ b/code/game/gamemodes/objective_items.dm
@@ -355,6 +355,7 @@
/datum/objective_item/steal/documents
name = "any set of secret documents of any organization"
+ valid_containers = list(/obj/item/folder)
targetitem = /obj/item/documents
exists_on_map = TRUE
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index 70451cd8b98..946bdb6d6cb 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -24,7 +24,7 @@
///The container to hold materials
var/datum/component/material_container/materials
-
+
///direction we output onto (if 0, on top of us)
var/drop_direction = 0
@@ -145,7 +145,7 @@
if(busy)
say("The autolathe is busy. Please wait for completion of previous operation.")
return
-
+
if(isclosedturf(get_step(src, drop_direction)))
say("Output is obstructed.")
return
@@ -210,8 +210,8 @@
update_static_data_for_all_viewers()
//print item
icon_state = "autolathe_n"
- var/time = is_stack ? 32 : (32 * coeff * multiplier) ** 0.8
- make_items(custom_materials, multiplier, is_stack, usr, time / multiplier)
+ var/time_per_item = is_stack ? 32 : ((32 * coeff * multiplier) ** 0.8) / multiplier
+ make_items(custom_materials, multiplier, is_stack, usr, time_per_item)
return TRUE
@@ -311,30 +311,36 @@
/obj/machinery/autolathe/proc/make_items(list/picked_materials, multiplier, is_stack, mob/user, time_per_item)
var/atom/our_loc = drop_location()
var/atom/drop_loc = get_step(src, drop_direction)
+ var/client_awarded = FALSE
busy = TRUE
+ SStgui.update_uis(src) //so ui immediatly knows its busy
while(multiplier > 0)
if(!busy)
break
- if(!multiplier)
- continue
stoplag(time_per_item)
var/obj/item/new_item
if(is_stack)
- new_item = new being_built.build_path(our_loc, multiplier, FALSE)
- var/obj/item/stack/stack_item = new_item
- stack_item.update_appearance()
+ new_item = new being_built.build_path(our_loc, multiplier)
else
new_item = new being_built.build_path(our_loc)
+ //custom materials for toolboxes
if(length(picked_materials))
new_item.set_custom_materials(picked_materials, 1 / multiplier) //Ensure we get the non multiplied amount
- for(var/x in picked_materials)
- var/datum/material/M = x
- if(!istype(M, /datum/material/glass) && !istype(M, /datum/material/iron))
- user.client.give_award(/datum/award/achievement/misc/getting_an_upgrade, user)
- if(drop_direction) //no need to call if ontop of us
+ if(!client_awarded) //so we dont award the medal multiple times
+ for(var/datum/material/mat in picked_materials)
+ if(!istype(mat, /datum/material/glass) && !istype(mat, /datum/material/iron))
+ user.client.give_award(/datum/award/achievement/misc/getting_an_upgrade, user)
+ client_awarded = TRUE
+
+ //no need to call if ontop of us
+ if(drop_direction)
new_item.Move(drop_loc)
+ //multiplier already applied in stack initialization. work done
+ if(is_stack)
+ break
+
multiplier--
icon_state = "autolathe"
diff --git a/code/game/machinery/bank_machine.dm b/code/game/machinery/bank_machine.dm
index c48671a6e18..4d276b6ebae 100644
--- a/code/game/machinery/bank_machine.dm
+++ b/code/game/machinery/bank_machine.dm
@@ -116,7 +116,8 @@
/obj/machinery/computer/bank_machine/proc/end_siphon()
siphoning = FALSE
unauthorized = FALSE
- new /obj/item/holochip(drop_location(), syphoning_credits) //get the loot
+ if(syphoning_credits > 0)
+ new /obj/item/holochip(drop_location(), syphoning_credits) //get the loot
syphoning_credits = 0
/obj/machinery/computer/bank_machine/proc/start_siphon(mob/living/carbon/user)
diff --git a/code/game/machinery/barsigns.dm b/code/game/machinery/barsigns.dm
index 69f13be11ac..764bd99b4ff 100644
--- a/code/game/machinery/barsigns.dm
+++ b/code/game/machinery/barsigns.dm
@@ -27,6 +27,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/barsign, 32)
/obj/machinery/barsign/Initialize(mapload)
. = ..()
set_sign(new /datum/barsign/hiddensigns/signoff)
+ find_and_hang_on_wall()
/obj/machinery/barsign/proc/set_sign(datum/barsign/sign)
if(!istype(sign))
diff --git a/code/game/machinery/botlaunchpad.dm b/code/game/machinery/botlaunchpad.dm
index f1c85a293c7..f77e11151e0 100644
--- a/code/game/machinery/botlaunchpad.dm
+++ b/code/game/machinery/botlaunchpad.dm
@@ -27,7 +27,7 @@
return
var/obj/item/multitool/multitool = tool
multitool.set_buffer(src)
- to_chat(user, span_notice("You save the data in the [multitool.name]'s buffer."))
+ balloon_alert(user, "saved to multitool buffer")
return TOOL_ACT_TOOLTYPE_SUCCESS
diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm
index 21a718d8705..5824f93dcc7 100644
--- a/code/game/machinery/buttons.dm
+++ b/code/game/machinery/buttons.dm
@@ -55,6 +55,7 @@
board.accesses = req_one_access
setup_device()
+ find_and_hang_on_wall()
/obj/machinery/button/Destroy()
QDEL_NULL(device)
@@ -233,6 +234,20 @@
device.pulsed(user)
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_BUTTON_PRESSED,src)
+/**
+ * Called when the mounted button's wall is knocked down.
+ */
+/obj/machinery/button/proc/knock_down()
+ if(device)
+ device.forceMove(get_turf(src))
+ device = null
+ if(board)
+ board.forceMove(get_turf(src))
+ req_access = list()
+ req_one_access = list()
+ board = null
+ qdel(src)
+
/obj/machinery/button/door
name = "door button"
desc = "A door remote control switch."
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index a47115a9f60..42f28a8b3ee 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -30,7 +30,6 @@
var/busy = FALSE
var/emped = FALSE //Number of consecutive EMP's on this camera
var/in_use_lights = 0
-
// Upgrades bitflag
var/upgrades = 0
@@ -104,6 +103,10 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/camera/xray, 0)
update_appearance()
alarm_manager = new(src)
+ find_and_hang_on_wall(directional = TRUE, \
+ custom_drop_callback = CALLBACK(src, PROC_REF(deconstruct), FALSE))
+
+ RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur))
/obj/machinery/camera/connect_to_shuttle(mapload, obj/docking_port/mobile/port, obj/docking_port/stationary/dock)
for(var/i in network)
@@ -155,7 +158,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/camera/xray, 0)
if(!status && powered())
. += span_info("It can reactivated with wirecutters.")
-/obj/machinery/camera/emp_act(severity)
+/obj/machinery/camera/emp_act(severity, reset_time = 90 SECONDS)
. = ..()
if(!status)
return
@@ -168,7 +171,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/camera/xray, 0)
set_light(0)
emped = emped+1 //Increase the number of consecutive EMP's
update_appearance()
- addtimer(CALLBACK(src, PROC_REF(post_emp_reset), emped, network), 90 SECONDS)
+ addtimer(CALLBACK(src, PROC_REF(post_emp_reset), emped, network), reset_time)
for(var/i in GLOB.player_list)
var/mob/M = i
if (M.client?.eye == src)
@@ -176,6 +179,11 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/camera/xray, 0)
M.reset_perspective(null)
to_chat(M, span_warning("The screen bursts into static!"))
+/obj/machinery/camera/proc/on_saboteur(datum/source, disrupt_duration)
+ SIGNAL_HANDLER
+ emp_act(EMP_LIGHT, reset_time = disrupt_duration)
+ return COMSIG_SABOTEUR_SUCCESS
+
/obj/machinery/camera/proc/post_emp_reset(thisemp, previous_network)
if(QDELETED(src))
return
@@ -188,7 +196,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/camera/xray, 0)
if(can_use())
GLOB.cameranet.addCamera(src)
emped = 0 //Resets the consecutive EMP count
- addtimer(CALLBACK(src, PROC_REF(cancelCameraAlarm)), 100)
+ addtimer(CALLBACK(src, PROC_REF(cancelCameraAlarm)), 10 SECONDS)
/obj/machinery/camera/ex_act(severity, target)
if(invuln)
diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm
index 37907a5ba29..786a2c3a39a 100644
--- a/code/game/machinery/camera/camera_assembly.dm
+++ b/code/game/machinery/camera/camera_assembly.dm
@@ -67,6 +67,7 @@
. = ..()
if(building)
setDir(ndir)
+ find_and_hang_on_wall()
/obj/structure/camera_assembly/update_icon_state()
icon_state = "[xray_module ? "xray" : null][initial(icon_state)]"
diff --git a/code/game/machinery/computer/_computer.dm b/code/game/machinery/computer/_computer.dm
index fc41fb57863..042f442fa33 100644
--- a/code/game/machinery/computer/_computer.dm
+++ b/code/game/machinery/computer/_computer.dm
@@ -26,7 +26,6 @@
/obj/machinery/computer/Initialize(mapload, obj/item/circuitboard/C)
. = ..()
-
power_change()
/obj/machinery/computer/process()
diff --git a/code/game/machinery/computer/atmos_computers/_air_sensor.dm b/code/game/machinery/computer/atmos_computers/_air_sensor.dm
index faef0370ad0..8d56b8a2f90 100644
--- a/code/game/machinery/computer/atmos_computers/_air_sensor.dm
+++ b/code/game/machinery/computer/atmos_computers/_air_sensor.dm
@@ -91,28 +91,28 @@
if(istype(multi_tool.buffer, /obj/machinery/atmospherics/components/unary/outlet_injector))
var/obj/machinery/atmospherics/components/unary/outlet_injector/input = multi_tool.buffer
inlet_id = input.id_tag
- multi_tool.set_buffer(null)
+ multi_tool.set_buffer(src)
balloon_alert(user, "connected to input")
else if(istype(multi_tool.buffer, /obj/machinery/atmospherics/components/unary/vent_pump))
var/obj/machinery/atmospherics/components/unary/vent_pump/output = multi_tool.buffer
//so its no longer controlled by air alarm
output.disconnect_from_area()
- //configuration copied from /obj/machinery/atmospherics/components/unary/vent_pump/siphon
+ //configuration copied from /obj/machinery/atmospherics/components/unary/vent_pump/siphon but with max pressure
output.pump_direction = ATMOS_DIRECTION_SIPHONING
output.pressure_checks = ATMOS_INTERNAL_BOUND
- output.internal_pressure_bound = 4000
+ output.internal_pressure_bound = MAX_OUTPUT_PRESSURE
output.external_pressure_bound = 0
//finally assign it to this sensor
outlet_id = output.id_tag
- multi_tool.set_buffer(null)
+ multi_tool.set_buffer(src)
balloon_alert(user, "connected to output")
else
multi_tool.set_buffer(src)
- balloon_alert(user, "added to multitool buffer")
+ balloon_alert(user, "sensor added to buffer")
- return TRUE
+ return TOOL_ACT_TOOLTYPE_SUCCESS
/**
* A portable version of the /obj/machinery/air_sensor
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index 4a289ae6aee..f32eff91c4e 100755
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -394,7 +394,29 @@ GLOBAL_VAR_INIT(cops_arrived, FALSE)
if(picture in GLOB.status_display_state_pictures)
post_status(picture)
else
- post_status("alert", picture)
+ if(picture == "currentalert") // You cannot set Code Blue display during Code Red and similiar
+ switch(SSsecurity_level.get_current_level_as_number())
+ if(SEC_LEVEL_DELTA)
+ post_status("alert", "deltaalert")
+ if(SEC_LEVEL_RED)
+ post_status("alert", "redalert")
+ if(SEC_LEVEL_BLUE)
+ post_status("alert", "bluealert")
+ if(SEC_LEVEL_GREEN)
+ post_status("alert", "greenalert")
+ // SKYRAT EDIT ADD START - Alert Levels
+ if(SEC_LEVEL_VIOLET)
+ post_status("alert", "violetalert")
+ if(SEC_LEVEL_ORANGE)
+ post_status("alert", "orangealert")
+ if(SEC_LEVEL_AMBER)
+ post_status("alert", "amberalert")
+ if(SEC_LEVEL_GAMMA)
+ post_status("alert", "gammaalert")
+ // SKYRAT EDIT ADD END - Alert Levels
+ else
+ post_status("alert", picture)
+
playsound(src, SFX_TERMINAL_TYPE, 50, FALSE)
if ("toggleAuthentication")
// Log out if we're logged in
@@ -662,6 +684,7 @@ GLOBAL_VAR_INIT(cops_arrived, FALSE)
"description" = shuttle_template.description,
"occupancy_limit" = shuttle_template.occupancy_limit,
"creditCost" = shuttle_template.credit_cost,
+ "initial_cost" = initial(shuttle_template.credit_cost),
"emagOnly" = shuttle_template.emag_only,
"prerequisites" = shuttle_template.prerequisites,
"ref" = REF(shuttle_template),
diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm
index 80bbfe04c06..6502ecbf530 100644
--- a/code/game/machinery/computer/dna_console.dm
+++ b/code/game/machinery/computer/dna_console.dm
@@ -235,10 +235,13 @@
// Set the default tgui state
set_default_state()
+/obj/machinery/computer/scan_consolenew/LateInitialize()
+ . = ..()
// Link machine with research techweb. Used for discovering and accessing
// already discovered mutations
if(!CONFIG_GET(flag/no_default_techweb_link) && !stored_research)
- stored_research = SSresearch.science_tech
+ CONNECT_TO_RND_SERVER_ROUNDSTART(stored_research, src)
+
/obj/machinery/computer/scan_consolenew/ui_interact(mob/user, datum/tgui/ui)
. = ..()
diff --git a/code/game/machinery/computer/operating_computer.dm b/code/game/machinery/computer/operating_computer.dm
index f512d92acb9..f7b0ef24ffd 100644
--- a/code/game/machinery/computer/operating_computer.dm
+++ b/code/game/machinery/computer/operating_computer.dm
@@ -17,13 +17,13 @@
/obj/machinery/computer/operating/Initialize(mapload)
. = ..()
- if(!CONFIG_GET(flag/no_default_techweb_link) && !linked_techweb)
- linked_techweb = SSresearch.science_tech
find_table()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/computer/operating/LateInitialize()
. = ..()
+ if(!CONFIG_GET(flag/no_default_techweb_link) && !linked_techweb)
+ CONNECT_TO_RND_SERVER_ROUNDSTART(linked_techweb, src)
experiment_handler = AddComponent( \
/datum/component/experiment_handler, \
diff --git a/code/game/machinery/computer/orders/order_computer/mining_order.dm b/code/game/machinery/computer/orders/order_computer/mining_order.dm
index 0b3af6812da..c680974e4c1 100644
--- a/code/game/machinery/computer/orders/order_computer/mining_order.dm
+++ b/code/game/machinery/computer/orders/order_computer/mining_order.dm
@@ -59,7 +59,7 @@
radio.talk_into(src, "A shaft miner has ordered equipment which will arrive on the cargo shuttle! Please make sure it gets to them as soon as possible!", radio_channel)
SSshuttle.shopping_list += new_order
-/obj/machinery/computer/order_console/mining/retrive_points(obj/item/card/id/id_card)
+/obj/machinery/computer/order_console/mining/retrieve_points(obj/item/card/id/id_card)
return round(id_card.registered_account.mining_points)
/obj/machinery/computer/order_console/mining/ui_act(action, params)
diff --git a/code/game/machinery/computer/orders/order_computer/order_computer.dm b/code/game/machinery/computer/orders/order_computer/order_computer.dm
index cd716b61e6c..718fa2bc218 100644
--- a/code/game/machinery/computer/orders/order_computer/order_computer.dm
+++ b/code/game/machinery/computer/orders/order_computer/order_computer.dm
@@ -74,9 +74,9 @@ GLOBAL_LIST_EMPTY(order_console_products)
/**
* points is any type of currency this machine accepts(money, mining points etc) which is displayed on the ui
* Args:
- * card - The ID card we retrive these points from
+ * card - The ID card we retrieve these points from
*/
-/obj/machinery/computer/order_console/proc/retrive_points(obj/item/card/id/id_card)
+/obj/machinery/computer/order_console/proc/retrieve_points(obj/item/card/id/id_card)
return round(id_card.registered_account?.account_balance)
/obj/machinery/computer/order_console/ui_data(mob/user)
@@ -95,7 +95,7 @@ GLOBAL_LIST_EMPTY(order_console_products)
var/mob/living/living_user = user
var/obj/item/card/id/id_card = living_user.get_idcard(TRUE)
if(id_card)
- data["points"] = retrive_points(id_card)
+ data["points"] = retrieve_points(id_card)
return data
@@ -223,7 +223,7 @@ GLOBAL_LIST_EMPTY(order_console_products)
return FALSE
/**
- * whatever type of points was retrieved in retrive_points() subtract those type of points from the card upon confirming order
+ * whatever type of points was retrieved in retrieve_points() subtract those type of points from the card upon confirming order
* Args:
* final_cost - amount of points to subtract from this card
* card - The ID card to subtract these points from
diff --git a/code/game/machinery/computer/orders/order_items/cook/order_milk_eggs.dm b/code/game/machinery/computer/orders/order_items/cook/order_milk_eggs.dm
index 12ceaee8d3f..fcd0737675b 100644
--- a/code/game/machinery/computer/orders/order_items/cook/order_milk_eggs.dm
+++ b/code/game/machinery/computer/orders/order_items/cook/order_milk_eggs.dm
@@ -36,6 +36,11 @@
item_path = /obj/item/food/fishmeat/octopus
cost_per_order = 12
+/datum/orderable_item/milk_eggs/chicken
+ name = "Chicken Breast"
+ item_path = /obj/item/food/meat/slab/chicken
+ cost_per_order = 15
+
/datum/orderable_item/milk_eggs/spider_eggs
name = "Spider Eggs"
item_path = /obj/item/food/spidereggs
diff --git a/code/game/machinery/computer/orders/order_items/cook/order_reagents.dm b/code/game/machinery/computer/orders/order_items/cook/order_reagents.dm
index 584403a1195..d6b4728d104 100644
--- a/code/game/machinery/computer/orders/order_items/cook/order_reagents.dm
+++ b/code/game/machinery/computer/orders/order_items/cook/order_reagents.dm
@@ -51,9 +51,9 @@
item_path = /obj/item/reagent_containers/condiment/vinegar
cost_per_order = 30
-/datum/orderable_item/reagents/quality_oil
- name = "Quality Oil"
- item_path = /obj/item/reagent_containers/condiment/quality_oil
+/datum/orderable_item/reagents/olive_oil
+ name = "Olive Oil"
+ item_path = /obj/item/reagent_containers/condiment/olive_oil
cost_per_order = 50 //Extra Virgin, just like you, the reader
/datum/orderable_item/reagents/peanut_butter
diff --git a/code/game/machinery/computer/orders/order_items/mining/order_toys.dm b/code/game/machinery/computer/orders/order_items/mining/order_toys.dm
index 06bd9032e74..cd1dbf5c674 100644
--- a/code/game/machinery/computer/orders/order_items/mining/order_toys.dm
+++ b/code/game/machinery/computer/orders/order_items/mining/order_toys.dm
@@ -14,7 +14,7 @@
cost_per_order = 300
/datum/orderable_item/toys_drones/mining_drone
- item_path = /mob/living/simple_animal/hostile/mining_drone
+ item_path = /mob/living/basic/mining_drone
cost_per_order = 800
/datum/orderable_item/toys_drones/drone_health
diff --git a/code/game/machinery/computer/teleporter.dm b/code/game/machinery/computer/teleporter.dm
index 7177da8f4ee..dd8a051cc8e 100644
--- a/code/game/machinery/computer/teleporter.dm
+++ b/code/game/machinery/computer/teleporter.dm
@@ -28,6 +28,14 @@
power_station = null
return ..()
+/obj/machinery/computer/teleporter/proc/check_for_disabled_beacon(datum/target)
+ if (!target)
+ return
+ if (target.weak_reference != target_ref)
+ return
+ turn_off()
+ set_teleport_target(null)
+
/obj/machinery/computer/teleporter/proc/link_power_station()
if(power_station)
return
@@ -65,6 +73,11 @@
return data
+/obj/machinery/computer/teleporter/proc/turn_off()
+ power_station.engaged = FALSE
+ power_station.teleporter_hub.update_appearance()
+ power_station.teleporter_hub.calibrated = FALSE
+
/obj/machinery/computer/teleporter/ui_act(action, params)
. = ..()
if(.)
@@ -79,15 +92,11 @@
switch(action)
if("regimeset")
- power_station.engaged = FALSE
- power_station.teleporter_hub.update_appearance()
- power_station.teleporter_hub.calibrated = FALSE
+ turn_off()
reset_regime()
. = TRUE
if("settarget")
- power_station.engaged = FALSE
- power_station.teleporter_hub.update_appearance()
- power_station.teleporter_hub.calibrated = FALSE
+ turn_off()
set_target(usr)
. = TRUE
if("calibrate")
@@ -105,11 +114,18 @@
return TRUE
/obj/machinery/computer/teleporter/proc/set_teleport_target(new_target)
+ var/datum/old_target
var/datum/weakref/new_target_ref = WEAKREF(new_target)
if (target_ref == new_target_ref)
return
+ if (target_ref)
+ old_target = target_ref.resolve()
SEND_SIGNAL(src, COMSIG_TELEPORTER_NEW_TARGET, new_target)
target_ref = new_target_ref
+ if (istype(old_target, /obj/item/beacon))
+ UnregisterSignal(old_target, COMSIG_BEACON_DISABLED)
+ if (istype(new_target, /obj/item/beacon))
+ RegisterSignal(new_target, COMSIG_BEACON_DISABLED, PROC_REF(check_for_disabled_beacon))
/obj/machinery/computer/teleporter/proc/finish_calibration()
calibrating = FALSE
diff --git a/code/game/machinery/computer/telescreen.dm b/code/game/machinery/computer/telescreen.dm
index b03ed092269..ceb3c2e923e 100644
--- a/code/game/machinery/computer/telescreen.dm
+++ b/code/game/machinery/computer/telescreen.dm
@@ -56,6 +56,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/computer/security/telescreen/entertai
/obj/machinery/computer/security/telescreen/entertainment/Initialize(mapload)
. = ..()
RegisterSignal(src, COMSIG_CLICK, PROC_REF(BigClick))
+ find_and_hang_on_wall()
// Bypass clickchain to allow humans to use the telescreen from a distance
/obj/machinery/computer/security/telescreen/entertainment/proc/BigClick()
diff --git a/code/game/machinery/defibrillator_mount.dm b/code/game/machinery/defibrillator_mount.dm
index d212f2ba45d..cb12a399260 100644
--- a/code/game/machinery/defibrillator_mount.dm
+++ b/code/game/machinery/defibrillator_mount.dm
@@ -23,6 +23,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/defibrillator_mount, 28)
/obj/machinery/defibrillator_mount/loaded/Initialize(mapload) //loaded subtype for mapping use
. = ..()
defib = new/obj/item/defibrillator/loaded(src)
+ find_and_hang_on_wall()
MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/defibrillator_mount, 28)
diff --git a/code/game/machinery/digital_clock.dm b/code/game/machinery/digital_clock.dm
index 0bfb8aeba72..d0b695428af 100644
--- a/code/game/machinery/digital_clock.dm
+++ b/code/game/machinery/digital_clock.dm
@@ -83,6 +83,7 @@
/obj/machinery/digital_clock/Initialize(mapload)
. = ..()
START_PROCESSING(SSdigital_clock, src)
+ find_and_hang_on_wall()
/obj/machinery/digital_clock/Destroy()
STOP_PROCESSING(SSdigital_clock, src)
diff --git a/code/game/machinery/dish_drive.dm b/code/game/machinery/dish_drive.dm
index 814fe788f8c..e84e21314b3 100644
--- a/code/game/machinery/dish_drive.dm
+++ b/code/game/machinery/dish_drive.dm
@@ -9,7 +9,9 @@
density = FALSE
circuit = /obj/item/circuitboard/machine/dish_drive
pass_flags = PASSTABLE
+ /// List of dishes the drive can hold
var/list/collectable_items = list(/obj/item/trash/waffles, // SKYRAT EDIT CHANGE - non-static list
+ /obj/item/trash/waffles,
/obj/item/broken_bottle,
/obj/item/kitchen/fork,
/obj/item/plate,
@@ -19,19 +21,26 @@
/obj/item/shard,
/obj/item/trash/tray,
)
- var/list/disposable_items = list(/obj/item/trash/waffles, // SKYRAT EDIT CHANGE - non-static list
+ /// List of items the drive detects as trash
+ var/static/list/disposable_items = list(/obj/item/trash/waffles,
+ /obj/item/trash/waffles,
/obj/item/broken_bottle,
/obj/item/plate_shard,
/obj/item/shard,
/obj/item/trash/tray,
)
- var/time_since_dishes = 0
+ /// Can this suck up dishes?
var/suction_enabled = TRUE
+ /// Does this automatically dispose of trash?
var/transmit_enabled = TRUE
+ /// List of dishes currently inside
var/list/dish_drive_contents
- var/succrange = 4 //SKYRAT EDIT ADDITION - SEC_HAUL
+ /// Distance this is capable of sucking dishes up over. (2 + servo tier)
+ var/suck_distance = 0
var/binrange = 7 //SKYRAT EDIT ADDITION - SEC_HAUL
+ COOLDOWN_DECLARE(time_since_dishes)
+
/obj/machinery/dish_drive/Initialize(mapload)
. = ..()
RefreshParts()
@@ -40,16 +49,34 @@
. = ..()
if(user.Adjacent(src))
. += span_notice("Alt-click it to beam its contents to any nearby disposal bins.")
+ if(!LAZYLEN(dish_drive_contents))
+ . += "[src] is empty!"
+ return
+ // Makes a list of all dishes in the drive, as well as what dish will be taken out next.
+ var/list/dish_list = list()
+ // All the types in our list
+ var/list/dish_types = list()
+ for(var/obj/dish in dish_drive_contents)
+ dish_types[dish.type] += 1
+ for(var/dish_path in unique_list(dish_types))
+ // Counts our dish
+ var/dish_amount = dish_types[dish_path]
+ // Handles plurals
+ var/obj/dish = dish_path
+ var/dish_name = dish_amount == 1 ? initial(dish.name) : "[initial(dish.name)][plural_s(initial(dish.name))]"
+ dish_list += list("[dish_amount] [dish_name]")
+
+ . += span_info("It contains [english_list(dish_list)].\n[peek(dish_drive_contents)] is at the top of the pile.")
/obj/machinery/dish_drive/attack_hand(mob/living/user, list/modifiers)
. = ..()
if(!LAZYLEN(dish_drive_contents))
- to_chat(user, span_warning("There's nothing in [src]!"))
+ balloon_alert(user, "drive empty")
return
- var/obj/item/I = LAZYACCESS(dish_drive_contents, LAZYLEN(dish_drive_contents)) //the most recently-added item
- LAZYREMOVE(dish_drive_contents, I)
- user.put_in_hands(I)
- to_chat(user, span_notice("You take out [I] from [src]."))
+ var/obj/item/dish = LAZYACCESS(dish_drive_contents, LAZYLEN(dish_drive_contents)) //the most recently-added item
+ LAZYREMOVE(dish_drive_contents, dish)
+ user.put_in_hands(dish)
+ balloon_alert(user, "[dish] taken")
playsound(src, 'sound/items/pshoom.ogg', 50, TRUE)
flick("synthesizer_beam", src)
@@ -58,23 +85,27 @@
default_unfasten_wrench(user, tool)
return TOOL_ACT_TOOLTYPE_SUCCESS
-/obj/machinery/dish_drive/attackby(obj/item/I, mob/living/user, params)
- if(is_type_in_list(I, collectable_items) && !user.combat_mode)
- if(!user.transferItemToLoc(I, src))
+/obj/machinery/dish_drive/attackby(obj/item/dish, mob/living/user, params)
+ if(is_type_in_list(dish, collectable_items) && !user.combat_mode)
+ if(!user.transferItemToLoc(dish, src))
return
- LAZYADD(dish_drive_contents, I)
- to_chat(user, span_notice("You put [I] in [src], and it's beamed into energy!"))
+ LAZYADD(dish_drive_contents, dish)
+ balloon_alert(user, "[dish] placed in drive")
playsound(src, 'sound/items/pshoom.ogg', 50, TRUE)
flick("synthesizer_beam", src)
return
- else if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), I))
+ else if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), dish))
return
- else if(default_deconstruction_crowbar(I, FALSE))
+ else if(default_deconstruction_crowbar(dish, FALSE))
return
..()
/obj/machinery/dish_drive/RefreshParts()
. = ..()
+ suck_distance = 0
+ for(var/datum/stock_part/servo/servo in component_parts)
+ suck_distance = servo.tier
+ // Lowers power use for total tier
var/total_rating = 0
for(var/datum/stock_part/stock_part in component_parts)
total_rating += stock_part.tier
@@ -83,31 +114,33 @@
else
update_mode_power_usage(IDLE_POWER_USE, max(0, initial(idle_power_usage) - total_rating))
update_mode_power_usage(ACTIVE_POWER_USE, max(0, initial(active_power_usage) - total_rating))
+ // Board options
var/obj/item/circuitboard/machine/dish_drive/board = locate() in component_parts
if(board)
suction_enabled = board.suction
transmit_enabled = board.transmit
/obj/machinery/dish_drive/process()
- if(time_since_dishes <= world.time && transmit_enabled)
+ if(COOLDOWN_FINISHED(src, time_since_dishes) && transmit_enabled)
do_the_dishes()
if(!suction_enabled)
return
- for(var/obj/item/I in view(succrange, src)) //SKYRAT EDIT CHANGE - ORIGINAL: for(var/obj/item/I in view(4, src))
- if(is_type_in_list(I, collectable_items) && I.loc != src && (!I.reagents || !I.reagents.total_volume) && (I.contents.len < 1))
- if(I.Adjacent(src))
- LAZYADD(dish_drive_contents, I)
- visible_message(span_notice("[src] beams up [I]!"))
- I.forceMove(src)
+
+ for(var/obj/item/dish in view(2 + suck_distance, src))
+ if(is_type_in_list(dish, collectable_items) && dish.loc != src && (!dish.reagents || !dish.reagents.total_volume) && (dish.contents.len < 1))
+ if(dish.Adjacent(src))
+ LAZYADD(dish_drive_contents, dish)
+ visible_message(span_notice("[src] beams up [dish]!"))
+ dish.forceMove(src)
playsound(src, 'sound/items/pshoom.ogg', 50, TRUE)
flick("synthesizer_beam", src)
else
- step_towards(I, src)
+ step_towards(dish, src)
/obj/machinery/dish_drive/attack_ai(mob/living/user)
if(machine_stat)
return
- to_chat(user, span_notice("You send a disposal transmission signal to [src]."))
+ balloon_alert(user, "disposal signal sent")
do_the_dishes(TRUE)
/obj/machinery/dish_drive/AltClick(mob/living/user)
@@ -126,10 +159,10 @@
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, TRUE)
return
var/disposed = 0
- for(var/obj/item/I in dish_drive_contents)
- if(is_type_in_list(I, disposable_items))
- LAZYREMOVE(dish_drive_contents, I)
- I.forceMove(bin)
+ for(var/obj/item/dish in dish_drive_contents)
+ if(is_type_in_list(dish, disposable_items))
+ LAZYREMOVE(dish_drive_contents, dish)
+ dish.forceMove(bin)
use_power(active_power_usage)
disposed++
if (disposed)
@@ -143,4 +176,4 @@
if(manual)
visible_message(span_notice("There are no disposable items in [src]!"))
return
- time_since_dishes = world.time + 600
+ COOLDOWN_START(src, time_since_dishes, 1 MINUTES)
diff --git a/code/game/machinery/dna_infuser/organ_sets/fly_organs.dm b/code/game/machinery/dna_infuser/organ_sets/fly_organs.dm
index 9d0c10e8666..5d4568a535c 100644
--- a/code/game/machinery/dna_infuser/organ_sets/fly_organs.dm
+++ b/code/game/machinery/dna_infuser/organ_sets/fly_organs.dm
@@ -115,7 +115,7 @@
var/mob/living/carbon/body = owner
ASSERT(istype(body))
// we do not lose any nutrition as a fly when vomiting out food
- body.vomit(lost_nutrition = 0, stun = FALSE, distance = 2, force = TRUE, purge_ratio = 0.67)
+ body.vomit(vomit_flags = (MOB_VOMIT_MESSAGE | MOB_VOMIT_FORCE | MOB_VOMIT_HARM), lost_nutrition = 0, distance = 2, purge_ratio = 0.67)
playsound(get_turf(owner), 'sound/effects/splat.ogg', 50, TRUE)
body.visible_message(
span_danger("[body] vomits on the floor!"),
diff --git a/code/game/machinery/doors/airlock_electronics.dm b/code/game/machinery/doors/airlock_electronics.dm
index 4c5e080c653..73ae0994eb5 100644
--- a/code/game/machinery/doors/airlock_electronics.dm
+++ b/code/game/machinery/doors/airlock_electronics.dm
@@ -22,6 +22,25 @@
. = ..()
. += span_notice("Has a neat selection menu for modifying airlock access levels.")
+/**
+ * Create a copy of the electronics
+ * Arguments
+ * * [location][atom]- the location to create the new copy in
+ */
+/obj/item/electronics/airlock/proc/create_copy(atom/location)
+ //create a copy
+ var/obj/item/electronics/airlock/new_electronics = new(location)
+ //copy all params
+ new_electronics.accesses = accesses.Copy()
+ new_electronics.one_access = one_access
+ new_electronics.unres_sides = unres_sides
+ new_electronics.passed_name = passed_name
+ new_electronics.passed_cycle_id = passed_cycle_id
+ new_electronics.shell = shell
+ //return copy
+ return new_electronics
+
+
/obj/item/electronics/airlock/ui_state(mob/user)
return GLOB.hands_state
diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm
index be630c0a19e..5292c3a950c 100644
--- a/code/game/machinery/firealarm.dm
+++ b/code/game/machinery/firealarm.dm
@@ -80,7 +80,7 @@
)
)
AddElement(/datum/element/contextual_screentip_mob_typechecks, hovering_mob_typechecks)
-
+ find_and_hang_on_wall()
update_appearance()
diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm
index 8d3c4febd70..8075b51dcab 100644
--- a/code/game/machinery/flasher.dm
+++ b/code/game/machinery/flasher.dm
@@ -28,6 +28,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/flasher, 26)
. = ..() // ..() is EXTREMELY IMPORTANT, never forget to add it
if(!built)
bulb = new(src)
+ find_and_hang_on_wall()
/obj/machinery/flasher/vv_edit_var(vname, vval)
. = ..()
diff --git a/code/game/machinery/harvester.dm b/code/game/machinery/harvester.dm
index b5fd04a98f2..63a48dcd976 100644
--- a/code/game/machinery/harvester.dm
+++ b/code/game/machinery/harvester.dm
@@ -13,6 +13,7 @@
var/harvesting = FALSE
var/warming_up = FALSE
var/list/operation_order = list() //Order of wich we harvest limbs.
+ var/output_dir = SOUTH //Direction to drop the limbs in
var/allow_clothing = FALSE
var/allow_living = FALSE
@@ -58,6 +59,12 @@
/obj/machinery/harvester/AltClick(mob/user)
. = ..()
+ if(!user.can_perform_action(src))
+ return
+ if(panel_open)
+ output_dir = turn(output_dir, -90)
+ to_chat(user, span_notice("You change [src]'s output settings, setting the output to [dir2text(output_dir)]."))
+ return
if(!can_interact(user))
return
if(harvesting || !user || !isliving(user) || state_open)
@@ -121,17 +128,7 @@
if(!LAZYLEN(operation_order)) //The list is empty, so we're done here
end_harvesting(success = TRUE)
return
- var/turf/target
- for(var/adir in list(EAST,NORTH,SOUTH,WEST))
- var/turf/T = get_step(src,adir)
- if(!T)
- continue
- if(isclosedturf(T))
- continue
- target = T
- break
- if(!target)
- target = get_turf(src)
+ var/turf/target = get_step(src, output_dir)
for(var/obj/item/bodypart/BP in operation_order) //first we do non-essential limbs
BP.drop_limb()
C.emote("scream")
@@ -219,4 +216,4 @@
else if(!harvesting)
. += span_notice("Alt-click [src] to start harvesting.")
if(in_range(user, src) || isobserver(user))
- . += span_notice("The status display reads: Harvest speed at [interval*0.1] seconds per organ.")
+ . += span_notice("The status display reads: Harvest speed at [interval*0.1] seconds per organ. Outputting to the [dir2text(output_dir)].")
diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
index dd11c09d9c9..4104d7b93f8 100644
--- a/code/game/machinery/hologram.dm
+++ b/code/game/machinery/hologram.dm
@@ -580,7 +580,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
if(speaker == holocall_to_update.hologram && holocall_to_update.user.client?.prefs.read_preference(/datum/preference/toggle/enable_runechat))
holocall_to_update.user.create_chat_message(speaker, message_language, raw_message, spans)
else
- holocall_to_update.user.Hear(message, speaker, message_language, raw_message, radio_freq, spans, message_mods, message_range)
+ holocall_to_update.user.Hear(message, speaker, message_language, raw_message, radio_freq, spans, message_mods, message_range = INFINITY)
if(outgoing_call?.hologram && speaker == outgoing_call.user)
outgoing_call.hologram.say(raw_message, sanitize = FALSE)
@@ -691,16 +691,16 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
if(!LAZYLEN(masters) || !masters[owner])
return TRUE
var/obj/effect/overlay/holo_pad_hologram/holo = masters[owner]
- var/transfered = FALSE
+ var/transferred = FALSE
if(!validate_location(new_turf))
if(!transfer_to_nearby_pad(new_turf, owner))
return FALSE
else
- transfered = TRUE
+ transferred = TRUE
//All is good.
holo.abstract_move(new_turf)
SET_PLANE(holo, ABOVE_GAME_PLANE, new_turf)
- if(!transfered)
+ if(!transferred)
update_holoray(owner, new_turf)
return TRUE
diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm
index 73f527ca7d5..060b29c4d20 100644
--- a/code/game/machinery/igniter.dm
+++ b/code/game/machinery/igniter.dm
@@ -162,6 +162,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/sparker, 26)
spark_system.set_up(2, 1, src)
spark_system.attach(src)
register_context()
+ find_and_hang_on_wall()
/obj/machinery/sparker/Destroy()
QDEL_NULL(spark_system)
diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm
index 10c19336119..7c73d2b6f65 100644
--- a/code/game/machinery/iv_drip.dm
+++ b/code/game/machinery/iv_drip.dm
@@ -243,12 +243,12 @@
if(!(get_dist(src, attached) <= 1 && isturf(attached.loc)))
if(isliving(attached))
- var/mob/living/attached_mob = attached
+ var/mob/living/carbon/attached_mob = attached
to_chat(attached, span_userdanger("The IV drip needle is ripped out of you, leaving an open bleeding wound!"))
var/list/arm_zones = shuffle(list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM))
var/obj/item/bodypart/chosen_limb = attached_mob.get_bodypart(arm_zones[1]) || attached_mob.get_bodypart(arm_zones[2]) || attached_mob.get_bodypart(BODY_ZONE_CHEST)
chosen_limb.receive_damage(3)
- chosen_limb.force_wound_upwards(/datum/wound/pierce/moderate, wound_source = "IV needle")
+ attached_mob.cause_wound_of_type_and_severity(WOUND_PIERCE, chosen_limb, WOUND_SEVERITY_MODERATE, wound_source = "IV needle")
else
visible_message(span_warning("[attached] is detached from [src]."))
detach_iv()
diff --git a/code/game/machinery/launch_pad.dm b/code/game/machinery/launch_pad.dm
index f3f463bcae7..5400cccf2f2 100644
--- a/code/game/machinery/launch_pad.dm
+++ b/code/game/machinery/launch_pad.dm
@@ -78,7 +78,7 @@
return
var/obj/item/multitool/M = I
M.set_buffer(src)
- to_chat(user, span_notice("You save the data in the [I.name]'s buffer."))
+ balloon_alert(user, "saved to multitool buffer")
return 1
if(default_deconstruction_crowbar(I))
diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm
index 5bc618162f0..c9b220bb0cd 100644
--- a/code/game/machinery/lightswitch.dm
+++ b/code/game/machinery/lightswitch.dm
@@ -31,6 +31,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/light_switch, 26)
area = get_area(src)
if(!name)
name = "light switch ([area.name])"
+ find_and_hang_on_wall(custom_drop_callback = CALLBACK(src, PROC_REF(deconstruct), TRUE))
update_appearance()
diff --git a/code/game/machinery/mass_driver.dm b/code/game/machinery/mass_driver.dm
index f925dfdbdc3..e3922415a66 100644
--- a/code/game/machinery/mass_driver.dm
+++ b/code/game/machinery/mass_driver.dm
@@ -3,10 +3,20 @@
desc = "The finest in spring-loaded piston toy technology, now on a space station near you."
icon = 'icons/obj/machines/floor.dmi'
icon_state = "mass_driver"
+ circuit = /obj/item/circuitboard/machine/mass_driver
var/power = 1
var/code = 1
var/id = 1
- var/drive_range = 50 //this is mostly irrelevant since current mass drivers throw into space, but you could make a lower-range mass driver for interstation transport or something I guess.
+ var/drive_range = 10
+ var/power_per_obj = 1000
+
+/obj/machinery/mass_driver/Initialize(mapload)
+ . = ..()
+ wires = new /datum/wires/mass_driver(src)
+
+/obj/machinery/mass_driver/Destroy()
+ QDEL_NULL(wires)
+ . = ..()
/obj/machinery/mass_driver/chapelgun
name = "holy driver"
@@ -31,9 +41,9 @@
id = "[port.shuttle_id]_[id]"
/obj/machinery/mass_driver/proc/drive(amount)
- if(machine_stat & (BROKEN|NOPOWER))
+ if(machine_stat & (BROKEN|NOPOWER) || panel_open)
return
- use_power(active_power_usage)
+ use_power(power_per_obj)
var/O_limit
var/atom/target = get_edge_target_turf(src, dir)
for(var/atom/movable/O in loc)
@@ -44,14 +54,33 @@
if(O_limit >= 20)
audible_message(span_notice("[src] lets out a screech, it doesn't seem to be able to handle the load."))
break
- use_power(active_power_usage)
+ use_power(power_per_obj)
O.throw_at(target, drive_range * power, power)
flick("mass_driver1", src)
+/obj/machinery/mass_driver/attackby(obj/item/I, mob/living/user, params)
+
+ if(is_wire_tool(I) && panel_open)
+ wires.interact(user)
+ return
+ if(default_deconstruction_screwdriver(user, "mass_driver_o", "mass_driver", I))
+ return
+ if(default_change_direction_wrench(user, I))
+ return
+ if(default_deconstruction_crowbar(I))
+ return
+
+ return ..()
+
+/obj/machinery/mass_driver/RefreshParts()
+ . = ..()
+ for(var/datum/stock_part/servo/new_servo in component_parts)
+ drive_range += new_servo.tier * 10
+
/obj/machinery/mass_driver/emp_act(severity)
. = ..()
if (. & EMP_PROTECT_SELF)
return
- if(machine_stat & (BROKEN|NOPOWER))
+ if(machine_stat & (BROKEN|NOPOWER) || panel_open)
return
drive()
diff --git a/code/game/machinery/mechlaunchpad.dm b/code/game/machinery/mechlaunchpad.dm
index 54cda76f989..254467fc217 100644
--- a/code/game/machinery/mechlaunchpad.dm
+++ b/code/game/machinery/mechlaunchpad.dm
@@ -37,7 +37,7 @@
return
var/obj/item/multitool/multitool = tool
multitool.set_buffer(src)
- to_chat(user, span_notice("You save the data in the [multitool.name]'s buffer."))
+ balloon_alert(user, "saved to multitool buffer")
return TRUE
/obj/machinery/mechpad/wirecutter_act(mob/living/user, obj/item/tool)
diff --git a/code/game/machinery/medipen_refiller.dm b/code/game/machinery/medipen_refiller.dm
index b5c97554865..8f17ad3faba 100644
--- a/code/game/machinery/medipen_refiller.dm
+++ b/code/game/machinery/medipen_refiller.dm
@@ -57,9 +57,9 @@
if(!length(reagent_container.reagents.reagent_list))
balloon_alert(user, "nothing to transfer!")
return
- var/units = reagent_container.reagents.trans_to(src, reagent_container.amount_per_transfer_from_this, transfered_by = user)
+ var/units = reagent_container.reagents.trans_to(src, reagent_container.amount_per_transfer_from_this, transferred_by = user)
if(units)
- balloon_alert(user, "[units] units transfered")
+ balloon_alert(user, "[units] units transferred")
else
balloon_alert(user, "reagent storage full!")
return
diff --git a/code/game/machinery/nebula_shielding.dm b/code/game/machinery/nebula_shielding.dm
index 73192dac2b7..cd10a23150c 100644
--- a/code/game/machinery/nebula_shielding.dm
+++ b/code/game/machinery/nebula_shielding.dm
@@ -16,6 +16,8 @@
var/power_use_per_block = BASE_MACHINE_ACTIVE_CONSUMPTION * 2
///State we use when actively blocking a nebula
var/active_icon_state
+ /// State for when we're broken and wont work anymore. Make sure to also set integrity_failure for this to work
+ var/broken_icon_state
/obj/machinery/nebula_shielding/Initialize(mapload)
. = ..()
@@ -24,21 +26,33 @@
///Nebula is asking us how strong we are. Return our shield strength is all is well
/obj/machinery/nebula_shielding/proc/get_nebula_shielding()
- if(panel_open)
+ if(panel_open || (machine_stat & BROKEN))
return
if(!powered())
- icon_state = initial(icon_state)
+ update_appearance(UPDATE_ICON_STATE)
return
use_power_from_net(power_use_per_block)
generate_reward()
- icon_state = active_icon_state
+
+ update_appearance(UPDATE_ICON_STATE)
+
return shielding_strength
///Generate a resource for defending against the nebula
/obj/machinery/nebula_shielding/proc/generate_reward()
return
+/obj/machinery/nebula_shielding/update_icon_state()
+ . = ..()
+
+ if((machine_stat & BROKEN) && broken_icon_state)
+ icon_state = broken_icon_state
+ else if(!powered())
+ icon_state = initial(icon_state)
+ else
+ icon_state = active_icon_state
+
///Short-lived nebula shielding sent by centcom in-case there hasn't been shielding for a while
/obj/machinery/nebula_shielding/emergency
density = TRUE
@@ -76,12 +90,15 @@
icon_state = "radioactive_shielding"
active_icon_state = "radioactive_shielding_on"
+ broken_icon_state = "radioactive_shielding_broken"
circuit = /obj/item/circuitboard/machine/radioactive_nebula_shielding
nebula_type = /datum/station_trait/nebula/hostile/radiation
shielding_strength = 4
+ integrity_failure = 0.4
+
/obj/machinery/nebula_shielding/radiation/examine(mob/user)
. = ..()
diff --git a/code/game/machinery/newscaster/newscaster_machine.dm b/code/game/machinery/newscaster/newscaster_machine.dm
index ad08823981b..1ae08c066f0 100644
--- a/code/game/machinery/newscaster/newscaster_machine.dm
+++ b/code/game/machinery/newscaster/newscaster_machine.dm
@@ -73,6 +73,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30)
GLOB.allCasters += src
GLOB.allbountyboards += src
update_appearance()
+ find_and_hang_on_wall()
/obj/machinery/newscaster/Destroy()
GLOB.allCasters -= src
@@ -578,7 +579,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30)
targetcam = R.aicamera
else if(ispAI(user))
var/mob/living/silicon/pai/R = user
- targetcam = R.camera
+ if(R.aicamera)
+ targetcam = R.aicamera
else if(iscyborg(user))
var/mob/living/silicon/robot/R = user
if(R.connected_ai)
diff --git a/code/game/machinery/newscaster/newspaper.dm b/code/game/machinery/newscaster/newspaper.dm
index 2010f7480fd..d605d6257c3 100644
--- a/code/game/machinery/newscaster/newspaper.dm
+++ b/code/game/machinery/newscaster/newspaper.dm
@@ -28,7 +28,7 @@
var/mob/living/carbon/human/H = user
var/obj/W = new /obj/item/reagent_containers/cup/glass/bottle/whiskey(H.loc)
playsound(H.loc, 'sound/items/drink.ogg', rand(10,50), TRUE)
- W.reagents.trans_to(H, W.reagents.total_volume, transfered_by = user)
+ W.reagents.trans_to(H, W.reagents.total_volume, transferred_by = user)
user.visible_message(span_suicide("[user] downs the contents of [W.name] in one gulp! Shoulda stuck to sudoku!"))
return TOXLOSS
diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm
index 79b421fa8de..fc646a3483e 100644
--- a/code/game/machinery/pipe/construction.dm
+++ b/code/game/machinery/pipe/construction.dm
@@ -338,7 +338,7 @@ Buildable meters
if(iscarbon(user))
var/mob/living/carbon/C = user
for(var/i in 1 to 20)
- C.vomit(0, TRUE, FALSE, 4, FALSE)
+ C.vomit(vomit_flags = (MOB_VOMIT_BLOOD | MOB_VOMIT_HARM), lost_nutrition = 0, distance = 4)
if(prob(20))
C.spew_organ()
sleep(0.5 SECONDS)
diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm
index b19a8032e7d..701d6222369 100644
--- a/code/game/machinery/porta_turret/portable_turret.dm
+++ b/code/game/machinery/porta_turret/portable_turret.dm
@@ -351,7 +351,7 @@ DEFINE_BITFIELD(turret_flags, list(
return
var/obj/item/multitool/M = I
M.set_buffer(src)
- to_chat(user, span_notice("You add [src] to multitool buffer."))
+ balloon_alert(user, "saved to multitool buffer")
else
return ..()
@@ -919,6 +919,7 @@ DEFINE_BITFIELD(turret_flags, list(
if(built)
locked = FALSE
power_change() //Checks power and initial settings
+ find_and_hang_on_wall()
/obj/machinery/turretid/Destroy()
turrets.Cut()
diff --git a/code/game/machinery/porta_turret/portable_turret_cover.dm b/code/game/machinery/porta_turret/portable_turret_cover.dm
index 89f41386691..86b1df20e7f 100644
--- a/code/game/machinery/porta_turret/portable_turret_cover.dm
+++ b/code/game/machinery/porta_turret/portable_turret_cover.dm
@@ -66,7 +66,7 @@
return
var/obj/item/multitool/M = I
M.set_buffer(parent_turret)
- to_chat(user, span_notice("You add [parent_turret] to multitool buffer."))
+ balloon_alert(user, "saved to multitool buffer")
return
return ..()
diff --git a/code/game/machinery/quantum_pad.dm b/code/game/machinery/quantum_pad.dm
index a855c2d5523..037b4692fc7 100644
--- a/code/game/machinery/quantum_pad.dm
+++ b/code/game/machinery/quantum_pad.dm
@@ -63,6 +63,7 @@
return
var/obj/item/multitool/M = I
M.set_buffer(src)
+ balloon_alert(user, "saved to multitool buffer")
to_chat(user, span_notice("You save the data in [I]'s buffer. It can now be saved to pads with closed panels."))
return TRUE
else if(I.tool_behaviour == TOOL_MULTITOOL)
@@ -71,14 +72,14 @@
var/obj/item/multitool/M = I
if(istype(M.buffer, /obj/machinery/quantumpad))
if(M.buffer == src)
- to_chat(user, span_warning("You cannot link a pad to itself!"))
+ balloon_alert(user, "cannot link to self!")
return TRUE
else
linked_pad = M.buffer
- to_chat(user, span_notice("You link [src] to the one in [I]'s buffer."))
+ balloon_alert(user, "data uploaded from buffer")
return TRUE
else
- to_chat(user, span_warning("There is no quantum pad data saved in [I]'s buffer!"))
+ balloon_alert(user, "no quantum pad data found!")
return TRUE
else if(istype(I, /obj/item/quantum_keycard))
diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm
index ddf55388d0b..99e7540a352 100644
--- a/code/game/machinery/recycler.dm
+++ b/code/game/machinery/recycler.dm
@@ -12,7 +12,6 @@
var/safety_mode = FALSE // Temporarily stops machine if it detects a mob
var/icon_name = "grinder-o"
var/bloody = FALSE
- var/eat_dir = WEST
var/amount_produced = 50
var/crush_damage = 1000
var/eat_victim_items = TRUE
@@ -34,6 +33,7 @@
/datum/material/bluespace
)
materials = AddComponent(/datum/component/material_container, allowed_materials, INFINITY, MATCONTAINER_NO_INSERT|BREAKDOWN_FLAGS_RECYCLER)
+ AddComponent(/datum/component/simple_rotation)
AddComponent(/datum/component/butchering/recycler, \
speed = 0.1 SECONDS, \
effectiveness = amount_produced, \
@@ -110,17 +110,12 @@
. = ..()
if(!anchored)
return
- if(border_dir == eat_dir)
+ if(border_dir == dir)
return TRUE
/obj/machinery/recycler/proc/on_entered(datum/source, atom/movable/enterer, old_loc)
SIGNAL_HANDLER
- // This is explicitly so we avoid processing items that are entering from nullspace,
- // to avoid infinite loops.
- if(!old_loc)
- return
-
INVOKE_ASYNC(src, PROC_REF(eat), enterer)
/obj/machinery/recycler/proc/eat(atom/movable/morsel, sound=TRUE)
diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm
index 99d4f716c9c..dbdf86dac37 100644
--- a/code/game/machinery/requests_console.dm
+++ b/code/game/machinery/requests_console.dm
@@ -127,6 +127,7 @@ GLOBAL_LIST_EMPTY(req_console_ckey_departments)
radio = new /obj/item/radio(src)
radio.set_listening(FALSE)
+ find_and_hang_on_wall()
/obj/machinery/requests_console/Destroy()
QDEL_NULL(radio)
@@ -199,7 +200,7 @@ GLOBAL_LIST_EMPTY(req_console_ckey_departments)
var/mob/living/L = usr
message = L.treat_message(message)["message"]
- minor_announce(message, "[department] Announcement:", html_encode = FALSE)
+ minor_announce(message, "[department] Announcement:", html_encode = FALSE, sound_override = ANNOUNCER_DEPARTMENTAL) // SKYRAT EDIT CHANGE - Announcer Sounds
GLOB.news_network.submit_article(message, department, "Station Announcements", null)
usr.log_talk(message, LOG_SAY, tag="station announcement from [src]")
message_admins("[ADMIN_LOOKUPFLW(usr)] has made a station announcement from [src] at [AREACOORD(usr)].")
diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm
index 91fddf8b65f..b4777c084c9 100644
--- a/code/game/machinery/spaceheater.dm
+++ b/code/game/machinery/spaceheater.dm
@@ -77,7 +77,7 @@
/obj/machinery/space_heater/on_construction()
set_panel_open(TRUE)
- cell = null
+ QDEL_NULL(cell)
/obj/machinery/space_heater/on_deconstruction()
if(cell)
diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm
index 20b64c6817e..76c82dd39dd 100644
--- a/code/game/machinery/status_display.dm
+++ b/code/game/machinery/status_display.dm
@@ -232,7 +232,7 @@
set_messages("shutl","not in service")
return PROCESS_KILL
else if(shuttle.timer)
- var/line1 = "<<< [shuttle.getModeStr()]"
+ var/line1 = shuttle.getModeStr()
var/line2 = shuttle.getTimerStr()
set_messages(line1, line2)
@@ -319,6 +319,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/status_display/evac, 32)
AddComponent(/datum/component/usb_port, list(
/obj/item/circuit_component/status_display,
))
+ find_and_hang_on_wall()
/obj/machinery/status_display/evac/Destroy()
SSradio.remove_object(src,frequency)
@@ -397,7 +398,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/status_display/evac, 32)
line1 = ""
line2 = ""
else
- line1 = "<<< [SSshuttle.supply.getModeStr()]"
+ line1 = SSshuttle.supply.getModeStr()
line2 = SSshuttle.supply.getTimerStr()
set_messages(line1, line2)
@@ -494,9 +495,17 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/status_display/ai, 32)
var/static/list/picture_options = list(
"Default" = "default",
+ "Delta Alert" = "deltaalert",
"Red Alert" = "redalert",
+ "Blue Alert" = "bluealert",
+ "Green Alert" = "greenalert",
+ "Violet Alert" = "violetalert", // SKYRAT EDIT ADD - Alert Levels
+ "Orange Alert" = "orangealert", // SKYRAT EDIT ADD - Alert Levels
+ "Amber Alert" = "amberalert", // SKYRAT EDIT ADD - Alert Levels
+ "Gamma Alert" = "gammaalert", // SKYRAT EDIT ADD - Alert Levels
"Biohazard" = "biohazard",
"Lockdown" = "lockdown",
+ "Radiation" = "radiation",
"Happy" = "ai_happy",
"Neutral" = "ai_neutral",
"Very Happy" = "ai_veryhappy",
diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm
index 402185e0928..516f5ec8453 100644
--- a/code/game/machinery/syndicatebomb.dm
+++ b/code/game/machinery/syndicatebomb.dm
@@ -409,12 +409,14 @@
/obj/item/bombcore/badmin/summon/detonate()
var/obj/machinery/syndicatebomb/B = loc
- spawn_and_random_walk(summon_path, src, amt_summon, walk_chance=50, admin_spawn=TRUE)
+ spawn_and_random_walk(summon_path, src, amt_summon, walk_chance=50, admin_spawn=TRUE, cardinals_only = FALSE)
qdel(B)
qdel(src)
/obj/item/bombcore/badmin/summon/clown
- summon_path = /mob/living/simple_animal/hostile/retaliate/clown
+ name = "bananium payload"
+ desc = "Clowns delivered fast and cheap!"
+ summon_path = /mob/living/basic/clown
amt_summon = 50
/obj/item/bombcore/badmin/summon/clown/defuse()
diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm
index 93fbafeb43d..8b6601dd471 100644
--- a/code/game/machinery/teleporter.dm
+++ b/code/game/machinery/teleporter.dm
@@ -186,13 +186,13 @@
var/obj/item/multitool/M = W
if(panel_open)
M.set_buffer(src)
- to_chat(user, span_notice("You download the data to the [W.name]'s buffer."))
+ balloon_alert(user, "saved to multitool buffer")
else
if(M.buffer && istype(M.buffer, /obj/machinery/teleport/station) && M.buffer != src)
if(linked_stations.len < efficiency)
linked_stations.Add(M.buffer)
M.set_buffer(null)
- to_chat(user, span_notice("You upload the data from the [W.name]'s buffer."))
+ balloon_alert(user, "data uploaded from buffer")
else
to_chat(user, span_alert("This station can't hold more information, try to use better parts."))
return
diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm
index 2f8cb369f95..3d37d2e52b4 100644
--- a/code/game/objects/buckling.dm
+++ b/code/game/objects/buckling.dm
@@ -197,10 +197,10 @@
//Handle any extras after buckling
//Called on buckle_mob()
-/atom/movable/proc/post_buckle_mob(mob/living/M)
+/atom/movable/proc/post_buckle_mob(mob/living/buckled_mob)
//same but for unbuckle
-/atom/movable/proc/post_unbuckle_mob(mob/living/M)
+/atom/movable/proc/post_unbuckle_mob(mob/living/unbuckled_mob)
/**
* Simple helper proc that runs a suite of checks to test whether it is possible or not to buckle the target mob to src.
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index 71ede0c55a3..b0af5c3ca02 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -79,7 +79,7 @@
to_chat(user, span_notice("[W] is full!"))
return
to_chat(user, span_notice("You scoop up [src] into [W]!"))
- reagents.trans_to(W, reagents.total_volume, transfered_by = user)
+ reagents.trans_to(W, reagents.total_volume, transferred_by = user)
if(!reagents.total_volume) //scooped up all of it
qdel(src)
return
diff --git a/code/game/objects/effects/decals/cleanable/aliens.dm b/code/game/objects/effects/decals/cleanable/aliens.dm
index e113eec5a36..4f4b2543792 100644
--- a/code/game/objects/effects/decals/cleanable/aliens.dm
+++ b/code/game/objects/effects/decals/cleanable/aliens.dm
@@ -40,8 +40,9 @@
return
if(mapload)
for (var/i in 1 to range)
- if(!isgroundlessturf(loc) || GET_TURF_BELOW(loc))
- new /obj/effect/decal/cleanable/xenoblood/xsplatter(loc)
+ var/turf/my_turf = get_turf(src)
+ if(!isgroundlessturf(my_turf) || GET_TURF_BELOW(my_turf))
+ new /obj/effect/decal/cleanable/xenoblood/xsplatter(my_turf)
if (!step_to(src, get_step(src, direction), 0))
break
return
diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm
index fc07a229251..d329de34a5f 100644
--- a/code/game/objects/effects/decals/cleanable/humans.dm
+++ b/code/game/objects/effects/decals/cleanable/humans.dm
@@ -159,8 +159,9 @@
return
if(mapload)
for (var/i in 1 to range)
- if(!isgroundlessturf(loc) || GET_TURF_BELOW(loc))
- new /obj/effect/decal/cleanable/blood/splatter(loc)
+ var/turf/my_turf = get_turf(src)
+ if(!isgroundlessturf(my_turf) || GET_TURF_BELOW(my_turf))
+ new /obj/effect/decal/cleanable/blood/splatter(my_turf)
if (!step_to(src, get_step(src, direction), 0))
break
return
diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm
index d97b1ad9515..6a519650d10 100644
--- a/code/game/objects/effects/decals/cleanable/misc.dm
+++ b/code/game/objects/effects/decals/cleanable/misc.dm
@@ -171,9 +171,23 @@
if(isflyperson(H))
playsound(get_turf(src), 'sound/items/drink.ogg', 50, TRUE) //slurp
H.visible_message(span_alert("[H] extends a small proboscis into the vomit pool, sucking it with a slurping sound."))
- reagents.trans_to(H, reagents.total_volume, transfered_by = user, methods = INGEST)
+ reagents.trans_to(H, reagents.total_volume, transferred_by = user, methods = INGEST)
qdel(src)
+/obj/effect/decal/cleanable/vomit/toxic // this has a more toned-down color palette, which may be why it's used as the default in so many spots
+ icon_state = "vomittox_1"
+ random_icon_states = list("vomittox_1", "vomittox_2", "vomittox_3", "vomittox_4")
+
+/obj/effect/decal/cleanable/vomit/purple // ourple
+ icon_state = "vomitpurp_1"
+ random_icon_states = list("vomitpurp_1", "vomitpurp_2", "vomitpurp_3", "vomitpurp_4")
+
+/obj/effect/decal/cleanable/vomit/nanites
+ name = "nanite-infested vomit"
+ desc = "Gosh, you can see something moving in there."
+ icon_state = "vomitnanite_1"
+ random_icon_states = list("vomitnanite_1", "vomitnanite_2", "vomitnanite_3", "vomitnanite_4")
+
/obj/effect/decal/cleanable/vomit/nebula
name = "nebula vomit"
desc = "Gosh, how... beautiful."
diff --git a/code/game/objects/effects/decals/cleanable/robots.dm b/code/game/objects/effects/decals/cleanable/robots.dm
index 65e6cc3900c..d248b5e691d 100644
--- a/code/game/objects/effects/decals/cleanable/robots.dm
+++ b/code/game/objects/effects/decals/cleanable/robots.dm
@@ -25,8 +25,9 @@
return
if(mapload)
for (var/i in 1 to range)
- if(prob(40) && (!isgroundlessturf(loc) || GET_TURF_BELOW(loc)))
- new /obj/effect/decal/cleanable/oil/streak(loc)
+ var/turf/my_turf = get_turf(src)
+ if(prob(40) && (!isgroundlessturf(my_turf) || GET_TURF_BELOW(my_turf)))
+ new /obj/effect/decal/cleanable/oil/streak(my_turf)
if (!step_to(src, get_step(src, direction), 0))
break
return
diff --git a/code/game/objects/effects/effect_system/fluid_spread/effects_foam.dm b/code/game/objects/effects/effect_system/fluid_spread/effects_foam.dm
index 914b19e6a88..787ce602a3a 100644
--- a/code/game/objects/effects/effect_system/fluid_spread/effects_foam.dm
+++ b/code/game/objects/effects/effect_system/fluid_spread/effects_foam.dm
@@ -459,6 +459,20 @@
allow_duplicate_results = FALSE
result_type = /obj/effect/decal/cleanable/dirt
+/obj/effect/spawner/foam_starter
+ var/datum/effect_system/fluid_spread/foam/foam_type = /datum/effect_system/fluid_spread/foam
+ var/foam_size = 4
+
+/obj/effect/spawner/foam_starter/Initialize(mapload)
+ . = ..()
+
+ var/datum/effect_system/fluid_spread/foam/foam = new foam_type()
+ foam.set_up(foam_size, holder = src, location = loc)
+ foam.start()
+
+/obj/effect/spawner/foam_starter/small
+ foam_size = 2
+
#undef MINIMUM_FOAM_DILUTION_RANGE
#undef MINIMUM_FOAM_DILUTION
#undef FOAM_REAGENT_SCALE
diff --git a/code/game/objects/effects/phased_mob.dm b/code/game/objects/effects/phased_mob.dm
index 7a0317c4c77..273a4c772a5 100644
--- a/code/game/objects/effects/phased_mob.dm
+++ b/code/game/objects/effects/phased_mob.dm
@@ -83,7 +83,7 @@
return
var/area/destination_area = newloc.loc
movedelay = world.time + movespeed
- if(newloc.flags_1 & NOJAUNT)
+ if(newloc.turf_flags & NOJAUNT)
to_chat(user, span_warning("Some strange aura is blocking the way."))
return
if(destination_area.area_flags & NOTELEPORT || SSmapping.level_trait(newloc.z, ZTRAIT_NOPHASE))
diff --git a/code/game/objects/effects/spawners/random/food_or_drink.dm b/code/game/objects/effects/spawners/random/food_or_drink.dm
index b9d01e8081a..b2639b2df68 100644
--- a/code/game/objects/effects/spawners/random/food_or_drink.dm
+++ b/code/game/objects/effects/spawners/random/food_or_drink.dm
@@ -56,6 +56,7 @@
/obj/item/seeds/liberty = 5,
/obj/item/seeds/replicapod = 5,
/obj/item/seeds/reishi = 5,
+ /obj/item/seeds/seedling = 5,
/obj/item/seeds/nettle/death = 1,
/obj/item/seeds/plump/walkingmushroom = 1,
/obj/item/seeds/cannabis/rainbow = 1,
@@ -243,7 +244,7 @@
/obj/item/reagent_containers/condiment/soysauce = 1,
/obj/item/reagent_containers/condiment/vinegar = 1,
/obj/item/reagent_containers/condiment/peanut_butter = 1,
- /obj/item/reagent_containers/condiment/quality_oil = 1,
+ /obj/item/reagent_containers/condiment/olive_oil = 1,
/obj/item/reagent_containers/condiment/cherryjelly = 1,
)
@@ -272,3 +273,53 @@
if(!HAS_TRAIT(SSstation, STATION_TRAIT_BIRTHDAY))
spawn_loot_chance = 0
return ..()
+
+/obj/effect/spawner/random/food_or_drink/donuts
+ name = "donut spawner"
+ icon_state = "donut"
+ loot = list(
+ /obj/item/food/donut/apple = 3,
+ /obj/item/food/donut/berry = 3,
+ /obj/item/food/donut/caramel = 3,
+ /obj/item/food/donut/choco = 3,
+ /obj/item/food/donut/plain = 3,
+ /obj/item/food/donut/blumpkin = 2,
+ /obj/item/food/donut/bungo = 2,
+ /obj/item/food/donut/laugh = 2,
+ /obj/item/food/donut/matcha = 2,
+ /obj/item/food/donut/trumpet = 2,
+ /obj/item/food/donut/chaos = 1,
+ /obj/item/food/donut/meat = 1,
+ )
+
+/obj/effect/spawner/random/food_or_drink/jelly_donuts
+ name = "jelly donut spawner"
+ icon_state = "jelly_donut"
+ loot = list(
+ /obj/item/food/donut/jelly/apple = 3,
+ /obj/item/food/donut/jelly/berry = 3,
+ /obj/item/food/donut/jelly/caramel = 3,
+ /obj/item/food/donut/jelly/choco = 3,
+ /obj/item/food/donut/jelly/plain = 3,
+ /obj/item/food/donut/jelly/blumpkin = 2,
+ /obj/item/food/donut/jelly/bungo = 2,
+ /obj/item/food/donut/jelly/laugh = 2,
+ /obj/item/food/donut/jelly/matcha = 2,
+ /obj/item/food/donut/jelly/trumpet = 2,
+ )
+
+/obj/effect/spawner/random/food_or_drink/slime_jelly_donuts
+ name = "slime jelly donut spawner"
+ icon_state = "slime_jelly_donut"
+ loot = list(
+ /obj/item/food/donut/jelly/slimejelly/apple = 3,
+ /obj/item/food/donut/jelly/slimejelly/berry = 3,
+ /obj/item/food/donut/jelly/slimejelly/caramel = 3,
+ /obj/item/food/donut/jelly/slimejelly/choco = 3,
+ /obj/item/food/donut/jelly/slimejelly/plain = 3,
+ /obj/item/food/donut/jelly/slimejelly/blumpkin = 2,
+ /obj/item/food/donut/jelly/slimejelly/bungo = 2,
+ /obj/item/food/donut/jelly/slimejelly/laugh = 2,
+ /obj/item/food/donut/jelly/slimejelly/matcha = 2,
+ /obj/item/food/donut/jelly/slimejelly/trumpet = 2,
+ )
diff --git a/code/game/objects/effects/spawners/random/lavaland_mobs.dm b/code/game/objects/effects/spawners/random/lavaland_mobs.dm
index 7ad2b3e6e30..8aa20cc90e7 100644
--- a/code/game/objects/effects/spawners/random/lavaland_mobs.dm
+++ b/code/game/objects/effects/spawners/random/lavaland_mobs.dm
@@ -7,11 +7,11 @@
icon_state = "large_egg"
loot = list(
/mob/living/basic/mining/bileworm = 1,
+ /mob/living/basic/mining/brimdemon = 1,
/mob/living/basic/mining/goldgrub = 1,
/mob/living/basic/mining/goliath = 1,
/mob/living/basic/mining/lobstrosity/lava = 1,
/mob/living/basic/mining/watcher = 1,
- /mob/living/simple_animal/hostile/asteroid/brimdemon = 1,
/mob/living/simple_animal/hostile/asteroid/hivelord/legion = 1,
)
diff --git a/code/game/objects/effects/spawners/random/medical.dm b/code/game/objects/effects/spawners/random/medical.dm
index 34541083775..ccbc109254a 100644
--- a/code/game/objects/effects/spawners/random/medical.dm
+++ b/code/game/objects/effects/spawners/random/medical.dm
@@ -132,7 +132,7 @@
name = "patient stretcher spawner"
icon_state = "rollerbed"
loot = list(
- /obj/structure/bed/roller,
+ /obj/structure/bed/medical/emergency,
/obj/vehicle/ridden/wheelchair,
)
diff --git a/code/game/objects/effects/spawners/random/structure.dm b/code/game/objects/effects/spawners/random/structure.dm
index bf8e77a9fcd..cf037b91b5c 100644
--- a/code/game/objects/effects/spawners/random/structure.dm
+++ b/code/game/objects/effects/spawners/random/structure.dm
@@ -235,3 +235,24 @@
/obj/structure/musician/piano,
/obj/structure/musician/piano/minimoog,
)
+
+/obj/effect/spawner/random/structure/shipping_container
+ name = "shipping container spawner"
+ icon = 'icons/obj/fluff/containers.dmi'
+ icon_state = "random_container"
+ loot = list(
+ /obj/structure/shipping_container/conarex = 3,
+ /obj/structure/shipping_container/deforest = 3,
+ /obj/structure/shipping_container/kahraman = 3,
+ /obj/structure/shipping_container/kahraman/alt = 3,
+ /obj/structure/shipping_container/kosmologistika = 3,
+ /obj/structure/shipping_container/interdyne = 3,
+ /obj/structure/shipping_container/nakamura = 3,
+ /obj/structure/shipping_container/nanotrasen = 3,
+ /obj/structure/shipping_container/nthi = 3,
+ /obj/structure/shipping_container/vitezstvi = 3,
+ /obj/structure/shipping_container/cybersun = 2,
+ /obj/structure/shipping_container/donk_co = 2,
+ /obj/structure/shipping_container/gorlex = 1,
+ /obj/structure/shipping_container/gorlex/red = 1,
+ )
diff --git a/code/game/objects/effects/spawners/random/trash.dm b/code/game/objects/effects/spawners/random/trash.dm
index 020724772dd..b10dbc1f7f8 100644
--- a/code/game/objects/effects/spawners/random/trash.dm
+++ b/code/game/objects/effects/spawners/random/trash.dm
@@ -266,3 +266,22 @@
/obj/item/food/breadslice/moldy/bacteria,
/obj/item/food/pizzaslice/moldy/bacteria,
)
+
+/obj/effect/spawner/random/trash/crushed_can
+ name = "crushed can spawner"
+ icon_state = "crushed_can"
+ loot = list(/obj/item/trash/can)
+ /// Whether the can will spawn with this spawner's icon_state instead of a random one (used for mapedits)
+ var/soda_icons = list(
+ "energy_drink", "monkey_energy", "thirteen_loko", "space_mountain_wind", "dr_gibb", "starkist",
+ "sodawater", "tonic", "cola", "purple_can", "ice_tea_can",
+ "sol_dry", "wellcheers", "space beer", "ebisu", "shimauma", "moonlabor",
+ "space_up", "lemon_lime", "shamblers", "shamblerseldritch", "air", "laughter",
+ "volt_energy", "melon_soda",
+ )
+
+/obj/effect/spawner/random/trash/crushed_can/make_item(spawn_loc, type_path_to_make)
+ var/obj/item/trash/can/crushed_can = .. ()
+ if(istype(crushed_can))
+ crushed_can.icon_state = pick(soda_icons)
+ return crushed_can
diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
index 3098d8c7125..e88753d25c1 100644
--- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm
+++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
@@ -654,3 +654,38 @@
/obj/effect/temp_visual/crit/Initialize(mapload)
. = ..()
animate(src, pixel_y = pixel_y + 16, alpha = 0, time = duration)
+
+/obj/effect/temp_visual/jet_plume
+ name = "jet plume"
+ icon_state = "jet_plume"
+ layer = BELOW_MOB_LAYER
+ plane = GAME_PLANE
+ duration = 0.4 SECONDS
+
+/// Plays a dispersing animation on hivelord and legion minions so they don't just vanish
+/obj/effect/temp_visual/hive_spawn_wither
+ name = "withering spawn"
+ duration = 1 SECONDS
+
+/obj/effect/temp_visual/hive_spawn_wither/Initialize(mapload, atom/copy_from)
+ if (isnull(copy_from))
+ . = ..()
+ return INITIALIZE_HINT_QDEL
+ icon = copy_from.icon
+ icon_state = copy_from.icon_state
+ pixel_x = copy_from.pixel_x
+ pixel_y = copy_from.pixel_y
+ duration = rand(0.5 SECONDS, 1 SECONDS)
+ var/matrix/transformation = matrix(transform)
+ transformation.Turn(rand(-70, 70))
+ transformation.Scale(0.7, 0.7)
+ animate(
+ src,
+ pixel_x = rand(-5, 5),
+ pixel_y = -5,
+ transform = transformation,
+ color = "#44444400",
+ time = duration,
+ flags = ANIMATION_RELATIVE,
+ )
+ return ..()
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 4cc3a963b5f..c10c04a9fa1 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -171,7 +171,8 @@
var/sharpness = NONE
///How a tool acts when you use it on something, such as wirecutters cutting wires while multitools measure power
- var/tool_behaviour = NONE
+ var/tool_behaviour = null
+
///How fast does the tool work
var/toolspeed = 1
@@ -207,10 +208,8 @@
///Grinder var:A reagent list containing the reagents this item produces when ground up in a grinder - this can be an empty list to allow for reagent transferring only
var/list/grind_results
- //Grinder var:A reagent list containing blah blah... but when JUICED in a grinder!
- var/list/juice_results
-
- var/canMouseDown = FALSE
+ ///A reagent the nutriments are converted into when the item is juiced.
+ var/datum/reagent/consumable/juice_typepath
/// Used in obj/item/examine to give additional notes on what the weapon does, separate from the predetermined output variables
var/offensive_notes
@@ -245,7 +244,6 @@
// Handle adding item associated actions
for(var/path in actions_types)
add_item_action(path)
-
actions_types = null
if(force_string)
@@ -867,6 +865,13 @@
return mutable_appearance(SSgreyscale.GetColoredIconByType(greyscale_config_belt, greyscale_colors), icon_state_to_use)
return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', icon_state_to_use)
+/**
+ * Extend this to give the item an appearance when placed in a surgical tray. Uses an icon state in `medicart.dmi`.
+ * * tray_extended - If true, the surgical tray the item is placed on is in "table mode"
+ */
+/obj/item/proc/get_surgery_tool_overlay(tray_extended)
+ return null
+
/obj/item/proc/update_slot_icon()
if(!ismob(loc))
return
@@ -971,13 +976,36 @@
/obj/item/proc/grind_requirements(obj/machinery/reagentgrinder/R) //Used to check for extra requirements for grinding an object
return TRUE
-///Called BEFORE the object is ground up - use this to change grind results based on conditions. Use "return -1" to prevent the grinding from occurring
+///Called BEFORE the object is ground up - use this to change grind results based on conditions. Return "-1" to prevent the grinding from occurring
/obj/item/proc/on_grind()
return SEND_SIGNAL(src, COMSIG_ITEM_ON_GRIND)
+///Grind item, adding grind_results to item's reagents and transfering to target_holder if specified
+/obj/item/proc/grind(datum/reagents/target_holder, mob/user)
+ if(on_grind() == -1)
+ return FALSE
+ if(target_holder)
+ target_holder.add_reagent_list(grind_results)
+ if(reagents)
+ reagents.trans_to(target_holder, reagents.total_volume, transferred_by = user)
+ return TRUE
+
+///Called BEFORE the object is ground up - use this to change grind results based on conditions. Return "-1" to prevent the grinding from occurring
/obj/item/proc/on_juice()
+ if(!juice_typepath)
+ return -1
return SEND_SIGNAL(src, COMSIG_ITEM_ON_JUICE)
+///Juice item, converting nutriments into juice_typepath and transfering to target_holder if specified
+/obj/item/proc/juice(datum/reagents/target_holder, mob/user)
+ if(on_juice() == -1)
+ return FALSE
+ if(reagents)
+ reagents.convert_reagent(/datum/reagent/consumable, juice_typepath, include_source_subtypes = TRUE)
+ if(target_holder)
+ reagents.trans_to(target_holder, reagents.total_volume, transferred_by = user)
+ return TRUE
+
/obj/item/proc/set_force_string()
switch(force)
if(0 to 4)
@@ -1316,7 +1344,7 @@
// victim's chest (for cavity implanting the item)
var/obj/item/bodypart/chest/victim_cavity = victim.get_bodypart(BODY_ZONE_CHEST)
if(victim_cavity.cavity_item)
- victim.vomit(5, FALSE, FALSE, distance = 0)
+ victim.vomit(vomit_flags = (MOB_VOMIT_MESSAGE | MOB_VOMIT_HARM), lost_nutrition = 5, distance = 0)
forceMove(drop_location())
to_chat(victim, span_warning("You vomit up a [name]! [source_item? "Was that in \the [source_item]?" : ""]"))
else
@@ -1703,3 +1731,9 @@
bare_wound_bonus = reset_fantasy_variable("bare_wound_bonus", bare_wound_bonus)
toolspeed = reset_fantasy_variable("toolspeed", toolspeed)
SEND_SIGNAL(src, COMSIG_ITEM_REMOVE_FANTASY_BONUSES, bonus)
+
+//automatically finds tool behavior if there is only one. requires an extension of the proc if a tool has multiple behaviors
+/obj/item/proc/get_all_tool_behaviours()
+ if (!isnull(tool_behaviour))
+ return list(tool_behaviour)
+ return null
diff --git a/code/game/objects/items/boxcutter.dm b/code/game/objects/items/boxcutter.dm
index 4213cfec1b3..62273c1080f 100644
--- a/code/game/objects/items/boxcutter.dm
+++ b/code/game/objects/items/boxcutter.dm
@@ -18,6 +18,9 @@
/// Used on Initialize, how much time to cut real handcuffs. Null means it can't.
var/snap_time_strong_handcuffs = null
+/obj/item/boxcutter/get_all_tool_behaviours()
+ return list(TOOL_KNIFE)
+
/obj/item/boxcutter/Initialize(mapload)
. = ..()
AddElement(/datum/element/update_icon_updates_onmob)
diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm
index 96d04719663..aaef891ee4a 100644
--- a/code/game/objects/items/cigs_lighters.dm
+++ b/code/game/objects/items/cigs_lighters.dm
@@ -219,17 +219,27 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(!lighting_text)
return ..()
- if(!reagents.has_reagent(/datum/reagent/oxygen)) //cigarettes need oxygen
- var/datum/gas_mixture/air = return_air()
- if(!air || !air.has_gas(/datum/gas/oxygen, 1)) //or oxygen on a tile to burn
- to_chat(user, span_notice("Your [name] needs a source of oxygen to burn."))
- return ..()
+ if(!check_oxygen(user)) //cigarettes need oxygen
+ balloon_alert(user, "no air!")
+ return ..()
if(smoketime > 0)
light(lighting_text)
else
to_chat(user, span_warning("There is nothing to smoke!"))
+/// Checks that we have enough air to smoke
+/obj/item/clothing/mask/cigarette/proc/check_oxygen(mob/user)
+ if (reagents.has_reagent(/datum/reagent/oxygen))
+ return TRUE
+ var/datum/gas_mixture/air = return_air()
+ if (!isnull(air) && air.has_gas(/datum/gas/oxygen, 1))
+ return TRUE
+ if (!iscarbon(user))
+ return FALSE
+ var/mob/living/carbon/the_smoker = user
+ return the_smoker.can_breathe_helmet()
+
/obj/item/clothing/mask/cigarette/afterattack(obj/item/reagent_containers/cup/glass, mob/user, proximity)
. = ..()
if(!proximity || lit) //can't dip if cigarette is lit (it will heat the reagents in the glass instead)
@@ -237,7 +247,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(!istype(glass)) //you can dip cigarettes into beakers
return
- if(glass.reagents.trans_to(src, chem_volume, transfered_by = user)) //if reagents were transfered, show the message
+ if(glass.reagents.trans_to(src, chem_volume, transferred_by = user)) //if reagents were transferred, show the message
to_chat(user, span_notice("You dip \the [src] into \the [glass]."))
//if not, either the beaker was empty, or the cigarette was full
else if(!glass.reagents.total_volume)
@@ -360,11 +370,10 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/clothing/mask/cigarette/process(seconds_per_tick)
var/mob/living/user = isliving(loc) ? loc : null
user?.ignite_mob()
- if(!reagents.has_reagent(/datum/reagent/oxygen)) //cigarettes need oxygen
- var/datum/gas_mixture/air = return_air()
- if(!air || !air.has_gas(/datum/gas/oxygen, 1)) //or oxygen on a tile to burn
- extinguish()
- return
+
+ if(!check_oxygen(user))
+ extinguish()
+ return
// SKYRAT EDIT ADDITION START - Pollution
var/turf/location = get_turf(src)
@@ -687,7 +696,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
packeditem = to_smoke.name
update_name()
if(to_smoke.reagents)
- to_smoke.reagents.trans_to(src, to_smoke.reagents.total_volume, transfered_by = user)
+ to_smoke.reagents.trans_to(src, to_smoke.reagents.total_volume, transferred_by = user)
qdel(to_smoke)
diff --git a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm
index 7148efdaffb..e5b7144dc8c 100644
--- a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm
+++ b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm
@@ -56,6 +56,13 @@
/datum/stock_part/capacitor = 1,
/obj/item/electronics/airlock = 1)
+/obj/item/circuitboard/machine/mass_driver
+ name = "Mass Driver"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
+ build_path = /obj/machinery/mass_driver
+ req_components = list(
+ /datum/stock_part/servo = 1,)
+
/obj/item/circuitboard/machine/autolathe
name = "Autolathe"
greyscale_colors = CIRCUIT_COLOR_ENGINEERING
@@ -1025,7 +1032,12 @@
build_path = /obj/machinery/rnd/server
req_components = list(
/obj/item/stack/cable_coil = 2,
- /datum/stock_part/scanning_module = 1)
+ /datum/stock_part/scanning_module = 1,
+ )
+
+/obj/item/circuitboard/machine/rdserver/oldstation
+ name = "Ancient R&D Server"
+ build_path = /obj/machinery/rnd/server/oldstation
/obj/item/circuitboard/machine/techfab/department/science
name = "\improper Departmental Techfab - Science"
diff --git a/code/game/objects/items/climbingrope.dm b/code/game/objects/items/climbingrope.dm
new file mode 100644
index 00000000000..2c96d1844b1
--- /dev/null
+++ b/code/game/objects/items/climbingrope.dm
@@ -0,0 +1,86 @@
+/obj/item/climbing_hook
+ name = "climbing hook"
+ desc = "Standard hook with rope to scale up holes. The rope is of average quality, but due to your weight amongst other factors, may not withstand extreme use."
+ icon = 'icons/obj/mining.dmi'
+ icon_state = "climbingrope"
+ inhand_icon_state = "crowbar_brass"
+ lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
+ force = 5
+ throwforce = 10
+ reach = 2
+ throw_range = 4
+ w_class = WEIGHT_CLASS_NORMAL
+ attack_verb_continuous = list("whacks", "flails", "bludgeons")
+ attack_verb_simple = list("whack", "flail", "bludgeon")
+ resistance_flags = FLAMMABLE
+ ///how many times can we climb with this rope
+ var/uses = 5
+ ///climb time
+ var/climb_time = 2.5 SECONDS
+
+/obj/item/climbing_hook/examine(mob/user)
+ . = ..()
+ var/list/look_binds = user.client.prefs.key_bindings["look up"]
+ . += span_notice("Firstly, look upwards by holding [english_list(look_binds, nothing_text = "(nothing bound)", and_text = " or ", comma_text = ", or ")]!")
+ . += span_notice("Then, click solid ground adjacent to the hole above you.")
+ . += span_notice("The rope looks like you could use it [uses] times before it falls apart.")
+
+/obj/item/climbing_hook/afterattack(turf/open/target, mob/user, proximity_flag, click_parameters)
+ . = ..()
+ if(target.z == user.z)
+ return
+ if(!istype(target) || isopenspaceturf(target))
+ return
+ if(target.is_blocked_turf(exclude_mobs = TRUE))
+ return
+ var/turf/user_turf = get_turf(user)
+ var/turf/above = GET_TURF_ABOVE(user_turf)
+ if(!isopenspaceturf(above) || !above.Adjacent(target)) //are we below a hole, is the target blocked, is the target adjacent to our hole
+ balloon_alert(user, "blocked!")
+ return
+ var/away_dir = get_dir(above, target)
+ user.visible_message(span_notice("[user] begins climbing upwards with [src]."), span_notice("You get to work on properly hooking [src] and going upwards."))
+ playsound(target, 'sound/effects/picaxe1.ogg', 50) //plays twice so people above and below can hear
+ playsound(user_turf, 'sound/effects/picaxe1.ogg', 50)
+ var/list/effects = list(new /obj/effect/temp_visual/climbing_hook(target, away_dir), new /obj/effect/temp_visual/climbing_hook(user_turf, away_dir))
+ if(do_after(user, climb_time, target))
+ user.Move(target)
+ uses--
+
+ if(uses <= 0)
+ user.visible_message(span_warning("[src] snaps and tears apart!"))
+ qdel(src)
+
+ QDEL_LIST(effects)
+
+/obj/item/climbing_hook/emergency
+ name = "emergency climbing hook"
+ desc = "An emergency climbing hook to scale up holes. The rope is EXTREMELY cheap and may not withstand extended use."
+ uses = 2
+ climb_time = 4 SECONDS
+ w_class = WEIGHT_CLASS_SMALL
+
+/obj/item/climbing_hook/syndicate
+ name = "suspicious climbing hook"
+ desc = "REALLY suspicious climbing hook to scale up holes. The hook has a syndicate logo engraved on it, and the rope appears rather durable."
+ icon_state = "climbingrope_s"
+ uses = 10
+ climb_time = 1.5 SECONDS
+
+/obj/item/climbing_hook/infinite //debug stuff
+ name = "infinite climbing hook"
+ desc = "A plasteel hook, with rope. Upon closer inspection, the rope appears to be made out of plasteel woven into regular rope, amongst many other reinforcements."
+ uses = INFINITY
+ climb_time = 1 SECONDS
+
+/obj/effect/temp_visual/climbing_hook
+ icon = 'icons/mob/silicon/aibots.dmi'
+ icon_state = "path_indicator"
+ layer = BELOW_MOB_LAYER
+ plane = GAME_PLANE
+ duration = 4 SECONDS
+
+/obj/effect/temp_visual/climbing_hook/Initialize(mapload, direction)
+ . = ..()
+ dir = direction
diff --git a/code/game/objects/items/cosmetics.dm b/code/game/objects/items/cosmetics.dm
index 71a13c863a6..686bd40c698 100644
--- a/code/game/objects/items/cosmetics.dm
+++ b/code/game/objects/items/cosmetics.dm
@@ -276,3 +276,12 @@
return
return ..()
*/
+
+/obj/item/razor/surgery
+ name = "surgical razor"
+ desc = "A medical grade razor. Its precision blades provide a clean shave for surgical preparation."
+ icon = 'icons/obj/cosmetic.dmi'
+ icon_state = "medrazor"
+
+/obj/item/razor/surgery/get_surgery_tool_overlay(tray_extended)
+ return "razor"
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index 580632a84ba..57bc04e7007 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -767,7 +767,7 @@
update_appearance()
if(actually_paints)
H.update_lips("spray_face", paint_color)
- reagents.trans_to(user, used, volume_multiplier, transfered_by = user, methods = VAPOR)
+ reagents.trans_to(user, used, volume_multiplier, transferred_by = user, methods = VAPOR)
return OXYLOSS
/obj/item/toy/crayon/spraycan/Initialize(mapload)
@@ -824,7 +824,7 @@
target.add_atom_colour(paint_color, WASHABLE_COLOUR_PRIORITY)
SEND_SIGNAL(target, COMSIG_LIVING_MOB_PAINTED)
use_charges(user, 2, requires_full = FALSE)
- reagents.trans_to(target, ., volume_multiplier, transfered_by = user, methods = VAPOR)
+ reagents.trans_to(target, ., volume_multiplier, transferred_by = user, methods = VAPOR)
if(pre_noise || post_noise)
playsound(user.loc, 'sound/effects/spray.ogg', 5, TRUE, 5)
@@ -851,7 +851,7 @@
holder.update_clothing(target_item.slot_flags)
if(!(SEND_SIGNAL(target, COMSIG_OBJ_PAINTED, user, src, color_is_dark) & DONT_USE_SPRAYCAN_CHARGES))
use_charges(user, 2, requires_full = FALSE)
- reagents.trans_to(target, ., volume_multiplier, transfered_by = user, methods = VAPOR)
+ reagents.trans_to(target, ., volume_multiplier, transferred_by = user, methods = VAPOR)
if(pre_noise || post_noise)
playsound(user.loc, 'sound/effects/spray.ogg', 5, TRUE, 5)
diff --git a/code/game/objects/items/debug_items.dm b/code/game/objects/items/debug_items.dm
index 04e8729bee5..68ae291e736 100644
--- a/code/game/objects/items/debug_items.dm
+++ b/code/game/objects/items/debug_items.dm
@@ -46,6 +46,28 @@
return FALSE
return TRUE
+/obj/item/debug/omnitool/get_all_tool_behaviours()
+ return list(TOOL_ANALYZER,
+ TOOL_BLOODFILTER,
+ TOOL_BONESET,
+ TOOL_CAUTERY,
+ TOOL_CROWBAR,
+ TOOL_DRILL,
+ TOOL_HEMOSTAT,
+ TOOL_KNIFE,
+ TOOL_MINING,
+ TOOL_MULTITOOL,
+ TOOL_RETRACTOR,
+ TOOL_ROLLINGPIN,
+ TOOL_RUSTSCRAPER,
+ TOOL_SAW,
+ TOOL_SCALPEL,
+ TOOL_SCREWDRIVER,
+ TOOL_SHOVEL,
+ TOOL_WELDER,
+ TOOL_WIRECUTTER,
+ TOOL_WRENCH,
+ )
/obj/item/debug/omnitool/attack_self(mob/user)
if(!user)
diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm
index 4b03fd8013a..a8fa34ed5f8 100644
--- a/code/game/objects/items/devices/aicard.dm
+++ b/code/game/objects/items/devices/aicard.dm
@@ -54,7 +54,8 @@
force = 7
/obj/item/aicard/syndie/loaded
- var/being_or_was_used = FALSE
+ /// Set to true while we're waiting for ghosts to sign up
+ var/finding_candidate = FALSE
/obj/item/aicard/syndie/loaded/examine(mob/user)
. = ..()
@@ -62,43 +63,56 @@
. += 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(AI || being_or_was_used)
+ if(!isnull(AI))
return ..()
- being_or_was_used = TRUE
+ if(finding_candidate)
+ balloon_alert(user, "loading...")
+ return TRUE
+ finding_candidate = TRUE
to_chat(user, span_notice("Connecting to S.E.L.F. dispatch..."))
- being_or_was_used = procure_ai(user)
+ procure_ai(user)
+ finding_candidate = FALSE
+ return TRUE
/obj/item/aicard/syndie/loaded/proc/procure_ai(mob/user)
- var/datum/antagonist/nukeop/creator_op = user.mind?.has_antag_datum(/datum/antagonist/nukeop,TRUE)
- if(!creator_op)
- return FALSE
- var/list/nuke_candidates = poll_ghost_candidates("Do you want to play as a syndicate artifical intelligence inside an intelliCard?", ROLE_OPERATIVE, ROLE_OPERATIVE, 150, POLL_IGNORE_SYNDICATE)
+ 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 FALSE
+ 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 FALSE
+ 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), null, ghos) // wow so cool i love how laws go before the mob to insert for no reason this definitely didnt delay this pr for weeks
- new_ai.key = ghos.key
+ 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, creator_op.nuke_team)
+ 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") // evli
- pre_attack(new_ai, user) // i love shitcode!
- AI.control_disabled = FALSE // re-enable wireless activity
- AI.radio_enabled = TRUE // ditto
+ 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 TRUE
+ return
/obj/item/aicard/Destroy(force)
if(AI)
@@ -141,7 +155,7 @@
if(isnull(AI))
return FALSE
- log_silicon("[key_name(user)] carded [key_name(AI)]", src)
+ log_silicon("[key_name(user)] carded [key_name(AI)]", list(src))
update_appearance()
AI.cancel_camera()
RegisterSignal(AI, COMSIG_MOB_STATCHANGE, PROC_REF(on_ai_stat_change))
diff --git a/code/game/objects/items/devices/beacon.dm b/code/game/objects/items/devices/beacon.dm
index 00517f78915..e2936c0f538 100644
--- a/code/game/objects/items/devices/beacon.dm
+++ b/code/game/objects/items/devices/beacon.dm
@@ -20,14 +20,18 @@
GLOB.teleportbeacons -= src
return ..()
+/obj/item/beacon/proc/turn_off()
+ icon_state = "beacon-off"
+ GLOB.teleportbeacons -= src
+ SEND_SIGNAL(src, COMSIG_BEACON_DISABLED)
+
/obj/item/beacon/attack_self(mob/user)
enabled = !enabled
if (enabled)
icon_state = "beacon"
GLOB.teleportbeacons += src
else
- icon_state = "beacon-off"
- GLOB.teleportbeacons -= src
+ turn_off()
to_chat(user, span_notice("You [enabled ? "enable" : "disable"] the beacon."))
return
diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm
index 447ebb87d03..ecf94d58f70 100644
--- a/code/game/objects/items/devices/flashlight.dm
+++ b/code/game/objects/items/devices/flashlight.dm
@@ -23,6 +23,8 @@
light_range = 4
light_power = 1
light_on = FALSE
+ /// If we've been forcibly disabled for a temporary amount of time.
+ COOLDOWN_DECLARE(disabled_time)
/// Can we toggle this light on and off (used for contexual screentips only)
var/toggle_context = TRUE
/// The sound the light makes when it's turned on
@@ -32,16 +34,15 @@
/// Is the light turned on or off currently
var/on = FALSE
-// SKYRAT EDIT REMOVAL BEGIN - MOVED TO MODUALR FLASHLIGHT.DM
-/*
/obj/item/flashlight/Initialize(mapload)
. = ..()
if(icon_state == "[initial(icon_state)]-on")
on = TRUE
update_brightness()
register_context()
-*/
-// SKYRAT EDIT REMOVAL END
+
+ if(toggle_context)
+ RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur))
/obj/item/flashlight/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
// single use lights can be toggled on once
@@ -68,19 +69,21 @@
if(light_system == STATIC_LIGHT)
update_light()
-// SKYRAT EDIT REMOVAL BEGIN - MOVED TO MODUALR FLASHLIGHT.DM
-/*
-/obj/item/flashlight/proc/toggle_light()
+/obj/item/flashlight/proc/toggle_light(mob/user)
+ var/disrupted = FALSE
on = !on
playsound(src, on ? sound_on : sound_off, 40, TRUE)
+ if(!COOLDOWN_FINISHED(src, disabled_time))
+ if(user)
+ balloon_alert(user, "disrupted!")
+ on = FALSE
+ disrupted = TRUE
update_brightness()
update_item_action_buttons()
- return TRUE
+ return !disrupted
/obj/item/flashlight/attack_self(mob/user)
- toggle_light()
-*/
-// SKYRAT EDIT REMOVAL END
+ toggle_light(user)
/obj/item/flashlight/attack_hand_secondary(mob/user, list/modifiers)
attack_self(user)
@@ -262,6 +265,14 @@
if(istype(user) && dir != user.dir)
setDir(user.dir)
+/// when hit by a light disruptor - turns the light off, forces the light to be disabled for a few seconds
+/obj/item/flashlight/proc/on_saboteur(datum/source, disrupt_duration)
+ SIGNAL_HANDLER
+ if(on)
+ toggle_light()
+ COOLDOWN_START(src, disabled_time, disrupt_duration)
+ return COMSIG_SABOTEUR_SUCCESS
+
/obj/item/flashlight/pen
name = "penlight"
desc = "A pen-sized light, used by medical staff. It can also be used to create a hologram to alert people of incoming medical assistance."
@@ -286,7 +297,7 @@
holo_cooldown = world.time + 10 SECONDS
return
-// see: [/datum/wound/burn/proc/uv()]
+// see: [/datum/wound/burn/flesh/proc/uv()]
/obj/item/flashlight/pen/paramedic
name = "paramedic penlight"
desc = "A high-powered UV penlight intended to help stave off infection in the field on serious burned patients. Probably really bad to look into."
@@ -420,16 +431,15 @@
damtype = BURN
. = ..()
-/obj/item/flashlight/flare/turn_off() //SKYRAT EDIT CHANGE
- //on = FALSE SKYRAT EDIT REMOVAL
+/obj/item/flashlight/flare/proc/turn_off()
+ on = FALSE
name = initial(name)
attack_verb_continuous = initial(attack_verb_continuous)
attack_verb_simple = initial(attack_verb_simple)
hitsound = initial(hitsound)
force = initial(force)
damtype = initial(damtype)
- //update_brightness() - SKYRAT EDIT MOVED TO PARENT
- . = ..() //SKYRAT EDIT - MODULAR PARENT PROC
+ update_brightness()
/obj/item/flashlight/flare/extinguish()
. = ..()
@@ -749,11 +759,9 @@
turn_off()
STOP_PROCESSING(SSobj, src)
-/* SKYRAT EDIT REMOVAL
/obj/item/flashlight/glowstick/proc/turn_off()
on = FALSE
update_appearance(UPDATE_ICON)
-*/
/obj/item/flashlight/glowstick/update_appearance(updates=ALL)
. = ..()
diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm
index 025f5fa5e88..17f5e7d4902 100644
--- a/code/game/objects/items/devices/multitool.dm
+++ b/code/game/objects/items/devices/multitool.dm
@@ -41,14 +41,25 @@
user.visible_message(span_suicide("[user] puts the [src] to [user.p_their()] chest. It looks like [user.p_theyre()] trying to pulse [user.p_their()] heart off!"))
return OXYLOSS//theres a reason it wasn't recommended by doctors
+/**
+ * Sets the multitool internal object buffer
+ *
+ * Arguments:
+ * * buffer - the new object to assign to the multitool's buffer
+ */
/obj/item/multitool/proc/set_buffer(datum/buffer)
if(src.buffer)
UnregisterSignal(src.buffer, COMSIG_QDELETING)
- if(QDELETED(buffer))
- return
src.buffer = buffer
- RegisterSignal(buffer, COMSIG_QDELETING, PROC_REF(on_buffer_del))
+ if(!QDELETED(buffer))
+ RegisterSignal(buffer, COMSIG_QDELETING, PROC_REF(on_buffer_del))
+/**
+ * Called when the buffer's stored object is deleted
+ *
+ * This proc does not clear the buffer of the multitool, it is here to
+ * handle the deletion of the object the buffer references
+ */
/obj/item/multitool/proc/on_buffer_del(datum/source)
SIGNAL_HANDLER
buffer = null
diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm
index 4c2e611bd25..13a054ec8e4 100644
--- a/code/game/objects/items/devices/radio/headset.dm
+++ b/code/game/objects/items/devices/radio/headset.dm
@@ -129,6 +129,7 @@ GLOBAL_LIST_INIT(channel_tokens, list(
name = "syndicate headset"
desc = "A syndicate headset that can be used to hear all radio frequencies. Protects ears from flashbangs."
icon_state = "syndie_headset"
+ worn_icon_state = "syndie_headset"
/obj/item/radio/headset/syndicate/alt/Initialize(mapload)
. = ..()
@@ -138,20 +139,6 @@ GLOBAL_LIST_INIT(channel_tokens, list(
name = "team leader headset"
command = TRUE
-/obj/item/radio/headset/syndicate/alt/psyker
- name = "psychic headset"
- desc = "A headset designed to boost psychic waves. Protects ears from flashbangs."
- icon_state = "psyker_headset"
-
-/obj/item/radio/headset/syndicate/alt/psyker/equipped(mob/living/user, slot)
- . = ..()
- if(slot_flags & slot)
- ADD_CLOTHING_TRAIT(user, TRAIT_ECHOLOCATION_EXTRA_RANGE)
-
-/obj/item/radio/headset/syndicate/alt/psyker/dropped(mob/user, silent)
- . = ..()
- REMOVE_CLOTHING_TRAIT(user, TRAIT_ECHOLOCATION_EXTRA_RANGE)
-
/obj/item/radio/headset/binary
keyslot = /obj/item/encryptionkey/binary
@@ -159,12 +146,14 @@ GLOBAL_LIST_INIT(channel_tokens, list(
name = "security radio headset"
desc = "This is used by your elite security force."
icon_state = "sec_headset"
+ worn_icon_state = "sec_headset"
keyslot = /obj/item/encryptionkey/headset_sec
/obj/item/radio/headset/headset_sec/alt
name = "security bowman headset"
desc = "This is used by your elite security force. Protects ears from flashbangs."
icon_state = "sec_headset_alt"
+ worn_icon_state = "sec_headset_alt"
/obj/item/radio/headset/headset_sec/alt/Initialize(mapload)
. = ..()
@@ -174,48 +163,56 @@ GLOBAL_LIST_INIT(channel_tokens, list(
name = "engineering radio headset"
desc = "When the engineers wish to chat like girls."
icon_state = "eng_headset"
+ worn_icon_state = "eng_headset"
keyslot = /obj/item/encryptionkey/headset_eng
/obj/item/radio/headset/headset_rob
name = "robotics radio headset"
desc = "Made specifically for the roboticists, who cannot decide between departments."
icon_state = "rob_headset"
+ worn_icon_state = "rob_headset"
keyslot = /obj/item/encryptionkey/headset_rob
/obj/item/radio/headset/headset_med
name = "medical radio headset"
desc = "A headset for the trained staff of the medbay."
icon_state = "med_headset"
+ worn_icon_state = "med_headset"
keyslot = /obj/item/encryptionkey/headset_med
/obj/item/radio/headset/headset_sci
name = "science radio headset"
desc = "A sciency headset. Like usual."
icon_state = "sci_headset"
+ worn_icon_state = "sci_headset"
keyslot = /obj/item/encryptionkey/headset_sci
/obj/item/radio/headset/headset_medsci
name = "medical research radio headset"
desc = "A headset that is a result of the mating between medical and science."
icon_state = "medsci_headset"
+ worn_icon_state = "medsci_headset"
keyslot = /obj/item/encryptionkey/headset_medsci
/obj/item/radio/headset/headset_srvsec
name = "law and order headset"
desc = "In the criminal justice headset, the encryption key represents two separate but equally important groups. Sec, who investigate crime, and Service, who provide services. These are their comms."
icon_state = "srvsec_headset"
+ worn_icon_state = "srvsec_headset"
keyslot = /obj/item/encryptionkey/headset_srvsec
/obj/item/radio/headset/headset_srvmed
name = "service medical headset"
desc = "A headset allowing the wearer to communicate with medbay and service."
icon_state = "srv_headset"
+ worn_icon_state = "srv_headset"
keyslot = /obj/item/encryptionkey/headset_srvmed
/obj/item/radio/headset/headset_com
name = "command radio headset"
desc = "A headset with a commanding channel."
icon_state = "com_headset"
+ worn_icon_state = "com_headset"
keyslot = /obj/item/encryptionkey/headset_com
/obj/item/radio/headset/heads
@@ -225,12 +222,14 @@ GLOBAL_LIST_INIT(channel_tokens, list(
name = "\proper the captain's headset"
desc = "The headset of the king."
icon_state = "com_headset"
+ worn_icon_state = "com_headset"
keyslot = /obj/item/encryptionkey/heads/captain
/obj/item/radio/headset/heads/captain/alt
name = "\proper the captain's bowman headset"
desc = "The headset of the boss. Protects ears from flashbangs."
icon_state = "com_headset_alt"
+ worn_icon_state = "com_headset_alt"
/obj/item/radio/headset/heads/captain/alt/Initialize(mapload)
. = ..()
@@ -240,18 +239,21 @@ GLOBAL_LIST_INIT(channel_tokens, list(
name = "\proper the research director's headset"
desc = "Headset of the fellow who keeps society marching towards technological singularity."
icon_state = "com_headset"
+ worn_icon_state = "com_headset"
keyslot = /obj/item/encryptionkey/heads/rd
/obj/item/radio/headset/heads/hos
name = "\proper the head of security's headset"
desc = "The headset of the man in charge of keeping order and protecting the station."
icon_state = "com_headset"
+ worn_icon_state = "com_headset"
keyslot = /obj/item/encryptionkey/heads/hos
/obj/item/radio/headset/heads/hos/alt
name = "\proper the head of security's bowman headset"
desc = "The headset of the man in charge of keeping order and protecting the station. Protects ears from flashbangs."
icon_state = "com_headset_alt"
+ worn_icon_state = "com_headset_alt"
/obj/item/radio/headset/heads/hos/alt/Initialize(mapload)
. = ..()
@@ -261,36 +263,42 @@ GLOBAL_LIST_INIT(channel_tokens, list(
name = "\proper the chief engineer's headset"
desc = "The headset of the guy in charge of keeping the station powered and undamaged."
icon_state = "com_headset"
+ worn_icon_state = "com_headset"
keyslot = /obj/item/encryptionkey/heads/ce
/obj/item/radio/headset/heads/cmo
name = "\proper the chief medical officer's headset"
desc = "The headset of the highly trained medical chief."
icon_state = "com_headset"
+ worn_icon_state = "com_headset"
keyslot = /obj/item/encryptionkey/heads/cmo
/obj/item/radio/headset/heads/hop
name = "\proper the head of personnel's headset"
desc = "The headset of the guy who will one day be captain."
icon_state = "com_headset"
+ worn_icon_state = "com_headset"
keyslot = /obj/item/encryptionkey/heads/hop
/obj/item/radio/headset/heads/qm
name = "\proper the quartermaster's headset"
desc = "The headset of the guy who runs the cargo department."
icon_state = "com_headset"
+ worn_icon_state = "com_headset"
keyslot = /obj/item/encryptionkey/heads/qm
/obj/item/radio/headset/headset_cargo
name = "supply radio headset"
desc = "A headset used by the QM's slaves."
icon_state = "cargo_headset"
+ worn_icon_state = "cargo_headset"
keyslot = /obj/item/encryptionkey/headset_cargo
/obj/item/radio/headset/headset_cargo/mining
name = "mining radio headset"
desc = "Headset used by shaft miners."
icon_state = "mine_headset"
+ worn_icon_state = "mine_headset"
// "puts the antenna down" while the headset is off
overlay_speaker_idle = "headset_up"
overlay_mic_idle = "headset_up"
@@ -300,12 +308,14 @@ GLOBAL_LIST_INIT(channel_tokens, list(
name = "service radio headset"
desc = "Headset used by the service staff, tasked with keeping the station full, happy and clean."
icon_state = "srv_headset"
+ worn_icon_state = "srv_headset"
keyslot = /obj/item/encryptionkey/headset_service
/obj/item/radio/headset/headset_cent
name = "\improper CentCom headset"
desc = "A headset used by the upper echelons of Nanotrasen."
icon_state = "cent_headset"
+ worn_icon_state = "cent_headset"
keyslot = /obj/item/encryptionkey/headset_cent
keyslot2 = /obj/item/encryptionkey/headset_com
@@ -320,6 +330,7 @@ GLOBAL_LIST_INIT(channel_tokens, list(
name = "\improper CentCom bowman headset"
desc = "A headset especially for emergency response personnel. Protects ears from flashbangs."
icon_state = "cent_headset_alt"
+ worn_icon_state = "cent_headset_alt"
keyslot2 = null
/obj/item/radio/headset/headset_cent/alt/Initialize(mapload)
diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm
index 918f241d16d..dcb7ddc1936 100644
--- a/code/game/objects/items/devices/radio/intercom.dm
+++ b/code/game/objects/items/devices/radio/intercom.dm
@@ -34,6 +34,9 @@
return
RegisterSignal(current_area, COMSIG_AREA_POWER_CHANGE, PROC_REF(AreaPowerCheck))
GLOB.intercoms_list += src
+ if(!unscrewed)
+ find_and_hang_on_wall(directional = TRUE, \
+ custom_drop_callback = CALLBACK(src, PROC_REF(knock_down)))
/obj/item/radio/intercom/Destroy()
. = ..()
@@ -79,8 +82,7 @@
if(tool.use_tool(src, user, 80))
user.visible_message(span_notice("[user] unsecures [src]!"), span_notice("You detach [src] from the wall."))
playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
- new/obj/item/wallframe/intercom(get_turf(src))
- qdel(src)
+ knock_down()
/**
* Override attack_tk_grab instead of attack_tk because we actually want attack_tk's
@@ -174,6 +176,13 @@
set_on(current_area.powered(AREA_USAGE_EQUIP)) // set "on" to the equipment power status of our area.
update_appearance()
+/**
+ * Called by the wall mount component and reused during the tool deconstruction proc.
+ */
+/obj/item/radio/intercom/proc/knock_down()
+ new/obj/item/wallframe/intercom(get_turf(src))
+ qdel(src)
+
//Created through the autolathe or through deconstructing intercoms. Can be applied to wall to make a new intercom on it!
/obj/item/wallframe/intercom
name = "intercom frame"
diff --git a/code/game/objects/items/devices/scanners/health_analyzer.dm b/code/game/objects/items/devices/scanners/health_analyzer.dm
index b2e6746ab93..22a0b272df7 100644
--- a/code/game/objects/items/devices/scanners/health_analyzer.dm
+++ b/code/game/objects/items/devices/scanners/health_analyzer.dm
@@ -513,7 +513,7 @@
#define AID_EMOTION_SAD "sad"
/// Displays wounds with extended information on their status vs medscanners
-/proc/woundscan(mob/user, mob/living/carbon/patient, obj/item/healthanalyzer/scanner)
+/proc/woundscan(mob/user, mob/living/carbon/patient, obj/item/healthanalyzer/scanner, simple_scan = FALSE)
if(!istype(patient) || user.incapacitated())
return
@@ -524,7 +524,7 @@
render_list += "Warning: Physical trauma[LAZYLEN(wounded_part.wounds) > 1? "s" : ""] detected in [wounded_part.name]"
for(var/limb_wound in wounded_part.wounds)
var/datum/wound/current_wound = limb_wound
- render_list += "
Player Ranks: [length(player_ranks) ? player_ranks.Join(", ") : "None"]"
+ // SKYRAT EDIT END
body += "
CentCom Galactic Ban DB: "
if(CONFIG_GET(string/centcom_ban_db))
body += "Search"
diff --git a/code/modules/admin/verbs/ai_triumvirate.dm b/code/modules/admin/verbs/ai_triumvirate.dm
index ca7ebfe7cc4..d63994a25c3 100644
--- a/code/modules/admin/verbs/ai_triumvirate.dm
+++ b/code/modules/admin/verbs/ai_triumvirate.dm
@@ -13,14 +13,15 @@ GLOBAL_DATUM(triple_ai_controller, /datum/triple_ai_controller)
. = ..()
RegisterSignal(SSjob, COMSIG_OCCUPATIONS_DIVIDED, PROC_REF(on_occupations_divided))
-/datum/triple_ai_controller/proc/on_occupations_divided(datum/source)
+/datum/triple_ai_controller/proc/on_occupations_divided(datum/source, pure, allow_all)
SIGNAL_HANDLER
for(var/datum/job/ai/ai_datum in SSjob.joinable_occupations)
ai_datum.spawn_positions = 3
- for(var/obj/effect/landmark/start/ai/secondary/secondary_ai_spawn in GLOB.start_landmarks_list)
- secondary_ai_spawn.latejoin_active = TRUE
- qdel(src)
+ if(!pure)
+ for(var/obj/effect/landmark/start/ai/secondary/secondary_ai_spawn in GLOB.start_landmarks_list)
+ secondary_ai_spawn.latejoin_active = TRUE
+ qdel(src)
/datum/triple_ai_controller/Destroy(force)
UnregisterSignal(SSjob, COMSIG_OCCUPATIONS_DIVIDED)
diff --git a/code/modules/admin/verbs/commandreport.dm b/code/modules/admin/verbs/commandreport.dm
index 635cb28cbb2..badf3babb66 100644
--- a/code/modules/admin/verbs/commandreport.dm
+++ b/code/modules/admin/verbs/commandreport.dm
@@ -46,6 +46,8 @@
var/command_report_content
/// Whether the report's contents are announced.
var/announce_contents = TRUE
+ /// Whether a copy of the report is printed at every console.
+ var/print_report = TRUE
/// The sound that's going to accompany our message.
var/played_sound = DEFAULT_ANNOUNCEMENT_SOUND
/// A static list of preset names that can be chosen.
@@ -75,6 +77,7 @@
data["custom_name"] = custom_name
data["command_report_content"] = command_report_content
data["announce_contents"] = announce_contents
+ data["print_report"] = print_report
data["played_sound"] = played_sound
return data
@@ -103,6 +106,8 @@
played_sound = params["picked_sound"]
if("toggle_announce")
announce_contents = !announce_contents
+ if("toggle_printing")
+ print_report = !print_report
if("submit_report")
if(!command_name)
to_chat(ui_user, span_danger("You can't send a report with no command name."))
@@ -132,7 +137,9 @@
if(announce_contents)
priority_announce(command_report_content, null, report_sound, has_important_message = TRUE)
- print_command_report(command_report_content, "[announce_contents ? "" : "Classified "][command_name] Update", !announce_contents)
+
+ if(!announce_contents || print_report)
+ print_command_report(command_report_content, "[announce_contents ? "" : "Classified "][command_name] Update", !announce_contents)
change_command_name(original_command_name)
diff --git a/code/modules/admin/view_variables/debug_variables.dm b/code/modules/admin/view_variables/debug_variables.dm
index 24ee0032a33..230a0e46284 100644
--- a/code/modules/admin/view_variables/debug_variables.dm
+++ b/code/modules/admin/view_variables/debug_variables.dm
@@ -90,7 +90,10 @@
for (var/i in GLOB.bitfields[name])
if (value & GLOB.bitfields[name][i])
flags += i
+ if(length(flags))
item = "[name_part] = [VV_HTML_ENCODE(jointext(flags, ", "))]"
+ else
+ item = "[name_part] = NONE"
else
item = "[name_part] = [VV_HTML_ENCODE(value)]"
diff --git a/code/modules/admin/view_variables/reference_tracking.dm b/code/modules/admin/view_variables/reference_tracking.dm
index 067179e1ecc..a5b2af68c77 100644
--- a/code/modules/admin/view_variables/reference_tracking.dm
+++ b/code/modules/admin/view_variables/reference_tracking.dm
@@ -22,10 +22,6 @@
if(usr?.client)
usr.client.running_find_references = type
-#ifdef UNIT_TESTS
- log_reftracker("Currently sleeping procs [byond_status()]")
-#endif
-
log_reftracker("Beginning search for references to a [type].")
var/starting_time = world.time
diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm
index 6a344bfe403..5bbbfaa40b8 100644
--- a/code/modules/antagonists/_common/antag_datum.dm
+++ b/code/modules/antagonists/_common/antag_datum.dm
@@ -1,3 +1,6 @@
+/// Max length of custom objective text
+#define CUSTOM_OBJECTIVE_MAX_LENGTH 300
+
GLOBAL_LIST_EMPTY(antagonists)
/datum/antagonist
@@ -52,6 +55,12 @@ GLOBAL_LIST_EMPTY(antagonists)
var/preview_outfit
/// Flags for antags to turn on or off and check!
var/antag_flags = FLAG_ANTAG_CAN_BE_INDUCTED
+ /// 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.
+ var/default_custom_objective = "Cause chaos on the space station."
+ /// Whether we give a hardcore random bonus for greentexting as this antagonist while playing hardcore random
+ var/hardcore_random_bonus = FALSE
//ANTAG UI
@@ -117,6 +126,15 @@ GLOBAL_LIST_EMPTY(antagonists)
ui = new(user, src, ui_name, name)
ui.open()
+/datum/antagonist/ui_act(action, params)
+ . = ..()
+ if(.)
+ return
+ switch(action)
+ if("change_objectives")
+ submit_player_objective()
+ return TRUE
+
/datum/antagonist/ui_state(mob/user)
return GLOB.always_state
@@ -124,6 +142,7 @@ GLOBAL_LIST_EMPTY(antagonists)
var/list/data = list()
data["antag_name"] = name
data["objectives"] = get_objectives()
+ data["can_change_objective"] = can_assign_self_objectives
return data
//button for antags to review their descriptions/info
@@ -168,7 +187,7 @@ GLOBAL_LIST_EMPTY(antagonists)
/datum/antagonist/proc/specialization(datum/mind/new_owner)
return src
-///Called by the transfer_to() mind proc after the mind (mind.current and new_character.mind) has moved but before the player (key and client) is transfered.
+///Called by the transfer_to() mind proc after the mind (mind.current and new_character.mind) has moved but before the player (key and client) is transferred.
/datum/antagonist/proc/on_body_transfer(mob/living/old_body, mob/living/new_body)
SHOULD_CALL_PARENT(TRUE)
remove_innate_effects(old_body)
@@ -260,8 +279,13 @@ GLOBAL_LIST_EMPTY(antagonists)
*/
/datum/antagonist/proc/is_banned(mob/player)
if(!player)
+ stack_trace("Called is_banned without a mob. This shouldn't happen.")
return FALSE
- . = (is_banned_from(player.ckey, list(ROLE_SYNDICATE, job_rank)) || QDELETED(player))
+
+ if(!player.ckey)
+ return FALSE
+
+ return (is_banned_from(player.ckey, list(ROLE_SYNDICATE, job_rank)) || QDELETED(player))
/**
* Proc that replaces a player who cannot play a specific antagonist due to being banned via a poll, and alerts the player of their being on the banlist.
@@ -523,3 +547,56 @@ GLOBAL_LIST_EMPTY(antagonists)
/// Used to create objectives for the antagonist.
/datum/antagonist/proc/forge_objectives()
return
+
+/**
+ * Allows player to replace their objectives with a new one they wrote themselves.
+ * * retain_existing - If true, will just be added as a new objective instead of replacing existing ones.
+ * * retain_escape - If true, will retain specifically 'escape alive' objectives (or similar)
+ * * force - Skips the check about whether this antagonist is supposed to set its own objectives, for badminning
+ */
+/datum/antagonist/proc/submit_player_objective(retain_existing = FALSE, retain_escape = TRUE, force = FALSE)
+ if (isnull(owner) || isnull(owner.current))
+ return
+ var/mob/living/owner_mob = owner.current
+ if (!force && !can_assign_self_objectives)
+ owner_mob.balloon_alert(owner_mob, "can't do that!")
+ return
+ var/custom_objective_text = tgui_input_text(
+ owner_mob,
+ message = "Specify your new objective.",
+ title = "Custom Objective",
+ default = default_custom_objective,
+ max_length = CUSTOM_OBJECTIVE_MAX_LENGTH,
+ )
+ if (QDELETED(src) || QDELETED(owner_mob) || isnull(custom_objective_text))
+ return // Some people take a long-ass time to type maybe they got dusted
+
+ log_game("[key_name(owner_mob)] [retain_existing ? "" : "opted out of their original objectives and "]chose a custom objective: [custom_objective_text]")
+ message_admins("[ADMIN_LOOKUPFLW(owner_mob)] has chosen a custom antagonist objective: [span_syndradio("[custom_objective_text]")] | [ADMIN_SMITE(owner_mob)] | [ADMIN_SYNDICATE_REPLY(owner_mob)]")
+
+ var/datum/objective/custom/custom_objective = new()
+ custom_objective.owner = owner
+ custom_objective.explanation_text = custom_objective_text
+ custom_objective.completed = TRUE
+
+ if (retain_existing)
+ objectives.Insert(1, custom_objective)
+ else if (!retain_escape)
+ objectives = list(custom_objective)
+ else
+ var/static/list/escape_objectives = list(
+ /datum/objective/escape,
+ /datum/objective/survive,
+ /datum/objective/martyr,
+ /datum/objective/exile,
+ )
+ for (var/datum/objective/check_objective in objectives)
+ if (is_type_in_list(check_objective, escape_objectives))
+ continue
+ objectives -= check_objective
+ objectives.Insert(1, custom_objective)
+
+ can_assign_self_objectives = FALSE
+ owner.announce_objectives()
+
+#undef CUSTOM_OBJECTIVE_MAX_LENGTH
diff --git a/code/modules/antagonists/_common/antag_spawner.dm b/code/modules/antagonists/_common/antag_spawner.dm
index 72755db7e26..47229ddd462 100644
--- a/code/modules/antagonists/_common/antag_spawner.dm
+++ b/code/modules/antagonists/_common/antag_spawner.dm
@@ -104,7 +104,9 @@
var/special_role_name = ROLE_NUCLEAR_OPERATIVE
/// The applied outfit
var/datum/outfit/syndicate/outfit = /datum/outfit/syndicate/reinforcement
- /// The antag datam applied
+ /// The outfit given to plasmaman operatives
+ var/datum/outfit/syndicate/plasma_outfit = /datum/outfit/syndicate/reinforcement/plasmaman
+ /// The antag datum applied
var/datum/antagonist/nukeop/antag_datum = /datum/antagonist/nukeop
/// Style used by the droppod
var/pod_style = STYLE_SYNDICATE
@@ -144,11 +146,11 @@
else
to_chat(user, span_warning("Unable to connect to Syndicate command. Please wait and try again later or use the beacon on your uplink to get your points refunded."))
-/obj/item/antag_spawner/nuke_ops/spawn_antag(client/C, turf/T, kind, datum/mind/user)
+/obj/item/antag_spawner/nuke_ops/spawn_antag(client/our_client, turf/T, kind, datum/mind/user)
var/mob/living/carbon/human/nukie = new()
var/obj/structure/closet/supplypod/pod = setup_pod()
- C.prefs.safe_transfer_prefs_to(nukie, is_antag = TRUE)
- nukie.ckey = C.key
+ our_client.prefs.safe_transfer_prefs_to(nukie, is_antag = TRUE)
+ nukie.ckey = our_client.key
var/datum/mind/op_mind = nukie.mind
if(length(GLOB.newplayer_start)) // needed as hud code doesn't render huds if the atom (in this case the nukie) is in nullspace, so just move the nukie somewhere safe
nukie.forceMove(pick(GLOB.newplayer_start))
@@ -157,6 +159,7 @@
antag_datum = new()
antag_datum.send_to_spawnpoint = FALSE
+
antag_datum.nukeop_outfit = use_subtypes ? pick(subtypesof(outfit)) : outfit
var/datum/antagonist/nukeop/creator_op = user.has_antag_datum(/datum/antagonist/nukeop, TRUE)
diff --git a/code/modules/antagonists/_common/antag_team.dm b/code/modules/antagonists/_common/antag_team.dm
index c568c58e310..902456d909b 100644
--- a/code/modules/antagonists/_common/antag_team.dm
+++ b/code/modules/antagonists/_common/antag_team.dm
@@ -58,11 +58,9 @@ GLOBAL_LIST_EMPTY(antagonist_teams)
var/win = TRUE
var/objective_count = 1
for(var/datum/objective/objective as anything in objectives)
- if(objective.check_completion())
- report += "Objective #[objective_count]: [objective.explanation_text] [span_greentext("Success!")]"
- else
- report += "Objective #[objective_count]: [objective.explanation_text] [span_redtext("Fail.")]"
+ if(!objective.check_completion())
win = FALSE
+ report += "Objective #[objective_count]: [objective.explanation_text] [objective.get_roundend_success_suffix()]"
objective_count++
if(win)
report += span_greentext("The [name] was successful!")
diff --git a/code/modules/antagonists/abductor/abductor_structures.dm b/code/modules/antagonists/abductor/abductor_structures.dm
index 8acb5e452f1..7da1d72d06b 100644
--- a/code/modules/antagonists/abductor/abductor_structures.dm
+++ b/code/modules/antagonists/abductor/abductor_structures.dm
@@ -5,7 +5,7 @@
name = "resting contraption"
desc = "This looks similar to contraptions from Earth. Could aliens be stealing our technology?"
icon = 'icons/obj/antags/abductor.dmi'
- buildstacktype = /obj/item/stack/sheet/mineral/abductor
+ build_stack_type = /obj/item/stack/sheet/mineral/abductor
icon_state = "bed"
/obj/structure/table_frame/abductor
diff --git a/code/modules/antagonists/abductor/equipment/gear/abductor_items.dm b/code/modules/antagonists/abductor/equipment/gear/abductor_items.dm
index 0c02105f9ed..f1213b47c43 100644
--- a/code/modules/antagonists/abductor/equipment/gear/abductor_items.dm
+++ b/code/modules/antagonists/abductor/equipment/gear/abductor_items.dm
@@ -556,30 +556,35 @@ Congratulations! You are now trained for invasive xenobiology research!"}
name = "alien scalpel"
desc = "It's a gleaming sharp knife made out of silvery-green metal."
icon = 'icons/obj/antags/abductor.dmi'
+ surgical_tray_overlay = "scalpel_alien"
toolspeed = 0.25
/obj/item/hemostat/alien
name = "alien hemostat"
desc = "You've never seen this before."
icon = 'icons/obj/antags/abductor.dmi'
+ surgical_tray_overlay = "hemostat_alien"
toolspeed = 0.25
/obj/item/retractor/alien
name = "alien retractor"
desc = "You're not sure if you want the veil pulled back."
icon = 'icons/obj/antags/abductor.dmi'
+ surgical_tray_overlay = "retractor_alien"
toolspeed = 0.25
/obj/item/circular_saw/alien
name = "alien saw"
desc = "Do the aliens also lose this, and need to find an alien hatchet?"
icon = 'icons/obj/antags/abductor.dmi'
+ surgical_tray_overlay = "saw_alien"
toolspeed = 0.25
/obj/item/surgicaldrill/alien
name = "alien drill"
desc = "Maybe alien surgeons have finally found a use for the drill."
icon = 'icons/obj/antags/abductor.dmi'
+ surgical_tray_overlay = "drill_alien"
toolspeed = 0.25
/obj/item/cautery/alien
@@ -587,6 +592,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
desc = "Why would bloodless aliens have a tool to stop bleeding? \
Unless..."
icon = 'icons/obj/antags/abductor.dmi'
+ surgical_tray_overlay = "cautery_alien"
toolspeed = 0.25
/obj/item/clothing/head/helmet/abductor
@@ -625,6 +631,24 @@ Congratulations! You are now trained for invasive xenobiology research!"}
///Which toolset do we have active currently?
var/active_toolset = TOOLSET_MEDICAL
+/obj/item/abductor/alien_omnitool/get_all_tool_behaviours()
+ return list(
+ TOOL_BLOODFILTER,
+ TOOL_BONESET,
+ TOOL_CAUTERY,
+ TOOL_CROWBAR,
+ TOOL_DRILL,
+ TOOL_HEMOSTAT,
+ TOOL_MULTITOOL,
+ TOOL_RETRACTOR,
+ TOOL_SAW,
+ TOOL_SCALPEL,
+ TOOL_SCREWDRIVER,
+ TOOL_WELDER,
+ TOOL_WIRECUTTER,
+ TOOL_WRENCH,
+ )
+
/obj/item/abductor/alien_omnitool/Initialize(mapload)
. = ..()
set_toolset() //This populates the tool list, and sets it to the hacking configuration.
diff --git a/code/modules/antagonists/abductor/equipment/glands/heal.dm b/code/modules/antagonists/abductor/equipment/glands/heal.dm
index a8e01a45eee..2fa677cba0e 100644
--- a/code/modules/antagonists/abductor/equipment/glands/heal.dm
+++ b/code/modules/antagonists/abductor/equipment/glands/heal.dm
@@ -1,3 +1,5 @@
+#define REJECTION_VOMIT_FLAGS (MOB_VOMIT_BLOOD | MOB_VOMIT_STUN | MOB_VOMIT_KNOCKDOWN | MOB_VOMIT_FORCE)
+
/obj/item/organ/internal/heart/gland/heal
abductor_hint = "organic replicator. Forcibly ejects damaged and robotic organs from the abductee and regenerates them. Additionally, forcibly removes reagents (via vomit) from the abductee if they have moderate toxin damage or poison within the bloodstream, and regenerates blood to a healthy threshold if too low. The abductee will also reject implants such as mindshields."
cooldown_low = 200
@@ -78,19 +80,19 @@
/obj/item/organ/internal/heart/gland/heal/proc/reject_implant(obj/item/implant/implant)
owner.visible_message(span_warning("[owner] vomits up a tiny mangled implant!"), span_userdanger("You suddenly vomit up a tiny mangled implant!"))
- owner.vomit(0, TRUE, TRUE, 1, FALSE, FALSE, FALSE, TRUE)
+ owner.vomit(REJECTION_VOMIT_FLAGS, lost_nutrition = 0)
implant.removed(owner)
qdel(implant)
/obj/item/organ/internal/heart/gland/heal/proc/reject_cyberimp(obj/item/organ/internal/cyberimp/implant)
owner.visible_message(span_warning("[owner] vomits up his [implant.name]!"), span_userdanger("You suddenly vomit up your [implant.name]!"))
- owner.vomit(0, TRUE, TRUE, 1, FALSE, FALSE, FALSE, TRUE)
+ owner.vomit(REJECTION_VOMIT_FLAGS, lost_nutrition = 0)
implant.Remove(owner)
implant.forceMove(owner.drop_location())
/obj/item/organ/internal/heart/gland/heal/proc/replace_appendix(obj/item/organ/internal/appendix/appendix)
if(appendix)
- owner.vomit(0, TRUE, TRUE, 1, FALSE, FALSE, FALSE, TRUE)
+ owner.vomit(REJECTION_VOMIT_FLAGS, lost_nutrition = 0)
appendix.Remove(owner)
appendix.forceMove(owner.drop_location())
owner.visible_message(span_warning("[owner] vomits up his [appendix.name]!"), span_userdanger("You suddenly vomit up your [appendix.name]!"))
@@ -106,7 +108,7 @@
/obj/item/organ/internal/heart/gland/heal/proc/replace_liver(obj/item/organ/internal/liver/liver)
if(liver)
owner.visible_message(span_warning("[owner] vomits up his [liver.name]!"), span_userdanger("You suddenly vomit up your [liver.name]!"))
- owner.vomit(0, TRUE, TRUE, 1, FALSE, FALSE, FALSE, TRUE)
+ owner.vomit(REJECTION_VOMIT_FLAGS, lost_nutrition = 0)
liver.Remove(owner)
liver.forceMove(owner.drop_location())
else
@@ -121,7 +123,7 @@
/obj/item/organ/internal/heart/gland/heal/proc/replace_lungs(obj/item/organ/internal/lungs/lungs)
if(lungs)
owner.visible_message(span_warning("[owner] vomits up his [lungs.name]!"), span_userdanger("You suddenly vomit up your [lungs.name]!"))
- owner.vomit(0, TRUE, TRUE, 1, FALSE, FALSE, FALSE, TRUE)
+ owner.vomit(REJECTION_VOMIT_FLAGS, lost_nutrition = 0)
lungs.Remove(owner)
lungs.forceMove(owner.drop_location())
else
@@ -136,7 +138,7 @@
/obj/item/organ/internal/heart/gland/heal/proc/replace_stomach(obj/item/organ/internal/stomach/stomach)
if(stomach)
owner.visible_message(span_warning("[owner] vomits up his [stomach.name]!"), span_userdanger("You suddenly vomit up your [stomach.name]!"))
- owner.vomit(0, TRUE, TRUE, 1, FALSE, FALSE, FALSE, TRUE)
+ owner.vomit(REJECTION_VOMIT_FLAGS, lost_nutrition = 0)
stomach.Remove(owner)
stomach.forceMove(owner.drop_location())
else
@@ -190,7 +192,7 @@
/obj/item/organ/internal/heart/gland/heal/proc/keep_replacing_blood()
var/keep_going = FALSE
- owner.vomit(0, TRUE, FALSE, 3, FALSE, FALSE, FALSE, TRUE)
+ owner.vomit(vomit_flags = (MOB_VOMIT_BLOOD | MOB_VOMIT_FORCE), lost_nutrition = 0, distance = 3)
owner.Stun(15)
owner.adjustToxLoss(-15, TRUE, TRUE)
@@ -226,3 +228,5 @@
var/obj/item/bodypart/chest/new_chest = new(null)
new_chest.replace_limb(owner, TRUE)
qdel(chest)
+
+#undef REJECTION_VOMIT_FLAGS
diff --git a/code/modules/antagonists/abductor/equipment/glands/plasma.dm b/code/modules/antagonists/abductor/equipment/glands/plasma.dm
index c167dd8a329..0d709579cc8 100644
--- a/code/modules/antagonists/abductor/equipment/glands/plasma.dm
+++ b/code/modules/antagonists/abductor/equipment/glands/plasma.dm
@@ -19,4 +19,4 @@
var/turf/open/T = get_turf(owner)
if(istype(T))
T.atmos_spawn_air("[GAS_PLASMA]=50;[TURF_TEMPERATURE(T20C)]")
- owner.vomit()
+ owner.vomit(VOMIT_CATEGORY_DEFAULT)
diff --git a/code/modules/antagonists/abductor/equipment/glands/slime.dm b/code/modules/antagonists/abductor/equipment/glands/slime.dm
index e3c966e3b6c..faebce9fc87 100644
--- a/code/modules/antagonists/abductor/equipment/glands/slime.dm
+++ b/code/modules/antagonists/abductor/equipment/glands/slime.dm
@@ -19,7 +19,7 @@
/obj/item/organ/internal/heart/gland/slime/activate()
to_chat(owner, span_warning("You feel nauseated!"))
- owner.vomit(20)
+ owner.vomit(VOMIT_CATEGORY_DEFAULT, lost_nutrition = 20)
var/mob/living/simple_animal/slime/Slime = new(get_turf(owner), "grey")
Slime.set_friends(list(owner))
diff --git a/code/modules/antagonists/brainwashing/brainwashing.dm b/code/modules/antagonists/brainwashing/brainwashing.dm
index 51372af4933..e58f54f2c65 100644
--- a/code/modules/antagonists/brainwashing/brainwashing.dm
+++ b/code/modules/antagonists/brainwashing/brainwashing.dm
@@ -1,30 +1,31 @@
-/proc/brainwash(mob/living/L, directives)
- if(!L.mind)
+/proc/brainwash(mob/living/brainwash_victim, directives)
+ if(!brainwash_victim.mind)
return
if(!islist(directives))
directives = list(directives)
- var/datum/mind/M = L.mind
- var/datum/antagonist/brainwashed/B = M.has_antag_datum(/datum/antagonist/brainwashed)
- if(B)
+ var/datum/mind/brainwash_mind = brainwash_victim.mind
+ var/datum/antagonist/brainwashed/brainwashed_datum = brainwash_mind.has_antag_datum(/datum/antagonist/brainwashed)
+ if(brainwashed_datum)
for(var/O in directives)
var/datum/objective/brainwashing/objective = new(O)
- B.objectives += objective
- B.greet()
+ brainwashed_datum.objectives += objective
+ brainwashed_datum.greet()
else
- B = new()
+ brainwashed_datum = new()
for(var/O in directives)
var/datum/objective/brainwashing/objective = new(O)
- B.objectives += objective
- M.add_antag_datum(B)
+ brainwashed_datum.objectives += objective
+ brainwash_mind.add_antag_datum(brainwashed_datum)
var/begin_message = " has been brainwashed with the following objectives: "
var/obj_message = english_list(directives)
- var/end_message = "."
- var/rendered = begin_message + obj_message + end_message
- deadchat_broadcast(rendered, "[L]", follow_target = L, turf_target = get_turf(L), message_type=DEADCHAT_ANNOUNCEMENT)
+ var/rendered = begin_message + obj_message
+ if(!(rendered[length(rendered)] in list(",",":",";",".","?","!","\'","-")))
+ rendered += "." //Good punctuation is important :)
+ deadchat_broadcast(rendered, "[brainwash_victim]", follow_target = brainwash_victim, turf_target = get_turf(brainwash_victim), message_type=DEADCHAT_ANNOUNCEMENT)
if(check_holidays(APRIL_FOOLS))
// Note: most of the time you're getting brainwashed you're unconscious
- L.say("You son of a bitch! I'm in.", forced = "That son of a bitch! They're in. (April Fools)")
+ brainwash_victim.say("You son of a bitch! I'm in.", forced = "That son of a bitch! They're in. (April Fools)")
/datum/antagonist/brainwashed
name = "\improper Brainwashed Victim"
diff --git a/code/modules/antagonists/brother/brother.dm b/code/modules/antagonists/brother/brother.dm
index deef0a390cb..7a797273785 100644
--- a/code/modules/antagonists/brother/brother.dm
+++ b/code/modules/antagonists/brother/brother.dm
@@ -9,6 +9,7 @@
suicide_cry = "FOR MY BROTHER!!"
var/datum/team/brother_team/team
antag_moodlet = /datum/mood_event/focused
+ hardcore_random_bonus = TRUE
/datum/antagonist/brother/create_team(datum/team/brother_team/new_team)
if(!new_team)
diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm
index 2fa239a2a9e..5c44acd5fc0 100644
--- a/code/modules/antagonists/changeling/changeling.dm
+++ b/code/modules/antagonists/changeling/changeling.dm
@@ -11,6 +11,9 @@
hijack_speed = 0.5
ui_name = "AntagInfoChangeling"
suicide_cry = "FOR THE HIVE!!"
+ can_assign_self_objectives = TRUE
+ default_custom_objective = "Consume the station's most valuable genomes."
+ hardcore_random_bonus = TRUE
/// Whether to give this changeling objectives or not
var/give_objectives = TRUE
/// Weather we assign objectives which compete with other lings
@@ -175,11 +178,16 @@
else
RegisterSignal(living_mob, COMSIG_MOB_HUD_CREATED, PROC_REF(on_hud_created))
+ make_brain_decoy(living_mob)
+
+/datum/antagonist/changeling/proc/make_brain_decoy(mob/living/ling)
+ var/obj/item/organ/internal/brain/our_ling_brain = ling.get_organ_slot(ORGAN_SLOT_BRAIN)
+ if(isnull(our_ling_brain) || our_ling_brain.decoy_override)
+ return
+
// Brains are optional for lings.
- var/obj/item/organ/internal/brain/our_ling_brain = living_mob.get_organ_slot(ORGAN_SLOT_BRAIN)
- if(our_ling_brain)
- our_ling_brain.organ_flags &= ~ORGAN_VITAL
- our_ling_brain.decoy_override = TRUE
+ // This is automatically cleared if the ling is.
+ our_ling_brain.AddComponent(/datum/component/ling_decoy_brain, src)
/datum/antagonist/changeling/proc/generate_name()
var/honorific
@@ -223,15 +231,10 @@
QDEL_NULL(lingchemdisplay)
QDEL_NULL(lingstingdisplay)
+ // The old body's brain still remains a decoy, I guess?
+
/datum/antagonist/changeling/on_removal()
remove_changeling_powers(include_innate = TRUE)
- if(!iscarbon(owner.current))
- return
- var/mob/living/carbon/carbon_owner = owner.current
- var/obj/item/organ/internal/brain/not_ling_brain = carbon_owner.get_organ_slot(ORGAN_SLOT_BRAIN)
- if(not_ling_brain && (not_ling_brain.decoy_override != initial(not_ling_brain.decoy_override)))
- not_ling_brain.organ_flags |= ORGAN_VITAL
- not_ling_brain.decoy_override = FALSE
return ..()
/datum/antagonist/changeling/farewell()
@@ -280,23 +283,29 @@
/datum/antagonist/changeling/proc/on_life(datum/source, seconds_per_tick, times_fired)
SIGNAL_HANDLER
+ var/delta_time = DELTA_WORLD_TIME(SSmobs)
+
// If dead, we only regenerate up to half chem storage.
if(owner.current.stat == DEAD)
- adjust_chemicals((chem_recharge_rate - chem_recharge_slowdown) * seconds_per_tick, total_chem_storage * 0.5)
+ adjust_chemicals((chem_recharge_rate - chem_recharge_slowdown) * delta_time, total_chem_storage * 0.5)
// If we're not dead - we go up to the full chem cap.
else
- adjust_chemicals((chem_recharge_rate - chem_recharge_slowdown) * seconds_per_tick)
+ adjust_chemicals((chem_recharge_rate - chem_recharge_slowdown) * delta_time)
/**
- * Signal proc for [COMSIG_LIVING_POST_FULLY_HEAL], getting admin-healed restores our chemicals.
+ * Signal proc for [COMSIG_LIVING_POST_FULLY_HEAL]
*/
-/datum/antagonist/changeling/proc/on_fullhealed(datum/source, heal_flags)
+/datum/antagonist/changeling/proc/on_fullhealed(mob/living/source, heal_flags)
SIGNAL_HANDLER
+ // Aheal restores all chemicals
if(heal_flags & HEAL_ADMIN)
adjust_chemicals(INFINITY)
+ // Makes sure the brain, if recreated, is a decoy as expected
+ make_brain_decoy(source)
+
/**
* Signal proc for [COMSIG_MOB_MIDDLECLICKON] and [COMSIG_MOB_ALTCLICKON].
* Allows the changeling to sting people with a click.
@@ -543,9 +552,12 @@
new_profile.socks = target.socks
// SKYRAT EDIT START
+ new_profile.bra = target.bra
+
new_profile.underwear_color = target.underwear_color
new_profile.undershirt_color = target.undershirt_color
new_profile.socks_color = target.socks_color
+ new_profile.bra_color = target.bra_color
new_profile.eye_color_left = target.eye_color_left
new_profile.eye_color_right = target.eye_color_right
new_profile.emissive_eyes = target.emissive_eyes
@@ -678,10 +690,6 @@
add_new_profile(owner.current)
/datum/antagonist/changeling/forge_objectives()
- //OBJECTIVES - random traitor objectives. Unique objectives "steal brain" and "identity theft".
- //No escape alone because changelings aren't suited for it and it'd probably just lead to rampant robusting
- //If it seems like they'd be able to do it in play, add a 10% chance to have to escape alone
-
var/escape_objective_possible = TRUE
switch(competitive_objectives ? rand(1,3) : 1)
@@ -789,9 +797,12 @@
user.socks = chosen_profile.socks
// SKYRAT EDIT START
+ user.bra = chosen_profile.bra
+
user.underwear_color = chosen_profile.underwear_color
user.undershirt_color = chosen_profile.undershirt_color
user.socks_color = chosen_profile.socks_color
+ user.bra_color = chosen_profile.bra_color
user.emissive_eyes = chosen_profile.emissive_eyes
user.dna.mutant_bodyparts = chosen_dna.mutant_bodyparts.Copy()
user.dna.body_markings = chosen_dna.body_markings.Copy()
@@ -973,27 +984,6 @@
/// ID HUD icon associated with the profile
var/id_icon
- /// SKYRAT EDIT START
- var/underwear_color
- var/undershirt_color
- var/socks_color
- var/eye_color_left
- var/eye_color_right
- var/emissive_eyes
- var/list/grad_style = list("None", "None")
- var/list/grad_color = list(null, null)
-
- var/physique
- var/list/worn_icon_digi_list = list()
- var/list/worn_icon_monkey_list = list()
- var/list/worn_icon_teshari_list = list()
- var/list/worn_icon_vox_list = list()
- var/list/supports_variations_flags_list = list()
- var/scream_type
- var/laugh_type
- var/age
- var/list/quirks = list()
- /// SKYRAT EDIT END
/// The TTS voice of the profile source
var/voice
@@ -1036,6 +1026,8 @@
new_profile.underwear_color = underwear_color
new_profile.undershirt_color = undershirt_color
new_profile.socks_color = socks_color
+ new_profile.bra = bra
+ new_profile.bra_color = bra_color
new_profile.eye_color_left = eye_color_left
new_profile.eye_color_right = eye_color_right
new_profile.emissive_eyes = emissive_eyes
@@ -1076,11 +1068,9 @@
for(var/datum/objective/objective in objectives)
// SKYRAT EDIT START - No greentext
/*
- if(objective.check_completion())
- parts += "Objective #[count]: [objective.explanation_text] [span_greentext("Success!")]"
- else
- parts += "Objective #[count]: [objective.explanation_text] [span_redtext("Fail.")]"
+ if(!objective.check_completion())
changeling_win = FALSE
+ parts += "Objective #[count]: [objective.explanation_text] [objective.get_roundend_success_suffix()]"
*/
parts += "Objective #[count]: [objective.explanation_text]"
// SKYRAT EDIT END - No greentext
diff --git a/code/modules/antagonists/changeling/powers/lesserform.dm b/code/modules/antagonists/changeling/powers/lesserform.dm
index f4aab1c8968..87bd7c7c8b6 100644
--- a/code/modules/antagonists/changeling/powers/lesserform.dm
+++ b/code/modules/antagonists/changeling/powers/lesserform.dm
@@ -20,7 +20,7 @@
//Transform into a monkey.
/datum/action/changeling/lesserform/sting_action(mob/living/carbon/human/user)
- if(!user || user.notransform)
+ if(!user || HAS_TRAIT(user, TRAIT_NO_TRANSFORM))
return FALSE
..()
return ismonkey(user) ? unmonkey(user) : become_monkey(user)
@@ -40,7 +40,6 @@
user.humanize(species = chosen_species, instant = transform_instantly)
changeling.transform(user, chosen_form)
- user.regenerate_icons()
return TRUE
/// Returns the form to transform back into, automatically selects your only profile if you only have one
diff --git a/code/modules/antagonists/changeling/powers/mmi_talk.dm b/code/modules/antagonists/changeling/powers/mmi_talk.dm
new file mode 100644
index 00000000000..f68968c223e
--- /dev/null
+++ b/code/modules/antagonists/changeling/powers/mmi_talk.dm
@@ -0,0 +1,140 @@
+/datum/action/changeling/mmi_talk
+ name = "MMI Talk"
+ desc = "Our decoy brain has been implanted into a Man-Machine Interface. \
+ In order to maintain our secrecy, we can speak through the decoy as if a normal brain. \
+ The decoy brain will relay speech it hears to you in purple."
+ button_icon = 'icons/obj/assemblies/assemblies.dmi'
+ button_icon_state = "mmi_off"
+ dna_cost = CHANGELING_POWER_UNOBTAINABLE
+ ignores_fakedeath = TRUE // Can be used while fake dead
+ req_stat = DEAD // Can be used while real dead too
+
+ /**
+ * Reference to the brain we're talking through.
+ *
+ * Set when created via the ling decoy component.
+ * If the brain ends up being qdelled, this action will also be qdelled, and thus this ref is cleared.
+ */
+ VAR_FINAL/obj/item/organ/internal/brain/brain_ref
+
+ /// A map view of the area around the MMI.
+ VAR_FINAL/atom/movable/screen/map_view/mmi_view
+ /// The background for the MMI map view.
+ VAR_FINAL/atom/movable/screen/background/mmi_view_background
+ /// The key that the map view uses.
+ VAR_FINAL/mmi_view_key
+ /// A movement detector that updates the map view when the MMI moves around.
+ VAR_FINAL/datum/movement_detector/update_view_tracker
+
+/datum/action/changeling/mmi_talk/Destroy()
+ brain_ref = null
+ QDEL_NULL(mmi_view)
+ QDEL_NULL(mmi_view_background)
+ QDEL_NULL(update_view_tracker)
+ return ..()
+
+/datum/action/changeling/mmi_talk/Remove(mob/remove_from)
+ . = ..()
+ SStgui.close_uis(src)
+
+/datum/action/changeling/mmi_talk/can_sting(mob/living/user, mob/living/target)
+ . = ..()
+ if(!.)
+ return FALSE
+ // This generally shouldn't happen, but just in case
+ if(isnull(brain_ref))
+ stack_trace("[type] can_sting was called with a null brain!")
+ return FALSE
+ if(!istype(brain_ref.loc, /obj/item/mmi))
+ stack_trace("[type] can_sting was called with a brain not located in an MMI!")
+ return FALSE
+ return TRUE
+
+/datum/action/changeling/mmi_talk/sting_action(mob/living/user, mob/living/target)
+ ..()
+ ui_interact(user)
+ return TRUE
+
+/datum/action/changeling/mmi_talk/ui_state(mob/user)
+ return GLOB.always_state
+
+/datum/action/changeling/mmi_talk/ui_status(mob/user, datum/ui_state/state)
+ if(user != owner)
+ return UI_CLOSE
+ return ..()
+
+/datum/action/changeling/mmi_talk/ui_static_data(mob/user)
+ var/list/data = list()
+ data["mmi_view"] = mmi_view_key
+ return data
+
+/datum/action/changeling/mmi_talk/ui_interact(mob/user, datum/tgui/ui)
+ if(isnull(mmi_view_key))
+ // it's worth noting a ling could have multiple of these actions.
+ mmi_view_key = "ling_mmi_[REF(src)]_view"
+ // Generate background
+ mmi_view_background = new()
+ mmi_view_background.assigned_map = mmi_view_key
+ mmi_view_background.del_on_map_removal = FALSE
+ mmi_view_background.fill_rect(1, 1, 5, 5)
+ // Generate map view
+ mmi_view = new()
+ mmi_view.generate_view(mmi_view_key)
+ // Generate movement detector (to update the view on MMI movement)
+ update_view_tracker = new(brain_ref, CALLBACK(src, PROC_REF(update_mmi_view)))
+
+ // Shows the view to the user foremost
+ mmi_view.display_to(user)
+ user.client.register_map_obj(mmi_view_background)
+ update_mmi_view()
+ // Makes the MMI relay heard messages
+ if(!HAS_TRAIT_FROM(brain_ref.loc, TRAIT_HEARING_SENSITIVE, REF(src)))
+ var/obj/item/mmi/mmi = brain_ref.loc
+ mmi.become_hearing_sensitive(REF(src))
+ RegisterSignal(mmi, COMSIG_MOVABLE_HEAR, PROC_REF(relay_hearing))
+ // Actually open the UI
+ ui = SStgui.try_update_ui(user, src, ui)
+ if(!ui)
+ ui = new(user, src, "LingMMITalk")
+ ui.open()
+
+/datum/action/changeling/mmi_talk/ui_close(mob/user)
+ var/obj/item/mmi/mmi = brain_ref.loc
+ UnregisterSignal(mmi, COMSIG_MOVABLE_HEAR)
+ mmi.lose_hearing_sensitivity(REF(src))
+
+/datum/action/changeling/mmi_talk/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
+ . = ..()
+ if(.)
+ return TRUE
+
+ if(action != "send_mmi_message")
+ return FALSE
+
+ var/obj/item/mmi/mmi = brain_ref.loc
+ if(mmi.brainmob.stat != CONSCIOUS)
+ to_chat(usr, span_warning("Our decoy brain is too damaged to speak."))
+ else
+ // Say will perform input sanitization and such for us
+ mmi.brainmob.say(params["message"], sanitize = TRUE)
+ return TRUE
+
+/// Used in callbacks to update the map view when the MMI moves.
+/datum/action/changeling/mmi_talk/proc/update_mmi_view()
+ mmi_view.vis_contents.Cut()
+ for(var/turf/visible_turf in view(2, get_turf(brain_ref)))
+ mmi_view.vis_contents += visible_turf
+
+/// Signal proc for [COMSIG_MOVABLE_HEAR] to relay stuff the MMI hears to the ling.
+/// Not super good, but it works.
+/datum/action/changeling/mmi_talk/proc/relay_hearing(obj/item/mmi/source, list/hear_args)
+ SIGNAL_HANDLER
+
+ // We can likely already hear them, so do not bother
+ if(can_see(owner, hear_args[HEARING_SPEAKER], 7))
+ return
+
+ var/list/new_args = hear_args.Copy()
+ new_args[HEARING_SPANS] |= "purple"
+ new_args[HEARING_RANGE] = INFINITY // so we can hear it from any distance away
+ owner.Hear(arglist(new_args))
diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm
index 309cffc0a75..bf4f8c2b3da 100644
--- a/code/modules/antagonists/changeling/powers/mutations.dm
+++ b/code/modules/antagonists/changeling/powers/mutations.dm
@@ -278,6 +278,7 @@
flags_1 = NONE
w_class = WEIGHT_CLASS_HUGE
slot_flags = NONE
+ antimagic_flags = NONE
pinless = TRUE
ammo_type = /obj/item/ammo_casing/magic/tentacle
fire_sound = 'sound/effects/splat.ogg'
diff --git a/code/modules/antagonists/changeling/powers/panacea.dm b/code/modules/antagonists/changeling/powers/panacea.dm
index 683fe7e16b6..25a267e03df 100644
--- a/code/modules/antagonists/changeling/powers/panacea.dm
+++ b/code/modules/antagonists/changeling/powers/panacea.dm
@@ -27,7 +27,7 @@
O.Remove(user)
if(iscarbon(user))
var/mob/living/carbon/C = user
- C.vomit(0)
+ C.vomit(VOMIT_CATEGORY_DEFAULT, lost_nutrition = 0)
O.forceMove(get_turf(user))
//Skyrat Edit Start: Cortical Borer
var/mob/living/basic/cortical_borer/cb_inside = user.has_borer()
diff --git a/code/modules/antagonists/changeling/powers/regenerate.dm b/code/modules/antagonists/changeling/powers/regenerate.dm
index 6595e331195..a83adade98d 100644
--- a/code/modules/antagonists/changeling/powers/regenerate.dm
+++ b/code/modules/antagonists/changeling/powers/regenerate.dm
@@ -15,22 +15,16 @@
..()
to_chat(user, span_notice("You feel an itching, both inside and outside as your tissues knit and reknit."))
var/mob/living/carbon/carbon_user = user
- if(length(carbon_user.get_missing_limbs()))
+ var/got_limbs_back = length(carbon_user.get_missing_limbs()) >= 1
+ carbon_user.fully_heal(HEAL_BODY)
+ // Occurs after fully heal so the ling themselves can hear the sound effects (if deaf prior)
+ if(got_limbs_back)
playsound(user, 'sound/magic/demon_consume.ogg', 50, TRUE)
carbon_user.visible_message(
span_warning("[user]'s missing limbs reform, making a loud, grotesque sound!"),
span_userdanger("Your limbs regrow, making a loud, crunchy sound and giving you great pain!"),
span_hear("You hear organic matter ripping and tearing!"),
)
-
carbon_user.emote("scream")
- carbon_user.fully_heal(HEAL_BODY)
-
- // Make sure the brain's nonvital
- // Shouldn't be necessary but you can never be certain with lingcode
- var/obj/item/organ/internal/brain/replacement_brain = user.get_organ_slot(ORGAN_SLOT_BRAIN)
- replacement_brain.organ_flags &= ~ORGAN_VITAL
- replacement_brain.decoy_override = TRUE
-
return TRUE
diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm
index 069ec9edc91..c3175d0ed4a 100644
--- a/code/modules/antagonists/cult/cult_items.dm
+++ b/code/modules/antagonists/cult/cult_items.dm
@@ -546,7 +546,7 @@ Striking a noncultist, however, will tear their flesh."}
if(totalcurses >= MAX_SHUTTLE_CURSES && (world.time < first_curse_time + SHUTTLE_CURSE_OMFG_TIMESPAN))
var/omfg_message = pick_list(CULT_SHUTTLE_CURSE, "omfg_announce") || "LEAVE US ALONE!"
- addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(priority_announce), omfg_message, "Priority Alert", 'sound/misc/notice1.ogg', null, "Nanotrasen Department of Transportation: Central Command"), rand(2 SECONDS, 6 SECONDS))
+ addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(priority_announce), omfg_message, "Priority Alert", 'sound/misc/announce_syndi.ogg', null, "Nanotrasen Department of Transportation: Central Command"), rand(2 SECONDS, 6 SECONDS))
for(var/mob/iter_player as anything in GLOB.player_list)
if(IS_CULTIST(iter_player))
iter_player.client?.give_award(/datum/award/achievement/misc/cult_shuttle_omfg, iter_player)
diff --git a/code/modules/antagonists/cult/cult_team.dm b/code/modules/antagonists/cult/cult_team.dm
index 7cfbc51b1a7..6254ded64a0 100644
--- a/code/modules/antagonists/cult/cult_team.dm
+++ b/code/modules/antagonists/cult/cult_team.dm
@@ -114,10 +114,7 @@
parts += "The cultists' objectives were:"
var/count = 1
for(var/datum/objective/objective in objectives)
- if(objective.check_completion())
- parts += "Objective #[count]: [objective.explanation_text] [span_greentext("Success!")]"
- else
- parts += "Objective #[count]: [objective.explanation_text] [span_redtext("Fail.")]"
+ parts += "Objective #[count]: [objective.explanation_text] [objective.get_roundend_success_suffix()]"
count++
if(members.len)
diff --git a/code/modules/antagonists/fugitive/hunters/hunter_gear.dm b/code/modules/antagonists/fugitive/hunters/hunter_gear.dm
index 71082f199e0..013359e9a68 100644
--- a/code/modules/antagonists/fugitive/hunters/hunter_gear.dm
+++ b/code/modules/antagonists/fugitive/hunters/hunter_gear.dm
@@ -198,3 +198,22 @@
continue
return found_fugitive
+
+/obj/item/radio/headset/psyker
+ name = "psychic headset"
+ desc = "A headset designed to boost psychic waves. Protects ears from flashbangs."
+ icon_state = "psyker_headset"
+ worn_icon_state = "syndie_headset"
+
+/obj/item/radio/headset/psyker/Initialize(mapload)
+ . = ..()
+ AddComponent(/datum/component/wearertargeting/earprotection, list(ITEM_SLOT_EARS))
+
+/obj/item/radio/headset/psyker/equipped(mob/living/user, slot)
+ . = ..()
+ if(slot_flags & slot)
+ ADD_CLOTHING_TRAIT(user, TRAIT_ECHOLOCATION_EXTRA_RANGE)
+
+/obj/item/radio/headset/psyker/dropped(mob/user, silent)
+ . = ..()
+ REMOVE_CLOTHING_TRAIT(user, TRAIT_ECHOLOCATION_EXTRA_RANGE)
diff --git a/code/modules/antagonists/fugitive/hunters/hunter_outfits.dm b/code/modules/antagonists/fugitive/hunters/hunter_outfits.dm
index 5865f76e999..7df6818cdc4 100644
--- a/code/modules/antagonists/fugitive/hunters/hunter_outfits.dm
+++ b/code/modules/antagonists/fugitive/hunters/hunter_outfits.dm
@@ -187,7 +187,7 @@
name = "Psyker-Shikari Hunter"
glasses = null
head = null
- ears = /obj/item/radio/headset/syndicate/alt/psyker
+ ears = /obj/item/radio/headset/psyker
uniform = /obj/item/clothing/under/pants/track
gloves = /obj/item/clothing/gloves/fingerless
shoes = /obj/item/clothing/shoes/jackboots
diff --git a/code/modules/antagonists/greentext/greentext.dm b/code/modules/antagonists/greentext/greentext.dm
index d06977d2a63..7133066f856 100644
--- a/code/modules/antagonists/greentext/greentext.dm
+++ b/code/modules/antagonists/greentext/greentext.dm
@@ -4,6 +4,7 @@
show_name_in_check_antagonists = TRUE //Not that it will be there for long
suicide_cry = "FOR THE GREENTEXT!!" // This can never actually show up, but not including it is a missed opportunity
count_against_dynamic_roll_chance = FALSE
+ hardcore_random_bonus = TRUE
/datum/antagonist/greentext/forge_objectives()
var/datum/objective/succeed_objective = new /datum/objective("Succeed")
diff --git a/code/modules/antagonists/heretic/heretic_antag.dm b/code/modules/antagonists/heretic/heretic_antag.dm
index 9f7df17e6cd..a0f0d86d33f 100644
--- a/code/modules/antagonists/heretic/heretic_antag.dm
+++ b/code/modules/antagonists/heretic/heretic_antag.dm
@@ -23,6 +23,9 @@
hijack_speed = 0.5
suicide_cry = "THE MANSUS SMILES UPON ME!!"
preview_outfit = /datum/outfit/heretic
+ can_assign_self_objectives = TRUE
+ default_custom_objective = "Turn a department into a testament for your dark knowledge."
+ hardcore_random_bonus = TRUE
/// Whether we give this antagonist objectives on gain.
var/give_objectives = TRUE
/// Whether we've ascended! (Completed one of the final rituals)
@@ -61,6 +64,7 @@
PATH_VOID = "blue",
PATH_BLADE = "label", // my favorite color is label
PATH_COSMIC = "purple",
+ PATH_KNOCK = "yellow",
)
var/static/list/path_to_rune_color = list(
PATH_START = COLOR_LIME,
@@ -70,6 +74,7 @@
PATH_VOID = COLOR_CYAN,
PATH_BLADE = COLOR_SILVER,
PATH_COSMIC = COLOR_PURPLE,
+ PATH_KNOCK = COLOR_YELLOW,
)
/datum/antagonist/heretic/Destroy()
@@ -110,6 +115,7 @@
var/list/data = list()
data["objectives"] = get_objectives()
+ data["can_change_objective"] = can_assign_self_objectives
for(var/path in researched_knowledge)
var/list/knowledge_data = list()
@@ -145,6 +151,19 @@
knowledge_points -= initial(researched_path.cost)
return TRUE
+/datum/antagonist/heretic/submit_player_objective(retain_existing = FALSE, retain_escape = TRUE, force = FALSE)
+ if (isnull(owner) || isnull(owner.current))
+ return
+ var/confirmed = tgui_alert(
+ owner.current,
+ message = "Are you sure? You will no longer be able to Ascend.",
+ title = "Reject the call?",
+ buttons = list("Yes", "No"),
+ ) == "Yes"
+ if (!confirmed)
+ return
+ return ..()
+
/datum/antagonist/heretic/ui_status(mob/user, datum/ui_state/state)
if(user.stat == DEAD)
return UI_CLOSE
@@ -456,11 +475,9 @@
for(var/datum/objective/objective as anything in objectives)
// SKYRAT EDIT START - No greentext
/*
- if(objective.check_completion())
- parts += "Objective #[count]: [objective.explanation_text] [span_greentext("Success!")]"
- else
- parts += "Objective #[count]: [objective.explanation_text] [span_redtext("Fail.")]"
+ if(!objective.check_completion())
succeeded = FALSE
+ parts += "Objective #[count]: [objective.explanation_text] [objective.get_roundend_success_suffix()]"
*/
parts += "Objective #[count]: [objective.explanation_text]"
// SKYRAT EDIT END - No greentext
@@ -502,6 +519,7 @@
.["Remove Heart Target"] = CALLBACK(src, PROC_REF(remove_target))
.["Adjust Knowledge Points"] = CALLBACK(src, PROC_REF(admin_change_points))
+ .["Give Focus"] = CALLBACK(src, PROC_REF(admin_give_focus))
/**
* Admin proc for giving a heretic a Living Heart easily.
@@ -577,6 +595,18 @@
knowledge_points += change_num
+/**
+ * Admin proc for giving a heretic a focus.
+ */
+/datum/antagonist/heretic/proc/admin_give_focus(mob/admin)
+ if(!admin.client?.holder)
+ to_chat(admin, span_warning("You shouldn't be using this!"))
+ return
+
+ var/mob/living/pawn = owner.current
+ pawn.equip_to_slot_if_possible(new /obj/item/clothing/neck/heretic_focus(get_turf(pawn)), ITEM_SLOT_NECK, TRUE, TRUE)
+ to_chat(pawn, span_hypnophrase("The Mansus has manifested you a focus."))
+
/datum/antagonist/heretic/antag_panel_data()
var/list/string_of_knowledge = list()
@@ -663,6 +693,8 @@
* Returns FALSE if not all of our objectives are complete, or TRUE otherwise.
*/
/datum/antagonist/heretic/proc/can_ascend()
+ if(!can_assign_self_objectives)
+ return FALSE // We spurned the offer of the Mansus :(
for(var/datum/objective/must_be_done as anything in objectives)
if(!must_be_done.check_completion())
return FALSE
diff --git a/code/modules/antagonists/heretic/heretic_knowledge.dm b/code/modules/antagonists/heretic/heretic_knowledge.dm
index da376b20a42..b51c2a5dcb8 100644
--- a/code/modules/antagonists/heretic/heretic_knowledge.dm
+++ b/code/modules/antagonists/heretic/heretic_knowledge.dm
@@ -511,7 +511,7 @@
// Fade in the summon while the ghost poll is ongoing.
// Also don't let them mess with the summon while waiting
summoned.alpha = 0
- summoned.notransform = TRUE
+ ADD_TRAIT(summoned, TRAIT_NO_TRANSFORM, REF(src))
summoned.move_resist = MOVE_FORCE_OVERPOWERING
animate(summoned, 10 SECONDS, alpha = 155)
@@ -526,7 +526,7 @@
var/mob/dead/observer/picked_candidate = pick(candidates)
// Ok let's make them an interactable mob now, since we got a ghost
summoned.alpha = 255
- summoned.notransform = FALSE
+ REMOVE_TRAIT(summoned, TRAIT_NO_TRANSFORM, REF(src))
summoned.move_resist = initial(summoned.move_resist)
summoned.ghostize(FALSE)
diff --git a/code/modules/antagonists/heretic/items/heretic_blades.dm b/code/modules/antagonists/heretic/items/heretic_blades.dm
index c074e13c8d3..63493a5dc4b 100644
--- a/code/modules/antagonists/heretic/items/heretic_blades.dm
+++ b/code/modules/antagonists/heretic/items/heretic_blades.dm
@@ -115,3 +115,14 @@
icon_state = "cosmic_blade"
inhand_icon_state = "cosmic_blade"
after_use_message = "The Stargazer hears your call..."
+
+// Path of Knock's blade
+/obj/item/melee/sickly_blade/knock
+ name = "\improper key blade"
+ desc = "A blade and a key, a key to what? \
+ What grand gates does it open?"
+ icon_state = "key_blade"
+ inhand_icon_state = "key_blade"
+ after_use_message = "The Mother of Ants hears your call..."
+ tool_behaviour = TOOL_CROWBAR
+ toolspeed = 1.3
diff --git a/code/modules/antagonists/heretic/items/keyring.dm b/code/modules/antagonists/heretic/items/keyring.dm
new file mode 100644
index 00000000000..0498ba9e8a2
--- /dev/null
+++ b/code/modules/antagonists/heretic/items/keyring.dm
@@ -0,0 +1,186 @@
+/obj/effect/knock_portal
+ name = "crack in reality"
+ desc = "A crack in space, impossibly deep and painful to the eyes. Definitely not safe."
+ icon = 'icons/effects/eldritch.dmi'
+ icon_state = "realitycrack"
+ light_system = STATIC_LIGHT
+ light_power = 1
+ light_on = TRUE
+ light_color = COLOR_GREEN
+ light_range = 3
+ opacity = TRUE
+ density = FALSE //so we dont block doors closing
+ layer = OBJ_LAYER //under doors
+ ///The knock portal we teleport to
+ var/obj/effect/knock_portal/destination
+ ///The airlock we are linked to, we delete if it is destroyed
+ var/obj/machinery/door/our_airlock
+
+/obj/effect/knock_portal/Initialize(mapload, target)
+ . = ..()
+ if(target)
+ our_airlock = target
+ RegisterSignal(target, COMSIG_QDELETING, PROC_REF(delete_on_door_delete))
+
+ var/static/list/loc_connections = list(
+ COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
+ )
+ AddElement(/datum/element/connect_loc, loc_connections)
+
+///Deletes us and our destination portal if our_airlock is destroyed
+/obj/effect/knock_portal/proc/delete_on_door_delete(datum/source)
+ SIGNAL_HANDLER
+ qdel(src)
+
+///Signal handler for when our location is entered, calls teleport on the victim, if their old_loc didnt contain a portal already (to prevent loops)
+/obj/effect/knock_portal/proc/on_entered(datum/source, mob/living/loser, atom/old_loc)
+ SIGNAL_HANDLER
+ if(istype(loser) && !(locate(type) in old_loc))
+ teleport(loser)
+
+/obj/effect/knock_portal/Destroy()
+ QDEL_NULL(destination)
+ our_airlock = null
+ return ..()
+
+///Teleports the teleportee, to a random airlock if the teleportee isnt a heretic, or the other portal if they are one
+/obj/effect/knock_portal/proc/teleport(mob/living/teleportee)
+ if(isnull(destination)) //dumbass
+ qdel(src)
+ return
+
+ //get it?
+ var/obj/machinery/door/doorstination = IS_HERETIC_OR_MONSTER(teleportee) ? destination.our_airlock : find_random_airlock()
+ if(!do_teleport(teleportee, get_turf(doorstination), channel = TELEPORT_CHANNEL_MAGIC))
+ return
+
+ if(!IS_HERETIC_OR_MONSTER(teleportee))
+ teleportee.apply_damage(20, BRUTE) //so they dont roll it like a jackpot machine to see if they can land in the armory
+ to_chat(teleportee, span_userdanger("You stumble through [src], battered by forces beyond your comprehension, landing anywhere but where you thought you were going."))
+
+ INVOKE_ASYNC(src, PROC_REF(async_opendoor), doorstination)
+
+///Returns a random airlock on the same Z level as our portal, that isnt our airlock
+/obj/effect/knock_portal/proc/find_random_airlock()
+ var/list/turf/possible_destinations = list()
+ for(var/obj/airlock as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/door/airlock))
+ if(airlock.z != z)
+ continue
+ if(airlock.loc == loc)
+ continue
+ possible_destinations += airlock
+ return pick(possible_destinations)
+
+///Asynchronous proc to unbolt, then open the passed door
+/obj/effect/knock_portal/proc/async_opendoor(obj/machinery/door/door)
+ if(istype(door, /obj/machinery/door/airlock)) //they can create portals on ANY door, but we should unlock airlocks so they can actually open
+ var/obj/machinery/door/airlock/as_airlock = door
+ as_airlock.unbolt()
+ door.open()
+
+///An ID card capable of shapeshifting to other IDs given by the Key Keepers Burden knowledge
+/obj/item/card/id/advanced/heretic
+ ///List of IDs this card consumed
+ var/list/obj/item/card/id/fused_ids = list()
+ ///The first portal in the portal pair, so we can clear it later
+ var/obj/effect/knock_portal/portal_one
+ ///The second portal in the portal pair, so we can clear it later
+ var/obj/effect/knock_portal/portal_two
+ ///The first door we are linking in the pair, so we can create a portal pair
+ var/datum/weakref/link
+
+/obj/item/card/id/advanced/heretic/examine(mob/user)
+ . = ..()
+ if(!IS_HERETIC_OR_MONSTER(user))
+ return
+ . += span_hypnophrase("Enchanted by the Mansus!")
+ . += span_hypnophrase("Using an ID on this will consume it and allow you to copy its accesses.")
+ . += span_hypnophrase("Using this in-hand allows you to change its appearance.")
+ . += span_hypnophrase("Using this on a pair of doors, allows you to link them together. Entering one door will transport you to the other, while heathens are instead teleported to a random airlock.")
+
+/obj/item/card/id/advanced/heretic/attack_self(mob/user)
+ . = ..()
+ if(!IS_HERETIC(user))
+ return
+ var/cardname = tgui_input_list(user, "Shapeshift into?", "Shapeshift", fused_ids)
+ if(!cardname)
+ balloon_alert(user, "no options!")
+ return ..()
+ var/obj/item/card/id/card = fused_ids[cardname]
+ shapeshift(card)
+
+///Changes our appearance to the passed ID card
+/obj/item/card/id/advanced/heretic/proc/shapeshift(obj/item/card/id/advanced/card)
+ trim = card.trim
+ assignment = card.assignment
+ registered_age = card.registered_age
+ registered_name = card.registered_name
+ icon_state = card.icon_state
+ inhand_icon_state = card.inhand_icon_state
+ assigned_icon_state = card.assigned_icon_state
+ name = card.name //not update_label because of the captains spare moment
+ update_icon()
+
+///Deletes and nulls our portal pair
+/obj/item/card/id/advanced/heretic/proc/clear_portals()
+ QDEL_NULL(portal_one)
+ QDEL_NULL(portal_two)
+
+///Clears portal references
+/obj/item/card/id/advanced/heretic/proc/clear_portal_refs()
+ SIGNAL_HANDLER
+ portal_one = null
+ portal_two = null
+
+///Creates a portal pair at door1 and door2, displays a balloon alert to user
+/obj/item/card/id/advanced/heretic/proc/make_portal(mob/user, obj/machinery/door/door1, obj/machinery/door/door2)
+ var/message = "linked"
+ if(portal_one || portal_two)
+ clear_portals()
+ message += ", previous cleared"
+
+ portal_one = new(get_turf(door2), door2)
+ portal_two = new(get_turf(door1), door1)
+ portal_one.destination = portal_two
+ RegisterSignal(portal_one, COMSIG_QDELETING, PROC_REF(clear_portal_refs)) //we only really need to register one because they already qdel both portals if one is destroyed
+ portal_two.destination = portal_one
+ balloon_alert(user, "[message]")
+
+/obj/item/card/id/advanced/heretic/attackby(obj/item/thing, mob/user, params)
+ if(!istype(thing, /obj/item/card/id/advanced) || !IS_HERETIC(user))
+ return ..()
+ var/obj/item/card/id/card = thing
+ fused_ids[card.name] = card
+ card.moveToNullspace()
+ playsound(drop_location(),'sound/items/eatfood.ogg', rand(10,50), TRUE)
+ access += card.access
+
+/obj/item/card/id/advanced/heretic/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
+ . = ..()
+ if(!proximity_flag || !IS_HERETIC(user))
+ return
+ if(istype(target, /obj/effect/knock_portal))
+ clear_portals()
+ return
+
+ if(!istype(target, /obj/machinery/door))
+ return
+
+ var/reference_resolved = link?.resolve()
+ if(reference_resolved == target)
+ return
+
+ if(reference_resolved)
+ make_portal(user, reference_resolved, target)
+ to_chat(user, span_notice("You use [src], to link [link] and [target] together."))
+ link = null
+ balloon_alert(user, "link 2/2")
+ else
+ link = WEAKREF(target)
+ balloon_alert(user, "link 1/2")
+
+/obj/item/card/id/advanced/heretic/Destroy()
+ QDEL_LIST_ASSOC(fused_ids)
+ link = null
+ clear_portals()
+ return ..()
diff --git a/code/modules/antagonists/heretic/items/lintel.dm b/code/modules/antagonists/heretic/items/lintel.dm
new file mode 100644
index 00000000000..140453842c0
--- /dev/null
+++ b/code/modules/antagonists/heretic/items/lintel.dm
@@ -0,0 +1,64 @@
+/obj/effect/forcefield/wizard/heretic
+ name = "consecrated lintel"
+ desc = "A field of papers flying in the air, repulsing heathens with impossible force."
+ icon_state = "lintel"
+ initial_duration = 8 SECONDS
+
+/obj/effect/forcefield/wizard/heretic/Bumped(mob/living/bumpee)
+ . = ..()
+ if(!istype(bumpee) || IS_HERETIC_OR_MONSTER(bumpee))
+ return
+ var/throwtarget = get_edge_target_turf(loc, get_dir(loc, get_step_away(bumpee, loc)))
+ bumpee.safe_throw_at(throwtarget, 10, 1, force = MOVE_FORCE_EXTREMELY_STRONG)
+ visible_message(span_danger("[src] repulses [bumpee] in a storm of paper!"))
+
+///A heretic item that spawns a barrier at the clicked turf, 3 uses
+/obj/item/heretic_lintel
+ name = "consecrated book"
+ desc = "Some kind of book, its contents make your head hurt. The material is not known to you and it seems to shift and twist unnaturally."
+ icon = 'icons/obj/service/library.dmi'
+ icon_state = "hereticlintel"
+ force = 10
+ damtype = BURN
+ worn_icon_state = "book"
+ throw_speed = 1
+ throw_range = 5
+ w_class = WEIGHT_CLASS_NORMAL
+ attack_verb_continuous = list("bashes", "curses")
+ attack_verb_simple = list("bash", "curse")
+ resistance_flags = FLAMMABLE
+ drop_sound = 'sound/items/handling/book_drop.ogg'
+ pickup_sound = 'sound/items/handling/book_pickup.ogg'
+ ///what type of barrier do we spawn when used
+ var/barrier_type = /obj/effect/forcefield/wizard/heretic
+ ///how many uses do we have left
+ var/uses = 3
+
+/obj/item/heretic_lintel/examine(mob/user)
+ . = ..()
+ if(!IS_HERETIC_OR_MONSTER(user))
+ return
+ . += span_hypnophrase("Materializes a barrier upon any tile in sight, which only you can pass through. Lasts 8 seconds.")
+ . += span_hypnophrase("It has [uses] uses left.")
+
+/obj/item/heretic_lintel/afterattack(atom/target, mob/user, proximity_flag)
+ . = ..()
+ if(IS_HERETIC(user))
+ var/turf/turf_target = get_turf(target)
+ if(locate(barrier_type) in turf_target)
+ user.balloon_alert(user, "already occupied!")
+ return
+ turf_target.visible_message(span_warning("A storm of paper materializes!"))
+ new /obj/effect/temp_visual/paper_scatter(turf_target)
+ playsound(turf_target, 'sound/magic/smoke.ogg', 30)
+ new barrier_type(turf_target, user)
+ uses--
+ if(uses <= 0)
+ to_chat(user, span_warning("[src] falls apart, turning into ash and dust!"))
+ qdel(src)
+ return
+ var/mob/living/carbon/human/human_user = user
+ to_chat(human_user, span_userdanger("Your mind burns as you stare deep into the book, a headache setting in like your brain is on fire!"))
+ human_user.adjustOrganLoss(ORGAN_SLOT_BRAIN, 30, 190)
+ human_user.add_mood_event("gates_of_mansus", /datum/mood_event/gates_of_mansus)
+ human_user.dropItemToGround(src)
diff --git a/code/modules/antagonists/heretic/knowledge/blade_lore.dm b/code/modules/antagonists/heretic/knowledge/blade_lore.dm
index d97b59763f3..01358807fce 100644
--- a/code/modules/antagonists/heretic/knowledge/blade_lore.dm
+++ b/code/modules/antagonists/heretic/knowledge/blade_lore.dm
@@ -388,7 +388,7 @@
When completed, you will be surrounded in a constant, regenerating orbit of blades. \
These blades will protect you from all attacks, but are consumed on use. \
Your Furious Steel spell will also have a shorter cooldown. \
- Additionally, you become a master of combat, gaining full wound and stun immunity. \
+ Additionally, you become a master of combat, gaining full wound immunity and the ability to shrug off short stuns. \
Your Sundered Blades deal bonus damage and heal you on attack for a portion of the damage dealt."
gain_text = "The Torn Champion is freed! I will become the blade reunited, and with my greater ambition, \
I AM UNMATCHED! A STORM OF STEEL AND SILVER IS UPON US! WITNESS MY ASCENSION!"
@@ -405,13 +405,29 @@
. = ..()
priority_announce("[generate_heretic_text()] Master of blades, the Torn Champion's disciple, [user.real_name] has ascended! Their steel is that which will cut reality in a maelstom of silver! [generate_heretic_text()]","[generate_heretic_text()]", ANNOUNCER_SPANOMALIES)
user.client?.give_award(/datum/award/achievement/misc/blade_ascension, user)
- user.add_traits(list(TRAIT_STUNIMMUNE, TRAIT_NEVER_WOUNDED), name)
+ ADD_TRAIT(user, TRAIT_NEVER_WOUNDED, name)
RegisterSignal(user, COMSIG_HERETIC_BLADE_ATTACK, PROC_REF(on_eldritch_blade))
user.apply_status_effect(/datum/status_effect/protective_blades/recharging, null, 8, 30, 0.25 SECONDS, 1 MINUTES)
-
+ user.add_stun_absorption(
+ source = name,
+ message = span_warning("%EFFECT_OWNER throws off the stun!"),
+ self_message = span_warning("You throw off the stun!"),
+ examine_message = span_hypnophrase("%EFFECT_OWNER_THEYRE standing stalwartly."),
+ // flashbangs are like 5-10 seoncds,
+ // a banana peel is ~5 seconds, depending on botany
+ // body throws and tackles are less than 5 seconds,
+ // stun baton / stamcrit detracts no time,
+ // and worst case: beepsky / tasers are 10 seconds.
+ max_seconds_of_stuns_blocked = 45 SECONDS,
+ delete_after_passing_max = FALSE,
+ recharge_time = 2 MINUTES,
+ )
var/datum/action/cooldown/spell/pointed/projectile/furious_steel/steel_spell = locate() in user.actions
steel_spell?.cooldown_time /= 2
+ var/mob/living/carbon/human/heretic = user
+ heretic.physiology.knockdown_mod = 0.75 // Otherwise knockdowns would probably overpower the stun absorption effect.
+
/datum/heretic_knowledge/ultimate/blade_final/proc/on_eldritch_blade(mob/living/source, mob/living/target, obj/item/melee/sickly_blade/blade)
SIGNAL_HANDLER
diff --git a/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm b/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm
index 4de3b510836..9e4d77bd95c 100644
--- a/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm
+++ b/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm
@@ -31,7 +31,7 @@
desc = "Opens up the Path of Cosmos to you. \
Allows you to transmute a sheet of plasma and a knife into an Cosmic Blade. \
You can only create two at a time."
- gain_text = "It looked at the stars to guide himself."
+ gain_text = "A nebula appeared in the sky, its infernal birth shone upon me. This was the start of a great transcendence."
next_knowledge = list(/datum/heretic_knowledge/cosmic_grasp)
required_atoms = list(
/obj/item/knife = 1,
@@ -43,8 +43,8 @@
/datum/heretic_knowledge/cosmic_grasp
name = "Grasp of Cosmos"
desc = "Your Mansus Grasp will give people a star mark (cosmic ring) and create a cosmic field where you stand."
- gain_text = "The more he looked the more everything made sense. \
- The stars traced out the path forward to his home."
+ gain_text = "Some stars dimmed, others' magnitude increased. \
+ With newfound strength I could channel the nebula's power into myself."
next_knowledge = list(/datum/heretic_knowledge/spell/cosmic_runes)
cost = 1
route = PATH_COSMIC
@@ -68,8 +68,8 @@
desc = "Grants you Cosmic Runes, a spell that creates two runes linked with eachother for easy teleportation. \
Only the entity activating the rune will get transported, and it can be used by anyone without a star mark. \
However, people with a star mark will get transported along with another person using the rune."
- gain_text = "When day came, the Sleeper got lost. \
- The sun outshone the stars, so he lost his guide."
+ gain_text = "The distant stars crept into my dreams, roaring and screaming without reason. \
+ I spoke, and heard my own words echoed back."
next_knowledge = list(
/datum/heretic_knowledge/mark/cosmic_mark,
/datum/heretic_knowledge/codex_cicatrix,
@@ -85,8 +85,8 @@
desc = "Your Mansus Grasp now applies the Mark of Cosmos. The mark is triggered from an attack with your Cosmic Blade. \
When triggered, the victim is returned to the location where the mark was originally applied to them. \
They will then be paralyzed for 2 seconds."
- gain_text = "As the guide was lost he found a new. The energy increased as the gaze he threw. \
- He didn't know, but with focus, the Sleepers energy began to flow."
+ gain_text = "The Beast now whispered to me occasionally, only small tidbits of their circumstances. \
+ I can help them, I have to help them."
next_knowledge = list(/datum/heretic_knowledge/knowledge_ritual/cosmic)
route = PATH_COSMIC
mark_type = /datum/status_effect/eldritch/cosmic
@@ -102,8 +102,8 @@
will be forced to sleep for 4 seconds. When the victim is hit it also creates a beam that \
deals a bit of fire damage and damages the cells. \
The beam lasts a minute, until the beam is obstructed or until a new target has been found."
- gain_text = "He dreamed to know how the matter travelled from star to star. \
- He lost interest in wanting to find out."
+ gain_text = "After waking in a cold sweat I felt a palm on my scalp, a sigil burned onto me. \
+ My veins now emitted a strange purple glow, the Beast knows I will surpass its expectations."
next_knowledge = list(/datum/heretic_knowledge/spell/star_blast)
spell_to_add = /datum/action/cooldown/spell/touch/star_touch
cost = 1
@@ -113,7 +113,7 @@
name = "Star Blast"
desc = "Fires a projectile that moves very slowly and creates cosmic fields on impact. \
Anyone hit by the projectile will recieve burn damage, a knockdown, and give people in a three tile range a star mark."
- gain_text = "He didn't try, yet felt the call of the night's Creator."
+ gain_text = "The Beast was behind me now at all times, with each sacrifice words of affirmation coursed through me."
next_knowledge = list(
/datum/heretic_knowledge/blade_upgrade/cosmic,
/datum/heretic_knowledge/reroll_targets,
@@ -131,8 +131,8 @@
The combo is reset after two seconds without making an attack, \
or if you attack someone already marked. If you combo more than four attacks you will recieve, \
a cosmic trail and increase your combo timer up to ten seconds."
- gain_text = "As he ascended to be a watcher, he needed to gather knowledge. \
- He started to draw it at his home."
+ gain_text = "The Beast took my blades in their hand, I kneeled and felt a sharp pain. \
+ The blades now glistened with fragmented power. I fell to the ground and wept at the beast's feet."
next_knowledge = list(/datum/heretic_knowledge/spell/cosmic_expansion)
route = PATH_COSMIC
/// Storage for the second target.
@@ -207,7 +207,7 @@
name = "Cosmic Expansion"
desc = "Grants you Cosmic Expansion, a spell that creates a 3x3 area of cosmic fields around you. \
Nearby beings will also receive a star mark."
- gain_text = "He was well known, so he had a lot of drawing to do to gather as much of the things he forgot."
+ gain_text = "The ground now shook beneath me. The Beast inhabited me, and their voice was intoxicating."
next_knowledge = list(
/datum/heretic_knowledge/ultimate/cosmic_final,
/datum/heretic_knowledge/eldritch_coin,
@@ -227,9 +227,10 @@
The Star Gazer is a strong ally who can even break down reinforced walls. \
The Star Gazer has an aura that will heal you and damage opponents. \
Star Touch can now teleport you to the Star Gazer when activated in your hand."
- gain_text = "The past is gone, the Star Gazer became a vessel to watch over the universe. \
- The Creator made this his path and he forgot his purpose. \
- THE TIME IS NOW, WITNESS MY ASCENSION, THE STAR GAZER HAS GAINED PURPOSE ONCE MORE!"
+ gain_text = "The Beast held out its hand, I grabbed hold and they pulled me to them. Their body was towering, but it seemed so small and feeble after all their tales compiled in my head. \
+ I clung on to them, they would protect me, and I would protect it. \
+ I closed my eyes with my head laid against their form. I was safe. \
+ WITNESS MY ASCENSION!"
route = PATH_COSMIC
/// A static list of command we can use with our mob.
var/static/list/star_gazer_commands = list(
diff --git a/code/modules/antagonists/heretic/knowledge/flesh_lore.dm b/code/modules/antagonists/heretic/knowledge/flesh_lore.dm
index a2e234f3ab8..07fa2718185 100644
--- a/code/modules/antagonists/heretic/knowledge/flesh_lore.dm
+++ b/code/modules/antagonists/heretic/knowledge/flesh_lore.dm
@@ -262,6 +262,8 @@
I finally began to understand. And then, blood rained from the heavens."
next_knowledge = list(/datum/heretic_knowledge/summon/stalker)
route = PATH_FLESH
+ ///What type of wound do we apply on hit
+ var/wound_type = /datum/wound/slash/flesh/severe
/datum/heretic_knowledge/blade_upgrade/flesh/do_melee_effects(mob/living/source, mob/living/target, obj/item/melee/sickly_blade/blade)
if(!iscarbon(target) || source == target)
@@ -269,7 +271,7 @@
var/mob/living/carbon/carbon_target = target
var/obj/item/bodypart/bodypart = pick(carbon_target.bodyparts)
- var/datum/wound/slash/severe/crit_wound = new()
+ var/datum/wound/crit_wound = new wound_type()
crit_wound.apply_wound(bodypart, attack_direction = get_dir(source, target))
/datum/heretic_knowledge/summon/stalker
diff --git a/code/modules/antagonists/heretic/knowledge/knock_lore.dm b/code/modules/antagonists/heretic/knowledge/knock_lore.dm
new file mode 100644
index 00000000000..fcb2c6ceb4c
--- /dev/null
+++ b/code/modules/antagonists/heretic/knowledge/knock_lore.dm
@@ -0,0 +1,227 @@
+/**
+ * # The path of Knock.
+ *
+ * Goes as follows:
+ *
+ * A Locksmith’s Secret
+ * Grasp of Knock
+ * > Sidepaths:
+ * Ashen Eyes
+ * Codex Cicatrix
+ * Key Keeper’s Burden
+ *
+ * Rite Of Passage
+ * Mark Of Knock
+ * Ritual of Knowledge
+ * Burglar's Finesse
+ * > Sidepaths:
+ * Apetra Vulnera
+ * Opening Blast
+ *
+ * Opening Blade
+ * Caretaker’s Last Refuge
+ *
+ * Many secrets behind the Spider Door
+ */
+/datum/heretic_knowledge/limited_amount/starting/base_knock
+ name = "A Locksmith’s Secret"
+ desc = "Opens up the Path of Knock to you. \
+ Allows you to transmute a knife and a crowbar into a Key Blade. \
+ You can only create two at a time and they function as fast crowbars. \
+ In addition, they can fit into utility belts."
+ gain_text = "The Knock permits no seal and no isolation. It thrusts us gleefully out of the safety of ignorance."
+ next_knowledge = list(/datum/heretic_knowledge/knock_grasp)
+ required_atoms = list(
+ /obj/item/knife = 1,
+ /obj/item/crowbar = 1,
+ )
+ result_atoms = list(/obj/item/melee/sickly_blade/knock)
+ limit = 2
+ route = PATH_KNOCK
+
+/datum/heretic_knowledge/knock_grasp
+ name = "Grasp of Knock"
+ desc = "Your mansus grasp allows you to access anything! Right click on an airlock or a locker to force it open. \
+ DNA locks on mechs will be removed, and any pilot will be ejected. Works on consoles. \
+ Makes a distinctive knocking sound on use."
+ gain_text = "Nothing may remain closed from my touch."
+ next_knowledge = list(
+ /datum/heretic_knowledge/key_ring,
+ /datum/heretic_knowledge/medallion,
+ /datum/heretic_knowledge/codex_cicatrix,
+ )
+ cost = 1
+ route = PATH_KNOCK
+
+/datum/heretic_knowledge/knock_grasp/on_gain(mob/user, datum/antagonist/heretic/our_heretic)
+ RegisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK_SECONDARY, PROC_REF(on_secondary_mansus_grasp))
+ RegisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK, PROC_REF(on_mansus_grasp))
+
+/datum/heretic_knowledge/knock_grasp/on_lose(mob/user, datum/antagonist/heretic/our_heretic)
+ UnregisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK_SECONDARY)
+ UnregisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK)
+
+/datum/heretic_knowledge/knock_grasp/proc/on_mansus_grasp(mob/living/source, mob/living/target)
+ SIGNAL_HANDLER
+ var/obj/item/clothing/under/suit = target.get_item_by_slot(ITEM_SLOT_ICLOTHING)
+ if(istype(suit) && suit.adjusted == NORMAL_STYLE)
+ suit.toggle_jumpsuit_adjust()
+ suit.update_appearance()
+
+/datum/heretic_knowledge/knock_grasp/proc/on_secondary_mansus_grasp(mob/living/source, atom/target)
+ SIGNAL_HANDLER
+
+ if(ismecha(target))
+ var/obj/vehicle/sealed/mecha/mecha = target
+ mecha.dna_lock = null
+ for(var/mob/living/occupant as anything in mecha.occupants)
+ if(isAI(occupant))
+ continue
+ mecha.mob_exit(occupant, randomstep = TRUE)
+ else if(istype(target,/obj/machinery/door/airlock))
+ var/obj/machinery/door/airlock/door = target
+ door.unbolt()
+ else if(istype(target, /obj/machinery/computer))
+ var/obj/machinery/computer/computer = target
+ computer.authenticated = TRUE
+ computer.balloon_alert(source, "unlocked")
+
+ var/turf/target_turf = get_turf(target)
+ SEND_SIGNAL(target_turf, COMSIG_ATOM_MAGICALLY_UNLOCKED, src, source)
+ playsound(target, 'sound/magic/hereticknock.ogg', 100, TRUE, -1)
+
+ return COMPONENT_USE_HAND
+
+/datum/heretic_knowledge/key_ring
+ name = "Key Keeper’s Burden"
+ desc = "Allows you to transmute a wallet, an iron rod, and an ID card to create an Eldritch Card. \
+ It functions the same as an ID Card, but attacking it with an ID card fuses it and gains its access. \
+ You can use it in-hand to change its form to a card you fused. \
+ Does not preserve the card used in the ritual."
+ gain_text = "Gateways shall open before me, my very will ensnaring reality."
+ required_atoms = list(
+ /obj/item/storage/wallet = 1,
+ /obj/item/stack/rods = 1,
+ /obj/item/card/id = 1,
+ )
+ result_atoms = list(/obj/item/card/id/advanced/heretic)
+ next_knowledge = list(/datum/heretic_knowledge/limited_amount/rite_of_passage)
+ cost = 1
+ route = PATH_KNOCK
+
+/datum/heretic_knowledge/limited_amount/rite_of_passage // item that creates 3 max at a time heretic only barriers, probably should limit to 1 only, holy people can also pass
+ name = "Rite Of Passage"
+ desc = "Allows you to transmute a white crayon, a wooden plank, and a multitool to create a Consecrated Book. \
+ It can materialize a barricade at range that only you and people resistant to magic can pass. 3 uses."
+ gain_text = "With this I can repel those that intend me harm."
+ required_atoms = list(
+ /obj/item/toy/crayon/white = 1,
+ /obj/item/stack/sheet/mineral/wood = 1,
+ /obj/item/multitool = 1,
+ )
+ result_atoms = list(/obj/item/heretic_lintel)
+ next_knowledge = list(/datum/heretic_knowledge/mark/knock_mark)
+ cost = 1
+ route = PATH_KNOCK
+
+/datum/heretic_knowledge/mark/knock_mark
+ name = "Mark of Knock"
+ desc = "Your Mansus Grasp now applies the Mark of Knock. \
+ Attack a marked person to bar them from all passages for the duration of the mark. \
+ This will make it so that they have no access whatsoever, even public access doors will reject them."
+ gain_text = "Their requests for passage will remain unheeded."
+ next_knowledge = list(/datum/heretic_knowledge/knowledge_ritual/knock)
+ route = PATH_KNOCK
+ mark_type = /datum/status_effect/eldritch/knock
+
+/datum/heretic_knowledge/knowledge_ritual/knock
+ next_knowledge = list(/datum/heretic_knowledge/spell/burglar_finesse)
+ route = PATH_KNOCK
+
+/datum/heretic_knowledge/spell/burglar_finesse
+ name = "Burglar's Finesse"
+ desc = "Grants you Burglar's Finesse, a single-target spell \
+ that puts a random item from the victims backpack into your hand."
+ gain_text = "Their trinkets will be mine, as will their lives in due time."
+ next_knowledge = list(
+ /datum/heretic_knowledge/spell/apetra_vulnera,
+ /datum/heretic_knowledge/spell/opening_blast,
+ /datum/heretic_knowledge/blade_upgrade/flesh/knock,
+ )
+ spell_to_add = /datum/action/cooldown/spell/pointed/burglar_finesse
+ cost = 2
+ route = PATH_KNOCK
+
+/datum/heretic_knowledge/blade_upgrade/flesh/knock //basically a chance-based weeping avulsion version of the former
+ name = "Opening Blade"
+ desc = "Your blade has a chance to cause a weeping avulsion on attack."
+ gain_text = "The power of my patron courses through my blade, willing their very flesh to part."
+ next_knowledge = list(/datum/heretic_knowledge/spell/caretaker_refuge)
+ route = PATH_KNOCK
+ wound_type = /datum/wound/slash/flesh/critical
+ var/chance = 35
+
+/datum/heretic_knowledge/blade_upgrade/flesh/knock/do_melee_effects(mob/living/source, mob/living/target, obj/item/melee/sickly_blade/blade)
+ if(prob(chance))
+ return ..()
+
+/datum/heretic_knowledge/spell/caretaker_refuge
+ name = "Caretaker’s Last Refuge"
+ desc = "Gives you a spell that makes you transparent and not dense. Cannot be used near living sentient beings. \
+ While in refuge, you cannot use your hands or spells, and you are immune to slowdown. \
+ You are invincible but unable to harm anything. Cancelled by being hit with an anti-magic item."
+ gain_text = "Then I saw my my own reflection cascaded mind-numbingly enough times that I was but a haze."
+ next_knowledge = list(/datum/heretic_knowledge/ultimate/knock_final)
+ route = PATH_KNOCK
+ spell_to_add = /datum/action/cooldown/spell/caretaker
+ cost = 1
+
+/datum/heretic_knowledge/ultimate/knock_final
+ name = "Many secrets behind the Spider Door"
+ desc = "The ascension ritual of the Path of Knock. \
+ Bring 3 corpses without organs in their torso to a transmutation rune to complete the ritual. \
+ When completed, you gain the ability to transform into empowered eldritch creatures \
+ and in addition, create a tear to the Spider Door; \
+ a tear in reality located at the site of this ritual. \
+ Eldritch creatures will endlessly pour from this rift \
+ who are bound to obey your instructions."
+ gain_text = "With her knowledge, and what I had seen, I knew what to do. \
+ I had to open the gates, with the holes in my foes as Ways! \
+ Reality will soon be torn, the Spider Gate opened! WITNESS ME!"
+ required_atoms = list(/mob/living/carbon/human = 3)
+ route = PATH_KNOCK
+
+/datum/heretic_knowledge/ultimate/knock_final/recipe_snowflake_check(mob/living/user, list/atoms, list/selected_atoms, turf/loc)
+ . = ..()
+ if(!.)
+ return FALSE
+
+ for(var/mob/living/carbon/human/body in atoms)
+ if(body.stat != DEAD)
+ continue
+ var/obj/item/bodypart/chest = body.get_bodypart(BODY_ZONE_CHEST)
+ if(LAZYLEN(chest.get_organs()))
+ to_chat(user, span_hierophant_warning("[body] has organs in their chest."))
+ continue
+
+ selected_atoms += body
+
+ if(!LAZYLEN(selected_atoms))
+ loc.balloon_alert(user, "ritual failed, not enough valid bodies!")
+ return FALSE
+ return TRUE
+
+/datum/heretic_knowledge/ultimate/knock_final/on_finished_recipe(mob/living/user, list/selected_atoms, turf/loc)
+ . = ..()
+ priority_announce("Delta-class dimensional anomaly detec[generate_heretic_text()] Reality rended, torn. Gates open, doors open, [user.real_name] has ascended! Fear the tide! [generate_heretic_text()]", "Centra[generate_heretic_text()]", ANNOUNCER_SPANOMALIES)
+ user.client?.give_award(/datum/award/achievement/misc/knock_ascension, user)
+
+ // buffs
+ var/datum/action/cooldown/spell/shapeshift/eldritch/ascension/transform_spell = new(user.mind)
+ transform_spell.Grant(user)
+
+ user.client?.give_award(/datum/award/achievement/misc/knock_ascension, user)
+ var/datum/antagonist/heretic/heretic_datum = IS_HERETIC(user)
+ var/datum/heretic_knowledge/blade_upgrade/flesh/knock/blade_upgrade = heretic_datum.get_knowledge(/datum/heretic_knowledge/blade_upgrade/flesh/knock)
+ blade_upgrade.chance += 30
+ new /obj/structure/knock_tear(loc, user.mind)
diff --git a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm
index 745941c33ea..6e532460aab 100644
--- a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm
+++ b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm
@@ -40,18 +40,17 @@
#ifndef UNIT_TESTS // This is a decently hefty thing to generate while unit testing, so we should skip it.
if(!heretic_level_generated)
heretic_level_generated = TRUE
- log_game("Generating z-level for heretic sacrifices...")
+ log_game("Loading heretic lazytemplate for heretic sacrifices...")
INVOKE_ASYNC(src, PROC_REF(generate_heretic_z_level))
#endif
/// Generate the sacrifice z-level.
/datum/heretic_knowledge/hunt_and_sacrifice/proc/generate_heretic_z_level()
- var/datum/map_template/heretic_sacrifice_level/new_level = new()
- if(!new_level.load_new_z())
- log_game("The heretic sacrifice z-level failed to load.")
- message_admins("The heretic sacrifice z-level failed to load. Heretic sacrifices won't be teleported to the shadow realm. \
+ if(!SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_HERETIC_SACRIFICE))
+ log_game("The heretic sacrifice template failed to load.")
+ message_admins("The heretic sacrifice lazy template failed to load. Heretic sacrifices won't be teleported to the shadow realm. \
If you want, you can spawn an /obj/effect/landmark/heretic somewhere to stop that from happening.")
- CRASH("Failed to initialize heretic sacrifice z-level!")
+ CRASH("Failed to lazy load heretic sacrifice template!")
/datum/heretic_knowledge/hunt_and_sacrifice/recipe_snowflake_check(mob/living/user, list/atoms, list/selected_atoms, turf/loc)
var/datum/antagonist/heretic/heretic_datum = IS_HERETIC(user)
diff --git a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_map.dm b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_map.dm
index a31f0a7cc97..983bbee32c6 100644
--- a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_map.dm
+++ b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_map.dm
@@ -3,14 +3,6 @@
/// A global assoc list of all landmarks that denote a heretic sacrifice location. [string heretic path] = [landmark].
GLOBAL_LIST_EMPTY(heretic_sacrifice_landmarks)
-/**
- * A map template loaded in when heretics are created.
- * Hereteic sacrifices are sent here when completed.
- */
-/datum/map_template/heretic_sacrifice_level
- name = "Heretic Sacrifice Level"
- mappath = "_maps/templates/heretic_sacrifice_template.dmm"
-
/// Lardmarks meant to designate where heretic sacrifices are sent.
/obj/effect/landmark/heretic
name = "default heretic sacrifice landmark"
@@ -42,6 +34,10 @@ GLOBAL_LIST_EMPTY(heretic_sacrifice_landmarks)
name = "rust heretic sacrifice landmark"
for_heretic_path = PATH_RUST
+/obj/effect/landmark/heretic/knock
+ name = "knock heretic sacrifice landmark"
+ for_heretic_path = PATH_KNOCK
+
// A fluff signpost object that doesn't teleport you somewhere when you touch it.
/obj/structure/no_effect_signpost
name = "signpost"
@@ -114,3 +110,8 @@ GLOBAL_LIST_EMPTY(heretic_sacrifice_landmarks)
name = "Mansus Rust Gate"
ambience_index = AMBIENCE_REEBE
sound_environment = SOUND_ENVIRONMENT_SEWER_PIPE
+
+/area/centcom/heretic_sacrifice/knock
+ name = "Mansus Knock Gate"
+ ambience_index = AMBIENCE_DANGER
+ sound_environment = SOUND_ENVIRONMENT_PSYCHOTIC
diff --git a/code/modules/antagonists/heretic/knowledge/side_cosmos_ash.dm b/code/modules/antagonists/heretic/knowledge/side_cosmos_ash.dm
index b776b7f4469..470d98e178b 100644
--- a/code/modules/antagonists/heretic/knowledge/side_cosmos_ash.dm
+++ b/code/modules/antagonists/heretic/knowledge/side_cosmos_ash.dm
@@ -5,7 +5,7 @@
desc = "Allows you to transmute a pool of ash, a liver, and a sheet of plasma into a Fire Shark. \
Fire Sharks are fast and strong in groups, but die quickly. They are also highly resistant against fire attacks. \
Fire Sharks inject phlogiston into its victims and spawn plasma once they die."
- gain_text = "My knowledge of the universe with the energy of remains, constructed it. It gave the Fire Shark life."
+ gain_text = "The cradle of the nebula was cold, but not dead. Light and heat flits even through the deepest darkness, and is hunted by its own predators."
next_knowledge = list(
/datum/heretic_knowledge/spell/cosmic_runes,
/datum/heretic_knowledge/spell/ash_passage,
@@ -38,7 +38,7 @@
desc = "Allows you to transmute a sheet of plasma and a diamond to create an Eldritch Coin. \
The coin will open or close nearby doors when landing on heads and bolt or unbolt nearby doors \
when landing on tails. If the coin gets inserted into an airlock it emags the door destroying the coin."
- gain_text = "It tossed the coin and won its bet, now it gains..."
+ gain_text = "The Mansus is a place of all sorts of sins. But greed held a special role."
next_knowledge = list(
/datum/heretic_knowledge/spell/cosmic_expansion,
/datum/heretic_knowledge/spell/flame_birth,
diff --git a/code/modules/antagonists/heretic/knowledge/side_flesh_void.dm b/code/modules/antagonists/heretic/knowledge/side_flesh_void.dm
index 4a315575d61..6439840fed5 100644
--- a/code/modules/antagonists/heretic/knowledge/side_flesh_void.dm
+++ b/code/modules/antagonists/heretic/knowledge/side_flesh_void.dm
@@ -26,6 +26,7 @@
Also has a chance to transfer wounds from you to the victim."
gain_text = "\"No matter the man, we bleed all the same.\" That's what the Marshal told me."
next_knowledge = list(
+ /datum/heretic_knowledge/spell/apetra_vulnera,
/datum/heretic_knowledge/spell/void_phase,
/datum/heretic_knowledge/summon/raw_prophet,
)
diff --git a/code/modules/antagonists/heretic/knowledge/side_knock_flesh.dm b/code/modules/antagonists/heretic/knowledge/side_knock_flesh.dm
new file mode 100644
index 00000000000..97218ce5e94
--- /dev/null
+++ b/code/modules/antagonists/heretic/knowledge/side_knock_flesh.dm
@@ -0,0 +1,28 @@
+// Sidepaths for knowledge between Knock and Flesh.
+
+/datum/heretic_knowledge/spell/apetra_vulnera
+ name = "Apetra Vulnera"
+ desc = "Grants you Apetra Vulnera, a spell \
+ which causes heavy bleeding on all bodyparts of the victim that have more than 15 brute damage. \
+ Wounds a random limb if no limb is sufficiently damaged."
+ gain_text = "Flesh opens, and blood spills. My master seeks sacrifice, and I shall appease."
+ next_knowledge = list(
+ /datum/heretic_knowledge/spell/blood_siphon,
+ /datum/heretic_knowledge/void_cloak,
+ )
+ spell_to_add = /datum/action/cooldown/spell/pointed/apetra_vulnera
+ cost = 1
+ route = PATH_SIDE
+
+/datum/heretic_knowledge/spell/opening_blast
+ name = "Wave Of Desperation"
+ desc = "Grants you Wave Of Desparation, a spell which can only be cast while restrained. \
+ It removes your restraints, repels and knocks down adjacent people, and applies the Mansus Grasp to everything nearby."
+ gain_text = "My shackles undone in dark fury, their feeble bindings crumble before my power."
+ next_knowledge = list(
+ /datum/heretic_knowledge/summon/ashy,
+ /datum/heretic_knowledge/void_cloak,
+ )
+ spell_to_add = /datum/action/cooldown/spell/aoe/wave_of_desperation
+ cost = 1
+ route = PATH_SIDE
diff --git a/code/modules/antagonists/heretic/magic/apetravulnera.dm b/code/modules/antagonists/heretic/magic/apetravulnera.dm
new file mode 100644
index 00000000000..801104dddf9
--- /dev/null
+++ b/code/modules/antagonists/heretic/magic/apetravulnera.dm
@@ -0,0 +1,59 @@
+/datum/action/cooldown/spell/pointed/apetra_vulnera
+ name = "Apetra Vulnera"
+ desc = "Causes severe bleeding on every limb of a target which has more than 15 brute damage. \
+ Wounds a random limb if no limb is sufficiently damaged."
+ background_icon_state = "bg_heretic"
+ overlay_icon_state = "bg_heretic_border"
+ button_icon = 'icons/mob/actions/actions_ecult.dmi'
+ button_icon_state = "cleave"
+
+ school = SCHOOL_FORBIDDEN
+ cooldown_time = 45 SECONDS
+
+ invocation = "AP'TRA VULN'RA!"
+ invocation_type = INVOCATION_WHISPER
+ spell_requirements = NONE
+
+ cast_range = 4
+ /// What type of wound we apply
+ var/wound_type = /datum/wound/slash/flesh/critical/cleave
+
+/datum/action/cooldown/spell/pointed/apetra_vulnera/is_valid_target(atom/cast_on)
+ return ..() && ishuman(cast_on)
+
+/datum/action/cooldown/spell/pointed/apetra_vulnera/cast(mob/living/carbon/human/cast_on)
+ . = ..()
+
+ if(IS_HERETIC_OR_MONSTER(cast_on))
+ return FALSE
+
+ if(!cast_on.blood_volume)
+ return FALSE
+
+ if(cast_on.can_block_magic(antimagic_flags))
+ cast_on.visible_message(
+ span_danger("[cast_on]'s bruises briefly glow, but repels the effect!"),
+ span_danger("Your bruises sting a little, but you are protected!")
+ )
+ return FALSE
+
+ var/a_limb_got_damaged = FALSE
+ for(var/obj/item/bodypart/bodypart in cast_on.bodyparts)
+ if(bodypart.brute_dam < 15)
+ continue
+ a_limb_got_damaged = TRUE
+ var/datum/wound/slash/crit_wound = new wound_type()
+ crit_wound.apply_wound(bodypart)
+
+ if(!a_limb_got_damaged)
+ var/datum/wound/slash/crit_wound = new wound_type()
+ crit_wound.apply_wound(pick(cast_on.bodyparts))
+
+ cast_on.visible_message(
+ span_danger("[cast_on]'s scratches and bruises are torn open by an unholy force!"),
+ span_danger("Your scratches and bruises are torn open by some horrible unholy force!")
+ )
+
+ new /obj/effect/temp_visual/cleave(get_turf(cast_on))
+
+ return TRUE
diff --git a/code/modules/antagonists/heretic/magic/ascended_shapeshift.dm b/code/modules/antagonists/heretic/magic/ascended_shapeshift.dm
new file mode 100644
index 00000000000..4395b4a54b3
--- /dev/null
+++ b/code/modules/antagonists/heretic/magic/ascended_shapeshift.dm
@@ -0,0 +1,32 @@
+// Given to ascended knock heretics, is a form of shapeshift that can turn into all 4 common heretic summons, and is not limited to 1 selection.
+/datum/action/cooldown/spell/shapeshift/eldritch/ascension
+ name = "Ascended Shapechange"
+ desc = "A spell that allows you to take on the form of another eldritch creature, gaining their abilities. \
+ You can change your choice at any time, and if your form dies, you dont die."
+ cooldown_time = 20 SECONDS
+ die_with_shapeshifted_form = FALSE
+ possible_shapes = list(
+ /mob/living/simple_animal/hostile/heretic_summon/raw_prophet,
+ /mob/living/simple_animal/hostile/heretic_summon/rust_spirit,
+ /mob/living/simple_animal/hostile/heretic_summon/ash_spirit,
+ /mob/living/simple_animal/hostile/heretic_summon/stalker,
+ )
+
+/datum/action/cooldown/spell/shapeshift/eldritch/ascension/do_shapeshift(mob/living/caster)
+ . = ..()
+ if(!.)
+ return
+ //buff our forms so this ascension ability isnt shit
+ playsound(caster, 'sound/magic/demon_consume.ogg', 50, TRUE)
+ var/mob/living/monster = .
+ monster.AddComponent(/datum/component/seethrough_mob)
+ monster.maxHealth *= 1.5
+ monster.health = monster.maxHealth
+ monster.melee_damage_lower = max((monster.melee_damage_lower * 2), 40)
+ monster.melee_damage_upper = monster.melee_damage_upper / 2
+ monster.transform *= 1.5
+ monster.AddElement(/datum/element/wall_smasher, strength_flag = ENVIRONMENT_SMASH_RWALLS)
+
+/datum/action/cooldown/spell/shapeshift/eldritch/ascension/do_unshapeshift(mob/living/caster)
+ . = ..()
+ shapeshift_type = null //pick another loser
diff --git a/code/modules/antagonists/heretic/magic/blood_cleave.dm b/code/modules/antagonists/heretic/magic/blood_cleave.dm
index eca27e55566..d5317f23e34 100644
--- a/code/modules/antagonists/heretic/magic/blood_cleave.dm
+++ b/code/modules/antagonists/heretic/magic/blood_cleave.dm
@@ -19,7 +19,7 @@
/// The radius of the cleave effect
var/cleave_radius = 1
/// What type of wound we apply
- var/wound_type = /datum/wound/slash/critical/cleave
+ var/wound_type = /datum/wound/slash/flesh/critical/cleave
/datum/action/cooldown/spell/pointed/cleave/is_valid_target(atom/cast_on)
return ..() && ishuman(cast_on)
@@ -45,7 +45,7 @@
)
var/obj/item/bodypart/bodypart = pick(victim.bodyparts)
- var/datum/wound/slash/crit_wound = new wound_type()
+ var/datum/wound/slash/flesh/crit_wound = new wound_type()
crit_wound.apply_wound(bodypart)
victim.apply_damage(20, BURN, wound_bonus = CANT_WOUND)
@@ -56,7 +56,7 @@
/datum/action/cooldown/spell/pointed/cleave/long
name = "Lesser Cleave"
cooldown_time = 60 SECONDS
- wound_type = /datum/wound/slash/severe
+ wound_type = /datum/wound/slash/flesh/severe
/obj/effect/temp_visual/cleave
icon = 'icons/effects/eldritch.dmi'
diff --git a/code/modules/antagonists/heretic/magic/burglar_finesse.dm b/code/modules/antagonists/heretic/magic/burglar_finesse.dm
new file mode 100644
index 00000000000..7bb6960354e
--- /dev/null
+++ b/code/modules/antagonists/heretic/magic/burglar_finesse.dm
@@ -0,0 +1,39 @@
+/datum/action/cooldown/spell/pointed/burglar_finesse
+ name = "Burglar's Finesse"
+ desc = "Steal a random item from the victim's backpack."
+ background_icon_state = "bg_heretic"
+ overlay_icon_state = "bg_heretic_border"
+ button_icon = 'icons/mob/actions/actions_ecult.dmi'
+ button_icon_state = "burglarsfinesse"
+
+ school = SCHOOL_FORBIDDEN
+ cooldown_time = 40 SECONDS
+
+ invocation = "Y'O'K!"
+ invocation_type = INVOCATION_WHISPER
+ spell_requirements = NONE
+
+ cast_range = 4
+
+/datum/action/cooldown/spell/pointed/burglar_finesse/is_valid_target(atom/cast_on)
+ return ..() && ishuman(cast_on) && (locate(/obj/item/storage/backpack) in cast_on.contents)
+
+/datum/action/cooldown/spell/pointed/burglar_finesse/cast(mob/living/carbon/human/cast_on)
+ . = ..()
+ if(cast_on.can_block_magic(antimagic_flags))
+ to_chat(cast_on, span_danger("You feel a light tug, but are otherwise fine, you were protected by holiness!"))
+ to_chat(owner, span_danger("[cast_on] is protected by holy forces!"))
+ return FALSE
+
+ var/obj/storage_item = locate(/obj/item/storage/backpack) in cast_on.contents
+
+ if(isnull(storage_item))
+ return FALSE
+
+ var/item = pick(storage_item.contents)
+ if(isnull(item))
+ return FALSE
+
+ to_chat(cast_on, span_warning("Your [storage_item] feels lighter..."))
+ to_chat(owner, span_notice("With a blink, you pull [item] out of [cast_on][p_s()] [storage_item]."))
+ owner.put_in_active_hand(item)
diff --git a/code/modules/antagonists/heretic/magic/caretaker.dm b/code/modules/antagonists/heretic/magic/caretaker.dm
new file mode 100644
index 00000000000..87f3a69dad1
--- /dev/null
+++ b/code/modules/antagonists/heretic/magic/caretaker.dm
@@ -0,0 +1,39 @@
+/datum/action/cooldown/spell/caretaker
+ name = "Caretaker’s Last Refuge"
+ desc = "Shifts you into the Caretaker's Refuge, rendering you translucent and intangible. \
+ While in the Refuge your movement is unrestricted, but you cannot use your hands or cast any spells. \
+ You cannot enter the Refuge while near other sentient beings, \
+ and you can be removed from it upon contact with antimagical artifacts."
+ background_icon_state = "bg_heretic"
+ overlay_icon_state = "bg_heretic_border"
+ button_icon = 'icons/mob/actions/actions_minor_antag.dmi'
+ button_icon_state = "ninja_cloak"
+ sound = 'sound/effects/curse2.ogg'
+
+ school = SCHOOL_FORBIDDEN
+ cooldown_time = 1 MINUTES
+
+ invocation_type = INVOCATION_NONE
+ spell_requirements = NONE
+
+/datum/action/cooldown/spell/caretaker/Remove(mob/living/remove_from)
+ if(remove_from.has_status_effect(/datum/status_effect/caretaker_refuge))
+ remove_from.remove_status_effect(/datum/status_effect/caretaker_refuge)
+ return ..()
+
+/datum/action/cooldown/spell/caretaker/is_valid_target(atom/cast_on)
+ return isliving(cast_on)
+
+/datum/action/cooldown/spell/caretaker/cast(atom/cast_on)
+ . = ..()
+ for(var/mob/living/alive in orange(5, owner))
+ if(alive.stat != DEAD && alive.client)
+ owner.balloon_alert(owner, "other minds nearby!")
+ return FALSE
+
+ var/mob/living/carbon/carbon_user = owner
+ if(carbon_user.has_status_effect(/datum/status_effect/caretaker_refuge))
+ carbon_user.remove_status_effect(/datum/status_effect/caretaker_refuge)
+ else
+ carbon_user.apply_status_effect(/datum/status_effect/caretaker_refuge)
+ return TRUE
diff --git a/code/modules/antagonists/heretic/magic/furious_steel.dm b/code/modules/antagonists/heretic/magic/furious_steel.dm
index f9b12612306..1c82f36e024 100644
--- a/code/modules/antagonists/heretic/magic/furious_steel.dm
+++ b/code/modules/antagonists/heretic/magic/furious_steel.dm
@@ -43,12 +43,12 @@
unset_click_ability(source, refund_cooldown = TRUE)
-/datum/action/cooldown/spell/pointed/projectile/furious_steel/InterceptClickOn(mob/living/caller, params, atom/click_target)
+/datum/action/cooldown/spell/pointed/projectile/furious_steel/InterceptClickOn(mob/living/caller, params, atom/target)
// Let the caster prioritize using items like guns over blade casts
if(caller.get_active_held_item())
return FALSE
// Let the caster prioritize melee attacks like punches and shoves over blade casts
- if(get_dist(caller, click_target) <= 1)
+ if(get_dist(caller, target) <= 1)
return FALSE
return ..()
diff --git a/code/modules/antagonists/heretic/magic/space_crawl.dm b/code/modules/antagonists/heretic/magic/space_crawl.dm
index 4c69bdf4fcd..69a15d812bb 100644
--- a/code/modules/antagonists/heretic/magic/space_crawl.dm
+++ b/code/modules/antagonists/heretic/magic/space_crawl.dm
@@ -60,10 +60,10 @@
*/
/datum/action/cooldown/spell/jaunt/space_crawl/proc/try_enter_jaunt(turf/our_turf, mob/living/jaunter)
// Begin the jaunt
- jaunter.notransform = TRUE
+ ADD_TRAIT(jaunter, TRAIT_NO_TRANSFORM, REF(src))
var/obj/effect/dummy/phased_mob/holder = enter_jaunt(jaunter, our_turf)
- if(!holder)
- jaunter.notransform = FALSE
+ if(isnull(holder))
+ REMOVE_TRAIT(jaunter, TRAIT_NO_TRANSFORM, REF(src))
return FALSE
RegisterSignal(holder, COMSIG_MOVABLE_MOVED, PROC_REF(update_status_on_signal))
@@ -82,14 +82,14 @@
new /obj/effect/temp_visual/space_explosion(our_turf)
jaunter.extinguish_mob()
- jaunter.notransform = FALSE
+ REMOVE_TRAIT(jaunter, TRAIT_NO_TRANSFORM, REF(src))
return TRUE
/**
* Attempts to Exit the passed space or misc turf.
*/
/datum/action/cooldown/spell/jaunt/space_crawl/proc/try_exit_jaunt(turf/our_turf, mob/living/jaunter)
- if(jaunter.notransform)
+ if(HAS_TRAIT_FROM(jaunter, TRAIT_NO_TRANSFORM, REF(src)))
to_chat(jaunter, span_warning("You cannot exit yet!!"))
return FALSE
diff --git a/code/modules/antagonists/heretic/magic/wave_of_desperation.dm b/code/modules/antagonists/heretic/magic/wave_of_desperation.dm
new file mode 100644
index 00000000000..3b78b56ddc0
--- /dev/null
+++ b/code/modules/antagonists/heretic/magic/wave_of_desperation.dm
@@ -0,0 +1,79 @@
+/datum/action/cooldown/spell/aoe/wave_of_desperation
+ name = "Wave Of Desperation"
+ desc = "Removes your restraints, repels and knocks down adjacent people, and applies certain effects of the Mansus Grasp upon everything nearby. \
+ Cannot be cast unless you are restrained, and the stress renders you unconscious 12 seconds later!"
+ background_icon_state = "bg_heretic"
+ overlay_icon_state = "bg_heretic_border"
+ button_icon = 'icons/mob/actions/actions_ecult.dmi'
+ button_icon_state = "uncuff"
+ sound = 'sound/magic/swap.ogg'
+
+ school = SCHOOL_FORBIDDEN
+ cooldown_time = 5 MINUTES
+
+ invocation = "F'K 'FF."
+ invocation_type = INVOCATION_WHISPER
+ spell_requirements = NONE
+
+ aoe_radius = 3
+
+/datum/action/cooldown/spell/aoe/wave_of_desperation/is_valid_target(mob/living/carbon/cast_on)
+ return ..() && istype(cast_on) && (cast_on.handcuffed || cast_on.legcuffed)
+
+// Before the cast, we do some small AOE damage around the caster
+/datum/action/cooldown/spell/aoe/wave_of_desperation/before_cast(mob/living/carbon/cast_on)
+ . = ..()
+ if(. & SPELL_CANCEL_CAST)
+ return
+
+ if(cast_on.handcuffed)
+ cast_on.visible_message(span_danger("[cast_on.handcuffed] on [cast_on] shatter!"))
+ QDEL_NULL(cast_on.handcuffed)
+ if(cast_on.legcuffed)
+ cast_on.visible_message(span_danger("[cast_on.legcuffed] on [cast_on] shatters!"))
+ QDEL_NULL(cast_on.legcuffed)
+
+ cast_on.apply_status_effect(/datum/status_effect/heretic_lastresort)
+ new /obj/effect/temp_visual/knockblast(get_turf(cast_on))
+
+ for(var/mob/living/victim in get_things_to_cast_on(cast_on, radius_override = 1))
+ victim.AdjustKnockdown(3 SECONDS)
+ victim.AdjustParalyzed(0.5 SECONDS)
+
+/datum/action/cooldown/spell/aoe/wave_of_desperation/get_things_to_cast_on(atom/center, radius_override)
+ . = list()
+ for(var/atom/nearby in orange(center, radius_override ? radius_override : aoe_radius))
+ if(nearby == owner || nearby == center || isarea(nearby))
+ continue
+ if(!ismob(nearby))
+ . += nearby
+ continue
+ var/mob/living/nearby_mob = nearby
+ if(!isturf(nearby_mob.loc))
+ continue
+ if(IS_HERETIC_OR_MONSTER(nearby_mob))
+ continue
+ if(nearby_mob.can_block_magic(antimagic_flags))
+ continue
+
+ . += nearby_mob
+
+/datum/action/cooldown/spell/aoe/wave_of_desperation/cast_on_thing_in_aoe(atom/victim, atom/caster)
+ if(!ismob(victim))
+ SEND_SIGNAL(owner, COMSIG_HERETIC_MANSUS_GRASP_ATTACK_SECONDARY, victim)
+
+ var/atom/movable/mover = victim
+ if(!istype(mover))
+ return
+
+ if(mover.anchored)
+ return
+ var/our_turf = get_turf(caster)
+ var/throwtarget = get_edge_target_turf(our_turf, get_dir(our_turf, get_step_away(mover, our_turf)))
+ mover.safe_throw_at(throwtarget, 3, 1, force = MOVE_FORCE_STRONG)
+
+/obj/effect/temp_visual/knockblast
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "shield-flash"
+ alpha = 180
+ duration = 1 SECONDS
diff --git a/code/modules/antagonists/heretic/status_effects/buffs.dm b/code/modules/antagonists/heretic/status_effects/buffs.dm
index 743aa2c5a01..f1c96c51ad4 100644
--- a/code/modules/antagonists/heretic/status_effects/buffs.dm
+++ b/code/modules/antagonists/heretic/status_effects/buffs.dm
@@ -74,7 +74,8 @@
heal_amt = 3
if(WOUND_SEVERITY_CRITICAL)
heal_amt = 6
- if(wound.wound_type == WOUND_BURN)
+ var/datum/wound_pregen_data/pregen_data = GLOB.all_wound_pregen_data[wound.type]
+ if (pregen_data.wounding_types_valid(list(WOUND_BURN)))
carbie.adjustFireLoss(-heal_amt)
else
carbie.adjustBruteLoss(-heal_amt)
@@ -235,3 +236,53 @@
return
addtimer(CALLBACK(src, PROC_REF(create_blade)), blade_recharge_time)
+
+/datum/status_effect/caretaker_refuge
+ id = "Caretaker’s Last Refuge"
+ status_type = STATUS_EFFECT_REFRESH
+ duration = -1
+ alert_type = null
+ var/static/list/caretaking_traits = list(TRAIT_HANDS_BLOCKED, TRAIT_IGNORESLOWDOWN)
+
+/datum/status_effect/caretaker_refuge/on_apply()
+ owner.add_traits(caretaking_traits, TRAIT_STATUS_EFFECT(id))
+ owner.status_flags |= GODMODE
+ animate(owner, alpha = 45,time = 0.5 SECONDS)
+ owner.density = FALSE
+ RegisterSignal(owner, SIGNAL_REMOVETRAIT(TRAIT_ALLOW_HERETIC_CASTING), PROC_REF(on_focus_lost))
+ RegisterSignal(owner, COMSIG_MOB_BEFORE_SPELL_CAST, PROC_REF(prevent_spell_usage))
+ RegisterSignal(owner, COMSIG_ATOM_HOLYATTACK, PROC_REF(nullrod_handler))
+ return TRUE
+
+/datum/status_effect/caretaker_refuge/on_remove()
+ owner.remove_traits(caretaking_traits, TRAIT_STATUS_EFFECT(id))
+ owner.status_flags &= ~GODMODE
+ owner.alpha = initial(owner.alpha)
+ owner.density = initial(owner.density)
+ UnregisterSignal(owner, SIGNAL_REMOVETRAIT(TRAIT_ALLOW_HERETIC_CASTING))
+ UnregisterSignal(owner, COMSIG_MOB_BEFORE_SPELL_CAST)
+ UnregisterSignal(owner, COMSIG_ATOM_HOLYATTACK)
+ owner.visible_message(
+ span_warning("The haze around [owner] disappears, leaving them materialized!"),
+ span_notice("You exit the refuge."),
+ )
+
+/datum/status_effect/caretaker_refuge/get_examine_text()
+ return span_warning("[owner.p_Theyre()] enveloped in an unholy haze!")
+
+/datum/status_effect/caretaker_refuge/proc/nullrod_handler(datum/source, obj/item/weapon)
+ SIGNAL_HANDLER
+ playsound(get_turf(owner), 'sound/effects/curse1.ogg', 80, TRUE)
+ owner.visible_message(span_warning("[weapon] repels the haze around [owner]!"))
+ owner.remove_status_effect(type)
+
+/datum/status_effect/caretaker_refuge/proc/on_focus_lost()
+ SIGNAL_HANDLER
+ to_chat(owner, span_danger("Without a focus, your refuge weakens and dissipates!"))
+ owner.remove_status_effect(type)
+
+/datum/status_effect/caretaker_refuge/proc/prevent_spell_usage(datum/source, datum/spell)
+ SIGNAL_HANDLER
+ if(!istype(spell, /datum/action/cooldown/spell/caretaker))
+ owner.balloon_alert(owner, "may not cast spells in refuge!")
+ return SPELL_CANCEL_CAST
diff --git a/code/modules/antagonists/heretic/status_effects/debuffs.dm b/code/modules/antagonists/heretic/status_effects/debuffs.dm
index 3c7715111be..c286c7b5092 100644
--- a/code/modules/antagonists/heretic/status_effects/debuffs.dm
+++ b/code/modules/antagonists/heretic/status_effects/debuffs.dm
@@ -110,7 +110,7 @@
var/chance = rand(0, 100)
switch(chance)
if(0 to 10)
- human_owner.vomit()
+ human_owner.vomit(VOMIT_CATEGORY_DEFAULT)
if(20 to 30)
human_owner.set_timed_status_effect(100 SECONDS, /datum/status_effect/dizziness, only_if_higher = TRUE)
human_owner.set_timed_status_effect(100 SECONDS, /datum/status_effect/jitter, only_if_higher = TRUE)
@@ -192,3 +192,25 @@
/datum/status_effect/star_mark/extended
duration = 3 MINUTES
+
+// Last Resort
+/datum/status_effect/heretic_lastresort
+ id = "heretic_lastresort"
+ alert_type = /atom/movable/screen/alert/status_effect/heretic_lastresort
+ duration = 12 SECONDS
+ status_type = STATUS_EFFECT_REPLACE
+ tick_interval = -1
+
+/atom/movable/screen/alert/status_effect/heretic_lastresort
+ name = "Last Resort"
+ desc = "Your head spins, heart pumping as fast as it can, losing the fight with the ground. Run to safety!"
+ icon_state = "lastresort"
+
+/datum/status_effect/heretic_lastresort/on_apply()
+ ADD_TRAIT(owner, TRAIT_IGNORESLOWDOWN, TRAIT_STATUS_EFFECT(id))
+ to_chat(owner, span_userdanger("You are on the brink of losing consciousness, run!"))
+ return TRUE
+
+/datum/status_effect/heretic_lastresort/on_remove()
+ REMOVE_TRAIT(owner, TRAIT_IGNORESLOWDOWN, TRAIT_STATUS_EFFECT(id))
+ owner.AdjustUnconscious(20 SECONDS, ignore_canstun = TRUE)
diff --git a/code/modules/antagonists/heretic/status_effects/mark_effects.dm b/code/modules/antagonists/heretic/status_effects/mark_effects.dm
index 83a7e7accff..068570f76c7 100644
--- a/code/modules/antagonists/heretic/status_effects/mark_effects.dm
+++ b/code/modules/antagonists/heretic/status_effects/mark_effects.dm
@@ -61,8 +61,7 @@
if(ishuman(owner))
var/mob/living/carbon/human/human_owner = owner
var/obj/item/bodypart/bodypart = pick(human_owner.bodyparts)
- var/datum/wound/slash/severe/crit_wound = new()
- crit_wound.apply_wound(bodypart)
+ human_owner.cause_wound_of_type_and_severity(WOUND_SLASH, bodypart, WOUND_SEVERITY_SEVERE)
return ..()
@@ -247,3 +246,17 @@
new teleport_effect(get_turf(owner))
owner.Paralyze(2 SECONDS)
return ..()
+
+// MARK OF KNOCK
+
+/datum/status_effect/eldritch/knock
+ effect_icon_state = "emark7"
+ duration = 10 SECONDS
+
+/datum/status_effect/eldritch/knock/on_apply()
+ . = ..()
+ ADD_TRAIT(owner, TRAIT_ALWAYS_NO_ACCESS, STATUS_EFFECT_TRAIT)
+
+/datum/status_effect/eldritch/knock/on_remove()
+ REMOVE_TRAIT(owner, TRAIT_ALWAYS_NO_ACCESS, STATUS_EFFECT_TRAIT)
+ return ..()
diff --git a/code/modules/antagonists/heretic/structures/knock_final.dm b/code/modules/antagonists/heretic/structures/knock_final.dm
new file mode 100644
index 00000000000..85face85609
--- /dev/null
+++ b/code/modules/antagonists/heretic/structures/knock_final.dm
@@ -0,0 +1,67 @@
+/obj/structure/knock_tear
+ name = "???"
+ desc = "It stares back. Theres no reason to remain. Run."
+ max_integrity = INFINITE
+ 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
+ light_range = 20
+ anchored = TRUE
+ density = FALSE
+ layer = HIGH_PIPE_LAYER //0.01 above sigil layer used by heretic runes
+ move_resist = INFINITY
+ var/datum/mind/ascendee
+ ///a static list of heretic summons, this shouldnt even matter enough to be static but whatever
+ var/static/list/monster_types
+
+/obj/structure/knock_tear/Initialize(mapload, ascendant)
+ . = ..()
+ 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
+ SSpoints_of_interest.make_point_of_interest(src)
+ INVOKE_ASYNC(src, PROC_REF(poll_ghosts))
+
+/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)
+
+/obj/structure/knock_tear/attack_ghost(mob/user)
+ . = ..()
+ if(.)
+ return
+ ghost_to_monster(user)
+
+/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"))
+ if(ask != "Yes" || QDELETED(src) || QDELETED(user))
+ return FALSE
+ var/monster_type = pick(monster_types)
+ var/mob/living/monster = new monster_type(loc)
+ monster.key = user.key
+ monster.set_name()
+ var/datum/antagonist/heretic_monster/woohoo_free_antag = new(src)
+ monster.mind.add_antag_datum(woohoo_free_antag)
+ if(ascendee)
+ monster.faction = ascendee.current.faction
+ woohoo_free_antag.set_owner(ascendee)
+ var/datum/objective/kill_all_your_friends = new()
+ kill_all_your_friends.owner = monster.mind
+ kill_all_your_friends.explanation_text = "The station's crew must be culled."
+ kill_all_your_friends.completed = TRUE
+ woohoo_free_antag.objectives += kill_all_your_friends
+
+/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
+ if(ascendee)
+ ascendee = null
+ return ..()
diff --git a/code/modules/antagonists/malf_ai/malf_ai.dm b/code/modules/antagonists/malf_ai/malf_ai.dm
index 19ad50ff550..7415d09b9dc 100644
--- a/code/modules/antagonists/malf_ai/malf_ai.dm
+++ b/code/modules/antagonists/malf_ai/malf_ai.dm
@@ -8,6 +8,8 @@
job_rank = ROLE_MALF
antag_hud_name = "traitor"
ui_name = "AntagInfoMalf"
+ can_assign_self_objectives = TRUE
+ default_custom_objective = "Make sure your precious crew are incapable of ever, ever leaving you."
///the name of the antag flavor this traitor has.
var/employer
///assoc list of strings set up after employer is given
@@ -192,6 +194,7 @@
data["allies"] = malfunction_flavor["allies"]
data["goal"] = malfunction_flavor["goal"]
data["objectives"] = get_objectives()
+ data["can_change_objective"] = can_assign_self_objectives
//module picker data
@@ -251,11 +254,9 @@
for(var/datum/objective/objective in objectives)
// SKYRAT EDIT START - No greentext
/*
- if(objective.check_completion())
- objectives_text += " Objective #[count]: [objective.explanation_text] [span_greentext("Success!")]"
- else
- objectives_text += " Objective #[count]: [objective.explanation_text] [span_redtext("Fail.")]"
+ if(!objective.check_completion())
malf_ai_won = FALSE
+ objectives_text += " Objective #[count]: [objective.explanation_text] [objective.get_roundend_success_suffix()]"
*/
objectives_text += " Objective #[count]: [objective.explanation_text]"
// SKYRAT EDIT END - No greentext
diff --git a/code/modules/antagonists/nightmare/nightmare_species.dm b/code/modules/antagonists/nightmare/nightmare_species.dm
index 73f2f02f847..88331353657 100644
--- a/code/modules/antagonists/nightmare/nightmare_species.dm
+++ b/code/modules/antagonists/nightmare/nightmare_species.dm
@@ -21,6 +21,8 @@
TRAIT_NOBLOOD,
TRAIT_NO_DNA_COPY,
TRAIT_NO_TRANSFORMATION_STING,
+ TRAIT_NODISMEMBER,
+ TRAIT_NEVER_WOUNDED,
)
mutantheart = /obj/item/organ/internal/heart/nightmare
diff --git a/code/modules/antagonists/ninja/ninjaDrainAct.dm b/code/modules/antagonists/ninja/ninjaDrainAct.dm
index ccb8e67fb9b..9230aaf913d 100644
--- a/code/modules/antagonists/ninja/ninjaDrainAct.dm
+++ b/code/modules/antagonists/ninja/ninjaDrainAct.dm
@@ -133,7 +133,7 @@
/obj/machinery/rnd/server/proc/ninjadrain_charge(mob/living/carbon/human/ninja, obj/item/mod/module/hacker/hacking_module)
if(!do_after(ninja, 30 SECONDS, target = src))
return
- SSresearch.science_tech.modify_points_all(0)
+ stored_research.modify_points_all(0)
to_chat(ninja, span_notice("Sabotage complete. Research notes corrupted."))
var/datum/antagonist/ninja/ninja_antag = ninja.mind.has_antag_datum(/datum/antagonist/ninja)
if(!ninja_antag)
diff --git a/code/modules/antagonists/ninja/ninja_explosive.dm b/code/modules/antagonists/ninja/ninja_explosive.dm
index 68241ce7769..4c014da1863 100644
--- a/code/modules/antagonists/ninja/ninja_explosive.dm
+++ b/code/modules/antagonists/ninja/ninja_explosive.dm
@@ -1,14 +1,14 @@
/**
* # Spider Charge
*
- * A unique version of c4 possessed only by the space ninja. Has a stronger blast radius.
- * Can only be detonated by space ninjas with the bombing objective. Can only be set up where the objective says it can.
+ * A unique version of c4 possessed only by the space ninja. Has a stronger blast radius.
+ * Can only be detonated by space ninjas with the bombing objective. Can only be set up where the objective says it can.
* When it primes, the space ninja responsible will have their objective set to complete.
*
*/
/obj/item/grenade/c4/ninja
name = "spider charge"
- desc = "A modified C-4 charge supplied to you by the Spider Clan. Its explosive power has been juiced up, but only works in one specific area."
+ desc = "A modified C-4 charge supplied by the Spider Clan. It has great explosive power, but is keyed to only work in one specific area."
icon_state = "ninja-explosive0"
inhand_icon_state = "ninja-explosive"
boom_sizes = list(4, 8, 12)
@@ -22,6 +22,15 @@
detonation_area = null
return ..()
+/obj/item/grenade/c4/ninja/examine(mob/user)
+ . = ..()
+ if (!IS_SPACE_NINJA(user))
+ return
+ if (isnull(detonation_area))
+ . += span_notice("This one was provided with no destination set, and cannot be used.")
+ else
+ . += span_notice("This device will only function in [detonation_area].")
+
/**
* set_detonation_area
*
@@ -38,9 +47,9 @@
return
detonation_area = objective.detonation_location
-/obj/item/grenade/c4/ninja/afterattack(atom/movable/AM, mob/ninja, flag)
+/obj/item/grenade/c4/ninja/afterattack(atom/movable/target, mob/ninja, flag)
if(!IS_SPACE_NINJA(ninja))
- to_chat(ninja, span_notice("While it appears normal, you can't seem to detonate the charge."))
+ say("Access denied.")
return
. |= AFTERATTACK_PROCESSED_ITEM
if (!check_loc(ninja))
@@ -57,7 +66,7 @@
qdel(src)
return
//Since we already did the checks in afterattack, the denonator must be a ninja with the bomb objective.
- if(!detonator)
+ if(isnull(detonator))
return
var/mob/ninja = detonator.resolve()
. = ..()
@@ -67,7 +76,7 @@
return
var/datum/antagonist/ninja/ninja_antag = ninja.mind.has_antag_datum(/datum/antagonist/ninja)
var/datum/objective/plant_explosive/objective = locate() in ninja_antag.objectives
- objective.completed = TRUE
+ objective?.completed = TRUE
/**
* check_loc
@@ -78,11 +87,11 @@
* * mob/user - The planter of the c4
*/
/obj/item/grenade/c4/ninja/proc/check_loc(mob/user)
- if(!detonation_area)
- to_chat(user, span_notice("You can't seem to activate the charge. It's location-locked, but you don't know where to detonate it."))
+ if(isnull(detonation_area))
+ balloon_alert(user, "no location set!")
return FALSE
if((get_area(target) != detonation_area) && (get_area(src) != detonation_area))
if (!active)
- to_chat(user, span_notice("This isn't the location you're supposed to use this!"))
+ balloon_alert(user, "wrong location!")
return FALSE
return TRUE
diff --git a/code/modules/antagonists/ninja/outfit.dm b/code/modules/antagonists/ninja/outfit.dm
index f91f660a3e8..9b81dd75f05 100644
--- a/code/modules/antagonists/ninja/outfit.dm
+++ b/code/modules/antagonists/ninja/outfit.dm
@@ -10,7 +10,7 @@
internals_slot = ITEM_SLOT_RPOCKET
belt = /obj/item/energy_katana
back = /obj/item/mod/control/pre_equipped/ninja
- implants = list(/obj/item/implant/explosive)
+ //implants = list(/obj/item/implant/explosive) SKYRAT EDIT REMOVAL
/datum/outfit/ninja/post_equip(mob/living/carbon/human/ninja)
var/obj/item/grenade/c4/ninja/charge = ninja.l_store
diff --git a/code/modules/antagonists/nukeop/nukeop.dm b/code/modules/antagonists/nukeop/nukeop.dm
index 2e8b53d5dfa..e2490d1a2b6 100644
--- a/code/modules/antagonists/nukeop/nukeop.dm
+++ b/code/modules/antagonists/nukeop/nukeop.dm
@@ -8,9 +8,13 @@
show_to_ghosts = TRUE
hijack_speed = 2 //If you can't take out the station, take the shuttle instead.
suicide_cry = "FOR THE SYNDICATE!!"
+ /// Which nukie team are we on?
var/datum/team/nuclear/nuke_team
- var/always_new_team = FALSE //If not assigned a team by default ops will try to join existing ones, set this to TRUE to always create new team.
- var/send_to_spawnpoint = TRUE //Should the user be moved to default spawnpoint.
+ /// If not assigned a team by default ops will try to join existing ones, set this to TRUE to always create new team.
+ var/always_new_team = FALSE
+ /// Should the user be moved to default spawnpoint after being granted this datum.
+ var/send_to_spawnpoint = TRUE
+ /// The DEFAULT outfit we will give to players granted this datum
var/nukeop_outfit = /datum/outfit/syndicate
preview_outfit = /datum/outfit/nuclear_operative_elite
@@ -40,13 +44,12 @@
if(!nukeop_outfit) // this variable is null in instances where an antagonist datum is granted via enslaving the mind (/datum/mind/proc/enslave_mind_to_creator), like in golems.
return
- // SKYRAT EDIT START
- //operative.set_species(/datum/species/human) //Plasmamen burn up otherwise, and besides, all other species are vulnerable to asimov AIs. Let's standardize all operatives being human.
- if(isplasmaman(operative))
- operative.equipOutfit(/datum/outfit/plasmaman) // they lose the turtleneck but that's fine
- // SKYRAT EDIT END
+ // If our nuke_ops_species pref is set to TRUE, (or we have no client) make us a human
+ if(isnull(operative.client) || operative.client.prefs.read_preference(/datum/preference/toggle/nuke_ops_species))
+ operative.set_species(/datum/species/human)
+
+ operative.equip_species_outfit(nukeop_outfit)
- operative.equipOutfit(nukeop_outfit)
return TRUE
/datum/antagonist/nukeop/greet()
@@ -243,7 +246,9 @@
name = "Nuclear Operative Leader"
nukeop_outfit = /datum/outfit/syndicate/leader
always_new_team = TRUE
+ /// Randomly chosen honorific, for distinction
var/title
+ /// The nuclear challenge remote we will spawn this player with.
var/challengeitem = /obj/item/nuclear_challenge
/datum/antagonist/nukeop/leader/memorize_code()
diff --git a/code/modules/antagonists/nukeop/outfits.dm b/code/modules/antagonists/nukeop/outfits.dm
index 45acac83d24..a3c97a76468 100644
--- a/code/modules/antagonists/nukeop/outfits.dm
+++ b/code/modules/antagonists/nukeop/outfits.dm
@@ -13,18 +13,33 @@
skillchips = list(/obj/item/skillchip/disk_verifier)
box = /obj/item/storage/box/survival/syndie
+ /// Amount of TC to automatically store in this outfit's uplink.
var/tc = 25
+ /// Enables big voice on this outfit's headset, used for nukie leaders.
var/command_radio = FALSE
+ /// The type of uplink to be given on equip.
var/uplink_type = /obj/item/uplink/nuclear
id_trim = /datum/id_trim/chameleon/operative
+/datum/outfit/syndicate/plasmaman
+ name = "Syndicate Operative - Basic (Plasmaman)"
+ head = /obj/item/clothing/head/helmet/space/plasmaman/syndie
+ uniform = /obj/item/clothing/under/plasmaman/syndicate
+ r_hand = /obj/item/tank/internals/plasmaman/belt/full
+
/datum/outfit/syndicate/leader
name = "Syndicate Leader - Basic"
command_radio = TRUE
id_trim = /datum/id_trim/chameleon/operative/nuke_leader
+/datum/outfit/syndicate/leader/plasmaman
+ name = "Syndicate Leader - Basic (Plasmaman)"
+ head = /obj/item/clothing/head/helmet/space/plasmaman/syndie
+ uniform = /obj/item/clothing/under/plasmaman/syndicate
+ r_hand = /obj/item/tank/internals/plasmaman/belt/full
+
/datum/outfit/syndicate/post_equip(mob/living/carbon/human/nukie, visualsOnly = FALSE)
if(visualsOnly)
return
@@ -64,6 +79,17 @@
/obj/item/pen/edagger = 1,
)
+/datum/outfit/syndicate/full/plasmaman
+ name = "Syndicate Operative - Full Kit (Plasmaman)"
+ back = /obj/item/mod/control/pre_equipped/nuclear/plasmaman
+ uniform = /obj/item/clothing/under/plasmaman/syndicate
+ r_pocket = /obj/item/tank/internals/plasmaman/belt/full
+ mask = null
+
+/datum/outfit/syndicate/full/plasmaman/New()
+ backpack_contents += /obj/item/clothing/head/helmet/space/plasmaman/syndie
+ return ..()
+
/datum/outfit/syndicate/reinforcement
name = "Syndicate Operative - Reinforcement"
tc = 0
@@ -80,6 +106,13 @@
to_chat(H, span_notice("You're an agent of [faction], sent to accompany the nuclear squad on their mission. \
Support your allies, and remember: Down with Nanotrasen."))
+/datum/outfit/syndicate/reinforcement/plasmaman
+ name = "Syndicate Operative - Reinforcement (Plasmaman)"
+ head = /obj/item/clothing/head/helmet/space/plasmaman/syndie
+ uniform = /obj/item/clothing/under/plasmaman/syndicate
+ r_hand = /obj/item/tank/internals/plasmaman/belt/full
+ tc = 0
+
/datum/outfit/syndicate/reinforcement/gorlex
name = "Syndicate Operative - Gorlex Reinforcement"
suit = /obj/item/clothing/suit/armor/vest/alt
diff --git a/code/modules/antagonists/obsessed/obsessed.dm b/code/modules/antagonists/obsessed/obsessed.dm
index 63adacca1e8..7c921fdd228 100644
--- a/code/modules/antagonists/obsessed/obsessed.dm
+++ b/code/modules/antagonists/obsessed/obsessed.dm
@@ -10,6 +10,7 @@
silent = TRUE //not actually silent, because greet will be called by the trauma anyway.
suicide_cry = "FOR MY LOVE!!"
preview_outfit = /datum/outfit/obsessed
+ hardcore_random_bonus = TRUE
var/datum/brain_trauma/special/obsessed/trauma
/datum/antagonist/obsessed/admin_add(datum/mind/new_owner,mob/admin)
diff --git a/code/modules/antagonists/pirate/pirate_event.dm b/code/modules/antagonists/pirate/pirate_event.dm
index c516d86c4e3..60be511b6ca 100644
--- a/code/modules/antagonists/pirate/pirate_event.dm
+++ b/code/modules/antagonists/pirate/pirate_event.dm
@@ -59,7 +59,7 @@
if(chosen_gang.paid_off)
return
- var/list/candidates = poll_ghost_candidates("Do you wish to be considered for pirate crew?", ROLE_TRAITOR)
+ var/list/candidates = poll_ghost_candidates("Do you wish to be considered for a pirate crew of [chosen_gang.name]?", ROLE_TRAITOR)
shuffle_inplace(candidates)
var/template_key = "pirate_[chosen_gang.ship_template_id]"
@@ -80,9 +80,9 @@
var/mob/our_candidate = candidates[1]
var/mob/spawned_mob = spawner.create_from_ghost(our_candidate)
candidates -= our_candidate
- notify_ghosts("The pirate ship has an object of interest: [spawned_mob]!", source = spawned_mob, action = NOTIFY_ORBIT, header="Pirates!")
+ notify_ghosts("The [chosen_gang.ship_name] has an object of interest: [spawned_mob]!", source = spawned_mob, action = NOTIFY_ORBIT, header="Pirates!")
else
- notify_ghosts("The pirate ship has an object of interest: [spawner]!", source = spawner, action = NOTIFY_ORBIT, header="Pirate Spawn Here!")
+ notify_ghosts("The [chosen_gang.ship_name] has an object of interest: [spawner]!", source = spawner, action = NOTIFY_ORBIT, header="Pirate Spawn Here!")
priority_announce(chosen_gang.arrival_announcement, sender_override = chosen_gang.ship_name)
diff --git a/code/modules/antagonists/pirate/pirate_gangs.dm b/code/modules/antagonists/pirate/pirate_gangs.dm
index 93c31e16bb7..ead128443ff 100644
--- a/code/modules/antagonists/pirate/pirate_gangs.dm
+++ b/code/modules/antagonists/pirate/pirate_gangs.dm
@@ -118,10 +118,10 @@ GLOBAL_LIST_INIT(heavy_pirate_gangs, init_pirate_gangs(is_heavy = TRUE))
///Expirienced formed employes of Interdyne Pharmaceutics now in a path of thievery and reckoning
/datum/pirate_gang/interdyne
- name = "Expharmacist Unrest"
+ name = "Restless Ex-Pharmacists"
is_heavy_threat = TRUE
- ship_template_id = "interdyne"
+ ship_template_id = "ex_interdyne"
ship_name_pool = "interdyne_names"
threat_title = "Funding for Research"
@@ -154,7 +154,7 @@ GLOBAL_LIST_INIT(heavy_pirate_gangs, init_pirate_gangs(is_heavy = TRUE))
///Agents from the space I.R.S. heavily armed to stea- I mean, collect the station's tax dues
/datum/pirate_gang/irs
- name = "Space IRS"
+ name = "Space IRS Agents"
is_heavy_threat = TRUE
ship_template_id = "irs"
diff --git a/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm b/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm
index 0966984c671..57eb95a978c 100644
--- a/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm
+++ b/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm
@@ -55,7 +55,8 @@
/// Handles interrupting research
/obj/machinery/shuttle_scrambler/proc/interrupt_research()
- for(var/obj/machinery/rnd/server/research_server as anything in SSresearch.science_tech.techweb_servers)
+ var/datum/techweb/science_web = locate(/datum/techweb/science) in SSresearch.techwebs
+ for(var/obj/machinery/rnd/server/research_server as anything in science_web.techweb_servers)
if(research_server.machine_stat & (NOPOWER|BROKEN|EMPED))
continue
research_server.emp_act(EMP_LIGHT)
@@ -182,8 +183,8 @@
/obj/machinery/piratepad/multitool_act(mob/living/user, obj/item/multitool/I)
. = ..()
if (istype(I))
- to_chat(user, span_notice("You register [src] in [I]s buffer."))
I.set_buffer(src)
+ balloon_alert(user, "saved to multitool buffer")
return TRUE
/obj/machinery/piratepad/screwdriver_act_secondary(mob/living/user, obj/item/screwdriver/screw)
diff --git a/code/modules/antagonists/revenant/revenant_abilities.dm b/code/modules/antagonists/revenant/revenant_abilities.dm
index d711bb97faf..ef00f51e45d 100644
--- a/code/modules/antagonists/revenant/revenant_abilities.dm
+++ b/code/modules/antagonists/revenant/revenant_abilities.dm
@@ -21,7 +21,7 @@
Harvest(A)
/mob/living/simple_animal/revenant/ranged_secondary_attack(atom/target, modifiers)
- if(revealed || notransform || inhibited || !Adjacent(target) || !incorporeal_move_check(target))
+ if(revealed || inhibited || HAS_TRAIT(src, TRAIT_NO_TRANSFORM) || !Adjacent(target) || !incorporeal_move_check(target))
return
var/list/icon_dimensions = get_icon_dimensions(target.icon)
diff --git a/code/modules/antagonists/revolution/revolution.dm b/code/modules/antagonists/revolution/revolution.dm
index 1857223df6b..e88730f7026 100644
--- a/code/modules/antagonists/revolution/revolution.dm
+++ b/code/modules/antagonists/revolution/revolution.dm
@@ -176,6 +176,7 @@
job_rank = ROLE_REV_HEAD
preview_outfit = /datum/outfit/revolutionary
+ hardcore_random_bonus = TRUE
var/remove_clumsy = FALSE
var/give_flash = FALSE
diff --git a/code/modules/antagonists/space_ninja/space_ninja.dm b/code/modules/antagonists/space_ninja/space_ninja.dm
index ff36c2f262d..1c2568820c2 100644
--- a/code/modules/antagonists/space_ninja/space_ninja.dm
+++ b/code/modules/antagonists/space_ninja/space_ninja.dm
@@ -9,6 +9,9 @@
antag_moodlet = /datum/mood_event/focused
suicide_cry = "FOR THE SPIDER CLAN!!"
preview_outfit = /datum/outfit/ninja_preview
+ can_assign_self_objectives = TRUE
+ ui_name = "AntagInfoNinja"
+ default_custom_objective = "Destroy vital station infrastructure, without being seen."
///Whether or not this ninja will obtain objectives
var/give_objectives = TRUE
@@ -33,7 +36,7 @@
antag_memory += "Surprise is my weapon. Shadows are my armor. Without them, I am nothing. "
/datum/objective/cyborg_hijack
- explanation_text = "Use your gloves to convert at least one cyborg to aide you in sabotaging the station."
+ explanation_text = "Use your gloves to convert at least one cyborg to aid you in sabotaging the station."
/datum/objective/door_jack
///How many doors that need to be opened using the gloves to pass the objective
diff --git a/code/modules/antagonists/survivalist/survivalist.dm b/code/modules/antagonists/survivalist/survivalist.dm
index 7cb9df6ed25..2480b186600 100644
--- a/code/modules/antagonists/survivalist/survivalist.dm
+++ b/code/modules/antagonists/survivalist/survivalist.dm
@@ -22,6 +22,7 @@
/datum/antagonist/survivalist/guns
greet_message = "Your own safety matters above all else, and the only way to ensure your safety is to stockpile weapons! Grab as many guns as possible, by any means necessary. Kill anyone who gets in your way."
+ hardcore_random_bonus = TRUE
/datum/antagonist/survivalist/guns/forge_objectives()
var/datum/objective/steal_n_of_type/summon_guns/guns = new
@@ -32,6 +33,7 @@
/datum/antagonist/survivalist/magic
name = "Amateur Magician"
greet_message = "Grow your newfound talent! Grab as many magical artefacts as possible, by any means necessary. Kill anyone who gets in your way."
+ hardcore_random_bonus = TRUE
/datum/antagonist/survivalist/magic/greet()
. = ..()
diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm
index 9a81645716d..aaf162c15f8 100644
--- a/code/modules/antagonists/traitor/datum_traitor.dm
+++ b/code/modules/antagonists/traitor/datum_traitor.dm
@@ -14,6 +14,9 @@
ui_name = "AntagInfoTraitor"
suicide_cry = "FOR THE SYNDICATE!!"
preview_outfit = /datum/outfit/traitor
+ can_assign_self_objectives = TRUE
+ default_custom_objective = "Perform an overcomplicated heist on valuable Nanotrasen assets."
+ hardcore_random_bonus = TRUE
var/give_objectives = TRUE
var/should_give_codewords = TRUE
///give this traitor an uplink?
@@ -67,6 +70,9 @@
uplink_handler.has_objectives = TRUE
uplink_handler.generate_objectives()
+ uplink_handler.can_replace_objectives = CALLBACK(src, PROC_REF(can_change_objectives))
+ uplink_handler.replace_objectives = CALLBACK(src, PROC_REF(submit_player_objective))
+
if(uplink_handler.progression_points < SStraitor.current_global_progression)
uplink_handler.progression_points = SStraitor.current_global_progression * SStraitor.newjoin_progression_coeff
@@ -94,8 +100,10 @@
return ..()
/datum/antagonist/traitor/on_removal()
- if(uplink_handler)
+ if(!isnull(uplink_handler))
uplink_handler.has_objectives = FALSE
+ uplink_handler.can_replace_objectives = null
+ uplink_handler.replace_objectives = null
return ..()
/datum/antagonist/traitor/proc/traitor_objective_to_html(datum/traitor_objective/to_display)
@@ -146,6 +154,10 @@
result += "Force add objective "
return result
+/// Returns true if we're allowed to assign ourselves a new objective
+/datum/antagonist/traitor/proc/can_change_objectives()
+ return can_assign_self_objectives
+
/// proc that generates the traitors replacement uplink code and radio frequency
/datum/antagonist/traitor/proc/generate_replacement_codes()
replacement_uplink_code = "[pick(GLOB.phonetic_alphabet)] [rand(10,99)]"
@@ -306,11 +318,9 @@
if(objectives.len) //If the traitor had no objectives, don't need to process this.
var/count = 1
for(var/datum/objective/objective in objectives)
- if(objective.check_completion())
- objectives_text += " Objective #[count]: [objective.explanation_text] [span_greentext("Success!")]"
- else
- objectives_text += " Objective #[count]: [objective.explanation_text] [span_redtext("Fail.")]"
+ if(!objective.check_completion())
traitor_won = FALSE
+ objectives_text += " Objective #[count]: [objective.explanation_text] [objective.get_roundend_success_suffix()]"
count++
if(uplink_handler.final_objective)
objectives_text += " [span_greentext("[traitor_won ? "Additionally" : "However"], the final objective \"[uplink_handler.final_objective]\" was completed!")]"
diff --git a/code/modules/antagonists/traitor/objectives/eyesnatching.dm b/code/modules/antagonists/traitor/objectives/eyesnatching.dm
index 49c53180b39..0540d83601c 100644
--- a/code/modules/antagonists/traitor/objectives/eyesnatching.dm
+++ b/code/modules/antagonists/traitor/objectives/eyesnatching.dm
@@ -179,9 +179,10 @@
if(!do_after(user, eye_snatch_enthusiasm, target = target, extra_checks = CALLBACK(src, PROC_REF(eyeballs_exist), eyeballies, head, target)))
return
- var/datum/wound/blunt/severe/severe_wound_type = /datum/wound/blunt/severe
- var/datum/wound/blunt/critical/critical_wound_type = /datum/wound/blunt/critical
- target.apply_damage(20, BRUTE, BODY_ZONE_HEAD, wound_bonus = rand(initial(severe_wound_type.threshold_minimum), initial(critical_wound_type.threshold_minimum) + 10), attacking_item = src)
+ var/min_wound = head.get_wound_threshold_of_wound_type(WOUND_BLUNT, WOUND_SEVERITY_SEVERE, return_value_if_no_wound = 30, wound_source = src)
+ var/max_wound = head.get_wound_threshold_of_wound_type(WOUND_BLUNT, WOUND_SEVERITY_CRITICAL, return_value_if_no_wound = 50, wound_source = src)
+
+ target.apply_damage(20, BRUTE, BODY_ZONE_HEAD, wound_bonus = rand(min_wound, max_wound + 10), attacking_item = src)
target.visible_message(
span_danger("[src] pierces through [target]'s skull, horribly mutilating their eyes!"),
span_userdanger("Something penetrates your skull, horribly mutilating your eyes! Holy fuck!"),
diff --git a/code/modules/antagonists/traitor/objectives/infect.dm b/code/modules/antagonists/traitor/objectives/infect.dm
index cfcc8b68499..8dd5e5c7619 100644
--- a/code/modules/antagonists/traitor/objectives/infect.dm
+++ b/code/modules/antagonists/traitor/objectives/infect.dm
@@ -156,6 +156,7 @@
volume = 30
amount_per_transfer_from_this = 30
list_reagents = list(/datum/reagent/medicine/sansufentanyl = 20)
+ stealthy = TRUE
//Was the injector used on someone yet?
var/used = FALSE
diff --git a/code/modules/antagonists/traitor/objectives/sleeper_protocol.dm b/code/modules/antagonists/traitor/objectives/sleeper_protocol.dm
index e825dc0d843..f28a79d6926 100644
--- a/code/modules/antagonists/traitor/objectives/sleeper_protocol.dm
+++ b/code/modules/antagonists/traitor/objectives/sleeper_protocol.dm
@@ -101,7 +101,13 @@
"The Captain is a lizardperson.",
"Nanotrasen isn't real.",
"They put something in the food to make you forget.",
- "You are the only real person on the station."
+ "You are the only real person on the station.",
+ "Things would be a lot better on the station if more people were screaming, someone should do something about that.",
+ "The people in charge around here have only ill intentions for the crew.",
+ "Help the crew? What have they ever done for you anyways?",
+ "Does your bag feel lighter? I bet those guys in Security stole something from it. Go get it back.",
+ "Command is incompetent, someone with some REAL authority should take over around here.",
+ "The cyborgs and the AI are stalking you. What are they planning?",
)
/datum/surgery_step/brainwash/sleeper_agent/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
diff --git a/code/modules/antagonists/traitor/uplink_handler.dm b/code/modules/antagonists/traitor/uplink_handler.dm
index 9b2b7dfb706..06ce9667035 100644
--- a/code/modules/antagonists/traitor/uplink_handler.dm
+++ b/code/modules/antagonists/traitor/uplink_handler.dm
@@ -48,11 +48,20 @@
var/debug_mode = FALSE
/// Whether the shop is locked or not. If set to true, nothing can be purchased.
var/shop_locked = FALSE
+ /// Callback which returns true if you can choose to replace your objectives with different ones
+ var/datum/callback/can_replace_objectives
+ /// Callback which performs that operation
+ var/datum/callback/replace_objectives
/datum/uplink_handler/New()
. = ..()
maximum_potential_objectives = CONFIG_GET(number/maximum_potential_objectives)
+/datum/uplink_handler/Destroy(force, ...)
+ can_replace_objectives = null
+ replace_objectives = null
+ return ..()
+
/// Called whenever an update occurs on this uplink handler. Used for UIs
/datum/uplink_handler/proc/on_update()
SEND_SIGNAL(src, COMSIG_UPLINK_HANDLER_ON_UPDATE)
diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm
index fc15d0b014b..3e4cf0766f5 100644
--- a/code/modules/antagonists/wizard/equipment/artefact.dm
+++ b/code/modules/antagonists/wizard/equipment/artefact.dm
@@ -86,7 +86,7 @@
/obj/item/veilrender/honkrender
name = "honk render"
desc = "A wicked curved blade of alien origin, recovered from the ruins of a vast circus."
- spawn_type = /mob/living/simple_animal/hostile/retaliate/clown
+ spawn_type = /mob/living/basic/clown
spawn_amt = 10
activate_descriptor = "depression"
rend_desc = "Gently wafting with the sounds of endless laughter."
@@ -97,7 +97,7 @@
/obj/item/veilrender/honkrender/honkhulkrender
name = "superior honk render"
desc = "A wicked curved blade of alien origin, recovered from the ruins of a vast circus. This one gleams with a special light."
- spawn_type = /mob/living/simple_animal/hostile/retaliate/clown/clownhulk
+ spawn_type = /mob/living/basic/clown/clownhulk
spawn_amt = 5
activate_descriptor = "depression"
rend_desc = "Gently wafting with the sounds of mirthful grunting."
@@ -150,7 +150,7 @@
/obj/tear_in_reality/proc/deranged(mob/living/carbon/C)
if(!C || C.stat == DEAD)
return
- C.vomit(0, TRUE, TRUE, 3, TRUE)
+ C.vomit(VOMIT_CATEGORY_BLOOD, lost_nutrition = 0, distance = 3)
C.spew_organ(3, 2)
C.investigate_log("has died from using telekinesis on a tear in reality.", INVESTIGATE_DEATHS)
C.death()
diff --git a/code/modules/antagonists/wizard/grand_ritual/fluff.dm b/code/modules/antagonists/wizard/grand_ritual/fluff.dm
new file mode 100644
index 00000000000..506da118d75
--- /dev/null
+++ b/code/modules/antagonists/wizard/grand_ritual/fluff.dm
@@ -0,0 +1,25 @@
+/**
+ * Fluff book to hint at the cheesy grand ritual.
+ */
+/obj/item/book/manual/ancient_parchment
+ name = "ancient parchment"
+ icon = 'icons/obj/scrolls.dmi'
+ icon_state = "scroll-ancient"
+ unique = TRUE
+ w_class = WEIGHT_CLASS_SMALL
+ starting_author = "Pelagius the Mad"
+ starting_title = "Worship and Reverence of the Divine Insanity"
+ starting_content = {"
+
+
+
+
+ Most of the scroll's contents are unintelligible, plagued with mold, milk stains and a stench of spolied goat cheese so potent,
+ you can barely resist turning your head to retch. What's left of the writings is vague and abstract, as if the author
+ was in a mad dash to pass on their findings.
+ However, the runes they have managed to scribe onto the parchment are oddly untouched by time, and remain distinct.
+ You also discover a schema for a more widely-used Grand Ritual rune, however it is dotted with yellow circles, which in turn are
+ filled with black dots. Are these supposed to be... cheese wheels?..
+ As you finish skimming through the wreck that is this scroll, you hear a faint snicker somewhere beyond your mind's eye...
+
+ "}
diff --git a/code/modules/antagonists/wizard/grand_ritual/grand_ritual.dm b/code/modules/antagonists/wizard/grand_ritual/grand_ritual.dm
index ce1d89edcc6..f3ac9b01071 100644
--- a/code/modules/antagonists/wizard/grand_ritual/grand_ritual.dm
+++ b/code/modules/antagonists/wizard/grand_ritual/grand_ritual.dm
@@ -1,3 +1,10 @@
+/**
+ * Total cheese goal to sacrifice to [REDACTED] during wizard grand rituals.
+ * The easiest way for a wizard to procure cheese is with Summon Cheese spell, which summons 9 per cast.
+ * The wizard needs to complete 7 rituals, so let's give them some breathing room with cheese offerings.
+ * 7 * 9 = 63, so the wizard can potentially miss two casts worth of cheese if they summon cheese on each rune.
+*/
+#define CHEESE_SACRIFICE_GOAL 50
/**
* The Grand Ritual is the Wizard's alternate victory condition
* and also a tool to make funny distractions and progress the round state.
@@ -30,6 +37,10 @@
var/drew_finale = FALSE
/// True while you are drawing a rune, prevents action spamming
var/drawing_rune = FALSE
+ /// Number of cheese sacrificed on previously drawn runes
+ var/total_cheese_sacrificed = 0
+ /// Whether we have sacrificed enough cheese or not
+ var/total_cheese_goal_met = FALSE
/// Weakref to a rune drawn in the current area, if there is one
var/datum/weakref/rune
@@ -150,13 +161,20 @@
/// Draws the ritual rune
/datum/action/cooldown/grand_ritual/proc/draw_rune(turf/target_turf)
drawing_rune = TRUE
+ var/next_rune_typepath = get_appropriate_rune_typepath()
target_turf.balloon_alert(owner, "conjuring rune...")
- var/obj/effect/temp_visual/wizard_rune/drawing/draw_effect = new(target_turf)
+ var/draw_effect_typepath = /obj/effect/temp_visual/wizard_rune/drawing
+ if(next_rune_typepath == /obj/effect/grand_rune/finale/cheesy)
+ draw_effect_typepath = /obj/effect/temp_visual/wizard_rune/drawing/cheese
+ var/obj/effect/temp_visual/wizard_rune/drawing/draw_effect = new draw_effect_typepath(target_turf)
if(!do_after(owner, 4 SECONDS, target_turf))
target_turf.balloon_alert(owner, "interrupted!")
drawing_rune = FALSE
qdel(draw_effect)
- new /obj/effect/temp_visual/wizard_rune/failed(target_turf)
+ var/fail_effect_typepath = /obj/effect/temp_visual/wizard_rune/failed
+ if(next_rune_typepath == /obj/effect/grand_rune/finale/cheesy)
+ fail_effect_typepath = /obj/effect/temp_visual/wizard_rune/failed/cheese
+ new fail_effect_typepath(target_turf)
return
var/evaporated_obstacles = FALSE
@@ -176,25 +194,37 @@
playsound(target_turf, 'sound/magic/blind.ogg', 100, TRUE)
target_turf.balloon_alert(owner, "rune created")
- var/obj/effect/grand_rune/new_rune = create_appropriate_rune(target_turf)
+ var/obj/effect/grand_rune/new_rune = new next_rune_typepath(target_turf, times_completed)
+ if(istype(new_rune, /obj/effect/grand_rune/finale))
+ drew_finale = TRUE
rune = WEAKREF(new_rune)
RegisterSignal(new_rune, COMSIG_GRAND_RUNE_COMPLETE, PROC_REF(on_rune_complete))
drawing_rune = FALSE
StartCooldown(2 MINUTES) // To put a damper on wizards who have 5 ranks of Teleport
/// The seventh rune we spawn is special
-/datum/action/cooldown/grand_ritual/proc/create_appropriate_rune(turf/target_turf)
+/datum/action/cooldown/grand_ritual/proc/get_appropriate_rune_typepath()
if (times_completed < GRAND_RITUAL_FINALE_COUNT - 1)
- return new /obj/effect/grand_rune(target_turf, times_completed)
+ return /obj/effect/grand_rune
if (drew_finale)
- return new /obj/effect/grand_rune(target_turf, times_completed)
- drew_finale = TRUE
- return new /obj/effect/grand_rune/finale(target_turf, times_completed)
+ return /obj/effect/grand_rune
+ if (total_cheese_sacrificed >= CHEESE_SACRIFICE_GOAL)
+ return /obj/effect/grand_rune/finale/cheesy
+ return /obj/effect/grand_rune/finale
/// Called when you finish invoking a rune you drew, get ready for another one.
-/datum/action/cooldown/grand_ritual/proc/on_rune_complete(atom/source)
+/datum/action/cooldown/grand_ritual/proc/on_rune_complete(atom/source, cheese_sacrificed)
SIGNAL_HANDLER
UnregisterSignal(source, COMSIG_GRAND_RUNE_COMPLETE)
+ total_cheese_sacrificed += cheese_sacrificed
+ if(total_cheese_sacrificed >= CHEESE_SACRIFICE_GOAL)
+ if(!total_cheese_goal_met)
+ total_cheese_goal_met = TRUE
+ to_chat(owner, span_revenbignotice("YES! CHEESE! CHEESE FOR EVERYONE! SUCH A GRAND FEAST! YOU SHALL HAVE YOUR PRIZE, MY CHAMPION!!"))
+ else
+ to_chat(owner, span_revennotice("You hear maddening laughter as you are hit with an overwhelming odor of fine cheddar..."))
+ else if (total_cheese_sacrificed)
+ to_chat(owner, span_revendanger("You please me, mortal. Do continue to send cheese, my feast still needs [CHEESE_SACRIFICE_GOAL - total_cheese_sacrificed] more to be magnificent..."))
rune = null
times_completed++
set_new_area()
@@ -203,8 +233,12 @@
to_chat(owner, span_warning("Your collected power is growing, \
but further rituals will alert your enemies to your position."))
if (GRAND_RITUAL_IMMINENT_FINALE_POTENCY)
- to_chat(owner, span_warning("You are overflowing with power! \
- Your next Grand Ritual will allow you to choose a powerful effect, and grant you victory."))
+ var/message = "You are overflowing with power! \
+ Your next Grand Ritual will allow you to choose a powerful effect, and grant you victory."
+ if(total_cheese_sacrificed >= CHEESE_SACRIFICE_GOAL)
+ message = "You are overflowing with chaotic energies! \
+ Your next Grand Ritual will conjure a powerful artefact for your use, and grant you victory."
+ to_chat(owner, span_warning(message))
if (GRAND_RITUAL_FINALE_COUNT)
SEND_SIGNAL(src, COMSIG_GRAND_RITUAL_FINAL_COMPLETE)
@@ -283,3 +317,13 @@
/obj/effect/temp_visual/wizard_rune/failed
icon_state = "wizard_rune_fail"
duration = 0.5 SECONDS
+
+/// Cheese drawing
+/obj/effect/temp_visual/wizard_rune/drawing/cheese
+ icon_state = "wizard_rune_cheese_draw"
+
+/// Cheese fail
+/obj/effect/temp_visual/wizard_rune/failed/cheese
+ icon_state = "wizard_rune_cheese_fail"
+
+#undef CHEESE_SACRIFICE_GOAL
diff --git a/code/modules/antagonists/wizard/grand_ritual/grand_ritual_finale.dm b/code/modules/antagonists/wizard/grand_ritual/grand_ritual_finale.dm
index 4b090b220d0..9a59b1f1a79 100644
--- a/code/modules/antagonists/wizard/grand_ritual/grand_ritual_finale.dm
+++ b/code/modules/antagonists/wizard/grand_ritual/grand_ritual_finale.dm
@@ -30,12 +30,13 @@
/datum/grand_finale/proc/get_radial_choice()
if (!name || !desc || !icon || !icon_state)
return
+ var/time_remaining_desc = ""
if (minimum_time >= world.time - SSticker.round_start_time)
- return
+ time_remaining_desc = "This ritual will be available to begin invoking in [DisplayTimeText(minimum_time - world.time - SSticker.round_start_time)]"
var/datum/radial_menu_choice/choice = new()
choice.name = name
choice.image = image(icon = icon, icon_state = icon_state)
- choice.info = desc
+ choice.info = desc + time_remaining_desc
return choice
/**
@@ -399,6 +400,57 @@
mode.execute_roundstart_rule(meteors) // Meteors will continue until morale is crushed.
priority_announce("Meteors have been detected on collision course with the station.", "Meteor Alert", ANNOUNCER_METEORS)
+/**
+ * Gives the wizard a defensive/mood buff and a Wabbajack, a juiced up chaos staff that will surely break something.
+ * Everyone but the wizard goes crazy, suffers major brain damage, and is given a vendetta against the wizard.
+ * Already insane people are instead cured of their madness, ignoring any other effects as the station around them loses its marbles.
+ */
+/datum/grand_finale/cheese
+ // we don't set name, desc and others, thus we won't appear in the radial choice of a normal finale rune
+ dire_warning = TRUE
+ minimum_time = 45 MINUTES //i'd imagine speedrunning this would be crummy, but the wizard's average lifespan is barely reaching this point
+
+/datum/grand_finale/cheese/trigger(mob/living/invoker)
+ message_admins("[key_name(invoker)] has summoned forth The Wabbajack and cursed the crew with madness!")
+ priority_announce("Danger: Extremely potent reality altering object has been summoned on station. Immediate evacuation advised. Brace for impact.", "Central Command Higher Dimensional Affairs", 'sound/effects/glassbr1.ogg')
+
+ for (var/mob/living/carbon/human/crewmate as anything in GLOB.human_list)
+ if (isnull(crewmate.mind))
+ continue
+ if (crewmate == invoker) //everyone but the wizard is royally fucked, no matter who they are
+ continue
+ if (crewmate.has_trauma_type(/datum/brain_trauma/mild/hallucinations)) //for an already insane person, this is retribution
+ to_chat(crewmate, span_boldwarning("Your surroundings suddenly fill with a cacophony of manic laughter and psychobabble..."))
+ to_chat(crewmate, span_nicegreen("...but as the moment passes, you realise that whatever eldritch power behind the event happened to affect you \
+ has resonated within the ruins of your already shattered mind, creating a singularity of mental instability! \
+ As it collapses unto itself, you feel... at peace, finally."))
+ if(crewmate.has_quirk(/datum/quirk/insanity))
+ crewmate.remove_quirk(/datum/quirk/insanity)
+ else
+ crewmate.cure_trauma_type(/datum/brain_trauma/mild/hallucinations, TRAUMA_RESILIENCE_ABSOLUTE)
+ else
+ //everyone else gets to relish in madness
+ //yes killing their mood will also trigger mood hallucinations
+ create_vendetta(crewmate.mind, invoker.mind)
+ to_chat(crewmate, span_boldwarning("Your surroundings suddenly fill with a cacophony of manic laughter and psychobabble. \n\
+ You feel your inner psyche shatter into a myriad pieces of jagged glass of colors unknown to the universe, \
+ infinitely reflecting a blinding, maddening light coming from the innermost sanctums of your destroyed mind. \n\
+ After a brief pause which felt like a millenia, one phrase rebounds ceaselessly in your head, imbued with the false hope of absolution... \n\
+ [invoker] must die."))
+ var/datum/brain_trauma/mild/hallucinations/added_trauma = new()
+ added_trauma.resilience = TRAUMA_RESILIENCE_ABSOLUTE
+ crewmate.adjustOrganLoss(ORGAN_SLOT_BRAIN, BRAIN_DAMAGE_DEATH - 25, BRAIN_DAMAGE_DEATH - 25) //you'd better hope chap didn't pick a hypertool
+ crewmate.gain_trauma(added_trauma)
+ crewmate.add_mood_event("wizard_ritual_finale", /datum/mood_event/madness_despair)
+
+ //drip our wizard out
+ invoker.apply_status_effect(/datum/status_effect/blessing_of_insanity)
+ invoker.add_mood_event("wizard_ritual_finale", /datum/mood_event/madness_elation)
+ var/obj/item/gun/magic/staff/chaos/true_wabbajack/the_wabbajack = new
+ invoker.put_in_active_hand(the_wabbajack)
+ to_chat(invoker, span_mind_control("Your every single instinct and rational thought is screaming at you as [the_wabbajack] appears in your firm grip..."))
+
#undef DOOM_SINGULARITY
#undef DOOM_TESLA
#undef DOOM_METEORS
+
diff --git a/code/modules/antagonists/wizard/grand_ritual/grand_rune.dm b/code/modules/antagonists/wizard/grand_ritual/grand_rune.dm
index 6288c5aef80..d1b01912ae9 100644
--- a/code/modules/antagonists/wizard/grand_ritual/grand_rune.dm
+++ b/code/modules/antagonists/wizard/grand_ritual/grand_rune.dm
@@ -31,6 +31,10 @@
var/times_invoked = 0
/// What colour you glow while channeling
var/spell_colour = "#de3aff48"
+ /// How much cheese was sacrificed to the other realm, if any
+ var/cheese_sacrificed = 0
+ /// What kind of remains this rune leaves behind after completing invokation
+ var/remains_typepath = /obj/effect/decal/cleanable/grand_remains
/// Magic words you say to invoke the ritual
var/list/magic_words = list()
/// Things you might yell when invoking a rune
@@ -67,7 +71,8 @@
. = ..()
src.potency = potency
invoke_time = get_invoke_time()
- magic_words = pick(possible_magic_words)
+ if(!length(magic_words))
+ magic_words = pick(possible_magic_words)
var/image/silicon_image = image(icon = 'icons/effects/eldritch.dmi', icon_state = null, loc = src)
silicon_image.override = TRUE
add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/silicons, "wizard_rune", silicon_image)
@@ -114,6 +119,7 @@
is_in_use = TRUE
add_channel_effect(user)
user.balloon_alert(user, "invoking rune...")
+
if(!do_after(user, invoke_time, src))
remove_channel_effect(user)
user.balloon_alert(user, "interrupted!")
@@ -121,6 +127,30 @@
return
times_invoked++
+
+ //fetch cheese on the rune
+ var/list/obj/item/food/cheese/wheel/cheese_list = list()
+ for(var/obj/item/food/cheese/wheel/nearby_cheese in range(1, src))
+ if(HAS_TRAIT(nearby_cheese, TRAIT_HAUNTED)) //already haunted
+ continue
+ cheese_list += nearby_cheese
+ //handle cheese sacrifice - haunt a part of all cheese on the rune with each invocation, then delete it
+ var/list/obj/item/food/cheese/wheel/cheese_to_haunt = list()
+ cheese_list = shuffle(cheese_list)
+ //the intent here is to sacrifice cheese in parts, roughly in thirds since we invoke the rune three times
+ //so hopefully this will properly do that, and on the third invocation it will just eat all remaining cheese
+ cheese_to_haunt = cheese_list.Copy(1, min(round(length(cheese_list) * times_invoked * 0.4), max(length(cheese_list), 3)))
+ for(var/obj/item/food/cheese/wheel/sacrifice as anything in cheese_to_haunt)
+ sacrifice.AddComponent(\
+ /datum/component/haunted_item, \
+ haunt_color = spell_colour, \
+ haunt_duration = 10 SECONDS, \
+ aggro_radius = 0, \
+ spawn_message = span_revenwarning("[sacrifice] begins to float and twirl into the air as it becomes enveloped in otherworldy energies..."), \
+ )
+ addtimer(CALLBACK(sacrifice, TYPE_PROC_REF(/obj/item/food/cheese/wheel, consume_cheese)), 10 SECONDS)
+ cheese_sacrificed += length(cheese_to_haunt)
+
user.say(magic_words[times_invoked], forced = "grand ritual invocation")
remove_channel_effect(user)
@@ -130,7 +160,7 @@
if(times_invoked >= GRAND_RUNE_INVOKES_TO_COMPLETE)
on_invocation_complete(user)
return
- flick("wizard_rune_flash", src)
+ flick("[icon_state]_flash", src)
playsound(src,'sound/magic/staff_animation.ogg', 75, TRUE)
INVOKE_ASYNC(src, PROC_REF(invoke_rune), user)
@@ -154,13 +184,13 @@
INVOKE_ASYNC(src, PROC_REF(summon_round_event), user) // Running the event sleeps
trigger_side_effects()
tear_reality()
- SEND_SIGNAL(src, COMSIG_GRAND_RUNE_COMPLETE)
- flick("activate", src)
+ SEND_SIGNAL(src, COMSIG_GRAND_RUNE_COMPLETE, cheese_sacrificed)
+ flick("[icon_state]_activate", src)
addtimer(CALLBACK(src, PROC_REF(remove_rune)), 6)
SSblackbox.record_feedback("amount", "grand_runes_invoked", 1)
/obj/effect/grand_rune/proc/remove_rune()
- new /obj/effect/decal/cleanable/grand_remains(get_turf(src))
+ new remains_typepath(get_turf(src))
qdel(src)
/// Triggers some form of event somewhere on the station
@@ -273,9 +303,15 @@
return ..()
/obj/effect/grand_rune/finale/interact(mob/living/user)
- if (chosen_effect)
- return ..()
- select_finale(user)
+ if (!chosen_effect)
+ select_finale(user)
+ return
+ var/round_time_passed = world.time - SSticker.round_start_time
+ if (chosen_effect && finale_effect.minimum_time >= round_time_passed)
+ to_chat(user, span_warning("The chosen grand finale will only be available in [DisplayTimeText(finale_effect.minimum_time - round_time_passed)]!"))
+ return
+ return ..()
+
#define PICK_NOTHING "Continuation"
@@ -308,6 +344,7 @@
invoke_time = get_invoke_time()
if (finale_effect.glow_colour)
spell_colour = finale_effect.glow_colour
+ add_filter("finale_picked_glow", 2, list("type" = "outline", "color" = spell_colour, "size" = 2))
/obj/effect/grand_rune/finale/summon_round_event(mob/living/user)
user.client?.give_award(/datum/award/achievement/misc/grand_ritual_finale, user)
@@ -321,6 +358,26 @@
return ..()
return finale_effect.ritual_invoke_time
+
+/**
+ * Spawned when 50 or more cheese was sacrificed during previous grand rituals.
+ * Will spawn instead of the usual grand ritual rune, and its effect is already set and can't be changed.
+ * Sorry, no narwal fighting on the open ocean this time.
+ */
+/obj/effect/grand_rune/finale/cheesy
+ name = "especially grand rune"
+ desc = "A ritual circle of maddening shapes and outlines, its mere presence an insult to reason."
+ icon_state = "wizard_rune_cheese"
+ magic_words = list("Greetings! Salutations!", "Welcome! Now go away.", "Leave. Run. Or die.")
+ remains_typepath = /obj/effect/decal/cleanable/grand_remains/cheese
+
+/obj/effect/grand_rune/finale/cheesy/Initialize(mapload, potency)
+ . = ..()
+ finale_effect = new /datum/grand_finale/cheese()
+ chosen_effect = TRUE
+ add_filter("finale_picked_glow", 2, list("type" = "outline", "color" = spell_colour, "size" = 2))
+
+
/**
* Spawned when we are done with the rune
*/
@@ -337,4 +394,9 @@
clean_type = CLEAN_TYPE_HARD_DECAL
layer = SIGIL_LAYER
+/obj/effect/decal/cleanable/grand_remains/cheese
+ name = "cheese soot marks"
+ desc = "The bizarre shapes on the ground turn out to be a cheese crust burned to black tar."
+ icon_state = "wizard_rune_cheese_burned"
+
#undef PICK_NOTHING
diff --git a/code/modules/antagonists/wizard/wizard.dm b/code/modules/antagonists/wizard/wizard.dm
index 8c3fa74f50a..1e8df43cfbe 100644
--- a/code/modules/antagonists/wizard/wizard.dm
+++ b/code/modules/antagonists/wizard/wizard.dm
@@ -12,6 +12,9 @@ GLOBAL_LIST_EMPTY(wizard_spellbook_purchases_by_key)
ui_name = "AntagInfoWizard"
suicide_cry = "FOR THE FEDERATION!!"
preview_outfit = /datum/outfit/wizard
+ can_assign_self_objectives = TRUE
+ default_custom_objective = "Demonstrate your incredible and destructive magical powers."
+ hardcore_random_bonus = TRUE
var/give_objectives = TRUE
var/strip = TRUE //strip before equipping
var/allow_rename = TRUE
@@ -197,9 +200,9 @@ GLOBAL_LIST_EMPTY(wizard_spellbook_purchases_by_key)
H.equipOutfit(outfit_type)
/datum/antagonist/wizard/ui_static_data(mob/user)
- . = ..()
var/list/data = list()
data["objectives"] = get_objectives()
+ data["can_change_objective"] = can_assign_self_objectives
return data
/datum/antagonist/wizard/ui_data(mob/user)
@@ -258,6 +261,7 @@ GLOBAL_LIST_EMPTY(wizard_spellbook_purchases_by_key)
/datum/antagonist/wizard/apprentice
name = "Wizard Apprentice"
antag_hud_name = "apprentice"
+ can_assign_self_objectives = FALSE
var/datum/mind/master
var/school = APPRENTICE_DESTRUCTION
outfit_type = /datum/outfit/wizard/apprentice
@@ -375,6 +379,7 @@ GLOBAL_LIST_EMPTY(wizard_spellbook_purchases_by_key)
show_in_antagpanel = FALSE
outfit_type = /datum/outfit/wizard/academy
move_to_lair = FALSE
+ can_assign_self_objectives = FALSE
/datum/antagonist/wizard/academy/assign_ritual()
return // Has other duties to be getting on with
@@ -409,13 +414,11 @@ GLOBAL_LIST_EMPTY(wizard_spellbook_purchases_by_key)
parts += " Grand Rituals completed: [ritual.times_completed] "
var/count = 1
- var/wizardwin = 1
+ var/wizardwin = TRUE
for(var/datum/objective/objective in objectives)
- if(objective.check_completion())
- parts += "Objective #[count]: [objective.explanation_text] [span_greentext("Success!")]"
- else
- parts += "Objective #[count]: [objective.explanation_text] [span_redtext("Fail.")]"
- wizardwin = 0
+ if(!objective.check_completion())
+ wizardwin = FALSE
+ parts += "Objective #[count]: [objective.explanation_text] [objective.get_roundend_success_suffix()]"
count++
if(wizardwin)
diff --git a/code/modules/asset_cache/assets/fish.dm b/code/modules/asset_cache/assets/fish.dm
index 14258663d9b..2fcf2b803e3 100644
--- a/code/modules/asset_cache/assets/fish.dm
+++ b/code/modules/asset_cache/assets/fish.dm
@@ -12,10 +12,3 @@
continue
id_list += id
Insert(id, fish_icon, fish_icon_state)
-
-
-/datum/asset/simple/fishing_minigame
- assets = list(
- "fishing_background_default" = 'icons/ui_icons/fishing/default.png',
- "fishing_background_lavaland" = 'icons/ui_icons/fishing/lavaland.png'
- )
diff --git a/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm b/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm
index 2da16155db7..acb718e1ff1 100644
--- a/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm
+++ b/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm
@@ -124,6 +124,7 @@ GLOBAL_LIST_EMPTY_TYPED(air_alarms, /obj/machinery/airalarm)
GLOB.air_alarms += src
update_appearance()
+ find_and_hang_on_wall()
/obj/machinery/airalarm/process()
if(!COOLDOWN_FINISHED(src, warning_cooldown))
diff --git a/code/modules/atmospherics/machinery/bluespace_vendor.dm b/code/modules/atmospherics/machinery/bluespace_vendor.dm
index 7ea5b827d4a..84753354018 100644
--- a/code/modules/atmospherics/machinery/bluespace_vendor.dm
+++ b/code/modules/atmospherics/machinery/bluespace_vendor.dm
@@ -69,6 +69,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/bluespace_vendor, 30)
/obj/machinery/bluespace_vendor/Initialize(mapload)
. = ..()
AddComponent(/datum/component/payment, tank_cost, SSeconomy.get_dep_account(ACCOUNT_ENG), PAYMENT_ANGRY)
+ find_and_hang_on_wall( FALSE)
/obj/machinery/bluespace_vendor/LateInitialize()
. = ..()
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
index 006d9c95648..3c1ba634cae 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
@@ -5,7 +5,7 @@
//
// Thus, the two variables affect pump operation are set in New():
// air1.volume
-// This is the volume of gas available to the pump that may be transfered to the output
+// This is the volume of gas available to the pump that may be transferred to the output
// air2.volume
// Higher quantities of this cause more air to be perfected later
// but overall network volume is also increased as this increases...
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
index 502e35c74e4..94013ccadc7 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
@@ -5,7 +5,7 @@
//
// Thus, the two variables affect pump operation are set in New():
// air1.volume
-// This is the volume of gas available to the pump that may be transfered to the output
+// This is the volume of gas available to the pump that may be transferred to the output
// air2.volume
// Higher quantities of this cause more air to be perfected later
// but overall network volume is also increased as this increases...
diff --git a/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm b/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm
index 1097a2a031a..9b080b59260 100644
--- a/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm
+++ b/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm
@@ -413,7 +413,7 @@
var/critical = selected_fuel.meltdown_flags & HYPERTORUS_FLAG_CRITICAL_MELTDOWN
if(critical)
priority_announce("WARNING - The explosion will likely cover a big part of the station and the coming EMP will wipe out most of the electronics. \
- Get as far away as possible from the reactor or find a way to shut it down.", "Alert")
+ Get as far away as possible from the reactor or find a way to shut it down.", "Alert", 'sound/misc/notice3.ogg')
var/speaking = "[emergency_alert] The Hypertorus fusion reactor has reached critical integrity failure. Emergency magnetic dampeners online."
radio.talk_into(src, speaking, common_channel, language = get_selected_language())
diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
index b9fb506faf1..862fbc65c89 100644
--- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
+++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
@@ -11,9 +11,9 @@
///Output pressure target
var/target_pressure = ONE_ATMOSPHERE
- ///Ratio between the node 1 and 2, determines the amount of gas transfered, sums up to 1
+ ///Ratio between the node 1 and 2, determines the amount of gas transferred, sums up to 1
var/node1_concentration = 0.5
- ///Ratio between the node 1 and 2, determines the amount of gas transfered, sums up to 1
+ ///Ratio between the node 1 and 2, determines the amount of gas transferred, sums up to 1
var/node2_concentration = 0.5
//node 3 is the outlet, nodes 1 & 2 are intakes
@@ -84,8 +84,12 @@
//Calculate necessary moles to transfer using PV=nRT
var/general_transfer = (target_pressure - output_starting_pressure) * air3.volume / R_IDEAL_GAS_EQUATION
- var/transfer_moles1 = air1.temperature ? node1_concentration * general_transfer / air1.temperature : 0
- var/transfer_moles2 = air2.temperature ? node2_concentration * general_transfer / air2.temperature : 0
+ //Calculate combined temperature for accurate output ratio
+ var/combined_heat_capacity = air1.heat_capacity() + air2.heat_capacity()
+ var/equalized_temperature = combined_heat_capacity ? (air1.thermal_energy() + air2.thermal_energy()) / combined_heat_capacity : 0
+
+ var/transfer_moles1 = equalized_temperature ? (node1_concentration * general_transfer) / equalized_temperature : 0
+ var/transfer_moles2 = equalized_temperature ? (node2_concentration * general_transfer) / equalized_temperature : 0
var/air1_moles = air1.total_moles()
var/air2_moles = air2.total_moles()
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/bluespace_sender.dm b/code/modules/atmospherics/machinery/components/unary_devices/bluespace_sender.dm
index d4977eb6454..1685a027a5f 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/bluespace_sender.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/bluespace_sender.dm
@@ -123,7 +123,7 @@ GLOBAL_LIST_EMPTY_TYPED(bluespace_senders, /obj/machinery/atmospherics/component
/obj/machinery/atmospherics/components/unary/bluespace_sender/multitool_act(mob/living/user, obj/item/item)
var/obj/item/multitool/multitool = item
multitool.set_buffer(src)
- to_chat(user, span_notice("You store linkage information in [item]'s buffer."))
+ balloon_alert(user, "saved to multitool buffer")
return TRUE
/obj/machinery/atmospherics/components/unary/bluespace_sender/wrench_act(mob/living/user, obj/item/tool)
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
index 2c4fceed68c..50b8e72c6a8 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
@@ -109,6 +109,8 @@
var/message_cooldown
///Cryo will continue to treat people with 0 damage but existing wounds, but will sound off when damage healing is done in case doctors want to directly treat the wounds instead
var/treating_wounds = FALSE
+ /// Cryo should notify doctors if the patient is dead, and eject them if autoeject is enabled
+ var/patient_dead = FALSE
fair_market_price = 10
payment_department = ACCOUNT_MED
@@ -268,19 +270,36 @@
/obj/machinery/atmospherics/components/unary/cryo_cell/process(seconds_per_tick)
..()
-
- if(!on)
- return
if(!occupant)
return
+ if(!on)
+ // Should turn on if set to auto
+ if(autoeject)
+ set_on(TRUE)
+ else
+ return
+
var/mob/living/mob_occupant = occupant
if(mob_occupant.on_fire)
mob_occupant.extinguish_mob()
if(!check_nap_violations())
return
- if(mob_occupant.stat == DEAD) // We don't bother with dead people.
+ if(mob_occupant.stat == DEAD) // Notify doctors and potentially eject if the patient is dead
+ set_on(FALSE)
+ var/msg = "Patient is deceased."
+ if(autoeject) // Eject if configured.
+ msg += " Auto ejecting patient now."
+ open_machine()
+ // Only need to tell them once
+ if(!patient_dead)
+ playsound(src, 'sound/machines/cryo_warning.ogg', volume)
+ patient_dead = TRUE
+ radio.talk_into(src, msg, radio_channel)
return
+
+ patient_dead = FALSE
+
if(mob_occupant.get_organic_health() >= mob_occupant.getMaxHealth()) // Don't bother with fully healed people.
if(iscarbon(mob_occupant))
var/mob/living/carbon/C = mob_occupant
@@ -383,6 +402,9 @@
/obj/machinery/atmospherics/components/unary/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)
+ to_chat(user, span_warning("You can't close [src] on yourself!"))
+ return
flick("pod-close-anim", src)
..(user)
return occupant
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm
index 269091d4bdf..452d5d7b243 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm
@@ -43,16 +43,13 @@
. += span_notice("You can link it with an air sensor using a multitool.")
/obj/machinery/atmospherics/components/unary/outlet_injector/multitool_act(mob/living/user, obj/item/multitool/multi_tool)
- . = ..()
-
if(istype(multi_tool.buffer, /obj/machinery/air_sensor))
var/obj/machinery/air_sensor/sensor = multi_tool.buffer
- sensor.inlet_id = id_tag
- multi_tool.set_buffer(null)
- balloon_alert(user, "input linked to sensor")
+ multi_tool.set_buffer(src)
+ sensor.multitool_act(user, multi_tool)
return TOOL_ACT_TOOLTYPE_SUCCESS
- balloon_alert(user, "saved in buffer")
+ balloon_alert(user, "injector saved in buffer")
multi_tool.set_buffer(src)
return TOOL_ACT_TOOLTYPE_SUCCESS
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm
index 6449dc49357..3422f3e3adf 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm
@@ -53,16 +53,13 @@
. += span_notice("You can link it with an air sensor using a multitool.")
/obj/machinery/atmospherics/components/unary/vent_pump/multitool_act(mob/living/user, obj/item/multitool/multi_tool)
- . = ..()
-
if(istype(multi_tool.buffer, /obj/machinery/air_sensor))
var/obj/machinery/air_sensor/sensor = multi_tool.buffer
- sensor.outlet_id = id_tag
- multi_tool.set_buffer(null)
- balloon_alert(user, "output linked to sensor")
+ multi_tool.set_buffer(src)
+ sensor.multitool_act(user, multi_tool)
return TOOL_ACT_TOOLTYPE_SUCCESS
- balloon_alert(user, "saved in buffer")
+ balloon_alert(user, "vent saved in buffer")
multi_tool.set_buffer(src)
return TOOL_ACT_TOOLTYPE_SUCCESS
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
index 7e9951214c9..051299950bc 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
@@ -261,10 +261,10 @@
for(var/gas in filter_types & env_gases)
filtered_out.add_gas(gas)
//take this gases portion of removal_ratio of the turfs air, or all of that gas if less than or equal to MINIMUM_MOLES_TO_SCRUB
- var/transfered_moles = max(QUANTIZE(env_gases[gas][MOLES] * removal_ratio * (env_gases[gas][MOLES] / total_moles_to_remove)), min(MINIMUM_MOLES_TO_SCRUB, env_gases[gas][MOLES]))
+ var/transferred_moles = max(QUANTIZE(env_gases[gas][MOLES] * removal_ratio * (env_gases[gas][MOLES] / total_moles_to_remove)), min(MINIMUM_MOLES_TO_SCRUB, env_gases[gas][MOLES]))
- filtered_gases[gas][MOLES] = transfered_moles
- env_gases[gas][MOLES] -= transfered_moles
+ filtered_gases[gas][MOLES] = transferred_moles
+ env_gases[gas][MOLES] -= transferred_moles
environment.garbage_collect()
diff --git a/code/modules/cards/cardhand.dm b/code/modules/cards/cardhand.dm
index b03a29a43f4..9dab4e65b58 100644
--- a/code/modules/cards/cardhand.dm
+++ b/code/modules/cards/cardhand.dm
@@ -29,7 +29,7 @@
/obj/item/toy/cards/cardhand/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
if(istype(held_item, /obj/item/toy/cards/deck))
var/obj/item/toy/cards/deck/dealer_deck = held_item
- if(dealer_deck.wielded)
+ if(HAS_TRAIT(dealer_deck, TRAIT_WIELDED))
context[SCREENTIP_CONTEXT_LMB] = "Deal card"
context[SCREENTIP_CONTEXT_RMB] = "Deal card faceup"
return CONTEXTUAL_SCREENTIP_SET
@@ -77,7 +77,7 @@
if(istype(weapon, /obj/item/toy/cards/deck))
var/obj/item/toy/cards/deck/dealer_deck = weapon
- if(!dealer_deck.wielded) // recycle cardhand into deck (if unwielded)
+ if(!HAS_TRAIT(dealer_deck, TRAIT_WIELDED)) // recycle cardhand into deck (if unwielded)
dealer_deck.insert(src)
user.balloon_alert_to_viewers("puts card in deck")
return
diff --git a/code/modules/cards/deck/deck.dm b/code/modules/cards/deck/deck.dm
index 189d88822ec..632b01d509d 100644
--- a/code/modules/cards/deck/deck.dm
+++ b/code/modules/cards/deck/deck.dm
@@ -21,8 +21,6 @@
var/decksize = INFINITY
/// The description of the cardgame that is played with this deck (used for memories)
var/cardgame_desc = "card game"
- /// Wielding status for holding with two hands
- var/wielded = FALSE
/// The holodeck computer used to spawn a holographic deck (see /obj/item/toy/cards/deck/syndicate/holographic)
var/obj/machinery/computer/holodeck/holodeck
/// If the cards in the deck have different card faces icons (blank and CAS decks do not)
@@ -33,8 +31,6 @@
/obj/item/toy/cards/deck/Initialize(mapload)
. = ..()
AddElement(/datum/element/drag_pickup)
- RegisterSignal(src, COMSIG_TWOHANDED_WIELD, PROC_REF(on_wield))
- RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, PROC_REF(on_unwield))
AddComponent(/datum/component/two_handed, attacksound='sound/items/cardflip.ogg')
register_context()
@@ -51,18 +47,6 @@
for(var/person in list("Jack", "Queen", "King"))
initial_cards += "[person] of [suit]"
-/// triggered on wield of two handed item
-/obj/item/toy/cards/deck/proc/on_wield(obj/item/source, mob/user)
- SIGNAL_HANDLER
-
- wielded = TRUE
-
-/// triggered on unwield of two handed item
-/obj/item/toy/cards/deck/proc/on_unwield(obj/item/source, mob/user)
- SIGNAL_HANDLER
-
- wielded = FALSE
-
/obj/item/toy/cards/deck/suicide_act(mob/living/carbon/user)
user.visible_message(span_suicide("[user] is slitting [user.p_their()] wrists with \the [src]! It looks like their luck ran out!"))
playsound(src, 'sound/items/cardshuffle.ogg', 50, TRUE)
@@ -87,7 +71,7 @@
/obj/item/toy/cards/deck/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
if(src == held_item)
var/obj/item/toy/cards/deck/dealer_deck = held_item
- context[SCREENTIP_CONTEXT_LMB] = dealer_deck.wielded ? "Recycle mode" : "Dealer mode"
+ context[SCREENTIP_CONTEXT_LMB] = HAS_TRAIT(dealer_deck, TRAIT_WIELDED) ? "Recycle mode" : "Dealer mode"
context[SCREENTIP_CONTEXT_ALT_LMB] = "Shuffle"
return CONTEXTUAL_SCREENTIP_SET
@@ -161,7 +145,7 @@
/obj/item/toy/cards/deck/AltClick(mob/living/user)
if(user.can_perform_action(src, NEED_DEXTERITY|FORBID_TELEKINESIS_REACH))
- if(wielded)
+ if(HAS_TRAIT(src, TRAIT_WIELDED))
shuffle_cards(user)
else
to_chat(user, span_notice("You must hold the [src] with both hands to shuffle."))
diff --git a/code/modules/cards/deck/tarot.dm b/code/modules/cards/deck/tarot.dm
index ced067c0c39..3dcdc8608c6 100644
--- a/code/modules/cards/deck/tarot.dm
+++ b/code/modules/cards/deck/tarot.dm
@@ -36,8 +36,16 @@
/// ghost notification cooldown
COOLDOWN_DECLARE(ghost_alert_cooldown)
-/obj/item/toy/cards/deck/tarot/haunted/on_wield(obj/item/source, mob/living/carbon/user)
+/obj/item/toy/cards/deck/tarot/haunted/Initialize(mapload)
. = ..()
+ AddComponent( \
+ /datum/component/two_handed, \
+ attacksound = 'sound/items/cardflip.ogg', \
+ wield_callback = CALLBACK(src, PROC_REF(on_wield)), \
+ unwield_callback = CALLBACK(src, PROC_REF(on_unwield)), \
+ )
+
+/obj/item/toy/cards/deck/tarot/haunted/proc/on_wield(obj/item/source, mob/living/carbon/user)
ADD_TRAIT(user, TRAIT_SIXTHSENSE, MAGIC_TRAIT)
to_chat(user, span_notice("The veil to the underworld is opened. You can sense the dead souls calling out..."))
@@ -54,15 +62,8 @@
action = NOTIFY_ORBIT,
)
-/obj/item/toy/cards/deck/tarot/haunted/on_unwield(obj/item/source, mob/living/carbon/user)
- . = ..()
+/obj/item/toy/cards/deck/tarot/haunted/proc/on_unwield(obj/item/source, mob/living/carbon/user)
REMOVE_TRAIT(user, TRAIT_SIXTHSENSE, MAGIC_TRAIT)
to_chat(user, span_notice("The veil to the underworld closes shut. You feel your senses returning to normal."))
-/obj/item/toy/cards/deck/tarot/haunted/dropped(mob/living/carbon/user, silent)
- . = ..()
- if(wielded)
- REMOVE_TRAIT(user, TRAIT_SIXTHSENSE, MAGIC_TRAIT)
- to_chat(user, span_notice("The veil to the underworld closes shut. You feel your senses returning to normal."))
-
#undef TAROT_GHOST_TIMER
diff --git a/code/modules/cards/singlecard.dm b/code/modules/cards/singlecard.dm
index b918d7708ca..169715c51d9 100644
--- a/code/modules/cards/singlecard.dm
+++ b/code/modules/cards/singlecard.dm
@@ -78,7 +78,7 @@
if(istype(held_item, /obj/item/toy/cards/deck))
var/obj/item/toy/cards/deck/dealer_deck = held_item
- if(dealer_deck.wielded)
+ if(HAS_TRAIT(dealer_deck, TRAIT_WIELDED))
context[SCREENTIP_CONTEXT_LMB] = "Deal card"
context[SCREENTIP_CONTEXT_RMB] = "Deal card faceup"
return CONTEXTUAL_SCREENTIP_SET
@@ -151,7 +151,7 @@
if(istype(item, /obj/item/toy/cards/deck))
var/obj/item/toy/cards/deck/dealer_deck = item
- if(!dealer_deck.wielded) // recycle card into deck (if unwielded)
+ if(!HAS_TRAIT(dealer_deck, TRAIT_WIELDED)) // recycle card into deck (if unwielded)
dealer_deck.insert(src)
user.balloon_alert_to_viewers("puts card in deck")
return
diff --git a/code/modules/cargo/exports/tools.dm b/code/modules/cargo/exports/tools.dm
index 7dbeb70fa0e..94e9c264365 100644
--- a/code/modules/cargo/exports/tools.dm
+++ b/code/modules/cargo/exports/tools.dm
@@ -99,7 +99,7 @@
/datum/export/weldingtool/experimental
cost = CARGO_CRATE_VALUE * 0.45
unit_name = "experimental welding tool"
- export_types = list(/obj/item/weldingtool/electric) //SKYRAT EDIT CHANGE - ELECTRIC WELDER
+ export_types = list(/obj/item/weldingtool/experimental)
/datum/export/jawsoflife
cost = CARGO_CRATE_VALUE * 0.5
diff --git a/code/modules/cargo/goodies.dm b/code/modules/cargo/goodies.dm
index 6fc900ce183..69677e87df5 100644
--- a/code/modules/cargo/goodies.dm
+++ b/code/modules/cargo/goodies.dm
@@ -3,7 +3,7 @@
access = NONE
group = "Goodies"
goody = TRUE
-/* // SKYRAT EDIT START - CARGO GUN
+
/datum/supply_pack/goody/dumdum38
name = ".38 DumDum Speedloader"
desc = "Contains one speedloader of .38 DumDum ammunition, good for embedding in soft targets."
@@ -31,7 +31,6 @@
cost = PAYCHECK_CREW * 40 //they really mean a premium here
access_view = ACCESS_WEAPONS
contains = list(/obj/item/gun/ballistic/revolver/c38/detective)
-*/ //SKYRAT EDIT END
/datum/supply_pack/goody/stingbang
name = "Stingbang Single-Pack"
@@ -40,7 +39,6 @@
access_view = ACCESS_WEAPONS
contains = list(/obj/item/grenade/stingbang)
-/* //SKYRAT EDIT START - GUN CARGO
/datum/supply_pack/goody/Survivalknives_single
name = "Survival Knife Single-Pack"
desc = "Contains one sharpened survival knive. Guaranteed to fit snugly inside any Nanotrasen-standard boot."
@@ -88,7 +86,6 @@
cost = PAYCHECK_COMMAND * 15
access_view = ACCESS_WEAPONS
contains = list(/obj/item/storage/belt/holster/energy/thermal)
-*/ //SKYRAT EDIT END
/datum/supply_pack/goody/sologamermitts
name = "Insulated Gloves Single-Pack"
@@ -162,15 +159,11 @@
cost = PAYCHECK_COMMAND * 4
contains = list(/obj/item/dog_bone)
-// SKYRAT EDIT REMOVAL BEGIN
-/*
/datum/supply_pack/goody/dyespray
name = "Hair Dye Spray"
desc = "A cool spray to dye your hair with awesome colors!"
cost = PAYCHECK_CREW * 2
contains = list(/obj/item/dyespray)
-*/
-// SKYRAT EDIT REMOVAL END
/datum/supply_pack/goody/beach_ball
name = "Beach Ball"
@@ -278,3 +271,9 @@
desc = "A standard-sized coffeepot, for use with a coffeemaker."
cost = PAYCHECK_CREW
contains = list(/obj/item/reagent_containers/cup/coffeepot)
+
+/datum/supply_pack/goody/climbing_hook
+ name = "Climbing hook"
+ desc = "A less cheap imported climbing hook. Absolutely no use outside of planetary stations."
+ cost = PAYCHECK_CREW * 5
+ contains = list(/obj/item/climbing_hook)
diff --git a/code/modules/cargo/markets/market_items/weapons.dm b/code/modules/cargo/markets/market_items/weapons.dm
index f40e4fa1447..6115b1e1557 100644
--- a/code/modules/cargo/markets/market_items/weapons.dm
+++ b/code/modules/cargo/markets/market_items/weapons.dm
@@ -63,3 +63,13 @@
price_max = CARGO_CRATE_VALUE * 2
stock_max = 2
availability_prob = 50
+
+/datum/market_item/weapon/fisher
+ name = "SC/FISHER Saboteur Handgun"
+ desc = "A self-recharging, compact pistol that disrupts flashlights and security cameras, if only temporarily. Also usable in melee."
+ item = /obj/item/gun/energy/recharge/fisher
+
+ price_min = CARGO_CRATE_VALUE * 2
+ price_max = CARGO_CRATE_VALUE * 4
+ stock_max = 1
+ availability_prob = 50
diff --git a/code/modules/cargo/orderconsole.dm b/code/modules/cargo/orderconsole.dm
index 1fe61a4172e..2c815a803b6 100644
--- a/code/modules/cargo/orderconsole.dm
+++ b/code/modules/cargo/orderconsole.dm
@@ -274,11 +274,6 @@
if(order.applied_coupon)
say("Coupon refunded.")
order.applied_coupon.forceMove(get_turf(src))
- //SKYRAT EDIT START
- if(istype(order, /datum/supply_order/company_import))
- var/datum/supply_order/company_import/the_order = order
- the_order.reimburse_armament()
- //SKYRAT EDIT END
SSshuttle.shopping_list -= order
. = TRUE
break
@@ -426,12 +421,6 @@
if("toggleprivate")
self_paid = !self_paid
. = TRUE
- //SKYRAT EDIT START
- if("company_import_window")
- var/datum/component/armament/company_imports/company_import_component = GetComponent(/datum/component/armament/company_imports)
- company_import_component.ui_interact(usr)
- . = TRUE
- //SKYRAT EDIT END
if(.)
post_signal(cargo_shuttle)
diff --git a/code/modules/cargo/packs/costumes_toys.dm b/code/modules/cargo/packs/costumes_toys.dm
index 298c3c3c1f4..6ac7ee5095d 100644
--- a/code/modules/cargo/packs/costumes_toys.dm
+++ b/code/modules/cargo/packs/costumes_toys.dm
@@ -158,6 +158,12 @@
crate_name = "standard costume crate"
crate_type = /obj/structure/closet/crate/wooden
+/datum/supply_pack/costumes_toys/costume/fill(obj/structure/closet/crate/C)
+ ..()
+ var/funny_gas_internals
+ funny_gas_internals = pick(subtypesof(/obj/item/tank/internals/emergency_oxygen/engi/clown) - /obj/item/tank/internals/emergency_oxygen/engi/clown)
+ new funny_gas_internals(C)
+
/datum/supply_pack/costumes_toys/randomised/toys
name = "Toy Crate"
desc = "Who cares about pride and accomplishment? Skip the gaming and get straight \
diff --git a/code/modules/cargo/packs/emergency.dm b/code/modules/cargo/packs/emergency.dm
index 9c50372b6a8..fca1a201ac1 100644
--- a/code/modules/cargo/packs/emergency.dm
+++ b/code/modules/cargo/packs/emergency.dm
@@ -117,8 +117,6 @@
contains = list(/obj/item/clothing/head/utility/radiation = 2,
/obj/item/clothing/suit/utility/radiation = 2,
/obj/item/geiger_counter = 2,
- /obj/item/clothing/suit/utility/radiation,
- /obj/item/geiger_counter,
/obj/item/reagent_containers/cup/glass/bottle/vodka,
/obj/item/reagent_containers/cup/glass/drinkingglass/shotglass = 2,
)
diff --git a/code/modules/cargo/packs/general.dm b/code/modules/cargo/packs/general.dm
index 73f958c0144..5ebdd5087a8 100644
--- a/code/modules/cargo/packs/general.dm
+++ b/code/modules/cargo/packs/general.dm
@@ -75,7 +75,6 @@
contains = list(/obj/item/fish_analyzer = 3)
crate_name = "fish analyzers crate"
-/* SKYRAT REMOVAL
/datum/supply_pack/misc/bicycle
name = "Bicycle"
desc = "Nanotrasen reminds all employees to never toy with powers outside their control."
@@ -83,7 +82,6 @@
contains = list(/obj/vehicle/ridden/bicycle)
crate_name = "bicycle crate"
crate_type = /obj/structure/closet/crate/large
-SKYRAT REMOVAL END */
/datum/supply_pack/misc/bigband
name = "Big Band Instrument Collection"
diff --git a/code/modules/cargo/packs/medical.dm b/code/modules/cargo/packs/medical.dm
index 04ff558605e..430c32a35ab 100644
--- a/code/modules/cargo/packs/medical.dm
+++ b/code/modules/cargo/packs/medical.dm
@@ -129,7 +129,7 @@
contains = list(
/obj/item/storage/backpack/duffelbag/med/surgery,
/obj/item/reagent_containers/medigel/sterilizine,
- /obj/item/roller,
+ /obj/item/emergency_bed,
)
crate_name = "surgical supplies crate"
diff --git a/code/modules/cargo/packs/organic.dm b/code/modules/cargo/packs/organic.dm
index 38b8292fe80..73c98cb4b3a 100644
--- a/code/modules/cargo/packs/organic.dm
+++ b/code/modules/cargo/packs/organic.dm
@@ -47,6 +47,7 @@
/obj/item/food/spiderleg,
/obj/item/food/fishmeat/carp,
/obj/item/food/meat/slab/human,
+ /obj/item/food/meat/slab/grassfed,
)
crate_name = "food crate"
@@ -61,18 +62,20 @@
including one replica-pod seed and two mystery seeds!"
cost = CARGO_CRATE_VALUE * 3
access_view = ACCESS_HYDROPONICS
- contains = list(/obj/item/seeds/nettle,
- /obj/item/seeds/replicapod,
- /obj/item/seeds/plump,
- /obj/item/seeds/liberty,
- /obj/item/seeds/amanita,
- /obj/item/seeds/reishi,
- /obj/item/seeds/bamboo,
- /obj/item/seeds/eggplant/eggy,
- /obj/item/seeds/rainbow_bunch,
- /obj/item/seeds/shrub,
- /obj/item/seeds/random = 2,
- )
+ contains = list(
+ /obj/item/seeds/amanita,
+ /obj/item/seeds/bamboo,
+ /obj/item/seeds/eggplant/eggy,
+ /obj/item/seeds/liberty,
+ /obj/item/seeds/nettle,
+ /obj/item/seeds/plump,
+ /obj/item/seeds/replicapod,
+ /obj/item/seeds/reishi,
+ /obj/item/seeds/rainbow_bunch,
+ /obj/item/seeds/seedling,
+ /obj/item/seeds/shrub,
+ /obj/item/seeds/random = 2,
+ )
crate_name = "exotic seeds crate"
crate_type = /obj/structure/closet/crate/hydroponics
diff --git a/code/modules/cargo/packs/security.dm b/code/modules/cargo/packs/security.dm
index ac0d92235ba..7abe5f7601e 100644
--- a/code/modules/cargo/packs/security.dm
+++ b/code/modules/cargo/packs/security.dm
@@ -3,8 +3,6 @@
access = ACCESS_SECURITY
crate_type = /obj/structure/closet/crate/secure/gear
-// SKYRAT EDIT REMOVAL BEGIN - CARGO ARMAMENTS
-/*
/datum/supply_pack/security/ammo
name = "Ammo Crate"
desc = "Contains three boxes of beanbag shotgun shells, three boxes \
@@ -18,11 +16,7 @@
/obj/item/ammo_box/c38/iceblox,
)
crate_name = "ammo crate"
-*/
-// SKYRAT EDIT REMOVAL END
-// SKYRAT EDIT REMOVAL BEGIN - Moved to modular
-/*
/datum/supply_pack/security/armor
name = "Armor Crate"
desc = "Three vests of well-rounded, decently-protective armor."
@@ -30,13 +24,11 @@
access_view = ACCESS_SECURITY
contains = list(/obj/item/clothing/suit/armor/vest = 3)
crate_name = "armor crate"
-*/
-// SKYRAT EDIT REMOVAL END
/datum/supply_pack/security/disabler
name = "Disabler Crate"
desc = "Three stamina-draining disabler weapons."
- cost = CARGO_CRATE_VALUE * 5 //SKYRAT EDIT 3 -> 5
+ cost = CARGO_CRATE_VALUE * 3
access_view = ACCESS_SECURITY
contains = list(/obj/item/gun/energy/disabler = 3)
crate_name = "disabler crate"
@@ -57,8 +49,6 @@
)
crate_name = "forensics crate"
-// SKYRAT EDIT REMOVAL BEGIN - Moved to modular
-/*
/datum/supply_pack/security/helmets
name = "Helmets Crate"
desc = "Contains three standard-issue brain buckets."
@@ -73,8 +63,6 @@
access_view = ACCESS_ARMORY
contains = list(/obj/item/gun/energy/laser = 3)
crate_name = "laser crate"
-*/
-// SKYRAT EDIT REMOVAL END
/datum/supply_pack/security/securitybarriers
name = "Security Barrier Grenades"
@@ -84,8 +72,6 @@
cost = CARGO_CRATE_VALUE * 2
crate_name = "security barriers crate"
-// SKYRAT EDIT REMOVAL BEGIN - SEC_HAUL
-/*
/datum/supply_pack/security/securityclothes
name = "Security Clothing Crate"
desc = "Contains appropriate outfits for the station's private security force. \
@@ -104,8 +90,6 @@
/obj/item/clothing/head/hats/hos/beret/navyhos,
)
crate_name = "security clothing crate"
-*/
-// SKYRAT EDIT REMOVAL END
/datum/supply_pack/security/stingpack
name = "Stingbang Grenade Pack"
@@ -215,8 +199,6 @@
contains = list(/obj/item/storage/box/chemimp)
crate_name = "chemical implant crate"
-// SKYRAT EDIT REMOVAL BEGIN - CARGO ARMAMENTS
-/*
/datum/supply_pack/security/armory/ballistic
name = "Combat Shotguns Crate"
desc = "For when the enemy absolutely needs to be replaced with lead. \
@@ -225,8 +207,6 @@
contains = list(/obj/item/gun/ballistic/shotgun/automatic/combat = 3,
/obj/item/storage/belt/bandolier = 3)
crate_name = "combat shotguns crate"
-*/
-// SKYRAT EDIT REMOVAL END
/datum/supply_pack/security/armory/dragnet
name = "DRAGnet Crate"
@@ -236,8 +216,6 @@
contains = list(/obj/item/gun/energy/e_gun/dragnet = 3)
crate_name = "\improper DRAGnet crate"
-// SKYRAT EDIT REMOVAL BEGIN - CARGO ARMAMENTS
-/*
/datum/supply_pack/security/armory/energy
name = "Energy Guns Crate"
desc = "Contains two Energy Guns, capable of firing both nonlethal and lethal \
@@ -246,8 +224,6 @@
contains = list(/obj/item/gun/energy/e_gun = 2)
crate_name = "energy gun crate"
crate_type = /obj/structure/closet/crate/secure/plasma
-*/
-// SKYRAT EDIT REMOVAL END
/datum/supply_pack/security/armory/exileimp
name = "Exile Implants Crate"
@@ -333,8 +309,6 @@
)
crate_name = "swat crate"
-// SKYRAT EDIT REMOVAL BEGIN - CARGO ARMAMENTS
-/*
/datum/supply_pack/security/armory/thermal
name = "Thermal Pistol Crate"
desc = "Contains a pair of holsters each with two experimental thermal pistols, \
@@ -342,8 +316,6 @@
cost = CARGO_CRATE_VALUE * 7
contains = list(/obj/item/storage/belt/holster/energy/thermal = 2)
crate_name = "thermal pistol crate"
-*/
-// SKYRAT EDIT REMOVAL END
/datum/supply_pack/security/sunglasses
name = "Sunglasses Crate"
diff --git a/code/modules/cargo/packs/service.dm b/code/modules/cargo/packs/service.dm
index a0582af3519..8c84864a802 100644
--- a/code/modules/cargo/packs/service.dm
+++ b/code/modules/cargo/packs/service.dm
@@ -162,8 +162,6 @@
crate_name = "shaft miner starter kit"
crate_type = /obj/structure/closet/crate/secure
-// SKYRAT EDIT REMOVAL BEGIN - GUN CARGO
-/*
/datum/supply_pack/service/survivalknives
name = "Survival Knives Crate"
desc = "Contains three sharpened survival knives. Each knife guaranteed to fit snugly \
@@ -171,8 +169,6 @@
cost = CARGO_CRATE_VALUE * 3
contains = list(/obj/item/knife/combat/survival = 3)
crate_name = "survival knife crate"
-*/
-// SKYRAT EDIT REMOVAL END
/datum/supply_pack/service/wedding
name = "Wedding Crate"
diff --git a/code/modules/cargo/packs/vending_restock.dm b/code/modules/cargo/packs/vending_restock.dm
index b659203b416..cfe9961cc3a 100644
--- a/code/modules/cargo/packs/vending_restock.dm
+++ b/code/modules/cargo/packs/vending_restock.dm
@@ -89,8 +89,6 @@
contains = list(/obj/item/vending_refill/cart)
crate_name = "\improper PTech supply crate"
-// SKYRAT EDIT REMOVAL BEGIN - SEC_HAUL
-/*
/datum/supply_pack/vending/sectech
name = "SecTech Supply Crate"
desc = "Officer Paul bought all the donuts? Then refill the security \
@@ -100,8 +98,6 @@
contains = list(/obj/item/vending_refill/security)
crate_name = "\improper SecTech supply crate"
crate_type = /obj/structure/closet/crate/secure/gear
-*/
-// SKYRAT EDIT REMOVAL END
/datum/supply_pack/vending/snack
name = "Snack Supply Crate"
@@ -211,8 +207,6 @@
)
crate_name = "science department wardrobe supply crate"
-// SKYRAT EDIT REMOVAL BEGIN - SEC_HAUL
-/*
/datum/supply_pack/vending/wardrobes/security
name = "Security Wardrobe Supply Crate"
desc = "This crate contains refills for the SecDrobe, \
@@ -223,5 +217,3 @@
/obj/item/vending_refill/wardrobe/law_wardrobe,
)
crate_name = "security department supply crate"
-*/
-// SKYRAT EDIT REMOVAL END
diff --git a/code/modules/cargo/supplypod_beacon.dm b/code/modules/cargo/supplypod_beacon.dm
index 436a0ca6b93..89c474635fa 100644
--- a/code/modules/cargo/supplypod_beacon.dm
+++ b/code/modules/cargo/supplypod_beacon.dm
@@ -7,11 +7,17 @@
lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi'
w_class = WEIGHT_CLASS_SMALL
+ armor_type = /datum/armor/supplypod_beacon
+ resistance_flags = FIRE_PROOF
var/obj/machinery/computer/cargo/express/express_console
var/linked = FALSE
var/ready = FALSE
var/launched = FALSE
+/datum/armor/supplypod_beacon
+ bomb = 100
+ fire = 100
+
/obj/item/supplypod_beacon/proc/update_status(consoleStatus)
switch(consoleStatus)
if (SP_LINKED)
@@ -49,6 +55,7 @@
/obj/item/supplypod_beacon/examine(user)
. = ..()
+ . += span_notice("It looks like it has a few anchoring bolts.")
if(!express_console)
. += span_notice("[src] is not currently linked to an Express Supply console.")
else
@@ -59,6 +66,11 @@
express_console.beacon = null
return ..()
+/obj/item/supplypod_beacon/wrench_act(mob/living/user, obj/item/tool)
+ . = ..()
+ default_unfasten_wrench(user, tool)
+ return TOOL_ACT_TOOLTYPE_SUCCESS
+
/obj/item/supplypod_beacon/proc/unlink_console()
if(express_console)
express_console.beacon = null
diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm
index c3c6bd24425..2e655e91651 100644
--- a/code/modules/client/client_defines.dm
+++ b/code/modules/client/client_defines.dm
@@ -160,8 +160,6 @@
///Autoclick list of two elements, first being the clicked thing, second being the parameters.
var/list/atom/selected_target[2]
- ///Autoclick variable referencing the associated item.
- var/obj/item/active_mousedown_item = null
///Used in MouseDrag to preserve the original mouse click parameters
var/mouseParams = ""
///Used in MouseDrag to preserve the last mouse-entered location. Weakref
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index 407b60074b1..a722272561e 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -598,7 +598,6 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
send2adminchat("Server", "[cheesy_message] (No admins online)")
QDEL_LIST_ASSOC_VAL(char_render_holders)
- active_mousedown_item = null
SSambience.remove_ambience_client(src)
SSmouse_entered.hovers -= src
SSping.currentrun -= src
diff --git a/code/modules/client/preferences/operative_species.dm b/code/modules/client/preferences/operative_species.dm
new file mode 100644
index 00000000000..0b55bc23b52
--- /dev/null
+++ b/code/modules/client/preferences/operative_species.dm
@@ -0,0 +1,23 @@
+/// When TRUE, will spawn you as a human when selected for an operative role
+/// When FALSE, players will be placed into the game as their character's species
+/datum/preference/toggle/nuke_ops_species
+ category = PREFERENCE_CATEGORY_NON_CONTEXTUAL
+ can_randomize = FALSE
+ default_value = TRUE
+ savefile_identifier = PREFERENCE_CHARACTER
+ savefile_key = "operative_species"
+
+/datum/preference/toggle/nuke_ops_species/is_accessible(datum/preferences/preferences)
+ . = ..()
+ if(!.)
+ return FALSE
+
+ // If one of the roles is ticked in the antag prefs menu, this option will show.
+ var/static/list/ops_roles = list(ROLE_OPERATIVE, ROLE_LONE_OPERATIVE, ROLE_OPERATIVE_MIDROUND, ROLE_CLOWN_OPERATIVE)
+ if(length(ops_roles & preferences.be_special))
+ return TRUE
+
+ return FALSE
+
+/datum/preference/toggle/nuke_ops_species/apply_to_human(mob/living/carbon/human/target, value)
+ return
diff --git a/code/modules/client/preferences/sounds.dm b/code/modules/client/preferences/sounds.dm
index 21a549f522b..f56430b5363 100644
--- a/code/modules/client/preferences/sounds.dm
+++ b/code/modules/client/preferences/sounds.dm
@@ -50,6 +50,22 @@
/datum/preference/numeric/sound_tts_volume/create_default_value()
return maximum
+/datum/preference/choiced/sound_achievement
+ category = PREFERENCE_CATEGORY_GAME_PREFERENCES
+ savefile_key = "sound_achievement"
+ savefile_identifier = PREFERENCE_PLAYER
+
+/datum/preference/choiced/sound_achievement/init_possible_values()
+ return list(CHEEVO_SOUND_PING, CHEEVO_SOUND_JINGLE, CHEEVO_SOUND_TADA, CHEEVO_SOUND_OFF)
+
+/datum/preference/choiced/sound_achievement/create_default_value()
+ return CHEEVO_SOUND_PING
+
+/datum/preference/choiced/sound_achievement/apply_to_client_updated(client/client, value)
+ var/sound/sound_to_send = LAZYACCESS(GLOB.achievement_sounds, value)
+ if(sound_to_send)
+ SEND_SOUND(client.mob, sound_to_send)
+
/// Controls hearing dance machines
/datum/preference/toggle/sound_jukebox
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
diff --git a/code/modules/clothing/belts/polymorph_belt.dm b/code/modules/clothing/belts/polymorph_belt.dm
index f6ccccae971..e63e2c3bee3 100644
--- a/code/modules/clothing/belts/polymorph_belt.dm
+++ b/code/modules/clothing/belts/polymorph_belt.dm
@@ -60,8 +60,8 @@
if (!isanimal_or_basicmob(target_mob))
balloon_alert(user, "target too complex!")
return TRUE
- if (!(target_mob.mob_biotypes & MOB_ORGANIC))
- balloon_alert(user, "organic life only!")
+ if (target_mob.mob_biotypes & (MOB_HUMANOID|MOB_ROBOTIC|MOB_SPECIAL|MOB_SPIRIT|MOB_UNDEAD))
+ balloon_alert(user, "incompatible!")
return TRUE
if (isanimal_or_basicmob(target_mob))
if (!target_mob.compare_sentience_type(SENTIENCE_ORGANIC))
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index 26792014fff..486f44f3504 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -1,5 +1,3 @@
-#define MOTH_EATING_CLOTHING_DAMAGE 15
-
/obj/item/clothing
name = "clothing"
resistance_flags = FLAMMABLE
@@ -108,11 +106,15 @@
if((clothing_flags & INEDIBLE_CLOTHING) || (resistance_flags & INDESTRUCTIBLE))
return ..()
if(isnull(moth_snack))
- moth_snack = new
- moth_snack.name = name
- moth_snack.clothing = WEAKREF(src)
+ create_moth_snack()
moth_snack.attack(target, user, params)
+/// Creates a food object in null space which we can eat and imagine we're eating this pair of shoes
+/obj/item/clothing/proc/create_moth_snack()
+ moth_snack = new
+ moth_snack.name = name
+ moth_snack.clothing = WEAKREF(src)
+
/obj/item/clothing/attackby(obj/item/W, mob/user, params)
if(!istype(W, repairable_by))
return ..()
@@ -544,8 +546,6 @@ BLIND // can't see anything
if(prob(0.2))
to_chat(L, span_warning("The damaged threads on your [src.name] chafe!"))
-#undef MOTH_EATING_CLOTHING_DAMAGE
-
/obj/item/clothing/apply_fantasy_bonuses(bonus)
. = ..()
set_armor(get_armor().generate_new_with_modifiers(list(ARMOR_ALL = bonus)))
diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm
index 688b63bddbb..fc665e57c8f 100644
--- a/code/modules/clothing/glasses/_glasses.dm
+++ b/code/modules/clothing/glasses/_glasses.dm
@@ -195,6 +195,7 @@
base_icon_state = "eyepatch"
inhand_icon_state = null
actions_types = list(/datum/action/item_action/flip)
+ dog_fashion = /datum/dog_fashion/head/eyepatch
/obj/item/clothing/glasses/eyepatch/attack_self(mob/user, modifiers)
. = ..()
diff --git a/code/modules/clothing/head/garlands.dm b/code/modules/clothing/head/garlands.dm
index 09a7a7532ca..4de0604044e 100644
--- a/code/modules/clothing/head/garlands.dm
+++ b/code/modules/clothing/head/garlands.dm
@@ -12,3 +12,42 @@
/obj/item/clothing/head/costume/garland/dropped(mob/living/user)
. = ..()
user.clear_mood_event("garland")
+
+/obj/item/clothing/head/costume/garland/rainbowbunch
+ name = "rainbow flower crown"
+ desc = "A flower crown made out of the flowers of the rainbow bunch plant."
+ icon_state = "rainbow_bunch_crown_1"
+ base_icon_state = "rainbow_bunch_crown"
+
+/obj/item/clothing/head/costume/garland/rainbowbunch/Initialize(mapload)
+ . = ..()
+ var/crown_type = rand(1,4)
+ icon_state = "[base_icon_state]_[crown_type]"
+ switch(crown_type)
+ if(1)
+ desc += " This one has red, yellow, and white flowers."
+ if(2)
+ desc += " This one has blue, yellow, green, and white flowers."
+ if(3)
+ desc += " This one has red, blue, purple, and pink flowers."
+ if(4)
+ desc += " This one has yellow, green, and white flowers."
+
+/obj/item/clothing/head/costume/garland/sunflower
+ name = "sunflower crown"
+ desc = "A bright flower crown made out sunflowers that is sure to brighten up anyone's day!"
+ icon_state = "sunflower_crown"
+ worn_icon_state = "sunflower_crown"
+
+/obj/item/clothing/head/costume/garland/poppy
+ name = "poppy crown"
+ desc = "A flower crown made out of a string of bright red poppies."
+ icon_state = "poppy_crown"
+ worn_icon_state = "poppy_crown"
+
+/obj/item/clothing/head/costume/garland/lily
+ name = "lily crown"
+ desc = "A leafy flower crown with a cluster of large white lilies at at the front."
+ icon_state = "lily_crown"
+ worn_icon_state = "lily_crown"
+
diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm
index 0259cb96ae8..2d3f5c79e62 100644
--- a/code/modules/clothing/head/jobs.dm
+++ b/code/modules/clothing/head/jobs.dm
@@ -206,6 +206,116 @@
/obj/item/clothing/head/fedora/det_hat/minor
flask_path = /obj/item/reagent_containers/cup/glass/flask/det/minor
+///Detectives Fedora, but like Inspector Gadget. Not a subtype to not inherit candy corn stuff
+/obj/item/clothing/head/fedora/inspector_hat
+ name = "inspector's fedora"
+ desc = "There's only one man can try to stop an evil villian."
+ armor_type = /datum/armor/fedora_det_hat
+ icon_state = "detective"
+ inhand_icon_state = "det_hat"
+ dog_fashion = /datum/dog_fashion/head/detective
+ ///prefix our phrases must begin with
+ var/prefix = "go go gadget"
+ ///an assoc list of phrase = item (like gun = revolver)
+ var/list/items_by_phrase = list()
+ ///how many gadgets can we hold
+ var/max_items = 4
+ ///items above this weight cannot be put in the hat
+ var/max_weight = WEIGHT_CLASS_NORMAL
+
+/obj/item/clothing/head/fedora/inspector_hat/Initialize(mapload)
+ . = ..()
+ become_hearing_sensitive(ROUNDSTART_TRAIT)
+ QDEL_NULL(atom_storage)
+
+/obj/item/clothing/head/fedora/inspector_hat/examine(mob/user)
+ . = ..()
+ . += span_notice("You can put items inside, and get them out by saying a phrase, or using it in-hand!")
+ . += span_notice("The prefix is [prefix], and you can change it with alt-click!\n")
+ for(var/phrase in items_by_phrase)
+ var/obj/item/item = items_by_phrase[phrase]
+ . += span_notice("[icon2html(item, user)] You can remove [item] by saying \"[prefix] [phrase]\"!")
+
+/obj/item/clothing/head/fedora/inspector_hat/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, list/message_mods = list(), message_range)
+ . = ..()
+ var/mob/living/carbon/wearer = loc
+ if(!istype(wearer) || speaker != wearer) //if we are worn
+ return FALSE
+
+ raw_message = htmlrendertext(raw_message)
+ 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)
+ return FALSE
+
+ if(wearer.put_in_active_hand(result))
+ wearer.visible_message(span_warning("[src] drops [result] into the hands of [wearer]!"))
+ else
+ balloon_alert(wearer, "cant put in hands!")
+
+ return TRUE
+
+/obj/item/clothing/head/fedora/inspector_hat/attackby(obj/item/item, mob/user, params)
+ . = ..()
+
+ if(LAZYLEN(contents) >= max_items)
+ balloon_alert(user, "full!")
+ return
+ if(item.w_class > max_weight)
+ balloon_alert(user, "too big!")
+ return
+
+ var/input = tgui_input_text(user, "What is the activation phrase?", "Activation phrase", "gadget", max_length = 26)
+ if(!input)
+ return
+ if(input in items_by_phrase)
+ balloon_alert(user, "already used!")
+ return
+
+ if(item.loc != user || !user.transferItemToLoc(item, src))
+ return
+
+ to_chat(user, span_notice("You install [item] into the [thtotext(contents.len)] slot in [src]."))
+ playsound(src, 'sound/machines/click.ogg', 30, TRUE)
+ items_by_phrase[input] = item
+
+/obj/item/clothing/head/fedora/inspector_hat/attack_self(mob/user)
+ . = ..()
+ var/phrase = tgui_input_list(user, "What item do you want to remove by phrase?", "Item Removal", items_by_phrase)
+ if(!phrase)
+ return
+ user.put_in_inactive_hand(items_by_phrase[phrase])
+
+/obj/item/clothing/head/fedora/inspector_hat/AltClick(mob/user)
+ . = ..()
+ var/new_prefix = tgui_input_text(user, "What should be the new prefix?", "Activation prefix", prefix, max_length = 24)
+ if(!new_prefix)
+ return
+ prefix = new_prefix
+
+/obj/item/clothing/head/fedora/inspector_hat/Exited(atom/movable/gone, direction)
+ . = ..()
+ for(var/phrase in items_by_phrase)
+ var/obj/item/result = items_by_phrase[phrase]
+ if(gone == result)
+ items_by_phrase -= phrase
+ return
+
+/obj/item/clothing/head/fedora/inspector_hat/atom_destruction(damage_flag)
+ for(var/phrase in items_by_phrase)
+ var/obj/item/result = items_by_phrase[phrase]
+ result.forceMove(drop_location())
+ items_by_phrase = null
+ return ..()
+
+/obj/item/clothing/head/fedora/inspector_hat/Destroy()
+ QDEL_LIST_ASSOC(items_by_phrase)
+ return ..()
+
//Mime
/obj/item/clothing/head/beret
name = "beret"
@@ -493,7 +603,7 @@
/obj/item/clothing/head/beret/cargo
name = "cargo beret"
desc = "No need to compensate when you can wear this beret!"
- greyscale_colors = "#c99840"
+ greyscale_colors = "#b7723d"
flags_1 = NONE
//Curator
diff --git a/code/modules/clothing/shoes/costume.dm b/code/modules/clothing/shoes/costume.dm
index e591bda1258..1a3e9b0b2be 100644
--- a/code/modules/clothing/shoes/costume.dm
+++ b/code/modules/clothing/shoes/costume.dm
@@ -71,6 +71,24 @@
desc = "t3h c00L3st sh03z j00'LL 3v3r f1nd."
icon_state = "glow_shoes"
inhand_icon_state = null
+ greyscale_colors = "#4A3A40#8EEEEE"
+ greyscale_config = /datum/greyscale_config/glow_shoes
+ greyscale_config_worn = /datum/greyscale_config/glow_shoes/worn
+ flags_1 = IS_PLAYER_COLORABLE_1
+
+/obj/item/clothing/shoes/glow/Initialize(mapload)
+ . = ..()
+ AddElement(/datum/element/gags_recolorable)
+ update_icon(UPDATE_OVERLAYS)
+
+/obj/item/clothing/shoes/glow/worn_overlays(mutable_appearance/standing, isinhands, icon_file)
+ . = ..()
+ if(!isinhands)
+ . += emissive_appearance(DEFAULT_SHOES_FILE, "glow_shoes_emissive", src, alpha = src.alpha)
+
+/obj/item/clothing/shoes/glow/update_overlays()
+ . = ..()
+ . += emissive_appearance('icons/obj/clothing/shoes.dmi', "glow_shoes_emissive", offset_spokesman = src, alpha = src.alpha)
/obj/item/clothing/shoes/jackbros
name = "frosty boots"
diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm
index 1e75acacca6..ceb31b23a28 100644
--- a/code/modules/clothing/spacesuits/plasmamen.dm
+++ b/code/modules/clothing/spacesuits/plasmamen.dm
@@ -436,3 +436,10 @@
desc = "A special containment helmet designed for CentCom Staff. You know, so any coffee spills don't kill the poor sod."
icon_state = "intern_envirohelm"
inhand_icon_state = null
+
+/obj/item/clothing/head/helmet/space/plasmaman/syndie
+ name = "tacticool envirosuit helmet"
+ desc = "There's no doubt about it, this helmet puts you above ALL of the other plasmamen. If you see another plasmaman wearing a helmet like this, it's either because they're a fellow badass, \
+ or they've murdered one of your fellow badasses and have taken it from them as a trophy. Either way, anyone wearing this deserves at least a cursory nod of respect."
+ icon_state = "syndie_envirohelm"
+ inhand_icon_state = null
diff --git a/code/modules/clothing/suits/ablativecoat.dm b/code/modules/clothing/suits/ablativecoat.dm
index 0a6967753e1..8bc37aaba22 100644
--- a/code/modules/clothing/suits/ablativecoat.dm
+++ b/code/modules/clothing/suits/ablativecoat.dm
@@ -4,6 +4,7 @@
worn_icon = 'icons/mob/clothing/head/helmet.dmi'
desc = "Hood hopefully belonging to an ablative trenchcoat. Includes a visor for cool-o-vision."
icon_state = "ablativehood"
+ flags_inv = HIDEHAIR|HIDEEARS
armor_type = /datum/armor/hooded_ablative
strip_delay = 30
var/hit_reflect_chance = 50
diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm
index 1f29d198d53..3ed9be8cb1d 100644
--- a/code/modules/clothing/suits/jobs.dm
+++ b/code/modules/clothing/suits/jobs.dm
@@ -219,19 +219,21 @@
allowed = list(
/obj/item/stamp,
/obj/item/storage/bag/mail,
+ /obj/item/universal_scanner,
)
// Quartermaster
/obj/item/clothing/suit/jacket/quartermaster
- name = "quatermaster's overcoat"
- desc = "A luxury, brown double-breasted overcoat, made from kangaroo skin. It's gold cuffs linked are styled on the credits symbol. It makes you feel more important then you probably are."
+ name = "quartermaster's overcoat"
+ desc = "A luxury, brown double-breasted overcoat made from kangaroo skin. It's gold cuffs are linked and styled on the credits symbol. It makes you feel more important than you probably are."
icon_state = "qm_coat"
blood_overlay_type = "coat"
body_parts_covered = CHEST|GROIN|LEGS|ARMS
allowed = list(
/obj/item/stamp,
/obj/item/storage/bag/mail,
+ /obj/item/universal_scanner,
)
/obj/item/clothing/suit/toggle/lawyer/greyscale
@@ -388,3 +390,35 @@
/obj/item/clothing/suit/jacket/research_director/Initialize(mapload)
. = ..()
allowed += /obj/item/storage/bag/xeno
+
+// Atmos
+/obj/item/clothing/suit/atmos_overalls
+ name = "atmospherics overalls"
+ desc = "A set of fireproof overalls, good for protecting thinner clothes from gas leaks."
+ icon = 'icons/obj/clothing/suits/utility.dmi'
+ worn_icon = 'icons/mob/clothing/suits/utility.dmi'
+ icon_state = "atmos_overalls"
+ inhand_icon_state = ""
+ body_parts_covered = CHEST|GROIN|LEGS
+ resistance_flags = FIRE_PROOF
+ armor_type = /datum/armor/atmos_overalls
+ species_exception = list(/datum/species/golem)
+ allowed = list(
+ /obj/item/analyzer,
+ /obj/item/construction/rcd,
+ /obj/item/fireaxe/metal_h2_axe,
+ /obj/item/pipe_dispenser,
+ /obj/item/storage/bag/construction,
+ /obj/item/t_scanner,
+ /obj/item/tank/internals/emergency_oxygen,
+ /obj/item/tank/internals/plasmaman,
+ )
+
+/datum/armor/atmos_overalls
+ fire = 100
+ acid = 50
+
+/obj/item/clothing/suit/atmos_overalls/worn_overlays(mutable_appearance/standing, isinhands, icon_file)
+ . = ..()
+ if(!isinhands)
+ . += emissive_appearance(icon_file, "[icon_state]-emissive", src, alpha = src.alpha)
diff --git a/code/modules/clothing/suits/shirt.dm b/code/modules/clothing/suits/shirt.dm
index b2c2e9057fb..e291250a580 100644
--- a/code/modules/clothing/suits/shirt.dm
+++ b/code/modules/clothing/suits/shirt.dm
@@ -1,13 +1,17 @@
-/obj/item/clothing/suit/costume/ianshirt
- name = "worn shirt"
- desc = "A worn out, curiously comfortable t-shirt with a picture of Ian. You wouldn't go so far as to say it feels like being hugged when you wear it, but it's pretty close. Good for sleeping in."
- icon_state = "ianshirt"
+/obj/item/clothing/suit/costume/wellworn_shirt
+ name = "well-worn shirt"
+ desc = "A worn out, curiously comfortable t-shirt. You wouldn't go so far as to say it feels like being hugged when you wear it, but it's pretty close. Good for sleeping in."
+ icon_state = "wellworn_shirt"
inhand_icon_state = null
+ greyscale_config = /datum/greyscale_config/wellworn_shirt
+ greyscale_config_worn = /datum/greyscale_config/wellworn_shirt/worn
+ greyscale_colors = "#FFFFFF"
species_exception = list(/datum/species/golem)
+ flags_1 = IS_PLAYER_COLORABLE_1
///How many times has this shirt been washed? (In an ideal world this is just the determinant of the transform matrix.)
var/wash_count = 0
-/obj/item/clothing/suit/costume/ianshirt/machine_wash(obj/machinery/washing_machine/washer)
+/obj/item/clothing/suit/costume/wellworn_shirt/machine_wash(obj/machinery/washing_machine/washer)
. = ..()
if(wash_count <= 5)
transform *= TRANSFORM_USING_VARIABLE(0.8, 1)
@@ -17,9 +21,60 @@
washer.visible_message("[src] implodes due to repeated washing.")
qdel(src)
-/obj/item/clothing/suit/costume/nerdshirt
+/obj/item/clothing/suit/costume/wellworn_shirt/graphic
+ name = "well-worn graphic shirt"
+ desc = "A worn out, curiously comfortable t-shirt with a character from Phanic the Weasel on the front. It adds some charm points to itself and the wearer, and reminds you of when the series was still good; way back in 2500."
+ icon_state = "wellworn_shirt_gamer"
+ greyscale_colors = "#FFFFFF#46B45B"
+ greyscale_config = /datum/greyscale_config/wellworn_shirt_graphic
+ greyscale_config_worn = /datum/greyscale_config/wellworn_shirt_graphic/worn
+
+/obj/item/clothing/suit/costume/wellworn_shirt/graphic/ian
+ name = "well-worn ian shirt"
+ desc = "A worn out, curiously comfortable t-shirt with a picture of Ian the Corgi. You wouldn't go so far as to say it feels like being hugged when you wear it, but it's pretty close. Good for sleeping in."
+ icon_state = "wellworn_shirt_ian"
+ greyscale_colors = "#FFFFFF#E1B26C"
+
+/obj/item/clothing/suit/costume/wellworn_shirt/wornout
+ name = "worn-out shirt"
+ desc = "A pretty grubby, yet still comfortable t-shirt. You've been sleeping in this one for a bit too long."
+ icon_state = "wornout_shirt"
+
+/obj/item/clothing/suit/costume/wellworn_shirt/wornout/graphic
+ name = "worn-out graphic shirt"
+ desc = "A pretty grubby, yet still comfortable t-shirt with a character from Phanic the Weasel on the front. The slightly raggedy nature recalls that one horrid title where they made him a vampire. You should get cheevos for sleeping in it this many days straight."
+ icon_state = "wornout_shirt_gamer"
+ greyscale_colors = "#FFFFFF#46B45B"
+ greyscale_config = /datum/greyscale_config/wornout_shirt_graphic
+ greyscale_config_worn = /datum/greyscale_config/wornout_shirt_graphic/worn
+
+/obj/item/clothing/suit/costume/wellworn_shirt/wornout/graphic/ian
+ name = "worn-out ian shirt"
+ desc = "A pretty grubby, yet still comfortable t-shirt with a picture of Ian the Corgi. It's gone past 'a bit worn' to 'well-loved;' excellent for use as pajamas."
+ icon_state = "wornout_shirt_ian"
+ greyscale_colors = "#FFFFFF#E1B26C"
+
+/obj/item/clothing/suit/costume/wellworn_shirt/messy
+ name = "messy worn-out shirt"
+ desc = "This worn-out, somehow comfortable t-shirt has reached a more thorough understanding of grime; maybe the fact that it's still gone unwashed could function as a sort of camo?"
+ icon_state = "messyworn_shirt"
+
+/obj/item/clothing/suit/costume/wellworn_shirt/messy/graphic
+ name = "messy graphic shirt"
+ desc = "This worn-out, somehow comfortable t-shirt has reached a more thorough understanding of grime. Normies will never understand that this is a collector's item, and your sense of fashion absolutely mogs theirs. Phanic Phorever."
+ icon_state = "messyworn_shirt_gamer"
+ greyscale_colors = "#FFFFFF#46B45B"
+ greyscale_config = /datum/greyscale_config/messyworn_shirt_graphic
+ greyscale_config_worn = /datum/greyscale_config/messyworn_shirt_graphic/worn
+
+/obj/item/clothing/suit/costume/wellworn_shirt/messy/graphic/ian
+ name = "messy ian shirt"
+ desc = "This worn-out, somehow comfortable t-shirt has reached a more thorough understanding of grime. You get the feeling like you understand how it's like to be a stray dog, yet Ian's face still comforts you."
+ icon_state = "messyworn_shirt_ian"
+ greyscale_colors = "#FFFFFF#E1B26C"
+
+/obj/item/clothing/suit/costume/wellworn_shirt/messy/graphic/gamer
name = "gamer shirt"
- desc = "A baggy shirt with vintage game character Phanic the Weasel. Why would anyone wear this?"
- icon_state = "nerdshirt"
- inhand_icon_state = null
- species_exception = list(/datum/species/golem)
+ desc = "A baggy, extremely well-used shirt with vintage game character Phanic the Weasel far-too-boldly displayed on the chest. Your mind cannot hope to withstand the assault of remembering the Phanic Phanart you've seen; let alone the stench of this top."
+ icon_state = "messyworn_shirt_gamer"
+ greyscale_colors = "#FFFFFF#46B45B"
diff --git a/code/modules/clothing/suits/wintercoats.dm b/code/modules/clothing/suits/wintercoats.dm
index a0f6e6d1047..60cbcae1473 100644
--- a/code/modules/clothing/suits/wintercoats.dm
+++ b/code/modules/clothing/suits/wintercoats.dm
@@ -590,6 +590,7 @@
allowed = list(
/obj/item/storage/bag/mail,
/obj/item/stamp,
+ /obj/item/universal_scanner,
)
/obj/item/clothing/head/hooded/winterhood/cargo
diff --git a/code/modules/clothing/under/accessories/medals.dm b/code/modules/clothing/under/accessories/medals.dm
index 90db5198ee6..cc91e286e2c 100644
--- a/code/modules/clothing/under/accessories/medals.dm
+++ b/code/modules/clothing/under/accessories/medals.dm
@@ -178,3 +178,29 @@
/obj/item/clothing/accessory/medal/plasma/nobel_science
name = "nobel sciences award"
desc = "A plasma medal which represents significant contributions to the field of science or engineering."
+
+/obj/item/clothing/accessory/medal/silver/emergency_services
+ name = "emergency services award"
+ desc = "A silver medal awarded to the outstanding emergency service workers of Nanotrasen, those who work tirelessly together through adversity to keep their crew safe and breathing in the harsh environments of outer space."
+ icon_state = "emergencyservices"
+
+ /// Flavor text that is appended to the description.
+ var/insignia_desc = null
+
+/obj/item/clothing/accessory/medal/silver/emergency_services/Initialize(mapload)
+ . = ..()
+ if(istext(insignia_desc))
+ desc += " [insignia_desc]"
+
+/obj/item/clothing/accessory/medal/silver/emergency_services/engineering
+ icon_state = "emergencyservices_engi"
+ insignia_desc = "The back of the medal bears an orange wrench."
+
+/obj/item/clothing/accessory/medal/silver/emergency_services/medical
+ icon_state = "emergencyservices_med"
+ insignia_desc = "The back of the medal bears a dark blue cross."
+
+/obj/item/clothing/accessory/medal/silver/elder_atmosian
+ name = "atmospheric mastery award"
+ desc = "Often referred to as the \"elder atmosian\" award, this medal is awarded to the exemplary scientists and technicians who push the boundaries and demonstrate mastery of atmospherics."
+ icon_state = "elderatmosian"
diff --git a/code/modules/clothing/under/jobs/cargo.dm b/code/modules/clothing/under/jobs/cargo.dm
index 12688a22737..4b2e74bff38 100644
--- a/code/modules/clothing/under/jobs/cargo.dm
+++ b/code/modules/clothing/under/jobs/cargo.dm
@@ -3,7 +3,7 @@
worn_icon = 'icons/mob/clothing/under/cargo.dmi'
/obj/item/clothing/under/rank/cargo/qm
- name = "quartermaster's outfit"
+ name = "quartermaster's uniform"
desc = "A brown dress shirt, coupled with a pair of black slacks. It's specially designed to prevent back injuries caused by pushing paper."
icon_state = "qm"
inhand_icon_state = "lb_suit"
@@ -17,7 +17,7 @@
dying_key = DYE_REGISTRY_JUMPSKIRT
/obj/item/clothing/under/rank/cargo/tech
- name = "cargo technician's outfit"
+ name = "cargo technician's uniform"
desc = "A brown sweater and black jeans, because, honestly, who likes shorts?"
icon_state = "cargotech"
inhand_icon_state = "lb_suit"
@@ -32,7 +32,7 @@
/obj/item/clothing/under/rank/cargo/tech/skirt
name = "cargo technician's skirt"
- desc = "Skiiiiirts! They're comfy and easy to wear!"
+ desc = "A brown sweater and a black skirt to match."
icon_state = "cargo_skirt"
inhand_icon_state = "lb_suit"
body_parts_covered = CHEST|GROIN|ARMS
@@ -40,9 +40,14 @@
dying_key = DYE_REGISTRY_JUMPSKIRT
female_sprite_flags = FEMALE_UNIFORM_TOP_ONLY
+/obj/item/clothing/under/rank/cargo/tech/skirt/alt
+ name = "cargo technician's shortskirt"
+ desc = "I like skiiiiirts! They're comfy and easy to wear!"
+ icon_state = "cargo_skirt_alt"
+
/obj/item/clothing/under/rank/cargo/miner
- desc = "It's a snappy jumpsuit with a sturdy set of overalls. It is very dirty."
name = "shaft miner's jumpsuit"
+ desc = "It's a snappy jumpsuit with a sturdy set of overalls. It is very dirty."
icon_state = "miner"
inhand_icon_state = null
armor_type = /datum/armor/clothing_under/cargo_miner
@@ -53,7 +58,7 @@
wound = 10
/obj/item/clothing/under/rank/cargo/miner/lavaland
- desc = "A green uniform for operating in hazardous environments."
name = "shaft miner's jumpsuit"
+ desc = "A grey uniform for operating in hazardous environments."
icon_state = "explorer"
inhand_icon_state = null
diff --git a/code/modules/clothing/under/syndicate.dm b/code/modules/clothing/under/syndicate.dm
index 0c2ed985ec1..19d5d3b93b2 100644
--- a/code/modules/clothing/under/syndicate.dm
+++ b/code/modules/clothing/under/syndicate.dm
@@ -149,3 +149,11 @@
bio = 50
fire = 50
acid = 40
+
+/obj/item/clothing/under/plasmaman/syndicate
+ name = "tacticool envirosuit"
+ desc = "A sinister looking envirosuit, for the boniest of operatives."
+ icon_state = "syndie_envirosuit"
+ has_sensor = NO_SENSORS
+ resistance_flags = FIRE_PROOF
+ inhand_icon_state = null
diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm
index e1366ed0e04..bd192dbef22 100644
--- a/code/modules/events/_event.dm
+++ b/code/modules/events/_event.dm
@@ -1,5 +1,4 @@
#define RANDOM_EVENT_ADMIN_INTERVENTION_TIME (3 MINUTES) //SKYRAT EDIT CHANGE
-#define NEVER_TRIGGERED_BY_WIZARDS -1
//this singleton datum is used by the events controller to dictate how it selects events
/datum/round_event_control
@@ -344,4 +343,3 @@ Runs the event
return ..()
#undef RANDOM_EVENT_ADMIN_INTERVENTION_TIME
-#undef NEVER_TRIGGERED_BY_WIZARDS
diff --git a/code/modules/events/brain_trauma.dm b/code/modules/events/brain_trauma.dm
index 1e5c09aff48..e063c89e152 100644
--- a/code/modules/events/brain_trauma.dm
+++ b/code/modules/events/brain_trauma.dm
@@ -2,6 +2,7 @@
name = "Spontaneous Brain Trauma"
typepath = /datum/round_event/brain_trauma
weight = 25
+ min_players = 13
category = EVENT_CATEGORY_HEALTH
description = "A crewmember gains a random trauma."
min_wizard_trigger_potency = 2
@@ -20,6 +21,10 @@
continue
if(!(H.mind.assigned_role.job_flags & JOB_CREW_MEMBER)) //please stop giving my centcom admin gimmicks full body paralysis
continue
+ // SKYRAT EDIT ADD START - Station/area event candidate filtering
+ if(engaged_role_play_check(H, station = TRUE, dorms = TRUE))
+ continue
+ // SKYRAT EDIT ADD END
traumatize(H)
announce_to_ghosts(H)
break
diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm
index a323c7d83f0..4f251e871c7 100644
--- a/code/modules/events/disease_outbreak.dm
+++ b/code/modules/events/disease_outbreak.dm
@@ -61,6 +61,10 @@
continue
if(length(candidate.diseases)) //Is our candidate already sick?
continue
+ // SKYRAT EDIT ADD START - Station/area event candidate filtering
+ if(engaged_role_play_check(candidate, station = TRUE, dorms = TRUE))
+ continue
+ // SKYRAT EDIT ADD END
disease_candidates += candidate
///Handles checking and alerting admins about the number of valid candidates
diff --git a/code/modules/events/fake_virus.dm b/code/modules/events/fake_virus.dm
index fb6bfd5be97..f690b1c4a8d 100644
--- a/code/modules/events/fake_virus.dm
+++ b/code/modules/events/fake_virus.dm
@@ -10,6 +10,10 @@
for(var/mob/living/carbon/human/victim in shuffle(GLOB.player_list))
if(victim.stat == DEAD || HAS_TRAIT(victim, TRAIT_CRITICAL_CONDITION) || !(victim.mind.assigned_role.job_flags & JOB_CREW_MEMBER))
continue
+ // SKYRAT EDIT ADD START - Station/area event candidate filtering
+ if(engaged_role_play_check(fake_virus_victims, station = TRUE, dorms = TRUE))
+ continue
+ // SKYRAT EDIT ADD END
fake_virus_victims += victim
//first we do hard status effect victims
diff --git a/code/modules/events/ghost_role/operative.dm b/code/modules/events/ghost_role/operative.dm
index 33cd9e059f0..4cf8da639bb 100644
--- a/code/modules/events/ghost_role/operative.dm
+++ b/code/modules/events/ghost_role/operative.dm
@@ -30,6 +30,10 @@
Mind.special_role = ROLE_LONE_OPERATIVE
Mind.active = TRUE
Mind.transfer_to(operative)
+ if(!operative.client?.prefs.read_preference(/datum/preference/toggle/nuke_ops_species))
+ var/species_type = operative.client.prefs.read_preference(/datum/preference/choiced/species)
+ operative.set_species(species_type) //Apply the preferred species to our freshly-made body.
+
Mind.add_antag_datum(/datum/antagonist/nukeop/lone)
message_admins("[ADMIN_LOOKUPFLW(operative)] has been made into lone operative by an event.")
diff --git a/code/modules/events/heart_attack.dm b/code/modules/events/heart_attack.dm
index 8a8902d5724..f073676c5b4 100644
--- a/code/modules/events/heart_attack.dm
+++ b/code/modules/events/heart_attack.dm
@@ -34,6 +34,10 @@
continue
if(!(candidate.mind.assigned_role.job_flags & JOB_CREW_MEMBER))//only crewmembers can get one, a bit unfair for some ghost roles and it wastes the event
continue
+ // SKYRAT EDIT ADD START - Station/area event candidate filtering
+ if(engaged_role_play_check(candidate, station = TRUE, dorms = TRUE))
+ continue
+ // SKYRAT EDIT ADD END
if(candidate.satiety <= -60 && !candidate.has_status_effect(/datum/status_effect/exercised)) //Multiple junk food items recently //No foodmaxxing for the achievement
heart_attack_candidates[candidate] = 3
else
diff --git a/code/modules/events/holiday/easter.dm b/code/modules/events/holiday/easter.dm
index f4fa2a038e0..ddade60e287 100644
--- a/code/modules/events/holiday/easter.dm
+++ b/code/modules/events/holiday/easter.dm
@@ -140,6 +140,7 @@
foodtypes = SUGAR | GRAIN | BREAKFAST
tastes = list("pastry" = 1, "easter" = 1)
bite_consumption = 2
+ crafting_complexity = FOOD_COMPLEXITY_1
/datum/crafting_recipe/food/hotcrossbun
name = "Hot Cross Bun"
@@ -167,6 +168,7 @@
icon_state = "scotchegg"
bite_consumption = 3
food_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/nutriment/vitamin = 2)
+ crafting_complexity = FOOD_COMPLEXITY_2
/datum/crafting_recipe/food/scotchegg
name = "Scotch egg"
@@ -194,6 +196,7 @@
desc = "Contains less than 10% real rabbit!"
icon_state = "chocolatebunny"
food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/sugar = 2, /datum/reagent/consumable/coco = 2, /datum/reagent/consumable/nutriment/vitamin = 1)
+ crafting_complexity = FOOD_COMPLEXITY_1
/datum/crafting_recipe/food/chocolatebunny
name = "Chocolate bunny"
diff --git a/code/modules/events/holiday/halloween.dm b/code/modules/events/holiday/halloween.dm
index b0b9aa35264..d52dd1b9c50 100644
--- a/code/modules/events/holiday/halloween.dm
+++ b/code/modules/events/holiday/halloween.dm
@@ -31,12 +31,14 @@
desc = "Spooky! It's got delicious calcium flavouring!"
icon = 'icons/obj/holiday/halloween_items.dmi'
icon_state = "skeletoncookie"
+ crafting_complexity = FOOD_COMPLEXITY_2
/obj/item/food/cookie/sugar/spookycoffin
name = "coffin cookie"
desc = "Spooky! It's got delicious coffee flavouring!"
icon = 'icons/obj/holiday/halloween_items.dmi'
icon_state = "coffincookie"
+ crafting_complexity = FOOD_COMPLEXITY_2
//spooky items
diff --git a/code/modules/events/immovable_rod/immovable_rod.dm b/code/modules/events/immovable_rod/immovable_rod.dm
index e2350d810a6..1280eb1faa7 100644
--- a/code/modules/events/immovable_rod/immovable_rod.dm
+++ b/code/modules/events/immovable_rod/immovable_rod.dm
@@ -249,7 +249,7 @@
* * strongman - the suplexer of the rod.
*/
/obj/effect/immovablerod/proc/suplex_rod(mob/living/strongman)
- strongman.client?.give_award(/datum/award/achievement/misc/feat_of_strength, strongman)
+ strongman.client?.give_award(/datum/award/achievement/jobs/feat_of_strength, strongman)
strongman.visible_message(
span_boldwarning("[strongman] suplexes [src] into the ground!"),
span_warning("You suplex [src] into the ground!")
diff --git a/code/modules/events/meteors/dark_matteor_event.dm b/code/modules/events/meteors/dark_matteor_event.dm
index 3d5918eb29b..86d38f93e6c 100644
--- a/code/modules/events/meteors/dark_matteor_event.dm
+++ b/code/modules/events/meteors/dark_matteor_event.dm
@@ -25,7 +25,7 @@
spawn_meteor(list(/obj/effect/meteor/dark_matteor = 1), null, target)
/datum/round_event/dark_matteor/announce(fake)
- priority_announce("Warning. Excessive tampering of meteor satellites has attracted a dark matt-eor. Signature approaching [GLOB.station_name]. Please brace for impact.", "Meteor Alert", 'sound/effects/curse1.ogg')
+ priority_announce("Warning. Excessive tampering of meteor satellites has attracted a dark matt-eor. Signature approaching [GLOB.station_name]. Please brace for impact.", "Meteor Alert", 'sound/misc/airraid.ogg')
/datum/event_admin_setup/warn_admin/dark_matteor
warning_text = "Dark Matt-eors spawn singularities. The round is ending once a dark matt-eor hits the station. Proceed anyways?"
diff --git a/code/modules/events/shuttle_loan/shuttle_loan_datum.dm b/code/modules/events/shuttle_loan/shuttle_loan_datum.dm
index 3cc5a15a507..424eb157efe 100644
--- a/code/modules/events/shuttle_loan/shuttle_loan_datum.dm
+++ b/code/modules/events/shuttle_loan/shuttle_loan_datum.dm
@@ -17,6 +17,8 @@
. = ..()
if(!logging_desc)
stack_trace("No logging blurb set for [src.type]!")
+ if(HAS_TRAIT(SSstation, STATION_TRAIT_LOANER_SHUTTLE))
+ bonus_points *= 1.15
/// Spawns paths added to `spawn_list`, and passes empty shuttle turfs so you can spawn more complicated things like dead bodies.
/datum/shuttle_loan_situation/proc/spawn_items(list/spawn_list, list/empty_shuttle_turfs)
diff --git a/code/modules/events/supermatter_surge.dm b/code/modules/events/supermatter_surge.dm
new file mode 100644
index 00000000000..6c790c84f8d
--- /dev/null
+++ b/code/modules/events/supermatter_surge.dm
@@ -0,0 +1,140 @@
+#define SURGE_DURATION_MIN 240 EVENT_SECONDS
+#define SURGE_DURATION_MAX 270 EVENT_SECONDS
+#define SURGE_SEVERITY_MIN 1
+#define SURGE_SEVERITY_MAX 4
+#define SURGE_SEVERITY_RANDOM 5
+/// The amount of bullet energy we add for the duration of the SM surge
+#define SURGE_BULLET_ENERGY_ADDITION 5
+/// The amount of powerloss inhibition (energy retention) we add for the duration of the SM surge
+#define SURGE_BASE_POWERLOSS_INHIBITION 0.55
+/// The powerloss inhibition scaling based on surge severity
+#define SURGE_POWERLOSS_INHIBITION_MODIFIER 0.175
+/// The power generation scaling based on surge severity
+#define SURGE_POWER_GENERATION_MODIFIER 0.075
+/// The heat modifier scaling based on surge severity
+#define SURGE_HEAT_MODIFIER 0.25
+
+/**
+ * Supermatter Surge
+ *
+ * An engineering challenge event where the properties of the SM changes to be in a 'surge' of power.
+ * For the duration of the event a powerloss inhibition is added to nitrogen, causing the crystal to retain more of its internal energy.
+ * Heat modifier is lowered to generate some heat but not a high temp burn.
+ * Bullet energy from emitters is raised slightly to raise meV while turned on.
+ */
+
+/datum/round_event_control/supermatter_surge
+ name = "Supermatter Surge"
+ typepath = /datum/round_event/supermatter_surge
+ category = EVENT_CATEGORY_ENGINEERING
+ weight = 15
+ max_occurrences = 1
+ earliest_start = 20 MINUTES
+ description = "The supermatter will increase in power and heat by a random amount, and announce it."
+ min_wizard_trigger_potency = 4
+ max_wizard_trigger_potency = 7
+ admin_setup = list(
+ /datum/event_admin_setup/input_number/surge_spiciness,
+ )
+
+/datum/round_event_control/supermatter_surge/can_spawn_event(players_amt, allow_magic = FALSE)
+ . = ..()
+
+ if(!SSjob.has_minimum_jobs(crew_threshold = 3, jobs = JOB_GROUP_ENGINEERS, head_jobs = list(JOB_CHIEF_ENGINEER)))
+ return FALSE
+
+/datum/round_event/supermatter_surge
+ announce_when = 4
+ end_when = SURGE_DURATION_MIN
+ /// How powerful is the supermatter surge going to be?
+ var/surge_class = SURGE_SEVERITY_RANDOM
+ /// Typecasted reference to the supermatter chosen at event start
+ var/obj/machinery/power/supermatter_crystal/engine
+ /// Typecasted reference to the nitrogen properies in the SM chamber
+ var/datum/sm_gas/nitrogen/sm_gas
+
+/datum/event_admin_setup/input_number/surge_spiciness
+ input_text = "Set surge intensity. (Higher is more severe.)"
+ min_value = SURGE_SEVERITY_MIN
+ max_value = SURGE_SEVERITY_MAX
+
+/datum/event_admin_setup/input_number/surge_spiciness/prompt_admins()
+ default_value = rand(SURGE_SEVERITY_MIN, SURGE_SEVERITY_MAX)
+ return ..()
+
+/datum/event_admin_setup/input_number/surge_spiciness/apply_to_event(datum/round_event/supermatter_surge/event)
+ event.surge_class = chosen_value
+
+/datum/round_event/supermatter_surge/setup()
+ engine = GLOB.main_supermatter_engine
+ if(isnull(engine))
+ stack_trace("SM surge event failed to find a supermatter engine!")
+ return
+
+ sm_gas = LAZYACCESS(engine.current_gas_behavior, /datum/gas/nitrogen)
+ if(isnull(sm_gas))
+ stack_trace("SM surge event failed to find gas properties for [engine].")
+ return
+
+ if(surge_class == SURGE_SEVERITY_RANDOM)
+ var/severity_weight = rand(1, 100)
+ switch(severity_weight)
+ if(1 to 14)
+ surge_class = 1
+ if(15 to 34)
+ surge_class = 2
+ if(35 to 69)
+ surge_class = 3
+ if(70 to 100)
+ surge_class = 4
+
+ end_when = rand(SURGE_DURATION_MIN, SURGE_DURATION_MAX)
+
+/datum/round_event/supermatter_surge/announce(fake)
+ priority_announce("The Crystal Integrity Monitoring System has detected unusual atmospheric properties in the supermatter chamber, energy output from the supermatter crystal has increased significantly. Engineering intervention is required to stabilize the engine.", "Class [surge_class] Supermatter Surge Alert", 'sound/machines/engine_alert3.ogg')
+
+/datum/round_event/supermatter_surge/start()
+ engine.bullet_energy = surge_class + SURGE_BULLET_ENERGY_ADDITION
+ sm_gas.powerloss_inhibition = (surge_class * SURGE_POWERLOSS_INHIBITION_MODIFIER) + SURGE_BASE_POWERLOSS_INHIBITION
+ sm_gas.heat_power_generation = (surge_class * SURGE_POWER_GENERATION_MODIFIER) - 1
+ sm_gas.heat_modifier = (surge_class * SURGE_HEAT_MODIFIER) - 1
+
+
+/datum/round_event/supermatter_surge/end()
+ engine.bullet_energy = initial(engine.bullet_energy)
+ sm_gas.powerloss_inhibition = initial(sm_gas.powerloss_inhibition)
+ sm_gas.heat_power_generation = initial(sm_gas.heat_power_generation)
+ sm_gas.heat_modifier = initial(sm_gas.heat_modifier)
+ priority_announce("The supermatter surge has dissipated, crystal output readings have normalized.", "Anomaly Cleared")
+ engine = null
+ sm_gas = null
+
+/datum/round_event_control/supermatter_surge/poly
+ name = "Supermatter Surge: Poly's Revenge"
+ typepath = /datum/round_event/supermatter_surge/poly
+ category = EVENT_CATEGORY_ENGINEERING
+ weight = 0
+ max_occurrences = 0
+ description = "For when Poly is sacrificed to the SM. Not really useful to run manually."
+ min_wizard_trigger_potency = NEVER_TRIGGERED_BY_WIZARDS
+ max_wizard_trigger_potency = NEVER_TRIGGERED_BY_WIZARDS
+ admin_setup = null
+
+/datum/round_event/supermatter_surge/poly
+ announce_when = 4
+ surge_class = 4
+ fakeable = FALSE
+
+/datum/round_event/supermatter_surge/poly/announce(fake)
+ priority_announce("The Crystal Integrity Monitoring System has detected unusual parrot type resonance in the supermatter chamber, energy output from the supermatter crystal has increased significantly. Engineering intervention is required to stabilize the engine.", "Class P Supermatter Surge Alert", 'sound/machines/engine_alert3.ogg')
+
+#undef SURGE_DURATION_MIN
+#undef SURGE_DURATION_MAX
+#undef SURGE_SEVERITY_MIN
+#undef SURGE_SEVERITY_MAX
+#undef SURGE_SEVERITY_RANDOM
+#undef SURGE_BULLET_ENERGY_ADDITION
+#undef SURGE_BASE_POWERLOSS_INHIBITION
+#undef SURGE_POWERLOSS_INHIBITION_MODIFIER
+#undef SURGE_POWER_GENERATION_MODIFIER
+#undef SURGE_HEAT_MODIFIER
diff --git a/code/modules/experisci/experiment/handlers/experiment_handler.dm b/code/modules/experisci/experiment/handlers/experiment_handler.dm
index 4c0b6ae3b44..abc5d4ad1dd 100644
--- a/code/modules/experisci/experiment/handlers/experiment_handler.dm
+++ b/code/modules/experisci/experiment/handlers/experiment_handler.dm
@@ -72,10 +72,7 @@
// Note this won't work at the moment for non-machines that have been included
// on the map as the servers aren't initialized when the non-machines are initializing
if (!(config_flags & EXPERIMENT_CONFIG_NO_AUTOCONNECT))
- var/list/found_servers = get_available_servers()
- var/obj/machinery/rnd/server/selected_server = length(found_servers) ? found_servers[1] : null
- if (selected_server)
- link_techweb(selected_server.stored_research)
+ CONNECT_TO_RND_SERVER_ROUNDSTART(linked_web, parent)
GLOB.experiment_handlers += src
@@ -328,32 +325,6 @@
// If we haven't returned yet then this shouldn't be allowed
return FALSE
-/**
- * Goes through all techwebs and goes through their servers to find ones on a valid z-level
- * Returns the full list of all techweb servers.
- */
-/datum/component/experiment_handler/proc/get_available_servers()
- var/list/local_servers = list()
- for (var/datum/techweb/techwebs as anything in SSresearch.techwebs)
- var/list/servers = find_valid_servers(techwebs)
- if(length(servers))
- local_servers += servers
- return local_servers
-
-/**
- * Goes through an individual techweb's servers and finds one on a valid z-level
- * Returns a list of existing ones, or an empty list otherwise.
- * Args:
- * - checking_web - The techweb we're checking the servers of.
- */
-/datum/component/experiment_handler/proc/find_valid_servers(datum/techweb/checking_web)
- var/list/valid_servers = list()
- for(var/obj/machinery/rnd/server/server as anything in checking_web.techweb_servers)
- if(!is_valid_z_level(get_turf(server), get_turf(parent)))
- continue
- valid_servers += server
- return valid_servers
-
/datum/component/experiment_handler/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if (!ui)
@@ -372,7 +343,7 @@
if(techwebs == linked_web) //disconnect if OUR techweb lost their servers.
unlink_techweb()
continue
- if(!length(find_valid_servers(techwebs)))
+ if(!length(SSresearch.find_valid_servers(get_turf(parent), techwebs)))
continue
var/list/data = list(
web_id = techwebs.id,
diff --git a/code/modules/explorer_drone/control_console.dm b/code/modules/explorer_drone/control_console.dm
index 208292c2437..7b371e8412b 100644
--- a/code/modules/explorer_drone/control_console.dm
+++ b/code/modules/explorer_drone/control_console.dm
@@ -131,6 +131,9 @@
target_site = locate(params["target_site"]) in GLOB.exploration_sites
if(!target_site)
return TRUE
+ if(!controlled_drone.check_blacklist())
+ say("Error - An unauthorized object was found inside the cargo!")
+ return TRUE
controlled_drone.launch_for(target_site)
return TRUE
if("explore")
diff --git a/code/modules/explorer_drone/exodrone.dm b/code/modules/explorer_drone/exodrone.dm
index 567d5a93412..72cf09bd81b 100644
--- a/code/modules/explorer_drone/exodrone.dm
+++ b/code/modules/explorer_drone/exodrone.dm
@@ -88,6 +88,15 @@ GLOBAL_LIST_EMPTY(exodrone_launchers)
if(EXODRONE_IDLE)
return "Idle."
+// Searches for blacklisted items hidden inside containers
+/obj/item/exodrone/proc/check_blacklist()
+ for(var/obj/item/contained_item in contents)
+ if(contained_item.contents)
+ for(var/subcontained_object in contained_item.get_all_contents())
+ if(is_type_in_typecache(subcontained_object, GLOB.blacklisted_cargo_types))
+ return FALSE
+ return TRUE
+
/// Starts travel for site, does not validate if it's possible
/obj/item/exodrone/proc/launch_for(datum/exploration_site/target_site)
if(!location) //We're launching from station, fuel up
diff --git a/code/modules/fishing/fish/chasm_detritus.dm b/code/modules/fishing/fish/chasm_detritus.dm
index 9e686958536..8d665378159 100644
--- a/code/modules/fishing/fish/chasm_detritus.dm
+++ b/code/modules/fishing/fish/chasm_detritus.dm
@@ -40,30 +40,29 @@ GLOBAL_LIST_INIT_TYPED(chasm_detritus_types, /datum/chasm_detritus, init_chasm_d
),
)
-/datum/chasm_detritus/proc/dispense_reward(turf/fishing_spot)
- if (prob(default_contents_chance))
+/datum/chasm_detritus/proc/dispense_detritus(mob/fisherman, turf/fishing_spot)
+ if(prob(default_contents_chance))
var/default_spawn = pick(default_contents[default_contents_key])
- return new default_spawn(fishing_spot)
- return find_chasm_contents(fishing_spot)
+ return new default_spawn(get_turf(fisherman))
+ return find_chasm_contents(fishing_spot, get_turf(fisherman))
/// Returns the chosen detritus from the given list of things to choose from
/datum/chasm_detritus/proc/determine_detritus(list/chasm_stuff)
return pick(chasm_stuff)
-/// Returns an objected which is currently inside of a nearby chasm.
-/datum/chasm_detritus/proc/find_chasm_contents(datum/source, turf/fishing_spot)
- SIGNAL_HANDLER
+/// Returns an object which is currently inside of a nearby chasm.
+/datum/chasm_detritus/proc/find_chasm_contents(turf/fishing_spot, turf/fisher_turf)
var/list/chasm_contents = get_chasm_contents(fishing_spot)
- if (!length(chasm_contents))
+ if(!length(chasm_contents))
var/default_spawn = pick(default_contents[default_contents_key])
- return new default_spawn(fishing_spot)
+ return new default_spawn(fisher_turf)
return determine_detritus(chasm_contents)
/datum/chasm_detritus/proc/get_chasm_contents(turf/fishing_spot)
. = list()
- for (var/obj/effect/abstract/chasm_storage/storage in range(5, fishing_spot))
+ for(var/obj/effect/abstract/chasm_storage/storage in range(5, fishing_spot))
for (var/thing as anything in storage.contents)
. += thing
@@ -76,7 +75,7 @@ GLOBAL_LIST_INIT_TYPED(chasm_detritus_types, /datum/chasm_detritus, init_chasm_d
/datum/chasm_detritus/restricted/get_chasm_contents(turf/fishing_spot)
. = list()
- for (var/obj/effect/abstract/chasm_storage/storage in range(5, fishing_spot))
+ for(var/obj/effect/abstract/chasm_storage/storage in range(5, fishing_spot))
for (var/thing as anything in storage.contents)
if(!istype(thing, chasm_storage_restricted_type))
continue
diff --git a/code/modules/fishing/fish/fish_traits.dm b/code/modules/fishing/fish/fish_traits.dm
index 6c7fb38e279..bec868ad24e 100644
--- a/code/modules/fishing/fish/fish_traits.dm
+++ b/code/modules/fishing/fish/fish_traits.dm
@@ -23,9 +23,9 @@ GLOBAL_LIST_INIT(fish_traits, init_subtypes_w_path_keys(/datum/fish_trait, list(
SHOULD_CALL_PARENT(TRUE)
return list(ADDITIVE_FISHING_MOD = 0, MULTIPLICATIVE_FISHING_MOD = 1)
-/// Returns special minigame rules applied by this trait
-/datum/fish_trait/proc/minigame_mod(obj/item/fishing_rod/rod, mob/fisherman)
- return list()
+/// Returns special minigame rules and effects applied by this trait
+/datum/fish_trait/proc/minigame_mod(obj/item/fishing_rod/rod, mob/fisherman, datum/fishing_challenge/minigame)
+ return
/// Applies some special qualities to the fish that has been spawned
/datum/fish_trait/proc/apply_to_fish(obj/item/fish/fish)
@@ -100,8 +100,8 @@ GLOBAL_LIST_INIT(fish_traits, init_subtypes_w_path_keys(/datum/fish_trait, list(
name = "Heavy"
catalog_description = "This fish tends to stay near the waterbed.";
-/datum/fish_trait/heavy/minigame_mod(obj/item/fishing_rod/rod, mob/fisherman)
- return list(FISHING_MINIGAME_RULE_HEAVY_FISH)
+/datum/fish_trait/heavy/minigame_mod(obj/item/fishing_rod/rod, mob/fisherman, datum/fishing_challenge/minigame)
+ minigame.fish_idle_velocity -= 10
/datum/fish_trait/carnivore
name = "Carnivore"
@@ -338,8 +338,9 @@ GLOBAL_LIST_INIT(fish_traits, init_subtypes_w_path_keys(/datum/fish_trait, list(
/datum/fish_trait/lubed/apply_to_fish(obj/item/fish/fish)
fish.AddComponent(/datum/component/slippery, 8 SECONDS, SLIDE|GALOSHES_DONT_HELP)
-/datum/fish_trait/lubed/minigame_mod(obj/item/fishing_rod/rod, mob/fisherman)
- return list(FISHING_MINIGAME_RULE_LUBED_FISH)
+/datum/fish_trait/lubed/minigame_mod(obj/item/fishing_rod/rod, mob/fisherman, datum/fishing_challenge/minigame)
+ minigame.reeling_velocity *= 1.4
+ minigame.gravity_velocity *= 1.4
/datum/fish_trait/amphibious
name = "Amphibious"
diff --git a/code/modules/fishing/fish/fish_types.dm b/code/modules/fishing/fish/fish_types.dm
index e8752acb1de..652b0aba8aa 100644
--- a/code/modules/fishing/fish/fish_types.dm
+++ b/code/modules/fishing/fish/fish_types.dm
@@ -465,6 +465,7 @@
/obj/item/fish/holo/puffer
name = "holographic pufferfish"
desc ="A holographic representation of 100% safe-to-eat pufferfish... that is, if holographic fishes were even edible."
+ icon_state = "pufferfish"
sprite_width = 8
sprite_height = 8
average_size = 60
diff --git a/code/modules/fishing/fishing_equipment.dm b/code/modules/fishing/fishing_equipment.dm
index 43a79106356..6169b41fd88 100644
--- a/code/modules/fishing/fishing_equipment.dm
+++ b/code/modules/fishing/fishing_equipment.dm
@@ -162,14 +162,14 @@
/obj/item/fishing_hook/stabilized
name = "gyro-stabilized hook"
- desc = "A quirky hook that grants the user a better control of the tool, allowing them to move the hook both and up and down when reeling in, otherwise keeping it stabilized."
+ desc = "A quirky hook that grants the user a better control of the tool, allowing them to move the bait both and up and down when reeling in, otherwise keeping it in place."
icon_state = "gyro"
fishing_hook_traits = FISHING_HOOK_BIDIRECTIONAL
rod_overlay_icon_state = "hook_gyro_overlay"
/obj/item/fishing_hook/stabilized/examine(mob/user)
. = ..()
- . += span_notice("While fishing, you can hold the Ctrl key to move the bait down, rather than up.")
+ . += span_notice("While fishing, you can hold the Right Mouse Button to move the bait down, rather than up.")
/obj/item/fishing_hook/jaws
name = "jawed hook"
@@ -188,7 +188,10 @@
/obj/item/storage/toolbox/fishing/Initialize(mapload)
. = ..()
// Can hold fishing rod despite the size
- var/static/list/exception_cache = typecacheof(/obj/item/fishing_rod)
+ var/static/list/exception_cache = typecacheof(
+ /obj/item/fishing_rod,
+ /obj/item/fishing_line,
+ )
atom_storage.exception_hold = exception_cache
/obj/item/storage/toolbox/fishing/PopulateContents()
@@ -204,6 +207,10 @@
force = 5
throwforce = 5
+/obj/item/storage/toolbox/fishing/small/Initialize(mapload)
+ . = ..()
+ atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL //It can still hold a fishing rod
+
/obj/item/storage/toolbox/fishing/small/PopulateContents()
new /obj/item/fishing_rod(src)
new /obj/item/fishing_hook(src)
diff --git a/code/modules/fishing/fishing_minigame.dm b/code/modules/fishing/fishing_minigame.dm
index d1b77e4ec0a..478279749e4 100644
--- a/code/modules/fishing/fishing_minigame.dm
+++ b/code/modules/fishing/fishing_minigame.dm
@@ -5,6 +5,35 @@
// UI minigame phase
#define MINIGAME_PHASE 3
+/// The height of the minigame slider. Not in pixels, but minigame units.
+#define FISHING_MINIGAME_AREA 1000
+/// Any lower than this, and the target position of the fish is considered null
+#define FISH_TARGET_MIN_DISTANCE 6
+/// The friction applied to fish jumps, so that it decelerates over time
+#define FISH_FRICTION_MULT 0.9
+/// Used to decide whether the fish can jump in a certain direction
+#define FISH_SHORT_JUMP_MIN_DISTANCE 100
+/// The maximum distance for a short jump
+#define FISH_SHORT_JUMP_MAX_DISTANCE 200
+// Acceleration mod when bait is over fish
+#define FISH_ON_BAIT_ACCELERATION_MULT 0.6
+/// The minimum velocity required for the bait to bounce
+#define BAIT_MIN_VELOCITY_BOUNCE 200
+/// The extra deceleration of velocity that happens when the bait switches direction
+#define BAIT_DECELERATION_MULT 2
+
+///Defines to know how the bait is moving on the minigame slider.
+#define REELING_STATE_IDLE 0
+#define REELING_STATE_UP 1
+#define REELING_STATE_DOWN 2
+
+///The pixel height of the minigame bar
+#define MINIGAME_SLIDER_HEIGHT 76
+///The standard pixel height of the bait
+#define MINIGAME_BAIT_HEIGHT 24
+///The standard pixel height of the fish (minus a pixel on each direction for the sake of a better looking sprite)
+#define MINIGAME_FISH_HEIGHT 4
+
/datum/fishing_challenge
/// When the ui minigame phase started
var/start_time
@@ -13,7 +42,7 @@
/// Fish AI type to use
var/fish_ai = FISH_AI_DUMB
/// Rule modifiers (eg weighted bait)
- var/list/special_effects = list()
+ var/special_effects = NONE
/// Did the game get past the baiting phase, used to track if bait should be consumed afterwards
var/bait_taken = FALSE
/// Result path
@@ -30,14 +59,67 @@
var/obj/item/fishing_rod/used_rod
/// Lure visual
var/obj/effect/fishing_lure/lure
- /// Background image from /datum/asset/simple/fishing_minigame
- var/background = "default"
+ /// Background icon state from fishing_hud.dmi
+ var/background = "background_default"
/// Fishing line visual
var/datum/beam/fishing_line
var/experience_multiplier = 1
+ /// How much space the fish takes on the minigame slider
+ var/fish_height = 50
+ /// How much space the bait takes on the minigame slider
+ var/bait_height = 320
+ /// The height in pixels of the bait bar
+ var/bait_pixel_height = MINIGAME_BAIT_HEIGHT
+ /// The height in pixels of the fish
+ var/fish_pixel_height = MINIGAME_FISH_HEIGHT
+ /// The position of the fish on the minigame slider
+ var/fish_position = 0
+ /// The position of the bait on the minigame slider
+ var/bait_position = 0
+ /// The current speed the fish is moving at
+ var/fish_velocity = 0
+ /// The current speed the bait is moving at
+ var/bait_velocity = 0
+
+ /// The completion score. If it reaches 100, it's a win. If it reaches 0, it's a loss.
+ var/completion = 30
+ /// How much completion is lost per second when the bait area is not intersecting with the fish's
+ var/completion_loss = 6
+ /// How much completion is gained per second when the bait area is intersecting with the fish's
+ var/completion_gain = 5
+
+ /// How likely the fish is to perform a standard jump, then multiplied by difficulty
+ var/short_jump_chance = 2.25
+ /// How likely the fish is to perform a long jump, then multiplied by difficulty
+ var/long_jump_chance = 0.0625
+ /// The speed limit for the short jump
+ var/short_jump_velocity_limit = 400
+ /// The speed limit for the long jump
+ var/long_jump_velocity_limit = 200
+ /// The current speed limit used
+ var/current_velocity_limit = 200
+ /// The base velocity of the fish, which may affect jump distances and falling speed.
+ var/fish_idle_velocity = 0
+ /// A position on the slider the fish wants to get to
+ var/target_position
+ /// If true, the fish can jump while a target position is set, thus overriding it
+ var/can_interrupt_move = TRUE
+
+ /// Whether the bait is idle or reeling up or down (left and right click)
+ var/reeling_state = REELING_STATE_IDLE
+ /// The acceleration of the bait while not reeling
+ var/gravity_velocity = -800
+ /// The acceleration of the bait while reeling
+ var/reeling_velocity = 1200
+ /// By how much the bait recoils back when hitting the bounds of the slider while idle
+ var/bait_bounce_mult = 0.6
+
+ ///The background as shown in the minigame, and the holder of the other visual overlays
+ var/atom/movable/screen/fishing_hud/fishing_hud
+
/datum/fishing_challenge/New(datum/component/fishing_spot/comp, reward_path, obj/item/fishing_rod/rod, mob/user)
src.user = user
src.reward_path = reward_path
@@ -52,32 +134,61 @@
if(ispath(reward_path,/obj/item/fish))
var/obj/item/fish/fish = reward_path
fish_ai = initial(fish.fish_ai_type)
+ switch(fish_ai)
+ if(FISH_AI_ZIPPY) // Keeps on jumping
+ short_jump_chance *= 3
+ if(FISH_AI_SLOW) // Only does long jump, and doesn't change direction until it gets there
+ short_jump_chance = 0
+ long_jump_chance = 1.5
+ long_jump_velocity_limit = 150
+ long_jump_velocity_limit = FALSE
// Apply fish trait modifiers
var/list/fish_list_properties = collect_fish_properties()
var/list/fish_traits = fish_list_properties[fish][NAMEOF(fish, fish_traits)]
for(var/fish_trait in fish_traits)
var/datum/fish_trait/trait = GLOB.fish_traits[fish_trait]
- special_effects += trait.minigame_mod(rod, user)
+ trait.minigame_mod(rod, user, src)
/// Enable special parameters
if(rod.line)
if(rod.line.fishing_line_traits & FISHING_LINE_BOUNCY)
- special_effects |= FISHING_MINIGAME_RULE_LIMIT_LOSS
+ completion_loss -= 2
if(rod.hook)
if(rod.hook.fishing_hook_traits & FISHING_HOOK_WEIGHTED)
- special_effects |= FISHING_MINIGAME_RULE_WEIGHTED_BAIT
+ bait_bounce_mult = 0.1
if(rod.hook.fishing_hook_traits & FISHING_HOOK_BIDIRECTIONAL)
special_effects |= FISHING_MINIGAME_RULE_BIDIRECTIONAL
if(rod.hook.fishing_hook_traits & FISHING_HOOK_NO_ESCAPE)
special_effects |= FISHING_MINIGAME_RULE_NO_ESCAPE
if(rod.hook.fishing_hook_traits & FISHING_HOOK_ENSNARE)
- special_effects |= FISHING_MINIGAME_RULE_LIMIT_LOSS
+ completion_loss -= 2
if(rod.hook.fishing_hook_traits & FISHING_HOOK_KILL)
special_effects |= FISHING_MINIGAME_RULE_KILL
- if((FISHING_MINIGAME_RULE_KILL in special_effects) && ispath(reward_path,/obj/item/fish))
+ if(special_effects & FISHING_MINIGAME_RULE_KILL && ispath(reward_path,/obj/item/fish))
RegisterSignal(user, COMSIG_MOB_FISHING_REWARD_DISPENSED, PROC_REF(hurt_fish))
difficulty += comp.fish_source.calculate_difficulty(reward_path, rod, user, src)
+ difficulty = round(difficulty)
+
+ /**
+ * If the chances are higher than 1% (100% at maximum difficulty), they'll scale
+ * less than proportionally (exponent less than 1) instead.
+ * This way we ensure fish with high jump chances won't get TOO jumpy until
+ * they near the maximum difficulty, at which they hit 100%
+ */
+ var/square_angle_rad = TORADIANS(90)
+ var/zero_one_difficulty = difficulty/100
+ if(short_jump_chance > 1)
+ short_jump_chance = (zero_one_difficulty**(square_angle_rad-TORADIANS(arctan(short_jump_chance * 1/square_angle_rad))))*100
+ else
+ short_jump_chance *= difficulty
+ if(long_jump_chance > 1)
+ long_jump_chance = (zero_one_difficulty**(square_angle_rad-TORADIANS(arctan(long_jump_chance * 1/square_angle_rad))))*100
+ else
+ long_jump_chance *= difficulty
+
+ bait_height -= difficulty
+ bait_pixel_height = round(MINIGAME_BAIT_HEIGHT * (bait_height/initial(bait_height)), 1)
/datum/fishing_challenge/Destroy(force, ...)
if(!completed)
@@ -86,6 +197,7 @@
QDEL_NULL(fishing_line)
if(lure)
QDEL_NULL(lure)
+ SStgui.close_uis(src)
user = null
used_rod = null
return ..()
@@ -119,13 +231,13 @@
/datum/fishing_challenge/proc/handle_click(mob/source, atom/target, modifiers)
SIGNAL_HANDLER
//You need to be holding the rod to use it.
- if(!source.get_active_held_item(used_rod) || LAZYACCESS(modifiers, SHIFT_CLICK))
+ if(!source.get_active_held_item(used_rod) || LAZYACCESS(modifiers, SHIFT_CLICK) || LAZYACCESS(modifiers, CTRL_CLICK) || LAZYACCESS(modifiers, ALT_CLICK))
return
if(phase == WAIT_PHASE) //Reset wait
send_alert("miss!")
start_baiting_phase()
else if(phase == BITING_PHASE)
- INVOKE_ASYNC(src, PROC_REF(start_minigame_phase))
+ start_minigame_phase()
return COMSIG_MOB_CANCEL_CLICKON
/// Challenge interrupted by something external
@@ -147,16 +259,20 @@
send_alert("stopped fishing")
complete(FALSE)
-/datum/fishing_challenge/proc/complete(win = FALSE, perfect_win = FALSE)
+/datum/fishing_challenge/proc/complete(win = FALSE)
+ if(completed)
+ return
deltimer(next_phase_timer)
completed = TRUE
+ if(phase == MINIGAME_PHASE)
+ remove_minigame_hud()
if(user)
REMOVE_TRAIT(user, TRAIT_GONE_FISHING, REF(src))
if(start_time)
- var/seconds_spent = (world.time - start_time)/10
- if(!(FISHING_MINIGAME_RULE_NO_EXP in special_effects))
- user.mind?.adjust_experience(/datum/skill/fishing, min(round(seconds_spent * FISHING_SKILL_EXP_PER_SECOND * experience_multiplier), FISHING_SKILL_EXP_CAP_PER_GAME))
- if(win && user.mind?.get_skill_level(/datum/skill/fishing) >= SKILL_LEVEL_LEGENDARY)
+ var/seconds_spent = (world.time - start_time) * 0.1
+ if(!(special_effects & FISHING_MINIGAME_RULE_NO_EXP))
+ user.mind?.adjust_experience(/datum/skill/fishing, round(seconds_spent * FISHING_SKILL_EXP_PER_SECOND * experience_multiplier))
+ if(user.mind?.get_skill_level(/datum/skill/fishing) >= SKILL_LEVEL_LEGENDARY)
user.client?.give_award(/datum/award/achievement/skill/legendary_fisher, user)
if(win)
if(reward_path != FISHING_DUD)
@@ -188,16 +304,10 @@
///The damage dealt per second to the fish when FISHING_MINIGAME_RULE_KILL is active.
#define FISH_DAMAGE_PER_SECOND 2
-/datum/fishing_challenge/proc/start_minigame_phase()
- phase = MINIGAME_PHASE
- deltimer(next_phase_timer)
- if((FISHING_MINIGAME_RULE_KILL in special_effects) && ispath(reward_path,/obj/item/fish))
- var/obj/item/fish/fish = reward_path
- var/wait_time = (initial(fish.health) / FISH_DAMAGE_PER_SECOND) SECONDS
- addtimer(CALLBACK(src, PROC_REF(win_anyway)), wait_time)
- start_time = world.time
- experience_multiplier += difficulty * FISHING_SKILL_DIFFIULTY_EXP_MULT
- ui_interact(user)
+///The player is no longer around to play the minigame, so we interrupt it.
+/datum/fishing_challenge/proc/on_user_logout(datum/source)
+ SIGNAL_HANDLER
+ interrupt(balloon_alert = FALSE)
/datum/fishing_challenge/proc/win_anyway()
if(!completed)
@@ -211,57 +321,251 @@
var/damage = CEILING((world.time - start_time)/10 * FISH_DAMAGE_PER_SECOND, 1)
reward.adjust_health(reward.health - damage)
+/datum/fishing_challenge/proc/start_minigame_phase()
+ if(!prepare_minigame_hud())
+ return
+ phase = MINIGAME_PHASE
+ deltimer(next_phase_timer)
+ if((FISHING_MINIGAME_RULE_KILL in special_effects) && ispath(reward_path,/obj/item/fish))
+ var/obj/item/fish/fish = reward_path
+ var/wait_time = (initial(fish.health) / FISH_DAMAGE_PER_SECOND) SECONDS
+ addtimer(CALLBACK(src, PROC_REF(win_anyway)), wait_time)
+ start_time = world.time
+ experience_multiplier += difficulty * FISHING_SKILL_DIFFIULTY_EXP_MULT
+
#undef FISH_DAMAGE_PER_SECOND
-/datum/fishing_challenge/ui_interact(mob/user, datum/tgui/ui)
- ui = SStgui.try_update_ui(user, src, ui)
- if(!ui)
- ui = new(user, src, "Fishing")
- ui.set_autoupdate(FALSE)
- ui.set_mouse_hook(TRUE)
- ui.open()
+///Initialize the minigame hud and register some signals to make it work.
+/datum/fishing_challenge/proc/prepare_minigame_hud()
+ if(!user.client || user.incapacitated())
+ return FALSE
+ . = TRUE
+ fishing_hud = new
+ fishing_hud.prepare_minigame(src)
+ RegisterSignal(user.client, COMSIG_CLIENT_MOUSEDOWN, PROC_REF(start_reeling))
+ RegisterSignal(user.client, COMSIG_CLIENT_MOUSEUP, PROC_REF(stop_reeling))
+ RegisterSignal(user, COMSIG_MOB_LOGOUT, PROC_REF(on_user_logout))
+ START_PROCESSING(SSfishing, src)
-/datum/fishing_challenge/ui_host(mob/user)
- return lure //Could be the target really
+///Stop processing and remove references to the minigame hud
+/datum/fishing_challenge/proc/remove_minigame_hud()
+ STOP_PROCESSING(SSfishing, src)
+ QDEL_NULL(fishing_hud)
-// Manually closing the ui is treated as lose
-/datum/fishing_challenge/ui_close(mob/user)
+///While the mouse button is held down, the bait will be reeling up (or down on r-click if the bidirectional rule is enabled)
+/datum/fishing_challenge/proc/start_reeling(client/source, datum/object, location, control, params)
+ SIGNAL_HANDLER
+ var/bidirectional = special_effects & FISHING_MINIGAME_RULE_BIDIRECTIONAL
+ var/list/modifiers = params2list(params)
+ if(bidirectional && LAZYACCESS(modifiers, RIGHT_CLICK))
+ reeling_state = REELING_STATE_DOWN
+ else
+ reeling_state = REELING_STATE_UP
+
+///Reset the reeling state to idle once the mouse button is released
+/datum/fishing_challenge/proc/stop_reeling(client/source, datum/object, location, control, params)
+ SIGNAL_HANDLER
+ reeling_state = REELING_STATE_IDLE
+
+///Update the state of the fish, the bait and the hud
+/datum/fishing_challenge/process(seconds_per_tick)
+ move_fish(seconds_per_tick)
+ move_bait(seconds_per_tick)
+ if(!QDELETED(fishing_hud))
+ update_visuals()
+
+///The proc that moves the fish around, just like in the old TGUI, mostly.
+/datum/fishing_challenge/proc/move_fish(seconds_per_tick)
+ var/long_chance = long_jump_chance * seconds_per_tick * 10
+ var/short_chance = short_jump_chance * seconds_per_tick * 10
+
+ // If we have the target but we're close enough, mark as target reached
+ if(abs(target_position - fish_position) < FISH_TARGET_MIN_DISTANCE)
+ target_position = null
+
+ // Switching to new long jump target can interrupt any other
+ if((can_interrupt_move || isnull(target_position)) && prob(long_chance))
+ /**
+ * Move at least 0.75 to full of the availible bar in given direction,
+ * and more likely to move in the direction where there's more space
+ */
+ var/distance_from_top = FISHING_MINIGAME_AREA - fish_position - fish_height
+ var/distance_from_bottom = fish_position
+ var/top_chance
+ if(distance_from_top < FISH_SHORT_JUMP_MIN_DISTANCE)
+ top_chance = 0
+ else
+ top_chance = (distance_from_top/max(distance_from_bottom, 1)) * 100
+ var/new_target = fish_position
+ if(prob(top_chance))
+ new_target += distance_from_top * rand(75, 100)/100
+ else
+ new_target -= distance_from_bottom * rand(75, 100)/100
+ target_position = round(new_target)
+ current_velocity_limit = long_jump_velocity_limit
+
+ // Move towards target
+ if(!isnull(target_position))
+ var/distance = target_position - fish_position
+ // about 5 at diff 15 , 10 at diff 30, 30 at diff 100
+ var/acceleration_mult = 0.3 * difficulty + 0.5
+ var/target_acceleration = distance * acceleration_mult * seconds_per_tick
+
+ fish_velocity = fish_velocity * FISH_FRICTION_MULT + target_acceleration
+ else if(prob(short_chance))
+ var/distance_from_top = FISHING_MINIGAME_AREA - fish_position - fish_height
+ var/distance_from_bottom = fish_position
+ var/jump_length
+ if(distance_from_top >= FISH_SHORT_JUMP_MIN_DISTANCE)
+ jump_length = rand(FISH_SHORT_JUMP_MIN_DISTANCE, FISH_SHORT_JUMP_MAX_DISTANCE)
+ if(distance_from_bottom >= FISH_SHORT_JUMP_MIN_DISTANCE && (!jump_length || prob(50)))
+ jump_length = -rand(FISH_SHORT_JUMP_MIN_DISTANCE, FISH_SHORT_JUMP_MAX_DISTANCE)
+ target_position = clamp(fish_position + jump_length, 0, FISHING_MINIGAME_AREA - fish_height)
+ current_velocity_limit = short_jump_velocity_limit
+
+ fish_velocity = clamp(fish_velocity + fish_idle_velocity, -current_velocity_limit, current_velocity_limit)
+ fish_position = clamp(fish_position + fish_velocity * seconds_per_tick, 0, FISHING_MINIGAME_AREA - fish_height)
+
+///The proc that moves the bait around, just like in the old TGUI, mostly.
+/datum/fishing_challenge/proc/move_bait(seconds_per_tick)
+ var/should_bounce = abs(bait_velocity) > BAIT_MIN_VELOCITY_BOUNCE
+ bait_position += bait_velocity * seconds_per_tick
+ // Hitting the top bound
+ if(bait_position > FISHING_MINIGAME_AREA - bait_height)
+ bait_position = FISHING_MINIGAME_AREA - bait_height
+ if(reeling_state == REELING_STATE_UP || !should_bounce)
+ bait_velocity = 0
+ else
+ bait_velocity = -bait_velocity * bait_bounce_mult
+ // Hitting rock bottom
+ else if(bait_position < 0)
+ bait_position = 0
+ if(reeling_state == REELING_STATE_DOWN || !should_bounce)
+ bait_velocity = 0
+ else
+ bait_velocity = -bait_velocity * bait_bounce_mult
+
+ var/fish_on_bait = (fish_position + fish_height >= bait_position) && (bait_position + bait_height >= fish_position)
+
+ var/bidirectional = special_effects & FISHING_MINIGAME_RULE_BIDIRECTIONAL
+
+ var/velocity_change
+ switch(reeling_state)
+ if(REELING_STATE_UP)
+ velocity_change = reeling_velocity
+ if(REELING_STATE_DOWN)
+ velocity_change = -reeling_velocity
+ if(REELING_STATE_IDLE)
+ if(!bidirectional || bait_velocity > 0)
+ velocity_change = gravity_velocity
+ else
+ velocity_change = -gravity_velocity
+ velocity_change *= (fish_on_bait ? FISH_ON_BAIT_ACCELERATION_MULT : 1) * seconds_per_tick
+
+ velocity_change = round(velocity_change)
+
+ /**
+ * Pull the brake on the velocity if the current velocity and the acceleration
+ * have different directions, making the bait less slippery, thus easier to control
+ */
+ if(bait_velocity > 0 && velocity_change < 0)
+ bait_velocity += max(-bait_velocity, velocity_change * BAIT_DECELERATION_MULT)
+ else if(bait_velocity < 0 && velocity_change > 0)
+ bait_velocity += min(-bait_velocity, velocity_change * BAIT_DECELERATION_MULT)
+
+ ///bidirectional baits stay bouyant while idle
+ if(bidirectional && reeling_state == REELING_STATE_IDLE)
+ if(velocity_change < 0)
+ bait_velocity = max(bait_velocity + velocity_change, 0)
+ else if(velocity_change > 0)
+ bait_velocity = min(bait_velocity + velocity_change, 0)
+ else
+ bait_velocity += velocity_change
+
+ //check that the fish area is still intersecting the bait now that it has moved
+ fish_on_bait = (fish_position + fish_height >= bait_position) && (bait_position + bait_height >= fish_position)
+
+ if(fish_on_bait)
+ completion += completion_gain * seconds_per_tick
+ if(completion >= 100)
+ complete(TRUE)
+ else
+ completion -= completion_loss * seconds_per_tick
+ if(completion <= 0 && !(special_effects & FISHING_MINIGAME_RULE_NO_ESCAPE))
+ user.balloon_alert(user, "it got away!")
+ complete(FALSE)
+
+ completion = clamp(completion, 0, 100)
+
+///update the vertical pixel position of both fish and bait, and the icon state of the completion bar
+/datum/fishing_challenge/proc/update_visuals()
+ var/bait_offset_mult = bait_position/FISHING_MINIGAME_AREA
+ fishing_hud.hud_bait.pixel_y = round(MINIGAME_SLIDER_HEIGHT * bait_offset_mult, 1)
+ var/fish_offset_mult = fish_position/FISHING_MINIGAME_AREA
+ fishing_hud.hud_fish.pixel_y = round(MINIGAME_SLIDER_HEIGHT * fish_offset_mult, 1)
+ fishing_hud.hud_completion.icon_state = "completion_[FLOOR(completion, 5)]"
+
+///The screen object which bait, fish, and completion bar are visually attached to.
+/atom/movable/screen/fishing_hud
+ icon = 'icons/hud/fishing_hud.dmi'
+ screen_loc = "CENTER+1:8,CENTER:2"
+ name = "fishing minigame"
+ appearance_flags = APPEARANCE_UI|KEEP_TOGETHER
+ alpha = 230
+ ///The fish as shown in the minigame
+ var/atom/movable/screen/hud_fish/hud_fish
+ ///The bait as shown in the minigame
+ var/atom/movable/screen/hud_bait/hud_bait
+ ///The completion bar as shown in the minigame
+ var/atom/movable/screen/hud_completion/hud_completion
+
+///Initialize bait, fish and completion bar and add them to the visual appearance of this screen object.
+/atom/movable/screen/fishing_hud/proc/prepare_minigame(datum/fishing_challenge/challenge)
+ icon_state = challenge.background
+ add_overlay("frame")
+ hud_bait = new(null, null, challenge)
+ hud_fish = new
+ hud_completion = new(null, null, challenge)
+ vis_contents += list(hud_bait, hud_fish, hud_completion)
+ challenge.user.client.screen += src
+
+/atom/movable/screen/fishing_hud/Destroy()
+ QDEL_NULL(hud_fish)
+ QDEL_NULL(hud_bait)
+ QDEL_NULL(hud_completion)
+ return ..()
+
+/atom/movable/screen/hud_bait
+ icon = 'icons/hud/fishing_hud.dmi'
+ icon_state = "bait"
+ vis_flags = VIS_INHERIT_ID
+
+/atom/movable/screen/hud_bait/Initialize(mapload, datum/hud/hud_owner, datum/fishing_challenge/challenge)
. = ..()
- if(!completed)
- send_alert("stopped fishing")
- complete(FALSE)
-
-/datum/fishing_challenge/ui_static_data(mob/user)
- . = ..()
- .["difficulty"] = clamp(difficulty, 1, 100)
- .["fish_ai"] = fish_ai
- .["special_effects"] = special_effects
- .["background_image"] = background
-
-/datum/fishing_challenge/ui_assets(mob/user)
- return list(get_asset_datum(/datum/asset/simple/fishing_minigame)) //preset screens
-
-/datum/fishing_challenge/ui_status(mob/user, datum/ui_state/state)
- return min(
- get_dist(user, lure) > 5 ? UI_CLOSE : UI_INTERACTIVE,
- ui_status_user_has_free_hands(user),
- ui_status_user_is_abled(user, lure),
- )
-
-/datum/fishing_challenge/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
- . = ..()
- if(.)
+ if(!challenge || challenge.bait_pixel_height == MINIGAME_BAIT_HEIGHT)
return
+ var/static/icon_height
+ if(!icon_height)
+ var/list/icon_dimensions = get_icon_dimensions(icon)
+ icon_height = icon_dimensions["height"]
+ var/height_percent_diff = challenge.bait_pixel_height/MINIGAME_BAIT_HEIGHT
+ transform = transform.Scale(1, height_percent_diff)
+ pixel_z = -icon_height * (1 - height_percent_diff) * 0.5
- if(phase != MINIGAME_PHASE)
- return
+/atom/movable/screen/hud_fish
+ icon = 'icons/hud/fishing_hud.dmi'
+ icon_state = "fish"
+ vis_flags = VIS_INHERIT_ID
- switch(action)
- if("win")
- complete(win = TRUE)
- if("lose")
- send_alert("it got away")
- complete(win = FALSE)
+/atom/movable/screen/hud_completion
+ icon = 'icons/hud/fishing_hud.dmi'
+ icon_state = "completion_0"
+ vis_flags = VIS_INHERIT_ID
+
+/atom/movable/screen/hud_completion/Initialize(mapload, datum/hud/hud_owner, datum/fishing_challenge/challenge)
+ . = ..()
+ if(challenge)
+ icon_state = "completion_[FLOOR(challenge.completion, 5)]"
/// The visual that appears over the fishing spot
/obj/effect/fishing_lure
@@ -280,3 +584,21 @@
#undef WAIT_PHASE
#undef BITING_PHASE
#undef MINIGAME_PHASE
+
+#undef FISHING_MINIGAME_AREA
+#undef FISH_TARGET_MIN_DISTANCE
+#undef FISH_FRICTION_MULT
+#undef FISH_SHORT_JUMP_MIN_DISTANCE
+#undef FISH_SHORT_JUMP_MAX_DISTANCE
+#undef FISH_ON_BAIT_ACCELERATION_MULT
+#undef BAIT_MIN_VELOCITY_BOUNCE
+#undef BAIT_DECELERATION_MULT
+
+#undef MINIGAME_SLIDER_HEIGHT
+#undef MINIGAME_BAIT_HEIGHT
+#undef MINIGAME_FISH_HEIGHT
+
+#undef REELING_STATE_IDLE
+#undef REELING_STATE_UP
+#undef REELING_STATE_DOWN
+
diff --git a/code/modules/fishing/fishing_rod.dm b/code/modules/fishing/fishing_rod.dm
index cc873036d08..7e01f693dd5 100644
--- a/code/modules/fishing/fishing_rod.dm
+++ b/code/modules/fishing/fishing_rod.dm
@@ -118,11 +118,14 @@
return hook?.reason_we_cant_fish(target_fish_source)
/obj/item/fishing_rod/proc/consume_bait(atom/movable/reward)
- if(!reward)
+ // catching things that aren't fish or alive mobs doesn't consume baits.
+ if(isnull(reward) || isnull(bait))
return
- var/mob/living/caught_mob = isliving(reward) ? reward : null
- // catching non-fish, non-mob movables, or dead mobs (probably from a chasm) doesn't consume baits.
- if(!bait || !isfish(reward) || !caught_mob || (caught_mob && caught_mob.stat == DEAD))
+ if(isliving(reward))
+ var/mob/living/caught_mob = reward
+ if(caught_mob.stat == DEAD)
+ return
+ else if(!isfish(reward))
return
QDEL_NULL(bait)
update_icon()
@@ -157,7 +160,7 @@
if(!istype(user))
return
var/beam_color = line?.line_color || default_line_color
- var/datum/beam/fishing_line/fishing_line_beam = new(user, target, icon_state = "fishing_line", beam_color = beam_color, override_target_pixel_y = target_py)
+ var/datum/beam/fishing_line/fishing_line_beam = new(user, target, icon_state = "fishing_line", beam_color = beam_color, emissive = FALSE, override_target_pixel_y = target_py)
fishing_line_beam.lefthand = user.get_held_index_of_item(src) % 2 == 1
RegisterSignal(fishing_line_beam, COMSIG_BEAM_BEFORE_DRAW, PROC_REF(check_los))
RegisterSignal(fishing_line_beam, COMSIG_QDELETING, PROC_REF(clear_line))
@@ -208,7 +211,7 @@
SIGNAL_HANDLER
. = NONE
- if(!CheckToolReach(src, source.target, cast_range))
+ if(!isturf(source.origin.loc) || !isturf(source.target.loc) || !CheckToolReach(src, source.target, cast_range))
SEND_SIGNAL(source, COMSIG_FISHING_LINE_SNAPPED) //Stepped out of range or los interrupted
return BEAM_CANCEL_DRAW
@@ -445,6 +448,7 @@
category = CAT_TOOLS
/obj/item/fishing_rod/telescopic
+ name = "telescopic fishing rod"
icon_state = "fishing_rod_telescopic"
desc = "A lightweight, ergonomic, easy to store telescopic fishing rod. "
inhand_icon_state = null
@@ -573,6 +577,31 @@
// Is the fishing rod held in left side hand
var/lefthand = FALSE
+ // Make these inline with final sprites
+ var/righthand_s_px = 13
+ var/righthand_s_py = 16
+
+ var/righthand_e_px = 18
+ var/righthand_e_py = 16
+
+ var/righthand_w_px = -20
+ var/righthand_w_py = 18
+
+ var/righthand_n_px = -14
+ var/righthand_n_py = 16
+
+ var/lefthand_s_px = -13
+ var/lefthand_s_py = 15
+
+ var/lefthand_e_px = 24
+ var/lefthand_e_py = 18
+
+ var/lefthand_w_px = -17
+ var/lefthand_w_py = 16
+
+ var/lefthand_n_px = 13
+ var/lefthand_n_py = 15
+
/datum/beam/fishing_line/Start()
update_offsets(origin.dir)
. = ..()
@@ -601,29 +630,3 @@
if(NORTH)
override_origin_pixel_x = lefthand ? lefthand_n_px : righthand_n_px
override_origin_pixel_y = lefthand ? lefthand_n_py : righthand_n_py
-
-// Make these inline with final sprites
-/datum/beam/fishing_line
- var/righthand_s_px = 13
- var/righthand_s_py = 16
-
- var/righthand_e_px = 18
- var/righthand_e_py = 16
-
- var/righthand_w_px = -20
- var/righthand_w_py = 18
-
- var/righthand_n_px = -14
- var/righthand_n_py = 16
-
- var/lefthand_s_px = -13
- var/lefthand_s_py = 15
-
- var/lefthand_e_px = 24
- var/lefthand_e_py = 18
-
- var/lefthand_w_px = -17
- var/lefthand_w_py = 16
-
- var/lefthand_n_px = 13
- var/lefthand_n_py = 15
diff --git a/code/modules/fishing/sources/_fish_source.dm b/code/modules/fishing/sources/_fish_source.dm
index 13d2fa6c687..5a34db9ce5f 100644
--- a/code/modules/fishing/sources/_fish_source.dm
+++ b/code/modules/fishing/sources/_fish_source.dm
@@ -16,7 +16,14 @@ GLOBAL_LIST_INIT(preset_fish_sources, init_subtypes_w_path_keys(/datum/fish_sour
/// How the spot type is described in fish catalog section about fish sources, will be skipped if null
var/catalog_description
/// Background image name from /datum/asset/simple/fishing_minigame
- var/background = "fishing_background_default"
+ var/background = "background_default"
+
+/datum/fish_source/New()
+ if(!PERFORM_ALL_TESTS(focus_only/fish_sources_tables))
+ return
+ for(var/path in fish_counts)
+ if(!(path in fish_table))
+ stack_trace("path [path] found in the 'fish_counts' list but not in the fish_table one of [type]")
/// Can we fish in this spot at all. Returns DENIAL_REASON or null if we're good to go
/datum/fish_source/proc/reason_we_cant_fish(obj/item/fishing_rod/rod, mob/fisherman)
@@ -38,7 +45,7 @@ GLOBAL_LIST_INIT(preset_fish_sources, init_subtypes_w_path_keys(/datum/fish_sour
. += SETTLER_DIFFICULTY_MOD
// Difficulty modifier added by the fisher's skill level
- if(!challenge || !(FISHING_MINIGAME_RULE_NO_EXP in challenge.special_effects))
+ if(!challenge || !(challenge.special_effects & FISHING_MINIGAME_RULE_NO_EXP))
. += fisherman.mind?.get_skill_modifier(/datum/skill/fishing, SKILL_VALUE_MODIFIER)
// Difficulty modifier added by the rod
@@ -116,24 +123,28 @@ GLOBAL_LIST_INIT(preset_fish_sources, init_subtypes_w_path_keys(/datum/fish_sour
if((reward_path in fish_counts)) // This is limited count result
fish_counts[reward_path] -= 1
if(!fish_counts[reward_path])
- fish_counts -= reward_path //Ran out of these since rolling (multiple fishermen on same source most likely)ù
+ fish_counts -= reward_path //Ran out of these since rolling (multiple fishermen on same source most likely)
+ fish_table -= reward_path
var/atom/movable/reward = spawn_reward(reward_path, fisherman, fishing_spot)
- if(!reward) //baloon alert instead
+ if(!reward) //balloon alert instead
fisherman.balloon_alert(fisherman,pick(duds))
return
if(isitem(reward)) //Try to put it in hand
INVOKE_ASYNC(fisherman, TYPE_PROC_REF(/mob, put_in_hands), reward)
+ else // for fishing things like corpses, move them to the turf of the fisherman
+ INVOKE_ASYNC(reward, TYPE_PROC_REF(/atom/movable, forceMove), get_turf(fisherman))
fisherman.balloon_alert(fisherman, "caught [reward]!")
+
SEND_SIGNAL(fisherman, COMSIG_MOB_FISHING_REWARD_DISPENSED, reward)
return reward
/// Spawns a reward from a atom path right where the fisherman is. Part of the dispense_reward() logic.
-/datum/fish_source/proc/spawn_reward(reward_path, mob/fisherman, turf/fishing_spot)
+/datum/fish_source/proc/spawn_reward(reward_path, mob/fisherman, turf/fishing_spot)
if(reward_path == FISHING_DUD)
return
if(ispath(reward_path, /datum/chasm_detritus))
- return GLOB.chasm_detritus_types[reward_path].dispense_reward(fishing_spot)
+ return GLOB.chasm_detritus_types[reward_path].dispense_detritus(fisherman, fishing_spot)
if(!ispath(reward_path, /atom/movable))
CRASH("Unsupported /datum path [reward_path] passed to fish_source/proc/spawn_reward()")
var/atom/movable/reward = new reward_path(get_turf(fisherman))
@@ -184,10 +195,6 @@ GLOBAL_LIST(fishing_property_cache)
var/list/final_table = fish_table.Copy()
for(var/result in final_table)
- if((result in fish_counts) && fish_counts[result] <= 0) //ran out of these, ignore
- final_table -= result
- continue
-
final_table[result] *= rod.multiplicative_fish_bonus(result, src)
final_table[result] += rod.additive_fish_bonus(result, src) //Decide on order here so it can be multiplicative
if(ispath(result, /obj/item/fish))
diff --git a/code/modules/fishing/sources/source_types.dm b/code/modules/fishing/sources/source_types.dm
index 77c95f6dca6..ffb37753881 100644
--- a/code/modules/fishing/sources/source_types.dm
+++ b/code/modules/fishing/sources/source_types.dm
@@ -6,7 +6,8 @@
/obj/item/fish/pufferfish = 15,
/obj/item/fish/cardinal = 15,
/obj/item/fish/greenchromis = 15,
- /obj/item/fish/lanternfish = 5
+ /obj/item/fish/lanternfish = 5,
+ /obj/item/fish/clownfish/lube = 3,
)
fish_counts = list(
/obj/item/fish/clownfish/lube = 2,
@@ -23,9 +24,10 @@
/obj/item/fish/guppy = 10,
)
catalog_description = "Fish dimension (Fishing portal generator)"
+
/datum/fish_source/chasm
catalog_description = "Chasm depths"
- background = "fishing_background_lavaland"
+ background = "background_lavaland"
fish_table = list(
FISHING_DUD = 5,
/obj/item/fish/chasm_crab = 15,
@@ -44,7 +46,7 @@
/datum/fish_source/lavaland
catalog_description = "Lava vents"
- background = "fishing_background_lavaland"
+ background = "background_lavaland"
fish_table = list(
FISHING_DUD = 5,
/obj/item/stack/ore/slag = 20,
@@ -74,7 +76,8 @@
/obj/item/stack/ore/plasma = 3,
/mob/living/basic/mining/lobstrosity = 1,
/obj/effect/decal/remains/plasma = 1,
-
+ /obj/item/stack/sheet/mineral/mythril = 1,
+ /obj/item/stack/sheet/mineral/adamantine = 1,
)
fish_counts = list(
/obj/item/stack/sheet/mineral/adamantine = 3,
@@ -97,6 +100,7 @@
FISHING_DUD = 18,
/obj/item/fish/sludgefish = 18,
/obj/item/fish/slimefish = 2,
+ /obj/item/storage/wallet/money = 2,
)
fish_counts = list(
/obj/item/storage/wallet/money = 2,
@@ -139,6 +143,9 @@
FISHING_DUD = 5,
/obj/item/fish/boned = 10,
/obj/item/stack/sheet/bone = 2,
+ /obj/item/clothing/gloves/bracer = 2,
+ /obj/effect/decal/remains/human = 2,
+ /obj/item/fish/mastodon = 1,
)
fish_counts = list(
/obj/item/clothing/gloves/bracer = 1,
diff --git a/code/modules/food_and_drinks/machinery/deep_fryer.dm b/code/modules/food_and_drinks/machinery/deep_fryer.dm
index 4b5689383d6..fc20112f08a 100644
--- a/code/modules/food_and_drinks/machinery/deep_fryer.dm
+++ b/code/modules/food_and_drinks/machinery/deep_fryer.dm
@@ -52,7 +52,7 @@ GLOBAL_LIST_INIT(oilfry_blacklisted_items, typecacheof(list(
/obj/machinery/deepfryer/Initialize(mapload)
. = ..()
create_reagents(50, OPENCONTAINER)
- reagents.add_reagent(/datum/reagent/consumable/cooking_oil, 25)
+ reagents.add_reagent(/datum/reagent/consumable/nutriment/fat/oil, 25)
fry_loop = new(src, FALSE)
/obj/machinery/deepfryer/Destroy()
@@ -93,12 +93,12 @@ GLOBAL_LIST_INIT(oilfry_blacklisted_items, typecacheof(list(
to_chat(user, span_warning("There's nothing to dissolve [weapon] in!"))
return
user.visible_message(span_notice("[user] drops [weapon] into [src]."), span_notice("You dissolve [weapon] in [src]."))
- weapon.reagents.trans_to(src, weapon.reagents.total_volume, transfered_by = user)
+ weapon.reagents.trans_to(src, weapon.reagents.total_volume, transferred_by = user)
qdel(weapon)
return
// Make sure we have cooking oil
- if(!reagents.has_reagent(/datum/reagent/consumable/cooking_oil))
- to_chat(user, span_warning("[src] has no cooking oil to fry with!"))
+ if(!reagents.has_reagent(/datum/reagent/consumable/nutriment/fat, check_subtypes = TRUE))
+ to_chat(user, span_warning("[src] has no fat or oil to fry with!"))
return
// Don't deep fry indestructible things, for sanity reasons
if(weapon.resistance_flags & INDESTRUCTIBLE)
@@ -131,7 +131,7 @@ GLOBAL_LIST_INIT(oilfry_blacklisted_items, typecacheof(list(
/obj/machinery/deepfryer/process(seconds_per_tick)
..()
- var/datum/reagent/consumable/cooking_oil/frying_oil = reagents.has_reagent(/datum/reagent/consumable/cooking_oil)
+ var/datum/reagent/consumable/nutriment/fat/frying_oil = reagents.has_reagent(/datum/reagent/consumable/nutriment/fat, check_subtypes = TRUE)
if(!frying_oil)
return
reagents.chem_temp = frying_oil.fry_temperature
diff --git a/code/modules/food_and_drinks/machinery/monkeyrecycler.dm b/code/modules/food_and_drinks/machinery/monkeyrecycler.dm
index 5bb772c7398..8978c975c5e 100644
--- a/code/modules/food_and_drinks/machinery/monkeyrecycler.dm
+++ b/code/modules/food_and_drinks/machinery/monkeyrecycler.dm
@@ -98,6 +98,6 @@ GLOBAL_LIST_EMPTY(monkey_recyclers)
/obj/machinery/monkey_recycler/multitool_act(mob/living/user, obj/item/multitool/I)
. = ..()
if(istype(I))
- to_chat(user, span_notice("You log [src] in the multitool's buffer."))
I.set_buffer(src)
+ balloon_alert(user, "saved to multitool buffer")
return TRUE
diff --git a/code/modules/food_and_drinks/machinery/processor.dm b/code/modules/food_and_drinks/machinery/processor.dm
index 4dbf65f67d2..2c1b0b9d3b3 100644
--- a/code/modules/food_and_drinks/machinery/processor.dm
+++ b/code/modules/food_and_drinks/machinery/processor.dm
@@ -69,6 +69,7 @@
var/cached_multiplier = (recipe.food_multiplier * rating_amount)
for(var/i in 1 to cached_multiplier)
var/atom/processed_food = new recipe.output(drop_location())
+ processed_food.reagents.clear_reagents()
what.reagents.copy_to(processed_food, what.reagents.total_volume, multiplier = 1 / cached_multiplier)
if(cached_mats)
processed_food.set_custom_materials(cached_mats, 1 / cached_multiplier)
diff --git a/code/modules/food_and_drinks/machinery/smartfridge.dm b/code/modules/food_and_drinks/machinery/smartfridge.dm
index 33012584015..6d6645e3368 100644
--- a/code/modules/food_and_drinks/machinery/smartfridge.dm
+++ b/code/modules/food_and_drinks/machinery/smartfridge.dm
@@ -513,7 +513,7 @@
base_build_path = /obj/machinery/smartfridge/drinks
/obj/machinery/smartfridge/drinks/accept_check(obj/item/O)
- if(!is_reagent_container(O) || (O.item_flags & ABSTRACT) || !O.reagents || !O.reagents.reagent_list.len)
+ if(!is_reagent_container(O) || (O.item_flags & ABSTRACT) || istype(O,/obj/item/reagent_containers/cup/bowl) || !O.reagents || !O.reagents.reagent_list.len)
return FALSE
if(istype(O, /obj/item/reagent_containers/cup) || istype(O, /obj/item/reagent_containers/cup/glass) || istype(O, /obj/item/reagent_containers/condiment))
return TRUE
@@ -526,7 +526,7 @@
base_build_path = /obj/machinery/smartfridge/food
/obj/machinery/smartfridge/food/accept_check(obj/item/O)
- if(IS_EDIBLE(O))
+ if(IS_EDIBLE(O) || (istype(O,/obj/item/reagent_containers/cup/bowl) && O.reagents && O.reagents.reagent_list.len))
return TRUE
return FALSE
diff --git a/code/modules/food_and_drinks/pizzabox.dm b/code/modules/food_and_drinks/pizzabox.dm
index a3292872362..1454f1e6917 100644
--- a/code/modules/food_and_drinks/pizzabox.dm
+++ b/code/modules/food_and_drinks/pizzabox.dm
@@ -100,7 +100,7 @@
pizza_overlay.pixel_y = -2
. += pizza_overlay
if(bomb)
- var/mutable_appearance/bomb_overlay = mutable_appearance(bomb.icon, bomb.icon_state)
+ var/mutable_appearance/bomb_overlay = mutable_appearance(bomb.icon, bomb.icon_state, layer = layer + 0.01)
bomb_overlay.pixel_y = 8
. += bomb_overlay
return
@@ -109,13 +109,13 @@
for(var/stacked_box in boxes)
box_offset += 3
var/obj/item/pizzabox/box = stacked_box
- var/mutable_appearance/box_overlay = mutable_appearance(box.icon, box.icon_state)
+ var/mutable_appearance/box_overlay = mutable_appearance(box.icon, box.icon_state, layer = layer + (box_offset * 0.01))
box_overlay.pixel_y = box_offset
. += box_overlay
var/obj/item/pizzabox/box = LAZYLEN(length(boxes)) ? boxes[length(boxes)] : src
if(box.boxtag != "")
- var/mutable_appearance/tag_overlay = mutable_appearance(icon, "pizzabox_tag")
+ var/mutable_appearance/tag_overlay = mutable_appearance(icon, "pizzabox_tag", layer = layer + (box_offset * 0.02))
tag_overlay.pixel_y = box_offset
. += tag_overlay
@@ -306,8 +306,9 @@
/obj/item/pizzabox/bomb/Initialize(mapload)
. = ..()
if(!pizza)
- var/randompizza = pick(subtypesof(/obj/item/food/pizza))
+ var/randompizza = pick(subtypesof(/obj/item/food/pizza) - /obj/item/food/pizza/flatbread) //also disincludes another base type
pizza = new randompizza(src)
+ update_appearance()
register_bomb(new /obj/item/bombcore/miniature/pizza(src))
set_wires(new /datum/wires/explosive/pizza(src))
diff --git a/code/modules/food_and_drinks/recipes/drinks/drinks_alcoholic.dm b/code/modules/food_and_drinks/recipes/drinks/drinks_alcoholic.dm
index da2d6f1f71a..1da96fc0aae 100644
--- a/code/modules/food_and_drinks/recipes/drinks/drinks_alcoholic.dm
+++ b/code/modules/food_and_drinks/recipes/drinks/drinks_alcoholic.dm
@@ -241,7 +241,7 @@
/datum/chemical_reaction/drink/pina_olivada
results = list(/datum/reagent/consumable/ethanol/pina_olivada = 5)
- required_reagents = list(/datum/reagent/consumable/pineapplejuice = 3, /datum/reagent/consumable/ethanol/rum = 1, /datum/reagent/consumable/quality_oil = 1)
+ required_reagents = list(/datum/reagent/consumable/pineapplejuice = 3, /datum/reagent/consumable/ethanol/rum = 1, /datum/reagent/consumable/nutriment/fat/oil/olive = 1)
/datum/chemical_reaction/drink/sbiten
results = list(/datum/reagent/consumable/ethanol/sbiten = 10)
@@ -410,7 +410,7 @@
/datum/chemical_reaction/drink/squirt_cider
results = list(/datum/reagent/consumable/ethanol/squirt_cider = 4)
- required_reagents = list(/datum/reagent/water = 2, /datum/reagent/consumable/tomatojuice = 2, /datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/salt = 1)
+ required_reagents = list(/datum/reagent/water/salt = 2, /datum/reagent/consumable/tomatojuice = 2, /datum/reagent/consumable/nutriment = 1)
mix_message = "The mix swirls and turns a bright red that reminds you of an apple's skin."
reaction_tags = REACTION_TAG_DRINK | REACTION_TAG_EASY | REACTION_TAG_OTHER
diff --git a/code/modules/food_and_drinks/recipes/food_mixtures.dm b/code/modules/food_and_drinks/recipes/food_mixtures.dm
index 54195f63c1f..24cb557b239 100644
--- a/code/modules/food_and_drinks/recipes/food_mixtures.dm
+++ b/code/modules/food_and_drinks/recipes/food_mixtures.dm
@@ -1,6 +1,4 @@
/datum/crafting_recipe/food
- /// A rough equivilance for how much nutrition this recipe's result will provide
- var/total_nutriment_factor = 0
/datum/crafting_recipe/food/on_craft_completion(mob/user, atom/result)
SHOULD_CALL_PARENT(TRUE)
@@ -10,12 +8,6 @@
/datum/crafting_recipe/food/New()
. = ..()
- if(ispath(result, /obj/item/food))
- var/obj/item/food/result_food = new result()
- for(var/datum/reagent/consumable/nutriment as anything in result_food.food_reagents)
- total_nutriment_factor += initial(nutriment.nutriment_factor) * result_food.food_reagents[nutriment]
- qdel(result_food)
-
parts |= reqs
/datum/crafting_recipe/food/crafting_ui_data()
@@ -24,7 +16,7 @@
if(ispath(result, /obj/item/food))
var/obj/item/food/item = result
data["foodtypes"] = bitfield_to_list(initial(item.foodtypes), FOOD_FLAGS)
- data["nutriments"] = total_nutriment_factor
+ data["complexity"] = initial(item.crafting_complexity)
return data
@@ -38,15 +30,25 @@
thermic_constant = 0
H_ion_release = 0
reaction_tags = REACTION_TAG_FOOD | REACTION_TAG_EASY
+ required_other = TRUE
/// Typepath of food that is created on reaction
var/atom/resulting_food_path
+ /// Reagent purity of the result, calculated on reaction
+ var/resulting_reagent_purity
+
+/datum/chemical_reaction/food/pre_reaction_other_checks(datum/reagents/holder)
+ resulting_reagent_purity = holder.get_average_purity(/datum/reagent/consumable)
+ return TRUE
/datum/chemical_reaction/food/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
if(resulting_food_path)
var/atom/location = holder.my_atom.drop_location()
for(var/i in 1 to created_volume)
- new resulting_food_path(location)
+ if(ispath(resulting_food_path, /obj/item/food) && !isnull(resulting_reagent_purity))
+ new resulting_food_path(location, resulting_reagent_purity)
+ else
+ new resulting_food_path(location)
/datum/chemical_reaction/food/tofu
required_reagents = list(/datum/reagent/consumable/soymilk = 10)
@@ -56,7 +58,7 @@
resulting_food_path = /obj/item/food/tofu
/datum/chemical_reaction/food/candycorn
- required_reagents = list(/datum/reagent/consumable/cornoil = 5)
+ required_reagents = list(/datum/reagent/consumable/nutriment/fat/oil = 5)
required_catalysts = list(/datum/reagent/consumable/sugar = 5)
mob_react = FALSE
reaction_flags = REACTION_INSTANT
@@ -95,6 +97,10 @@
required_reagents = list(/datum/reagent/consumable/corn_starch = 1, /datum/reagent/toxin/acid = 1)
required_temp = 374
+/datum/chemical_reaction/food/rice_flour
+ results = list(/datum/reagent/consumable/rice_flour = 10)
+ required_reagents = list(/datum/reagent/consumable/flour = 5,/datum/reagent/consumable/rice = 5)
+
/datum/chemical_reaction/food/caramel
results = list(/datum/reagent/consumable/caramel = 1)
required_reagents = list(/datum/reagent/consumable/sugar = 1)
@@ -152,6 +158,12 @@
reaction_flags = REACTION_INSTANT
resulting_food_path = /obj/item/food/dough
+/datum/chemical_reaction/food/rice_dough
+ required_reagents = list(/datum/reagent/consumable/rice_flour = 20,/datum/reagent/water = 10)
+ mix_message = "The ingredients form a rice dough."
+ reaction_flags = REACTION_INSTANT
+ resulting_food_path = /obj/item/food/rice_dough
+
/datum/chemical_reaction/food/cakebatter
required_reagents = list(/datum/reagent/consumable/eggyolk = 6, /datum/reagent/consumable/eggwhite = 12, /datum/reagent/consumable/flour = 15, /datum/reagent/consumable/sugar = 5)
mix_message = "The ingredients form a cake batter."
@@ -206,7 +218,7 @@
required_reagents = list(/datum/reagent/consumable/milk = 1, /datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/flour = 1)
/datum/chemical_reaction/food/mothic_pizza_dough
- required_reagents = list(/datum/reagent/consumable/milk = 5, /datum/reagent/consumable/quality_oil = 2, /datum/reagent/medicine/salglu_solution = 5, /datum/reagent/consumable/cornmeal = 10, /datum/reagent/consumable/flour = 5)
+ required_reagents = list(/datum/reagent/consumable/milk = 5, /datum/reagent/consumable/nutriment/fat/oil/olive = 2, /datum/reagent/medicine/salglu_solution = 5, /datum/reagent/consumable/cornmeal = 10, /datum/reagent/consumable/flour = 5)
mix_message = "The ingredients form a pizza dough."
reaction_flags = REACTION_INSTANT
resulting_food_path = /obj/item/food/mothic_pizza_dough
@@ -244,14 +256,15 @@
mix_message = "The mixture thickens into yoghurt."
reaction_flags = REACTION_INSTANT
-/datum/chemical_reaction/food/quality_oil_upconvert
- required_reagents = list(/datum/reagent/consumable/quality_oil = 1, /datum/reagent/consumable/cooking_oil = 2)
- results = list(/datum/reagent/consumable/quality_oil = 2)
+/datum/chemical_reaction/food/olive_oil_upconvert
+ required_catalysts = list(/datum/reagent/consumable/nutriment/fat/oil/olive = 1)
+ required_reagents = list( /datum/reagent/consumable/nutriment/fat/oil = 2)
+ results = list(/datum/reagent/consumable/nutriment/fat/oil/olive = 2)
mix_message = "The cooking oil dilutes the quality oil- how delightfully devilish..."
reaction_flags = REACTION_INSTANT
-/datum/chemical_reaction/food/quality_oil
- results = list(/datum/reagent/consumable/quality_oil = 2)
+/datum/chemical_reaction/food/olive_oil
+ results = list(/datum/reagent/consumable/nutriment/fat/oil/olive = 2)
required_reagents = list(/datum/reagent/consumable/olivepaste = 4, /datum/reagent/water = 1)
reaction_flags = REACTION_INSTANT
diff --git a/code/modules/food_and_drinks/recipes/soup_guide.dm b/code/modules/food_and_drinks/recipes/soup_guide.dm
index a2bc0faccdb..3a9ba05ff0c 100644
--- a/code/modules/food_and_drinks/recipes/soup_guide.dm
+++ b/code/modules/food_and_drinks/recipes/soup_guide.dm
@@ -28,7 +28,6 @@
var/datum/glass_style/has_foodtype/soup_style = GLOB.glass_style_singletons[expected_container][result]
if(istype(soup_style))
data["foodtypes"] = bitfield_to_list(soup_style.drink_type, FOOD_FLAGS)
- data["nutriments"] = total_nutriment_factor
return data
@@ -39,10 +38,6 @@
for(var/obj/item/ingredienttype as anything in chemical_reaction.required_ingredients)
LAZYSET(reqs, ingredienttype, chemical_reaction.required_ingredients[ingredienttype])
- if(ispath(result, /datum/reagent/consumable))
- var/datum/reagent/consumable/soup_result = result
- total_nutriment_factor += initial(soup_result.nutriment_factor) * result_amount
-
/datum/crafting_recipe/food/reaction/soup/meatball_soup
reaction = /datum/chemical_reaction/food/soup/meatballsoup
diff --git a/code/modules/food_and_drinks/recipes/soup_mixtures.dm b/code/modules/food_and_drinks/recipes/soup_mixtures.dm
index edc7867568f..ad2caa84ca6 100644
--- a/code/modules/food_and_drinks/recipes/soup_mixtures.dm
+++ b/code/modules/food_and_drinks/recipes/soup_mixtures.dm
@@ -4,7 +4,7 @@
/datum/reagent/consumable/nutriment/soup
name = "Soup"
chemical_flags = NONE
- nutriment_factor = 12 * REAGENTS_METABOLISM // Slightly less to that of nutriment as soups will come with nutriments in tow
+ nutriment_factor = 12 // Slightly less to that of nutriment as soups will come with nutriments in tow
burning_temperature = 520
default_container = /obj/item/reagent_containers/cup/bowl
glass_price = FOOD_PRICE_CHEAP
@@ -47,7 +47,7 @@
/// Tracks the total number of ingredient items needed, for calculating multipliers. Only done once in first on_reaction
VAR_FINAL/total_ingredient_max
- /// Multiplier applied to all reagents transfered from reagents to pot when the soup is cooked
+ /// Multiplier applied to all reagents transferred from reagents to pot when the soup is cooked
var/ingredient_reagent_multiplier = 0.8
/// What percent of nutriment is converted to "soup" (what percent does not stay final product)?
/// Raise this if your ingredients have a lot of nutriment and is overpowering your other reagents
@@ -85,6 +85,34 @@
if(!length(required_ingredients))
return
+ // If a food item is supposed to be made, remove relevant ingredients from the pot, then make the item
+ if(!isnull(resulting_food_path))
+ var/list/tracked_ingredients
+ LAZYINITLIST(tracked_ingredients)
+ var/ingredient_max_multiplier = INFINITY
+ var/obj/item/reagent_containers/cup/soup_pot/pot = holder.my_atom
+
+ // Tracked ingredients are indexed by type and point to a list containing the actual items
+ for(var/obj/item/ingredient as anything in pot.added_ingredients)
+ if(is_type_in_list(ingredient, required_ingredients))
+ LAZYADD(tracked_ingredients[ingredient.type],ingredient)
+ // Find the max number of ingredients that may be used for making the food item
+ for(var/list/ingredient_type as anything in tracked_ingredients)
+ ingredient_max_multiplier = min(ingredient_max_multiplier,LAZYLEN(tracked_ingredients[ingredient_type]))
+ // Create the food items, removing the relavent ingredients at the same time
+ for(var/i in 1 to (min(created_volume,ingredient_max_multiplier)))
+ for(var/list/ingredient_type as anything in tracked_ingredients)
+ var/ingredient = tracked_ingredients[ingredient_type][i]
+ LAZYREMOVE(pot.added_ingredients,ingredient)
+ qdel(ingredient)
+ var/obj/item/created = new resulting_food_path(get_turf(pot))
+ created.pixel_y += 8
+ // Re-add required reagents that were not used in this step
+ if(created_volume > ingredient_max_multiplier)
+ for(var/reagent_path as anything in required_reagents)
+ holder.add_reagent(reagent_path,(required_reagents[reagent_path])*(created_volume-ingredient_max_multiplier))
+
+
// This only happens if we're being instant reacted so let's just skip to what we really want
if(isnull(reaction))
testing("Soup reaction of type [type] instant reacted, cleaning up.")
@@ -113,7 +141,6 @@
/datum/chemical_reaction/food/soup/reaction_step(datum/reagents/holder, datum/equilibrium/reaction, delta_t, delta_ph, step_reaction_vol)
if(!length(required_ingredients))
return
-
testing("Soup reaction step progressing with an increment volume of [step_reaction_vol] and delta_t of [delta_t].")
var/obj/item/reagent_containers/cup/soup_pot/pot = holder.my_atom
var/list/cached_ingredients = reaction.data["ingredients"]
@@ -171,7 +198,7 @@
/**
* Cleans up the ingredients and adds whatever leftover reagents to the mixture
*
- * * holder: The sou ppot
+ * * holder: The soup pot
* * reaction: The reaction being cleaned up, note this CAN be null if being instant reacted
* * react_vol: How much soup was produced
*/
@@ -180,29 +207,26 @@
reaction?.data["ingredients"] = null
- for(var/obj/item/ingredient as anything in pot.added_ingredients)
- // Let's not mess with indestructible items.
- // Chef doesn't need more ways to delete things with cooking.
- if(ingredient.resistance_flags & INDESTRUCTIBLE)
- continue
+ // If soup is made, remove ingredients as their reagents were added to the soup
+ if(react_vol)
+ for(var/obj/item/ingredient as anything in pot.added_ingredients)
+ // Let's not mess with indestructible items.
+ // Chef doesn't need more ways to delete things with cooking.
+ if(ingredient.resistance_flags & INDESTRUCTIBLE)
+ continue
- // Things that had reagents or ingredients in the soup will get deleted
- else if(!isnull(ingredient.reagents) || is_type_in_list(ingredient, required_ingredients))
+ // Everything else will just get fried
+ if(isnull(ingredient.reagents) && !is_type_in_list(ingredient, required_ingredients))
+ ingredient.AddElement(/datum/element/fried_item, 30)
+ continue
+
+ // Things that had reagents or ingredients in the soup will get deleted
LAZYREMOVE(pot.added_ingredients, ingredient)
// Send everything left behind
transfer_ingredient_reagents(ingredient, holder)
// Delete, it's done
qdel(ingredient)
- // Everything else will just get fried
- else
- ingredient.AddElement(/datum/element/fried_item, 30)
-
- // Spawning physical food results
- if(resulting_food_path)
- var/obj/item/created = new resulting_food_path(get_turf(pot))
- created.pixel_y += 8
-
// Anything left in the ingredient list will get dumped out
pot.dump_ingredients(get_turf(pot), y_offset = 8)
// Blackbox log the chemical reaction used, to account for soup reaction that don't produce typical results
@@ -560,8 +584,8 @@
/datum/chemical_reaction/food/soup/chili_sin_carne
required_reagents = list(
- /datum/reagent/water = 40,
- /datum/reagent/consumable/salt = 5,
+ /datum/reagent/water = 30,
+ /datum/reagent/water/salt = 10,
)
required_ingredients = list(
/obj/item/food/grown/chili = 1,
@@ -730,7 +754,7 @@
/datum/reagent/consumable/nutriment/soup/clown_tears
name = "Clown's Tears"
description = "The sorrow and melancholy of a thousand bereaved clowns, forever denied their Honkmechs."
- nutriment_factor = 5 * REAGENTS_METABOLISM
+ nutriment_factor = 5
ph = 9.2
data = list("a bad joke" = 1, "mournful honking" = 1)
color = "#EEF442"
@@ -1097,8 +1121,8 @@
/datum/chemical_reaction/food/soup/electron
required_reagents = list(
- /datum/reagent/water = 45,
- /datum/reagent/consumable/salt = 5,
+ /datum/reagent/water = 40,
+ /datum/reagent/water/salt = 10,
)
required_ingredients = list(
/obj/item/food/grown/mushroom/jupitercup = 1,
@@ -1661,8 +1685,8 @@
/datum/chemical_reaction/food/soup/rice_porridge
required_reagents = list(
- /datum/reagent/water = 30,
- /datum/reagent/consumable/salt = 5,
+ /datum/reagent/water = 20,
+ /datum/reagent/water/salt = 10,
)
required_ingredients = list(
/obj/item/food/boiledrice = 1,
@@ -1803,7 +1827,7 @@
/obj/item/food/spaghetti/rawnoodles = 1
)
required_catalysts = list(
- /datum/reagent/water = 30
+ /datum/reagent/water/salt = 10,
)
resulting_food_path = /obj/item/food/spaghetti/boilednoodles
ingredient_reagent_multiplier = 0
@@ -1950,7 +1974,7 @@
name = "\improper New Osaka Sunrise soup"
icon = 'icons/obj/food/martian.dmi'
icon_state = "new_osaka_sunrise"
- drink_type = MEAT | GRAIN | DAIRY | VEGETABLES
+ drink_type = VEGETABLES | BREAKFAST
/datum/chemical_reaction/food/soup/new_osaka_sunrise
required_reagents = list(
@@ -2079,7 +2103,7 @@
name = "\improper Hong Kong macaroni soup"
icon = 'icons/obj/food/martian.dmi'
icon_state = "hong_kong_macaroni"
- drink_type = MEAT | VEGETABLES
+ drink_type = MEAT | VEGETABLES | GRAIN
/datum/chemical_reaction/food/soup/hong_kong_macaroni
required_reagents = list(
@@ -2137,7 +2161,7 @@
name = "secret noodle soup"
icon = 'icons/obj/food/martian.dmi'
icon_state = "secret_noodle_soup"
- drink_type = MEAT | VEGETABLES
+ drink_type = MEAT | VEGETABLES | GRAIN
/datum/chemical_reaction/food/soup/secret_noodle_soup
required_reagents = list(
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_burger.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_burger.dm
index 5ef95ca8ab6..06b5e8952ed 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_burger.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_burger.dm
@@ -382,7 +382,7 @@
/obj/item/food/grown/cabbage = 1,
/obj/item/toy/crayon/green = 1,
/obj/item/flashlight/flare = 1,
- /datum/reagent/consumable/cooking_oil = 15
+ /datum/reagent/consumable/nutriment/fat/oil = 15
)
result = /obj/item/food/burger/crazy
category = CAT_BURGER
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm
index b70b3b9114c..4a2c9f2935d 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm
@@ -141,14 +141,14 @@
result = /obj/item/food/cake/hardware_cake
category = CAT_CAKE
-/datum/crafting_recipe/food/bscccake
- name = "blackberry and strawberry chocolate cake"
+/datum/crafting_recipe/food/berry_chocolate_cake
+ name = "strawberry chocolate cake"
reqs = list(
/obj/item/food/cake/plain = 1,
/obj/item/food/chocolatebar = 2,
/obj/item/food/grown/berries = 5
)
- result = /obj/item/food/cake/bscc
+ result = /obj/item/food/cake/berry_chocolate_cake
category = CAT_CAKE
/datum/crafting_recipe/food/pavlovacream
@@ -173,13 +173,13 @@
result = /obj/item/food/cake/pavlova/nuts
category = CAT_CAKE
-/datum/crafting_recipe/food/bscvcake
+/datum/crafting_recipe/food/berry_vanilla_cake
name = "blackberry and strawberry vanilla cake"
reqs = list(
/obj/item/food/cake/plain = 1,
/obj/item/food/grown/berries = 5
)
- result = /obj/item/food/cake/bsvc
+ result = /obj/item/food/cake/berry_vanilla_cake
category = CAT_CAKE
/datum/crafting_recipe/food/clowncake
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_guide.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_guide.dm
index 30eee31295b..ea6d10cb668 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_guide.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_guide.dm
@@ -180,12 +180,12 @@
result = /datum/reagent/consumable/yoghurt
reaction = /datum/chemical_reaction/food/yoghurt
-/datum/crafting_recipe/food/reaction/quality_oil
- result = /datum/reagent/consumable/quality_oil
- reaction = /datum/chemical_reaction/food/quality_oil
+/datum/crafting_recipe/food/reaction/olive_oil
+ result = /datum/reagent/consumable/nutriment/fat/oil/olive
+ reaction = /datum/chemical_reaction/food/olive_oil
-/datum/crafting_recipe/food/reaction/quality_oil/upconvert
- reaction = /datum/chemical_reaction/food/quality_oil_upconvert
+/datum/crafting_recipe/food/reaction/olive_oil/upconvert
+ reaction = /datum/chemical_reaction/food/olive_oil_upconvert
/datum/crafting_recipe/food/reaction/moonshine
reaction = /datum/chemical_reaction/drink/moonshine
@@ -228,6 +228,7 @@
/datum/crafting_recipe/food/rollingpin/pizza_sheet
reqs = list(/obj/item/food/pizzaslice/margherita = 1)
result = /obj/item/stack/sheet/pizza
+ category = CAT_PIZZA
// Tools: Knife
@@ -249,7 +250,7 @@
/datum/crafting_recipe/food/knife/cakeslice
reqs = list(/obj/item/food/cake/plain = 1)
result = /obj/item/food/cakeslice/plain
- category = CAT_PASTRY
+ category = CAT_CAKE
/datum/crafting_recipe/food/knife/pizzaslice
reqs = list(/obj/item/food/pizza/margherita = 1)
@@ -266,9 +267,9 @@
result = /obj/item/food/rootdoughslice
category = CAT_BREAD
-/datum/crafting_recipe/food/knife/pastrybase
+/datum/crafting_recipe/food/knife/rawpastrybase
reqs = list(/obj/item/food/piedough = 1)
- result = /obj/item/food/pastrybase
+ result = /obj/item/food/rawpastrybase
category = CAT_BREAD
/datum/crafting_recipe/food/knife/butterslice
@@ -357,7 +358,7 @@
/datum/crafting_recipe/food/knife/lil_baked_rice
reqs = list(/obj/item/food/big_baked_rice = 1)
result = /obj/item/food/lil_baked_rice
- category = CAT_SALAD
+ category = CAT_MOTH
/datum/crafting_recipe/food/knife/watermelonslice
reqs = list(/obj/item/food/grown/watermelon = 1)
@@ -447,7 +448,7 @@
/datum/crafting_recipe/food/grill/grilled_cheese_sandwich
reqs = list(/obj/item/food/sandwich/cheese = 1)
result = /obj/item/food/sandwich/cheese/grilled
- category = CAT_BREAD
+ category = CAT_SANDWICH
/datum/crafting_recipe/food/grill/grilled_cheese
reqs = list(/obj/item/food/cheese/firm_cheese_slice = 1)
@@ -511,6 +512,11 @@
"Bake until ready"
)
+/datum/crafting_recipe/food/grill/hard_taco_shell
+ reqs = list(/obj/item/food/tortilla = 1)
+ result = /obj/item/food/hard_taco_shell
+ category = CAT_MEXICAN
+
// Machinery: Grinder
/datum/crafting_recipe/food/grinder
machinery = list(/obj/machinery/reagentgrinder)
@@ -644,7 +650,7 @@
/datum/crafting_recipe/food/processor/tortilla
reqs = list(/obj/item/food/grown/corn = 1)
result = /obj/item/food/tortilla
- category = CAT_BREAD
+ category = CAT_MEXICAN
/datum/crafting_recipe/food/processor/tempeh
reqs = list(/obj/item/food/tempehstarter = 1)
@@ -748,12 +754,12 @@
/datum/crafting_recipe/food/oven/pie
reqs = list(/obj/item/food/piedough = 1)
result = /obj/item/food/pie/plain
- category = CAT_PASTRY
+ category = CAT_PIE
/datum/crafting_recipe/food/oven/cake
reqs = list(/obj/item/food/cakebatter = 1)
result = /obj/item/food/cake/plain
- category = CAT_PASTRY
+ category = CAT_CAKE
/datum/crafting_recipe/food/oven/breadstick
reqs = list(/obj/item/food/raw_breadstick = 1)
@@ -777,7 +783,7 @@
/datum/crafting_recipe/food/oven/big_baked_rice
reqs = list(/obj/item/food/raw_baked_rice = 1)
result = /obj/item/food/big_baked_rice
- category = CAT_SALAD
+ category = CAT_MOTH
/datum/crafting_recipe/food/oven/ratatouille
reqs = list(/obj/item/food/raw_ratatouille = 1)
@@ -787,7 +793,7 @@
/datum/crafting_recipe/food/oven/stuffed_peppers
reqs = list(/obj/item/food/raw_stuffed_peppers = 1)
result = /obj/item/food/stuffed_peppers
- category = CAT_SALAD
+ category = CAT_MOTH
/datum/crafting_recipe/food/oven/roasted_bell_pepper
reqs = list(/obj/item/food/grown/bell_pepper = 1)
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_lizard.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_lizard.dm
index ccb0b975cb7..714c36223a4 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_lizard.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_lizard.dm
@@ -74,7 +74,7 @@
/obj/item/food/grown/garlic = 1,
/datum/reagent/consumable/lemonjuice = 3,
/datum/reagent/consumable/blackpepper = 2,
- /datum/reagent/consumable/quality_oil = 3
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 3
)
result = /obj/item/food/lizard_escargot
category = CAT_LIZARD
@@ -148,7 +148,7 @@
/obj/item/food/steeped_mushrooms = 1,
/obj/item/food/grown/mushroom/plumphelmet = 1,
/obj/item/food/grown/mushroom/chanterelle = 1,
- /datum/reagent/consumable/quality_oil = 5
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 5
)
result = /obj/item/food/mushroomy_stirfry
category = CAT_LIZARD
@@ -204,7 +204,7 @@
/obj/item/food/spaghetti/nizaya = 1,
/obj/item/food/grown/garlic = 1,
/obj/item/food/grown/chili = 1,
- /datum/reagent/consumable/quality_oil = 5
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 5
)
result = /obj/item/food/spaghetti/garlic_nizaya
category = CAT_LIZARD
@@ -228,7 +228,7 @@
/obj/item/food/spaghetti/nizaya = 1,
/obj/item/food/steeped_mushrooms = 1,
/obj/item/food/grown/garlic = 1,
- /datum/reagent/consumable/quality_oil = 5
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 5
)
result = /obj/item/food/spaghetti/mushroom_nizaya
category = CAT_LIZARD
@@ -239,7 +239,7 @@
/obj/item/food/root_flatbread = 1,
/obj/item/food/grown/garlic = 1,
/datum/reagent/consumable/lemonjuice = 2,
- /datum/reagent/consumable/quality_oil = 3
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 3
)
result = /obj/item/food/pizza/flatbread/rustic
category = CAT_LIZARD
@@ -251,7 +251,7 @@
/obj/item/food/grown/garlic = 1,
/obj/item/food/grown/tomato = 1,
/obj/item/food/meatball = 2,
- /datum/reagent/consumable/quality_oil = 3
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 3
)
result = /obj/item/food/pizza/flatbread/italic
category = CAT_LIZARD
@@ -313,7 +313,7 @@
/obj/item/food/root_flatbread = 1,
/obj/item/food/grown/tomato = 1,
/obj/item/food/grown/mushroom = 3,
- /datum/reagent/consumable/quality_oil = 3
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 3
)
result = /obj/item/food/pizza/flatbread/mushroom
category = CAT_LIZARD
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_martian.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_martian.dm
index b184347a38f..fb4f29284b8 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_martian.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_martian.dm
@@ -648,7 +648,7 @@
/obj/item/food/friedegg = 1,
/obj/item/food/grown/chili = 1,
/datum/reagent/consumable/yoghurt = 5,
- /datum/reagent/consumable/quality_oil = 2,
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 2,
)
result = /obj/item/food/cilbir
category = CAT_MARTIAN
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm
index 908ac40c016..47bd455cd85 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm
@@ -173,7 +173,7 @@
/obj/item/food/meat/slab/rawcrab = 1
)
result = /obj/item/food/crab_rangoon
- category = CAT_MISCFOOD
+ category = CAT_SEAFOOD
/datum/crafting_recipe/food/royalcheese
name = "Royal Cheese"
@@ -203,7 +203,7 @@
/datum/reagent/consumable/salt = 5,
/obj/item/food/grown/herbs = 2,
/obj/item/food/grown/garlic = 1,
- /datum/reagent/consumable/quality_oil = 5,
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 5,
/obj/item/food/canned/pine_nuts = 1
)
result = /obj/item/food/pesto
@@ -215,7 +215,7 @@
/obj/item/food/canned/tomatoes = 1,
/datum/reagent/consumable/salt = 2,
/obj/item/food/grown/herbs = 1,
- /datum/reagent/consumable/quality_oil = 5
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 5
)
result = /obj/item/food/tomato_sauce
category = CAT_MISCFOOD
@@ -422,8 +422,7 @@
reqs = list(
/obj/item/reagent_containers/cup/beaker/large = 1,
/obj/item/food/grown/cucumber = 10,
- /datum/reagent/water = 10,
- /datum/reagent/consumable/salt = 10,
+ /datum/reagent/water/salt = 20,
)
result = /obj/item/storage/fancy/pickles_jar
category = CAT_MISCFOOD
@@ -434,7 +433,7 @@
reqs = list(
/obj/item/food/grown/eggplant = 1,
/obj/item/food/grown/garlic = 1,
- /datum/reagent/consumable/quality_oil = 3,
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 3,
)
result = /obj/item/food/sauteed_eggplant
category = CAT_MISCFOOD
@@ -458,7 +457,7 @@
/obj/item/food/pita_bread = 1,
/obj/item/food/grown/eggplant = 1,
/obj/item/food/grown/garlic = 1,
- /datum/reagent/consumable/quality_oil = 5,
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 5,
/datum/reagent/consumable/lemonjuice = 3,
)
result = /obj/item/food/baba_ghanoush
@@ -501,7 +500,7 @@
name = "Tzatziki sauce"
reqs = list(
/obj/item/food/grown/cucumber = 1,
- /datum/reagent/consumable/quality_oil = 2,
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 2,
/obj/item/food/grown/garlic = 1,
/datum/reagent/consumable/salt = 1,
)
@@ -548,7 +547,7 @@
reqs = list(
/datum/reagent/consumable/flour = 10,
/datum/reagent/water = 5,
- /datum/reagent/consumable/quality_oil = 2,
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 2,
/datum/reagent/consumable/sugar = 2,
)
result = /obj/item/food/raw_pita_bread
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_moth.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_moth.dm
index 880b51a3909..bb20f4ab0b3 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_moth.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_moth.dm
@@ -23,7 +23,7 @@
/obj/item/seeds/sunflower = 1,
/obj/item/seeds/pumpkin = 1,
/obj/item/seeds/poppy = 1,
- /datum/reagent/consumable/quality_oil = 2
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 2
)
result = /obj/item/food/toasted_seeds
category = CAT_MOTH
@@ -210,7 +210,7 @@
/obj/item/food/grown/tomato = 1,
/obj/item/food/cheese/mozzarella = 1,
/obj/item/food/grown/herbs = 1,
- /datum/reagent/consumable/quality_oil = 2,
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 2,
/datum/reagent/consumable/vinegar = 2
)
result = /obj/item/food/caprese_salad
@@ -219,7 +219,7 @@
/datum/crafting_recipe/food/fleet_salad
name = "Lörtonknusksolt (Fleet salad)"
reqs = list(
- /datum/reagent/consumable/quality_oil = 2,
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 2,
/datum/reagent/consumable/vinegar = 2,
/obj/item/food/breadslice/plain = 1,
/obj/item/food/grilled_cheese = 1,
@@ -233,7 +233,7 @@
/datum/crafting_recipe/food/cotton_salad
name = "Flöfrölenknusksolt (Cotton salad)"
reqs = list(
- /datum/reagent/consumable/quality_oil = 2,
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 2,
/datum/reagent/consumable/vinegar = 2,
/obj/item/food/grown/carrot = 1,
/obj/item/food/mothic_salad = 1,
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_salad.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_salad.dm
index 653aac9672c..8ed91683c05 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_salad.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_salad.dm
@@ -104,7 +104,7 @@
/obj/item/food/grown/carrot = 1,
/obj/item/food/onion_slice/red = 2,
/obj/item/food/grown/cabbage = 1,
- /datum/reagent/consumable/quality_oil = 2,
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 2,
)
result = /obj/item/food/salad/kale_salad
category = CAT_SALAD
@@ -117,7 +117,7 @@
/obj/item/food/grown/tomato = 1,
/obj/item/food/onion_slice/red = 2,
/obj/item/food/cheese/wedge = 1,
- /datum/reagent/consumable/quality_oil = 5,
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 5,
/obj/item/food/grown/cucumber = 1,
)
result = /obj/item/food/salad/greek_salad
@@ -130,7 +130,7 @@
/obj/item/food/grown/cabbage = 2,
/obj/item/food/onion_slice/red = 1,
/obj/item/food/cheese/wedge = 1,
- /datum/reagent/consumable/quality_oil = 5,
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 5,
/obj/item/food/breadslice/plain = 1,
)
result = /obj/item/food/salad/caesar_salad
@@ -143,7 +143,7 @@
/obj/item/food/grown/cabbage = 2,
/obj/item/food/grown/carrot = 1,
/obj/item/food/grown/peas = 1,
- /datum/reagent/consumable/quality_oil = 5,
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 5,
)
result = /obj/item/food/salad/spring_salad
category = CAT_SALAD
@@ -167,7 +167,7 @@
/obj/item/food/grown/herbs = 3,
/obj/item/food/grown/berries = 2,
/obj/item/food/pineappleslice = 2,
- /datum/reagent/consumable/quality_oil = 2,
+ /datum/reagent/consumable/nutriment/fat/oil/olive = 2,
)
result = /obj/item/food/salad/spinach_fruit_salad
category = CAT_SALAD
diff --git a/code/modules/holiday/holidays.dm b/code/modules/holiday/holidays.dm
index 8a8946fa836..c2b1165f74c 100644
--- a/code/modules/holiday/holidays.dm
+++ b/code/modules/holiday/holidays.dm
@@ -18,8 +18,8 @@
var/year_offset = 0
///Timezones this holiday is celebrated in (defaults to three timezones spanning a 50 hour window covering all timezones)
var/list/timezones = list(TIMEZONE_LINT, TIMEZONE_UTC, TIMEZONE_ANYWHERE_ON_EARTH)
- ///If this is defined, drones without a default hat will spawn with this one during the holiday; check drones_as_items.dm to see this used
- var/obj/item/drone_hat
+ ///If this is defined, drones/assistants without a default hat will spawn with this item in their head clothing slot.
+ var/obj/item/holiday_hat
///When this holiday is active, does this prevent mail from arriving to cargo? Try not to use this for longer holidays.
var/mail_holiday = FALSE
var/poster_name = "generic celebration poster"
@@ -109,6 +109,7 @@
name = "Fleet Day"
begin_month = JANUARY
begin_day = 19
+ holiday_hat = /obj/item/clothing/head/mothcap
/datum/holiday/fleet_day/greet()
return "This day commemorates another year of successful survival aboard the Mothic Grand Nomad Fleet. Moths galaxywide are encouraged to eat, drink, and be merry."
@@ -155,7 +156,7 @@
name = "Birthday of Space Station 13"
begin_day = 16
begin_month = FEBRUARY
- drone_hat = /obj/item/clothing/head/costume/festive
+ holiday_hat = /obj/item/clothing/head/costume/festive
poster_name = "station birthday poster"
poster_desc = "A poster celebrating another year of the station's operation. Why anyone would be happy to be here is byond you."
poster_icon = "holiday_cake" // is a lie
@@ -220,7 +221,7 @@
name = "St. Patrick's Day"
begin_day = 17
begin_month = MARCH
- drone_hat = /obj/item/clothing/head/soft/green
+ holiday_hat = /obj/item/clothing/head/soft/green
/datum/holiday/no_this_is_patrick/getStationPrefix()
return pick("Blarney","Green","Leprechaun","Booze")
@@ -235,6 +236,7 @@
begin_month = APRIL
begin_day = 1
end_day = 2
+ holiday_hat = /obj/item/clothing/head/chameleon/broken
/datum/holiday/april_fools/celebrate()
. = ..()
@@ -252,7 +254,7 @@
name = "Cosmonautics Day"
begin_day = 12
begin_month = APRIL
- drone_hat = /obj/item/clothing/head/syndicatefake
+ holiday_hat = /obj/item/clothing/head/syndicatefake
/datum/holiday/spess/greet()
return "On this day over 600 years ago, Comrade Yuri Gagarin first ventured into space!"
@@ -261,6 +263,7 @@
name = "Four-Twenty"
begin_day = 20
begin_month = APRIL
+ holiday_hat = /obj/item/clothing/head/rasta
/datum/holiday/fourtwenty/getStationPrefix()
return pick("Snoop","Blunt","Toke","Dank","Cheech","Chong")
@@ -283,7 +286,7 @@
timezones = list(TIMEZONE_TKT, TIMEZONE_TOT, TIMEZONE_NZST, TIMEZONE_NFT, TIMEZONE_LHST, TIMEZONE_AEST, TIMEZONE_ACST, TIMEZONE_ACWST, TIMEZONE_AWST, TIMEZONE_CXT, TIMEZONE_CCT, TIMEZONE_CKT, TIMEZONE_NUT)
begin_day = 25
begin_month = APRIL
- drone_hat = /obj/item/food/grown/poppy
+ holiday_hat = /obj/item/food/grown/poppy
/datum/holiday/anz/getStationPrefix()
return pick("Australian","New Zealand","Poppy", "Southern Cross")
@@ -294,7 +297,7 @@
name = "Labor Day"
begin_day = 1
begin_month = MAY
- drone_hat = /obj/item/clothing/head/utility/hardhat
+ holiday_hat = /obj/item/clothing/head/utility/hardhat
mail_holiday = TRUE
//Draconic Day is celebrated on May 3rd, the date on which the Draconic language was merged (#26780)
@@ -313,7 +316,7 @@
name = "Firefighter's Day"
begin_day = 4
begin_month = MAY
- drone_hat = /obj/item/clothing/head/utility/hardhat/red
+ holiday_hat = /obj/item/clothing/head/utility/hardhat/red
/datum/holiday/firefighter/getStationPrefix()
return pick("Burning","Blazing","Plasma","Fire")
@@ -322,7 +325,6 @@
name = "Bee Day"
begin_day = 20
begin_month = MAY
- drone_hat = /obj/item/clothing/mask/animal/small/bee
/datum/holiday/bee/getStationPrefix()
return pick("Bee","Honey","Hive","Africanized","Mead","Buzz")
@@ -355,6 +357,7 @@
name = "Summer Solstice"
begin_day = 21
begin_month = JUNE
+ holiday_hat = /obj/item/clothing/head/costume/garland
/datum/holiday/pride_week
name = PRIDE_WEEK
@@ -377,13 +380,13 @@
name = "Doctor's Day"
begin_day = 1
begin_month = JULY
- drone_hat = /obj/item/clothing/head/costume/nursehat
+ holiday_hat = /obj/item/clothing/head/costume/nursehat
/datum/holiday/ufo
name = "UFO Day"
begin_day = 2
begin_month = JULY
- drone_hat = /obj/item/clothing/mask/facehugger/dead
+ holiday_hat = /obj/item/clothing/head/collectable/xenom
/datum/holiday/ufo/getStationPrefix() //Is such a thing even possible?
return pick("Ayy","Truth","Tsoukalos","Mulder","Scully") //Yes it is!
@@ -394,6 +397,7 @@
begin_day = 4
begin_month = JULY
mail_holiday = TRUE
+ holiday_hat = /obj/item/clothing/head/cowboy/brown
/datum/holiday/usa/getStationPrefix()
return pick("Independent","American","Burger","Bald Eagle","Star-Spangled", "Fireworks")
@@ -408,7 +412,7 @@
timezones = list(TIMEZONE_CEST)
begin_day = 14
begin_month = JULY
- drone_hat = /obj/item/clothing/head/beret
+ holiday_hat = /obj/item/clothing/head/beret
mail_holiday = TRUE
/datum/holiday/france/getStationPrefix()
@@ -430,7 +434,7 @@
name = "Wizard's Day"
begin_month = JULY
begin_day = 27
- drone_hat = /obj/item/clothing/head/wizard
+ holiday_hat = /obj/item/clothing/head/wizard
/datum/holiday/wizards_day/getStationPrefix()
return pick("Dungeon", "Elf", "Magic", "D20", "Edition")
@@ -470,6 +474,7 @@
name = "Tiziran Unification Day"
begin_month = SEPTEMBER
begin_day = 1
+ holiday_hat = /obj/item/clothing/head/costume/lizard
/datum/holiday/tiziran_unification/greet()
return "On this day over 400 years ago, Lizardkind first united under a single banner, ready to face the stars as one unified people."
@@ -493,7 +498,7 @@
name = "Talk-Like-a-Pirate Day"
begin_day = 19
begin_month = SEPTEMBER
- drone_hat = /obj/item/clothing/head/costume/pirate
+ holiday_hat = /obj/item/clothing/head/costume/pirate
/datum/holiday/pirate/greet()
return "Ye be talkin' like a pirate today or else ye'r walkin' tha plank, matey!"
@@ -523,13 +528,13 @@
name = "Smiling Day"
begin_day = 7
begin_month = OCTOBER
- drone_hat = /obj/item/clothing/head/costume/papersack/smiley
+ holiday_hat = /obj/item/clothing/head/costume/papersack/smiley
/datum/holiday/boss
name = "Boss' Day"
begin_day = 16
begin_month = OCTOBER
- drone_hat = /obj/item/clothing/head/hats/tophat
+ holiday_hat = /obj/item/clothing/head/hats/tophat
/datum/holiday/un_day
name = "Anniversary of the Foundation of the United Nations"
@@ -578,7 +583,7 @@
name = "Remembrance Day"
begin_month = NOVEMBER
begin_day = 11
- drone_hat = /obj/item/food/grown/poppy
+ holiday_hat = /obj/item/food/grown/poppy
/datum/holiday/remembrance_day/getStationPrefix()
return pick("Peace", "Armistice", "Poppy")
@@ -600,7 +605,7 @@
name = "Flowers Day"
begin_day = 19
begin_month = NOVEMBER
- drone_hat = /obj/item/food/grown/moonflower
+ holiday_hat = /obj/item/food/grown/moonflower
/datum/holiday/hello
name = "Saying-'Hello' Day"
@@ -629,7 +634,7 @@
begin_day = 1
begin_month = DECEMBER
end_day = 31
- drone_hat = /obj/item/clothing/head/costume/santa
+ holiday_hat = /obj/item/clothing/head/costume/santa
/datum/holiday/festive_season/greet()
return "Have a nice festive season!"
@@ -643,20 +648,18 @@
name = MONKEYDAY
begin_day = 14
begin_month = DECEMBER
- drone_hat = /obj/item/clothing/mask/gas/monkeymask
/datum/holiday/doomsday
name = "Mayan Doomsday Anniversary"
begin_day = 21
begin_month = DECEMBER
- drone_hat = /obj/item/clothing/mask/animal/small/tribal
/datum/holiday/xmas
name = CHRISTMAS
begin_day = 23
begin_month = DECEMBER
end_day = 27
- drone_hat = /obj/item/clothing/head/costume/santa
+ holiday_hat = /obj/item/clothing/head/costume/santa
mail_holiday = TRUE
/datum/holiday/xmas/getStationPrefix()
@@ -693,7 +696,7 @@
begin_month = DECEMBER
end_day = 2
end_month = JANUARY
- drone_hat = /obj/item/clothing/head/costume/festive
+ holiday_hat = /obj/item/clothing/head/costume/festive
mail_holiday = TRUE
/datum/holiday/new_year/getStationPrefix()
@@ -808,7 +811,7 @@
/datum/holiday/easter
name = EASTER
- drone_hat = /obj/item/clothing/head/costume/rabbitears
+ holiday_hat = /obj/item/clothing/head/costume/rabbitears
var/const/days_early = 1 //to make editing the holiday easier
var/const/days_extra = 1
diff --git a/code/modules/holiday/nth_week.dm b/code/modules/holiday/nth_week.dm
index 55cfec74be6..ef4815de066 100644
--- a/code/modules/holiday/nth_week.dm
+++ b/code/modules/holiday/nth_week.dm
@@ -35,7 +35,7 @@
begin_week = 4
begin_month = NOVEMBER
begin_weekday = THURSDAY
- drone_hat = /obj/item/clothing/head/hats/tophat //This is the closest we can get to a pilgrim's hat
+ holiday_hat = /obj/item/clothing/head/hats/tophat //This is the closest we can get to a pilgrim's hat
/datum/holiday/nth_week/thanksgiving/canada
name = "Thanksgiving in Canada"
diff --git a/code/modules/hydroponics/beekeeping/honeycomb.dm b/code/modules/hydroponics/beekeeping/honeycomb.dm
index b62802410da..41bf1aeb76e 100644
--- a/code/modules/hydroponics/beekeeping/honeycomb.dm
+++ b/code/modules/hydroponics/beekeeping/honeycomb.dm
@@ -7,7 +7,7 @@
food_reagents = list(/datum/reagent/consumable/honey = 5)
tastes = list("honey" = 1)
preserved_food = TRUE
-
+ starting_reagent_purity = 1
var/honey_color = ""
/obj/item/food/honeycomb/Initialize(mapload)
diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm
index 7a2b8f9841f..1f2951b3356 100644
--- a/code/modules/hydroponics/biogenerator.dm
+++ b/code/modules/hydroponics/biogenerator.dm
@@ -2,7 +2,8 @@
#define MAX_ITEMS_PER_RATING 10
/// How many items are converted per cycle, per rating point of the manipulator used.
#define PROCESSED_ITEMS_PER_RATING 5
-
+/// Starting purity of reagents made in biogenerator
+#define BIOGEN_REAGENT_PURITY 0.3
/obj/machinery/biogenerator
name = "biogenerator"
@@ -387,7 +388,7 @@
if(!use_biomass(design.materials, amount))
return FALSE
- beaker.reagents.add_reagent(design.make_reagent, amount)
+ beaker.reagents.add_reagent(design.make_reagent, amount, added_purity = BIOGEN_REAGENT_PURITY)
if(design.build_path)
if(!use_biomass(design.materials, amount))
@@ -568,3 +569,4 @@
#undef MAX_ITEMS_PER_RATING
#undef PROCESSED_ITEMS_PER_RATING
+#undef BIOGEN_REAGENT_PURITY
diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm
index 71c48c6e5c3..098c6e81ce6 100644
--- a/code/modules/hydroponics/grown.dm
+++ b/code/modules/hydroponics/grown.dm
@@ -38,11 +38,14 @@
var/wine_power = 10
/// Color of the grown object, for use in coloring greyscale splats.
var/filling_color
- /// If the grown food has an alternaitve icon state to use in places.
+ /// If the grown food has an alternative icon state to use in places.
var/alt_icon
/// Should we pixel offset ourselves at init? for mapping
var/offset_at_init = TRUE
+/obj/item/food/grown/New(loc, obj/item/seeds/new_seed)
+ return ..()
+
/obj/item/food/grown/Initialize(mapload, obj/item/seeds/new_seed)
if(!tastes)
tastes = list("[name]" = 1) //This happens first else the component already inits
@@ -75,12 +78,10 @@
. = ..() //Only call it here because we want all the genes and shit to be applied before we add edibility. God this code is a mess.
+ reagents.clear_reagents()
seed.prepare_result(src)
transform *= TRANSFORM_USING_VARIABLE(seed.potency, 100) + 0.5 //Makes the resulting produce's sprite larger or smaller based on potency!
- if(seed.get_gene(/datum/plant_gene/trait/brewing))
- ferment()
-
/obj/item/food/grown/Destroy()
if(isatom(seed))
QDEL_NULL(seed)
@@ -111,48 +112,49 @@
/// Turns the nutriments and vitamins into the distill reagent or fruit wine
/obj/item/food/grown/proc/ferment()
+ var/reagent_purity = seed.get_reagent_purity()
+ var/purity_above_base = clamp((reagent_purity - 0.5) * 2, 0, 1)
+ var/quality_min = 0
+ var/quality_max = DRINK_FANTASTIC
+ var/quality = round(LERP(quality_min, quality_max, purity_above_base))
for(var/datum/reagent/reagent in reagents.reagent_list)
- if(reagent.type != /datum/reagent/consumable/nutriment && reagent.type != /datum/reagent/consumable/nutriment/vitamin)
+ if(!istype(reagent, /datum/reagent/consumable))
continue
- var/purity = clamp(seed.lifespan/200 + seed.endurance/200, 0, 1)
- var/quality_min = 0
- var/quality_max = DRINK_FANTASTIC
- var/quality = round(LERP(quality_min, quality_max, purity))
if(distill_reagent)
var/data = list()
var/datum/reagent/consumable/ethanol/booze = distill_reagent
data["quality"] = quality
- data["boozepwr"] = round(initial(booze.boozepwr) * purity)
- reagents.add_reagent(distill_reagent, reagent.volume, data, added_purity = purity)
+ data["boozepwr"] = round(initial(booze.boozepwr) * reagent_purity * 2) // default boozepwr at 50% purity
+ reagents.add_reagent(distill_reagent, reagent.volume, data, added_purity = reagent_purity)
else
var/data = list()
data["names"] = list("[initial(name)]" = 1)
- data["color"] = filling_color
- data["boozepwr"] = round(wine_power * purity)
+ data["color"] = filling_color || reagent.color // filling_color is not guaranteed to be set for every plant. try to use it if we have it, otherwise use the reagent's color var
+ data["boozepwr"] = round(wine_power * reagent_purity * 2) // default boozepwr at 50% purity
data["quality"] = quality
if(wine_flavor)
data["tastes"] = list(wine_flavor = 1)
else
data["tastes"] = list(tastes[1] = 1)
- reagents.add_reagent(/datum/reagent/consumable/ethanol/fruit_wine, reagent.volume, data, added_purity = purity)
+ reagents.add_reagent(/datum/reagent/consumable/ethanol/fruit_wine, reagent.volume, data, added_purity = reagent_purity)
reagents.del_reagent(reagent.type)
-/obj/item/food/grown/on_grind()
- . = ..()
- var/nutriment = reagents.get_reagent_amount(/datum/reagent/consumable/nutriment)
- if(grind_results?.len)
- for(var/i in 1 to grind_results.len)
- grind_results[grind_results[i]] = nutriment
- reagents.del_reagent(/datum/reagent/consumable/nutriment)
- reagents.del_reagent(/datum/reagent/consumable/nutriment/vitamin)
+/obj/item/food/grown/grind(datum/reagents/target_holder, mob/user)
+ if(on_grind() == -1)
+ return FALSE
-/obj/item/food/grown/on_juice()
- var/nutriment = reagents.get_reagent_amount(/datum/reagent/consumable/nutriment)
- if(juice_results?.len)
- for(var/i in 1 to juice_results.len)
- juice_results[juice_results[i]] = nutriment
- reagents.del_reagent(/datum/reagent/consumable/nutriment)
- reagents.del_reagent(/datum/reagent/consumable/nutriment/vitamin)
+ var/grind_results_num = LAZYLEN(grind_results)
+ if(grind_results_num)
+ var/average_purity = reagents.get_average_purity()
+ var/total_nutriment_amount = reagents.get_reagent_amount(/datum/reagent/consumable/nutriment, include_subtypes = TRUE)
+ var/single_reagent_amount = grind_results_num > 1 ? round(total_nutriment_amount / grind_results_num, CHEMICAL_QUANTISATION_LEVEL) : total_nutriment_amount
+ reagents.remove_all_type(/datum/reagent/consumable/nutriment, total_nutriment_amount)
+ for(var/reagent in grind_results)
+ reagents.add_reagent(reagent, single_reagent_amount, added_purity = average_purity)
+
+ if(reagents && target_holder)
+ reagents.trans_to(target_holder, reagents.total_volume, transferred_by = user)
+ return TRUE
#undef BITE_SIZE_POTENCY_MULTIPLIER
#undef BITE_SIZE_VOLUME_MULTIPLIER
diff --git a/code/modules/hydroponics/grown/aloe.dm b/code/modules/hydroponics/grown/aloe.dm
index b031999ebdf..cfbefce6dba 100644
--- a/code/modules/hydroponics/grown/aloe.dm
+++ b/code/modules/hydroponics/grown/aloe.dm
@@ -23,7 +23,7 @@
icon_state = "aloe"
bite_consumption_mod = 3
foodtypes = VEGETABLES
- juice_results = list(/datum/reagent/consumable/aloejuice = 0)
+ juice_typepath = /datum/reagent/consumable/aloejuice
distill_reagent = /datum/reagent/consumable/ethanol/tequila
/obj/item/food/grown/aloe/make_bakeable()
diff --git a/code/modules/hydroponics/grown/apple.dm b/code/modules/hydroponics/grown/apple.dm
index d4ac640ab44..b994749c2f8 100644
--- a/code/modules/hydroponics/grown/apple.dm
+++ b/code/modules/hydroponics/grown/apple.dm
@@ -22,7 +22,7 @@
desc = "It's a little piece of Eden."
icon_state = "apple"
foodtypes = FRUIT
- juice_results = list(/datum/reagent/consumable/applejuice = 0)
+ juice_typepath = /datum/reagent/consumable/applejuice
tastes = list("apple" = 1)
distill_reagent = /datum/reagent/consumable/ethanol/hcider
diff --git a/code/modules/hydroponics/grown/banana.dm b/code/modules/hydroponics/grown/banana.dm
index a47dbceb8a8..64979b048cb 100644
--- a/code/modules/hydroponics/grown/banana.dm
+++ b/code/modules/hydroponics/grown/banana.dm
@@ -25,7 +25,7 @@
trash_type = /obj/item/grown/bananapeel
bite_consumption_mod = 3
foodtypes = FRUIT
- juice_results = list(/datum/reagent/consumable/banana = 0)
+ juice_typepath = /datum/reagent/consumable/banana
distill_reagent = /datum/reagent/consumable/ethanol/bananahonk
/obj/item/food/grown/banana/make_edible()
@@ -39,7 +39,7 @@
desc += " The curve on this one looks particularly acute."
///Clowns will always like bananas.
-/obj/item/food/grown/banana/proc/check_liked(fraction, mob/living/carbon/human/consumer)
+/obj/item/food/grown/banana/proc/check_liked(mob/living/carbon/human/consumer)
var/obj/item/organ/internal/liver/liver = consumer.get_organ_slot(ORGAN_SLOT_LIVER)
if (!HAS_TRAIT(consumer, TRAIT_AGEUSIA) && liver && HAS_TRAIT(liver, TRAIT_COMEDY_METABOLISM))
return FOOD_LIKED
@@ -49,7 +49,6 @@
var/obj/item/grown/bananapeel/peel = .
if(istype(peel))
peel.grind_results = list(/datum/reagent/medicine/coagulant/banana_peel = peel.seed.potency * 0.2)
- peel.juice_results = list(/datum/reagent/medicine/coagulant/banana_peel = peel.seed.potency * 0.2)
/obj/item/food/grown/banana/suicide_act(mob/living/user)
user.visible_message(span_suicide("[user] is aiming [src] at [user.p_them()]self! It looks like [user.p_theyre()] trying to commit suicide!"))
@@ -170,6 +169,7 @@
/obj/item/food/grown/banana/bunch/Initialize(mapload, obj/item/seeds/new_seed)
. = ..()
+ reagents.clear_reagents()
reagents.add_reagent(/datum/reagent/consumable/monkey_energy, 10)
reagents.add_reagent(/datum/reagent/consumable/banana, 10)
diff --git a/code/modules/hydroponics/grown/beans.dm b/code/modules/hydroponics/grown/beans.dm
index f79c4590218..8643c616b47 100644
--- a/code/modules/hydroponics/grown/beans.dm
+++ b/code/modules/hydroponics/grown/beans.dm
@@ -15,7 +15,7 @@
icon_dead = "soybean-dead"
genes = list(/datum/plant_gene/trait/repeated_harvest)
mutatelist = list(/obj/item/seeds/soya/koi)
- reagents_add = list(/datum/reagent/consumable/nutriment/vitamin = 0.04, /datum/reagent/consumable/nutriment = 0.05, /datum/reagent/consumable/cooking_oil = 0.03) //Vegetable oil!
+ reagents_add = list(/datum/reagent/consumable/nutriment/vitamin = 0.04, /datum/reagent/consumable/nutriment = 0.05, /datum/reagent/consumable/nutriment/fat/oil = 0.03) //Vegetable oil!
/obj/item/food/grown/soybeans
seed = /obj/item/seeds/soya
diff --git a/code/modules/hydroponics/grown/berries.dm b/code/modules/hydroponics/grown/berries.dm
index 0c27184f2ce..45b0db82ea3 100644
--- a/code/modules/hydroponics/grown/berries.dm
+++ b/code/modules/hydroponics/grown/berries.dm
@@ -25,7 +25,7 @@
icon_state = "berrypile"
gender = PLURAL
foodtypes = FRUIT
- juice_results = list(/datum/reagent/consumable/berryjuice = 0)
+ juice_typepath = /datum/reagent/consumable/berryjuice
tastes = list("berry" = 1)
distill_reagent = /datum/reagent/consumable/ethanol/gin
@@ -48,7 +48,7 @@
icon_state = "poisonberrypile"
bite_consumption_mod = 3
foodtypes = FRUIT | TOXIC
- juice_results = list(/datum/reagent/consumable/poisonberryjuice = 0)
+ juice_typepath = /datum/reagent/consumable/poisonberryjuice
tastes = list("poison-berry" = 1)
distill_reagent = null
wine_power = 35
@@ -74,7 +74,7 @@
icon_state = "deathberrypile"
bite_consumption_mod = 3
foodtypes = FRUIT | TOXIC
- juice_results = list(/datum/reagent/consumable/poisonberryjuice = 0)
+ juice_typepath = /datum/reagent/consumable/poisonberryjuice
tastes = list("death-berry" = 1)
distill_reagent = null
wine_power = 50
@@ -134,7 +134,7 @@
icon_state = "grapes"
bite_consumption_mod = 2
foodtypes = FRUIT
- juice_results = list(/datum/reagent/consumable/grapejuice = 0)
+ juice_typepath = /datum/reagent/consumable/grapejuice
tastes = list("grape" = 1)
distill_reagent = /datum/reagent/consumable/ethanol/wine
@@ -185,6 +185,6 @@
desc = "A branch with töchtaüse berries on it. They're a favourite on the Mothic Fleet, but not in this form."
icon_state = "toechtauese_branch"
foodtypes = FRUIT
- juice_results = list(/datum/reagent/consumable/toechtauese_juice = 0)
+ juice_typepath = /datum/reagent/consumable/toechtauese_juice
tastes = list("fiery itchy pain" = 1)
distill_reagent = /datum/reagent/toxin/itching_powder
diff --git a/code/modules/hydroponics/grown/cereals.dm b/code/modules/hydroponics/grown/cereals.dm
index 1a9db3c25d0..92ef29cc195 100644
--- a/code/modules/hydroponics/grown/cereals.dm
+++ b/code/modules/hydroponics/grown/cereals.dm
@@ -97,7 +97,8 @@
/obj/item/food/grown/meatwheat/attack_self(mob/living/user)
user.visible_message(span_notice("[user] crushes [src] into meat."), span_notice("You crush [src] into something that resembles meat."))
playsound(user, 'sound/effects/blobattack.ogg', 50, TRUE)
- var/obj/item/food/meat/slab/meatwheat/M = new
+ var/reagent_purity = seed.get_reagent_purity()
+ var/obj/item/food/meat/slab/meatwheat/M = new(null, reagent_purity)
qdel(src)
user.put_in_hands(M)
return 1
diff --git a/code/modules/hydroponics/grown/citrus.dm b/code/modules/hydroponics/grown/citrus.dm
index de0643faed6..c624722f823 100644
--- a/code/modules/hydroponics/grown/citrus.dm
+++ b/code/modules/hydroponics/grown/citrus.dm
@@ -29,7 +29,7 @@
name = "lime"
desc = "It's so sour, your face will twist."
icon_state = "lime"
- juice_results = list(/datum/reagent/consumable/limejuice = 0)
+ juice_typepath = /datum/reagent/consumable/limejuice
// Orange
/obj/item/seeds/orange
@@ -56,7 +56,7 @@
desc = "It's a tangy fruit."
icon_state = "orange"
foodtypes = ORANGES
- juice_results = list(/datum/reagent/consumable/orangejuice = 0)
+ juice_typepath = /datum/reagent/consumable/orangejuice
distill_reagent = /datum/reagent/consumable/ethanol/triple_sec
// Lemon
@@ -82,7 +82,7 @@
name = "lemon"
desc = "When life gives you lemons, make lemonade."
icon_state = "lemon"
- juice_results = list(/datum/reagent/consumable/lemonjuice = 0)
+ juice_typepath = /datum/reagent/consumable/lemonjuice
// Combustible lemon
/obj/item/seeds/firelemon //combustible lemon is too long so firelemon
@@ -137,7 +137,7 @@
foodtypes = ORANGES
alt_icon = "orange"
bite_consumption_mod = 2
- juice_results = list(/datum/reagent/consumable/orangejuice = 0)
+ juice_typepath = /datum/reagent/consumable/orangejuice
distill_reagent = /datum/reagent/toxin/mindbreaker
tastes = list("polygons" = 1, "bluespace" = 1, "the true nature of reality" = 1)
diff --git a/code/modules/hydroponics/grown/cocoa_vanilla.dm b/code/modules/hydroponics/grown/cocoa_vanilla.dm
index e7a13ffbbb6..4e9a9810b42 100644
--- a/code/modules/hydroponics/grown/cocoa_vanilla.dm
+++ b/code/modules/hydroponics/grown/cocoa_vanilla.dm
@@ -80,7 +80,7 @@
bite_consumption_mod = 2
trash_type = /obj/item/food/grown/bungopit
foodtypes = FRUIT
- juice_results = list(/datum/reagent/consumable/bungojuice = 0)
+ juice_typepath = /datum/reagent/consumable/bungojuice
tastes = list("bungo" = 2, "tropical fruitiness" = 1)
distill_reagent = null
diff --git a/code/modules/hydroponics/grown/corn.dm b/code/modules/hydroponics/grown/corn.dm
index 655123d5a74..a606cf62017 100644
--- a/code/modules/hydroponics/grown/corn.dm
+++ b/code/modules/hydroponics/grown/corn.dm
@@ -14,7 +14,7 @@
icon_grow = "corn-grow" // Uses one growth icons set for all the subtypes
icon_dead = "corn-dead" // Same for the dead icon
mutatelist = list(/obj/item/seeds/corn/snapcorn)
- reagents_add = list(/datum/reagent/consumable/cornoil = 0.2, /datum/reagent/consumable/nutriment/vitamin = 0.04, /datum/reagent/consumable/nutriment = 0.1)
+ reagents_add = list(/datum/reagent/consumable/nutriment/fat/oil = 0.2, /datum/reagent/consumable/nutriment/vitamin = 0.04, /datum/reagent/consumable/nutriment = 0.1)
/obj/item/food/grown/corn
seed = /obj/item/seeds/corn
@@ -25,7 +25,7 @@
bite_consumption_mod = 2
foodtypes = VEGETABLES
grind_results = list(/datum/reagent/consumable/cornmeal = 0)
- juice_results = list(/datum/reagent/consumable/corn_starch = 0)
+ juice_typepath = /datum/reagent/consumable/corn_starch
tastes = list("corn" = 1)
distill_reagent = /datum/reagent/consumable/ethanol/whiskey
diff --git a/code/modules/hydroponics/grown/cucumber.dm b/code/modules/hydroponics/grown/cucumber.dm
index 649ef8b5212..f3712c6a5c9 100644
--- a/code/modules/hydroponics/grown/cucumber.dm
+++ b/code/modules/hydroponics/grown/cucumber.dm
@@ -22,5 +22,5 @@
desc = "Oblong and green, with pimples, the standard of salads."
icon_state = "cucumber"
foodtypes = VEGETABLES
- juice_results = list(/datum/reagent/consumable/cucumberjuice = 0)
+ juice_typepath = /datum/reagent/consumable/cucumberjuice
tastes = list("cucumber" = 1)
diff --git a/code/modules/hydroponics/grown/flowers.dm b/code/modules/hydroponics/grown/flowers.dm
index 0b66ab0e6f5..333c7f57c45 100644
--- a/code/modules/hydroponics/grown/flowers.dm
+++ b/code/modules/hydroponics/grown/flowers.dm
@@ -23,15 +23,12 @@
seed = /obj/item/seeds/poppy
name = "poppy"
desc = "Long-used as a symbol of rest, peace, and death."
- icon_state = "map_flower"
+ icon_state = "poppy"
slot_flags = ITEM_SLOT_HEAD
alternate_worn_layer = ABOVE_BODY_FRONT_HEAD_LAYER
bite_consumption_mod = 2
foodtypes = VEGETABLES | GROSS
distill_reagent = /datum/reagent/consumable/ethanol/vermouth
- greyscale_config = /datum/greyscale_config/flower_simple
- greyscale_config_worn = /datum/greyscale_config/flower_simple_worn
- greyscale_colors = "#d23838"
// Lily
/obj/item/seeds/poppy/lily
@@ -41,13 +38,17 @@
species = "lily"
plantname = "Lily Plants"
product = /obj/item/food/grown/poppy/lily
+ growthstages = 3
+ growing_icon = 'icons/obj/service/hydroponics/growing_flowers.dmi'
+ icon_grow = "lily-grow"
+ icon_dead = "lily-dead"
mutatelist = list(/obj/item/seeds/poppy/lily/trumpet)
/obj/item/food/grown/poppy/lily
seed = /obj/item/seeds/poppy/lily
name = "lily"
- desc = "A beautiful orange flower."
- greyscale_colors = "#fe881f"
+ desc = "A beautiful white flower."
+ icon_state = "lily"
//Spacemans's Trumpet
/obj/item/seeds/poppy/lily/trumpet
@@ -91,13 +92,17 @@
species = "geranium"
plantname = "Geranium Plants"
product = /obj/item/food/grown/poppy/geranium
+ growthstages = 3
+ growing_icon = 'icons/obj/service/hydroponics/growing_flowers.dmi'
+ icon_grow = "geranium-grow"
+ icon_dead = "geranium-dead"
mutatelist = list(/obj/item/seeds/poppy/geranium/fraxinella)
/obj/item/food/grown/poppy/geranium
seed = /obj/item/seeds/poppy/geranium
name = "geranium"
desc = "A beautiful blue flower."
- greyscale_colors = "#1499bb"
+ icon_state = "geranium"
///Fraxinella seeds.
/obj/item/seeds/poppy/geranium/fraxinella
@@ -173,7 +178,7 @@
icon_grow = "sunflower-grow"
icon_dead = "sunflower-dead"
mutatelist = list(/obj/item/seeds/sunflower/moonflower, /obj/item/seeds/sunflower/novaflower)
- reagents_add = list(/datum/reagent/consumable/cornoil = 0.08, /datum/reagent/consumable/nutriment = 0.04)
+ reagents_add = list(/datum/reagent/consumable/nutriment/fat/oil = 0.08, /datum/reagent/consumable/nutriment = 0.04)
/obj/item/food/grown/sunflower // FLOWER POWER!
seed = /obj/item/seeds/sunflower
diff --git a/code/modules/hydroponics/grown/herbs.dm b/code/modules/hydroponics/grown/herbs.dm
index 45d2ed1146d..b22be06ec6a 100644
--- a/code/modules/hydroponics/grown/herbs.dm
+++ b/code/modules/hydroponics/grown/herbs.dm
@@ -22,6 +22,6 @@
icon_state = "herbs"
foodtypes = VEGETABLES
grind_results = list(/datum/reagent/consumable/nutriment = 0)
- juice_results = list(/datum/reagent/consumable/nutriment = 0)
+ juice_typepath = /datum/reagent/consumable/nutriment
tastes = list("nondescript herbs" = 1)
distill_reagent = /datum/reagent/consumable/ethanol/fernet
diff --git a/code/modules/hydroponics/grown/korta_nut.dm b/code/modules/hydroponics/grown/korta_nut.dm
index 0622b9d59d4..bf6ab82d474 100644
--- a/code/modules/hydroponics/grown/korta_nut.dm
+++ b/code/modules/hydroponics/grown/korta_nut.dm
@@ -23,7 +23,7 @@
icon_state = "korta_nut"
foodtypes = NUTS
grind_results = list(/datum/reagent/consumable/korta_flour = 0)
- juice_results = list(/datum/reagent/consumable/korta_milk = 0)
+ juice_typepath = /datum/reagent/consumable/korta_milk
tastes = list("peppery heat" = 1)
distill_reagent = /datum/reagent/consumable/ethanol/kortara
@@ -47,6 +47,6 @@
desc = "A sweet treat lizards love to eat."
icon_state = "korta_nut"
grind_results = list(/datum/reagent/consumable/korta_flour = 0)
- juice_results = list(/datum/reagent/consumable/korta_milk = 0, /datum/reagent/consumable/korta_nectar = 0)
+ juice_typepath = /datum/reagent/consumable/korta_nectar
tastes = list("peppery sweet" = 1)
distill_reagent = /datum/reagent/consumable/ethanol/kortara
diff --git a/code/modules/hydroponics/grown/melon.dm b/code/modules/hydroponics/grown/melon.dm
index e517883a2ea..80962a2d182 100644
--- a/code/modules/hydroponics/grown/melon.dm
+++ b/code/modules/hydroponics/grown/melon.dm
@@ -30,7 +30,7 @@
bite_consumption_mod = 2
w_class = WEIGHT_CLASS_NORMAL
foodtypes = FRUIT
- juice_results = list(/datum/reagent/consumable/watermelonjuice = 0)
+ juice_typepath = /datum/reagent/consumable/watermelonjuice
wine_power = 40
/obj/item/food/grown/watermelon/make_processable()
@@ -62,7 +62,7 @@
bite_consumption_mod = 2
w_class = WEIGHT_CLASS_NORMAL
foodtypes = FRUIT
- juice_results = list(/datum/reagent/water/holywater = 0)
+ juice_typepath = /datum/reagent/water/holywater
wine_power = 70 //Water to wine, baby.
wine_flavor = "divinity"
@@ -78,7 +78,7 @@
* Checks whether or not the person eating the holymelon
* is a holy_role (chaplain), as chaplains love holymelons.
*/
-/obj/item/food/grown/holymelon/proc/check_holyness(fraction, mob/mob_eating)
+/obj/item/food/grown/holymelon/proc/check_holyness(mob/mob_eating)
if(!ishuman(mob_eating))
return
var/mob/living/carbon/human/holy_person = mob_eating
diff --git a/code/modules/hydroponics/grown/peas.dm b/code/modules/hydroponics/grown/peas.dm
index e88b4fba1b1..c232ed247c6 100644
--- a/code/modules/hydroponics/grown/peas.dm
+++ b/code/modules/hydroponics/grown/peas.dm
@@ -54,7 +54,7 @@
desc = "Ridens Cicer, guaranteed to improve your mood dramatically upon consumption!"
icon_state = "laughpeas"
foodtypes = VEGETABLES
- juice_results = list (/datum/reagent/consumable/laughsyrup = 0)
+ juice_typepath = /datum/reagent/consumable/laughsyrup
tastes = list ("a prancing rabbit" = 1) //Vib Ribbon sends her regards.. wherever she is.
wine_power = 90
wine_flavor = "a vector-graphic rabbit dancing on your tongue"
diff --git a/code/modules/hydroponics/grown/pineapple.dm b/code/modules/hydroponics/grown/pineapple.dm
index 060a7b172d3..3c0e462f388 100644
--- a/code/modules/hydroponics/grown/pineapple.dm
+++ b/code/modules/hydroponics/grown/pineapple.dm
@@ -30,7 +30,7 @@
throw_range = 5
w_class = WEIGHT_CLASS_NORMAL
foodtypes = FRUIT | PINEAPPLE
- juice_results = list(/datum/reagent/consumable/pineapplejuice = 0)
+ juice_typepath = /datum/reagent/consumable/pineapplejuice
tastes = list("pineapple" = 1)
wine_power = 40
diff --git a/code/modules/hydroponics/grown/plum.dm b/code/modules/hydroponics/grown/plum.dm
index 997efa41222..cac12bdb1eb 100644
--- a/code/modules/hydroponics/grown/plum.dm
+++ b/code/modules/hydroponics/grown/plum.dm
@@ -22,7 +22,7 @@
desc = "A poet's favorite fruit. Noice."
icon_state = "plum"
foodtypes = FRUIT
- juice_results = list(/datum/reagent/consumable/plumjuice = 0)
+ juice_typepath = /datum/reagent/consumable/plumjuice
tastes = list("plum" = 1)
distill_reagent = /datum/reagent/consumable/ethanol/plumwine
diff --git a/code/modules/hydroponics/grown/potato.dm b/code/modules/hydroponics/grown/potato.dm
index 4178e82e0c8..837937e41d1 100644
--- a/code/modules/hydroponics/grown/potato.dm
+++ b/code/modules/hydroponics/grown/potato.dm
@@ -25,7 +25,7 @@
desc = "Boil 'em! Mash 'em! Stick 'em in a stew!"
icon_state = "potato"
foodtypes = VEGETABLES
- juice_results = list(/datum/reagent/consumable/potato_juice = 0)
+ juice_typepath = /datum/reagent/consumable/potato_juice
distill_reagent = /datum/reagent/consumable/ethanol/vodka
/obj/item/food/grown/potato/make_bakeable()
diff --git a/code/modules/hydroponics/grown/pumpkin.dm b/code/modules/hydroponics/grown/pumpkin.dm
index 07a25d14c94..561bd5119aa 100644
--- a/code/modules/hydroponics/grown/pumpkin.dm
+++ b/code/modules/hydroponics/grown/pumpkin.dm
@@ -24,7 +24,7 @@
icon_state = "pumpkin"
bite_consumption_mod = 2
foodtypes = FRUIT
- juice_results = list(/datum/reagent/consumable/pumpkinjuice = 0)
+ juice_typepath = /datum/reagent/consumable/pumpkinjuice
wine_power = 20
///Which type of lantern this gourd produces when carved.
var/carved_type = /obj/item/clothing/head/utility/hardhat/pumpkinhead
@@ -57,6 +57,6 @@
icon_state = "blumpkin"
bite_consumption_mod = 3
foodtypes = FRUIT
- juice_results = list(/datum/reagent/consumable/blumpkinjuice = 0)
+ juice_typepath = /datum/reagent/consumable/blumpkinjuice
wine_power = 50
carved_type = /obj/item/clothing/head/utility/hardhat/pumpkinhead/blumpkin
diff --git a/code/modules/hydroponics/grown/root.dm b/code/modules/hydroponics/grown/root.dm
index 8afa52be9da..df37e3bf2b7 100644
--- a/code/modules/hydroponics/grown/root.dm
+++ b/code/modules/hydroponics/grown/root.dm
@@ -22,7 +22,7 @@
icon_state = "carrot"
bite_consumption_mod = 2
foodtypes = VEGETABLES
- juice_results = list(/datum/reagent/consumable/carrotjuice = 0)
+ juice_typepath = /datum/reagent/consumable/carrotjuice
wine_power = 30
/obj/item/food/grown/carrot/attackby(obj/item/I, mob/user, params)
@@ -53,7 +53,7 @@
desc = "Closely related to carrots."
icon_state = "parsnip"
foodtypes = VEGETABLES
- juice_results = list(/datum/reagent/consumable/parsnipjuice = 0)
+ juice_typepath = /datum/reagent/consumable/parsnipjuice
wine_power = 35
diff --git a/code/modules/hydroponics/grown/seedling.dm b/code/modules/hydroponics/grown/seedling.dm
new file mode 100644
index 00000000000..57fd11280b6
--- /dev/null
+++ b/code/modules/hydroponics/grown/seedling.dm
@@ -0,0 +1,28 @@
+/obj/item/seeds/seedling
+ name = "pack of seedling seeds"
+ desc = "These seeds grow into a floral assistant which can help look after other plants!"
+ icon_state = "seed-seedling"
+ growing_icon = 'icons/obj/service/hydroponics/growing_fruits.dmi'
+ species = "seedling"
+ plantname = "Seedling Plant"
+ product = /mob/living/basic/seedling
+ lifespan = 40
+ endurance = 7
+ maturation = 10
+ production = 1
+ growthstages = 2
+ yield = 1
+ instability = 15
+ potency = 30
+
+/obj/item/seeds/seedling/harvest(mob/harvester)
+ var/obj/machinery/hydroponics/parent = loc
+ var/list/grow_locations = get_adjacent_open_turfs(parent)
+ var/turf/final_location = length(grow_locations) ? pick(grow_locations) : get_turf(parent)
+ var/mob/living/basic/seedling/seed_pet = new product(final_location)
+ seed_pet.befriend(harvester)
+ parent.update_tray(user = harvester, product_count = 1)
+
+/obj/item/seeds/seedling/evil
+ product = /mob/living/basic/seedling/meanie
+ icon_state = "seed-seedling-evil"
diff --git a/code/modules/hydroponics/grown/tomato.dm b/code/modules/hydroponics/grown/tomato.dm
index 1adfe4ac39b..c2fa44c7662 100644
--- a/code/modules/hydroponics/grown/tomato.dm
+++ b/code/modules/hydroponics/grown/tomato.dm
@@ -24,7 +24,7 @@
splat_type = /obj/effect/decal/cleanable/food/tomato_smudge
foodtypes = FRUIT
grind_results = list(/datum/reagent/consumable/ketchup = 0)
- juice_results = list(/datum/reagent/consumable/tomatojuice = 0)
+ juice_typepath = /datum/reagent/consumable/tomatojuice
distill_reagent = /datum/reagent/consumable/enzyme
// Blood Tomato
diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm
index 26fb90236a3..2b2556790e2 100644
--- a/code/modules/hydroponics/growninedible.dm
+++ b/code/modules/hydroponics/growninedible.dm
@@ -10,6 +10,12 @@
var/obj/item/seeds/seed = null // type path, gets converted to item on New(). It's safe to assume it's always a seed item.
/// Should we pixel offset ourselves at init? for mapping
var/offset_at_init = TRUE
+ /// The reagent this plant distill to. If NULL, it uses a generic fruit_wine reagent and adjusts its variables.
+ var/distill_reagent
+
+// This may look like it's doing nothing but it's necessary, we do this to have kwargs work in New (for passing into Initialize)
+/obj/item/grown/New(loc, obj/item/seeds/new_seed)
+ return ..()
/obj/item/grown/Initialize(mapload, obj/item/seeds/new_seed)
. = ..()
diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm
index a847d8aef04..8c42dce397f 100644
--- a/code/modules/hydroponics/hydroponics.dm
+++ b/code/modules/hydroponics/hydroponics.dm
@@ -865,7 +865,7 @@
transfer_amount = reagent_source.reagents.total_volume
SEND_SIGNAL(reagent_source, COMSIG_ITEM_ON_COMPOSTED, user)
else
- transfer_amount = reagent_source.amount_per_transfer_from_this
+ transfer_amount = min(reagent_source.amount_per_transfer_from_this, reagent_source.reagents.total_volume)
if(istype(reagent_source, /obj/item/reagent_containers/syringe/))
var/obj/item/reagent_containers/syringe/syr = reagent_source
visi_msg="[user] injects [target] with [syr]"
@@ -882,7 +882,7 @@
for(var/obj/machinery/hydroponics/H in trays)
//cause I don't want to feel like im juggling 15 tamagotchis and I can get to my real work of ripping flooring apart in hopes of validating my life choices of becoming a space-gardener
//This was originally in apply_chemicals, but due to apply_chemicals only holding nutrients, we handle it here now.
- if(reagent_source.reagents.has_reagent(/datum/reagent/water, 1))
+ if(reagent_source.reagents.has_reagent(/datum/reagent/water))
var/water_amt = reagent_source.reagents.get_reagent_amount(/datum/reagent/water) * transfer_amount / reagent_source.reagents.total_volume
var/water_amt_adjusted = H.adjust_waterlevel(round(water_amt))
reagent_source.reagents.remove_reagent(/datum/reagent/water, water_amt_adjusted)
@@ -892,7 +892,7 @@
var/transfer_me_to_tray = reagent_source.reagents.get_reagent_amount(not_water_reagent.type) * transfer_amount / reagent_source.reagents.total_volume
reagent_source.reagents.trans_id_to(H.reagents, not_water_reagent.type, transfer_me_to_tray)
else
- reagent_source.reagents.trans_to(H.reagents, transfer_amount, transfered_by = user)
+ reagent_source.reagents.trans_to(H.reagents, transfer_amount, transferred_by = user)
lastuser = WEAKREF(user)
if(IS_EDIBLE(reagent_source) || istype(reagent_source, /obj/item/reagent_containers/pill))
qdel(reagent_source)
diff --git a/code/modules/hydroponics/seed_extractor.dm b/code/modules/hydroponics/seed_extractor.dm
index 7e45fd18d75..a3804c9262f 100644
--- a/code/modules/hydroponics/seed_extractor.dm
+++ b/code/modules/hydroponics/seed_extractor.dm
@@ -213,6 +213,19 @@
"rate" = reagent.rate
))
seed_data["volume_mod"] = (locate(/datum/plant_gene/trait/maxchem) in to_add.genes) ? 2 : 1
+ 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)
+ 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
+ seed_data["juice_name"] = initial(product_juice_typepath.name)
+ 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)
piles[seed_id] = seed_data
return TRUE
diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm
index 799a0abfb40..013b8fa3c5c 100644
--- a/code/modules/hydroponics/seeds.dm
+++ b/code/modules/hydroponics/seeds.dm
@@ -235,7 +235,7 @@
for(var/datum/plant_gene/trait/trait in parent.myseed.genes)
if((trait.mutability_flags & PLANT_GENE_MUTATABLE) && trait.can_add(mutated_seed))
mutated_seed.genes += trait.Copy()
- t_prod = new t_prod(output_loc, mutated_seed)
+ t_prod = new t_prod(output_loc, new_seed = mutated_seed)
t_prod.transform = initial(t_prod.transform)
t_prod.transform *= TRANSFORM_USING_VARIABLE(t_prod.seed.potency, 100) + 0.5
ADD_TRAIT(t_prod, TRAIT_PLANT_WILDMUTATE, INNATE_TRAIT)
@@ -244,7 +244,7 @@
t_prod.seed.set_instability(round(instability * 0.5))
continue
else
- t_prod = new product(output_loc, src)
+ t_prod = new product(output_loc, new_seed = src)
if(parent.myseed.plantname != initial(parent.myseed.plantname))
t_prod.name = lowertext(parent.myseed.plantname)
if(productdesc)
@@ -278,6 +278,7 @@
reagent_max += reagents_add[rid]
if(IS_EDIBLE(T) || istype(T, /obj/item/grown))
var/obj/item/food/grown/grown_edible = T
+ var/reagent_purity = get_reagent_purity()
for(var/rid in reagents_add)
var/reagent_overflow_mod = reagents_add[rid]
if(reagent_max > 1)
@@ -289,12 +290,13 @@
data = list("blood_type" = "O-")
if(istype(grown_edible) && (rid == /datum/reagent/consumable/nutriment || rid == /datum/reagent/consumable/nutriment/vitamin))
data = grown_edible.tastes // apple tastes of apple.
- T.reagents.add_reagent(rid, amount, data)
+ T.reagents.add_reagent(rid, amount, data, added_purity = reagent_purity)
//Handles the juicing trait, swaps nutriment and vitamins for that species various juices if they exist. Mutually exclusive with distilling.
- if(get_gene(/datum/plant_gene/trait/juicing) && grown_edible.juice_results)
- grown_edible.on_juice()
- grown_edible.reagents.add_reagent_list(grown_edible.juice_results)
+ if(get_gene(/datum/plant_gene/trait/juicing) && grown_edible.juice_typepath)
+ grown_edible.juice()
+ else if(get_gene(/datum/plant_gene/trait/brewing))
+ grown_edible.ferment()
/// The number of nutriments we have inside of our plant, for use in our heating / cooling genes
var/num_nutriment = T.reagents.get_reagent_amount(/datum/reagent/consumable/nutriment)
@@ -314,6 +316,14 @@
T.reagents.handle_reactions()
playsound(T.loc, 'sound/effects/space_wind.ogg', 50)
+/// Returns reagent purity based on seed stats
+/obj/item/seeds/proc/get_reagent_purity()
+ var/purity_from_lifespan = lifespan / 400 //up to +25% for lifespan
+ var/purity_from_endurance = endurance / 400 //up to +25% for endurance
+ var/purity_from_instability = rand(-instability, instability) / 400 //up to +-25% at random for instability
+ var/result_purity = clamp(0.5 + purity_from_lifespan + purity_from_endurance + purity_from_instability, 0, 1) //50% base + stats
+ return result_purity
+
/// Setters procs ///
/**
diff --git a/code/modules/industrial_lift/tram/tram_landmark.dm b/code/modules/industrial_lift/tram/tram_landmark.dm
index 72dd32698dc..76341a7d064 100644
--- a/code/modules/industrial_lift/tram/tram_landmark.dm
+++ b/code/modules/industrial_lift/tram/tram_landmark.dm
@@ -61,7 +61,7 @@ GLOBAL_LIST_EMPTY(tram_landmarks)
name = "DESTINATION/NOT/FOUND"
specific_lift_id = IMMOVABLE_ROD_DESTINATIONS
-/obj/effect/landmark/tram/nav/hilbert/research
+/obj/effect/landmark/tram/nav/hilbert
name = HILBERT_TRAM
specific_lift_id = TRAM_NAV_BEACONS
dir = WEST
diff --git a/code/modules/jobs/access.dm b/code/modules/jobs/access.dm
index 2a5a14b066d..5b64770175c 100644
--- a/code/modules/jobs/access.dm
+++ b/code/modules/jobs/access.dm
@@ -5,6 +5,8 @@
return TRUE
if(result_bitflags & COMPONENT_OBJ_DISALLOW) // override all other checks
return FALSE
+ if(HAS_TRAIT(accessor, TRAIT_ALWAYS_NO_ACCESS))
+ return FALSE
//check if it doesn't require any access at all
if(check_access(null))
return TRUE
diff --git a/code/modules/jobs/job_types/assistant.dm b/code/modules/jobs/job_types/assistant.dm
index a5a68b7152a..89e7d04742c 100644
--- a/code/modules/jobs/job_types/assistant.dm
+++ b/code/modules/jobs/job_types/assistant.dm
@@ -48,6 +48,12 @@ Assistant
/datum/outfit/job/assistant/pre_equip(mob/living/carbon/human/target)
..()
+ for(var/holidayname in GLOB.holidays)
+ var/datum/holiday/holiday_today = GLOB.holidays[holidayname]
+ var/obj/item/special_hat = holiday_today.holiday_hat
+ if(prob(HOLIDAY_HAT_CHANCE) && !isnull(special_hat) && isnull(head))
+ head = special_hat
+
give_jumpsuit(target)
/datum/outfit/job/assistant/proc/give_jumpsuit(mob/living/carbon/human/target)
diff --git a/code/modules/jobs/job_types/atmospheric_technician.dm b/code/modules/jobs/job_types/atmospheric_technician.dm
index 8947a77c508..d016688042a 100644
--- a/code/modules/jobs/job_types/atmospheric_technician.dm
+++ b/code/modules/jobs/job_types/atmospheric_technician.dm
@@ -44,6 +44,7 @@
id_trim = /datum/id_trim/job/atmospheric_technician
uniform = /obj/item/clothing/under/rank/engineering/atmospheric_technician
+ suit = /obj/item/clothing/suit/atmos_overalls
belt = /obj/item/storage/belt/utility/atmostech
ears = /obj/item/radio/headset/headset_eng
l_pocket = /obj/item/modular_computer/pda/atmos
@@ -60,6 +61,7 @@
/datum/outfit/job/atmos/mod
name = "Atmospheric Technician (MODsuit)"
+ suit = null
suit_store = /obj/item/tank/internals/oxygen
back = /obj/item/mod/control/pre_equipped/atmospheric
mask = /obj/item/clothing/mask/gas/atmos
diff --git a/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm b/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm
index 15dd39861a4..3e752910a29 100644
--- a/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm
+++ b/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm
@@ -21,7 +21,7 @@ If the scythe isn't empowered when you sheath it, you take a heap of damage and
return FALSE
var/obj/item/bodypart/part = hand
- if(isnull(part) || scythe.empowerment > SCYTHE_SATED)
+ if(isnull(part) || scythe.empowerment >= SCYTHE_SATED)
return ..()
to_chat(owner, span_userdanger("[scythe] tears into you for your unworthy display of arrogance!"))
diff --git a/code/modules/jobs/job_types/chief_medical_officer.dm b/code/modules/jobs/job_types/chief_medical_officer.dm
index 92c272167a0..998c19a215d 100644
--- a/code/modules/jobs/job_types/chief_medical_officer.dm
+++ b/code/modules/jobs/job_types/chief_medical_officer.dm
@@ -38,7 +38,7 @@
/obj/effect/spawner/random/medical/surgery_tool_advanced = 4,
/obj/effect/spawner/random/medical/surgery_tool_alien = 1
)
- family_heirlooms = list(/obj/item/storage/medkit/ancient/heirloom, /obj/item/scalpel, /obj/item/hemostat, /obj/item/circular_saw, /obj/item/retractor, /obj/item/cautery)
+ family_heirlooms = list(/obj/item/storage/medkit/ancient/heirloom, /obj/item/scalpel, /obj/item/hemostat, /obj/item/circular_saw, /obj/item/retractor, /obj/item/cautery, /obj/item/statuebust/hippocratic)
rpg_title = "High Cleric"
job_flags = STATION_JOB_FLAGS | JOB_BOLD_SELECT_TEXT | JOB_CANNOT_OPEN_SLOTS
diff --git a/code/modules/jobs/job_types/medical_doctor.dm b/code/modules/jobs/job_types/medical_doctor.dm
index 6f7359ddb7a..e3a396609eb 100644
--- a/code/modules/jobs/job_types/medical_doctor.dm
+++ b/code/modules/jobs/job_types/medical_doctor.dm
@@ -24,7 +24,7 @@
/datum/job_department/medical,
)
- family_heirlooms = list(/obj/item/storage/medkit/ancient/heirloom, /obj/item/scalpel, /obj/item/hemostat, /obj/item/circular_saw, /obj/item/retractor, /obj/item/cautery)
+ family_heirlooms = list(/obj/item/storage/medkit/ancient/heirloom, /obj/item/scalpel, /obj/item/hemostat, /obj/item/circular_saw, /obj/item/retractor, /obj/item/cautery, /obj/item/statuebust/hippocratic)
mail_goodies = list(
/obj/item/healthanalyzer/advanced = 15,
diff --git a/code/modules/jobs/job_types/paramedic.dm b/code/modules/jobs/job_types/paramedic.dm
index 53e9b22bf1d..3dac90b4baf 100644
--- a/code/modules/jobs/job_types/paramedic.dm
+++ b/code/modules/jobs/job_types/paramedic.dm
@@ -48,7 +48,7 @@
suit = /obj/item/clothing/suit/toggle/labcoat/paramedic
suit_store = /obj/item/flashlight/pen/paramedic
backpack_contents = list(
- /obj/item/roller = 1,
+ /obj/item/emergency_bed = 1,
)
belt = /obj/item/storage/belt/medical/paramedic
ears = /obj/item/radio/headset/headset_med
diff --git a/code/modules/jobs/job_types/virologist.dm b/code/modules/jobs/job_types/virologist.dm
index 39cbc0ccce7..bdbfd7d687c 100644
--- a/code/modules/jobs/job_types/virologist.dm
+++ b/code/modules/jobs/job_types/virologist.dm
@@ -26,7 +26,7 @@
/datum/job_department/medical,
)
- family_heirlooms = list(/obj/item/reagent_containers/syringe)
+ family_heirlooms = list(/obj/item/reagent_containers/syringe, /obj/item/statuebust/hippocratic)
mail_goodies = list(
/obj/item/reagent_containers/cup/bottle/random_virus = 15,
diff --git a/code/modules/library/random_books.dm b/code/modules/library/random_books.dm
index 1b15eeb5e97..3dcdff50a58 100644
--- a/code/modules/library/random_books.dm
+++ b/code/modules/library/random_books.dm
@@ -94,6 +94,7 @@
/obj/structure/bookcase/random/reference
name = "bookcase (Reference)"
random_category = "Reference"
+ ///Chance to spawn a random manual book
var/ref_book_prob = 20
/obj/structure/bookcase/random/reference/Initialize(mapload)
@@ -101,3 +102,15 @@
while(books_to_load > 0 && prob(ref_book_prob))
books_to_load--
new /obj/item/book/manual/random(src)
+
+/obj/structure/bookcase/random/reference/wizard
+ desc = "It reeks of cheese..."
+ ///Whether this shelf has spawned a cheese granter
+ var/static/cheese_granter_spawned = FALSE
+
+/obj/structure/bookcase/random/reference/wizard/after_random_load()
+ if(cheese_granter_spawned)
+ return
+ cheese_granter_spawned = TRUE
+ new /obj/item/book/granter/action/spell/summon_cheese(src)
+ new /obj/item/book/manual/ancient_parchment(src)
diff --git a/code/modules/mafia/controller.dm b/code/modules/mafia/controller.dm
index a0e5b26b5d9..1916a65f7b1 100644
--- a/code/modules/mafia/controller.dm
+++ b/code/modules/mafia/controller.dm
@@ -369,7 +369,7 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
* * role: mafia_role datum to reward.
*/
/datum/mafia_controller/proc/award_role(award, datum/mafia_role/rewarded)
- var/client/role_client = GLOB.directory[rewarded.body.client]
+ var/client/role_client = rewarded.body.client
role_client?.give_award(award, rewarded.body)
/**
diff --git a/code/modules/mafia/outfits.dm b/code/modules/mafia/outfits.dm
index b962b4530f1..0edb796212b 100644
--- a/code/modules/mafia/outfits.dm
+++ b/code/modules/mafia/outfits.dm
@@ -29,7 +29,7 @@
/datum/outfit/mafia/ninja
name = "Mafia Ninja"
glasses = /obj/item/clothing/glasses/sunglasses
- suit = /obj/item/clothing/suit/costume/ianshirt
+ suit = /obj/item/clothing/suit/costume/wellworn_shirt/graphic/ian
uniform = /obj/item/clothing/under/pants/jeans
shoes = /obj/item/clothing/shoes/sandal
diff --git a/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm b/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm
index 80b81d988cb..5e459758ee4 100644
--- a/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm
+++ b/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm
@@ -132,13 +132,13 @@
icon = 'icons/obj/storage/crates.dmi'
icon_state = "grave"
base_icon_state = "grave"
- dense_when_open = TRUE
+ density = FALSE
material_drop = /obj/item/stack/ore/glass/basalt
material_drop_amount = 5
anchorable = FALSE
anchored = TRUE
divable = FALSE //As funny as it may be, it would make little sense how you got yourself inside it in first place.
- breakout_time = 90 SECONDS
+ breakout_time = 2 MINUTES
open_sound = 'sound/effects/shovel_dig.ogg'
close_sound = 'sound/effects/shovel_dig.ogg'
can_install_electronics = FALSE
@@ -163,6 +163,11 @@
return NONE
+/obj/structure/closet/crate/grave/close(mob/living/user)
+ . = ..()
+ // So that graves stay undense
+ set_density(FALSE)
+
/obj/structure/closet/crate/grave/examine(mob/user)
. = ..()
. += span_notice("It can be [EXAMINE_HINT((opened ? "closed" : "dug open"))] with a shovel.")
@@ -271,6 +276,29 @@
deconstruct(TRUE)
return TRUE
+/obj/structure/closet/crate/grave/container_resist_act(mob/living/user)
+ if(opened)
+ return
+ // The player is trying to dig themselves out of an early grave
+ user.changeNext_move(CLICK_CD_BREAKOUT)
+ user.last_special = world.time + CLICK_CD_BREAKOUT
+ user.visible_message(
+ span_warning("[src]'s dirt begins to shift and rumble!"),
+ span_notice("You desperately begin to claw at the dirt around you, trying to force yourself upwards through the soil... (this will take about [DisplayTimeText(breakout_time)].)"),
+ span_hear("You hear the sound of shifting dirt from [src]."),
+ )
+ if(do_after(user, breakout_time, target = src))
+ if(opened)
+ return
+ user.visible_message(
+ span_danger("[user] emerges from [src], scattering dirt everywhere!"),
+ span_notice("You triumphantly surface out of [src], scattering dirt all around the grave!"),
+ )
+ bust_open()
+ else
+ if(user.loc == src)
+ to_chat(user, span_warning("You fail to dig yourself out of [src]!"))
+
/obj/structure/closet/crate/grave/filled/lead_researcher
name = "ominous burial mound"
desc = "Even in a place filled to the brim with graves, this one shows a level of preperation and planning that fills you with dread."
diff --git a/code/modules/mapfluff/ruins/lavalandruin_code/puzzle.dm b/code/modules/mapfluff/ruins/lavalandruin_code/puzzle.dm
index 461e9ee8c19..0e5437b9fd4 100644
--- a/code/modules/mapfluff/ruins/lavalandruin_code/puzzle.dm
+++ b/code/modules/mapfluff/ruins/lavalandruin_code/puzzle.dm
@@ -295,7 +295,7 @@
/obj/effect/sliding_puzzle/prison/dispense_reward()
prisoner.forceMove(get_turf(src))
- prisoner.notransform = FALSE
+ REMOVE_TRAIT(prisoner, TRAIT_NO_TRANSFORM, element_type)
prisoner = null
//Some armor so it's harder to kill someone by mistake.
@@ -344,7 +344,7 @@
return FALSE
//First grab the prisoner and move them temporarily into the generator so they won't get thrown around.
- prisoner.notransform = TRUE
+ ADD_TRAIT(prisoner, TRAIT_NO_TRANSFORM, cube.element_type)
prisoner.forceMove(cube)
to_chat(prisoner,span_userdanger("You're trapped by the prison cube! You will remain trapped until someone solves it."))
diff --git a/code/modules/mapfluff/ruins/objects_and_mobs/cursed_slot_machine.dm b/code/modules/mapfluff/ruins/objects_and_mobs/cursed_slot_machine.dm
index e85a90b783c..ab6b2bb1825 100644
--- a/code/modules/mapfluff/ruins/objects_and_mobs/cursed_slot_machine.dm
+++ b/code/modules/mapfluff/ruins/objects_and_mobs/cursed_slot_machine.dm
@@ -34,36 +34,18 @@
if(!ishuman(user))
return
- var/mob/living/carbon/human/human_user = user
-
- if(in_use)
- balloon_alert(human_user, "already spinning!")
- return
-
- if(!COOLDOWN_FINISHED(src, spin_cooldown))
- to_chat(human_user, span_danger("The machine doesn't engage. You get the compulsion to try again in a few seconds."))
- return
-
- in_use = TRUE
-
- var/signal_value = SEND_SIGNAL(human_user, COMSIG_CURSED_SLOT_MACHINE_USE, max_curse_amount)
-
- if(signal_value & SLOT_MACHINE_USE_POSTPONE)
- return
-
- if(signal_value & SLOT_MACHINE_USE_CANCEL) // failsafe in case we don't want to let the machine be used for some reason (like if we're maxed out on curses but not getting gibbed)
- say("We're sorry, but we can no longer serve you at this establishment.")
+ if(!check_and_set_usage(user))
return
user.visible_message(
- span_warning("[human_user] pulls [src]'s lever with a glint in [user.p_their()] eyes!"),
+ span_warning("[user] pulls [src]'s lever with a glint in [user.p_their()] eyes!"),
span_warning("You feel a draining as you pull the lever, but you know it'll be worth it."),
)
icon_screen = "slots_screen_working"
update_appearance()
playsound(src, 'sound/lavaland/cursed_slot_machine.ogg', 50, FALSE)
- addtimer(CALLBACK(src, PROC_REF(determine_victor), human_user), 5 SECONDS)
+ addtimer(CALLBACK(src, PROC_REF(determine_victor), user), 5 SECONDS)
/obj/structure/cursed_slot_machine/update_overlays()
. = ..()
@@ -71,11 +53,32 @@
. += mutable_appearance(icon, overlay_state)
. += emissive_appearance(icon, overlay_state, src)
-/obj/structure/cursed_slot_machine/proc/determine_victor(mob/living/user)
+/// Validates that the user can use the cursed slot machine. User is the person using the slot machine. Returns TRUE if we can, FALSE otherwise.
+/obj/structure/cursed_slot_machine/proc/check_and_set_usage(mob/living/carbon/human/user)
+ if(in_use)
+ balloon_alert_to_viewers("already spinning!")
+ return FALSE
+
+ var/signal_value = SEND_SIGNAL(user, COMSIG_CURSED_SLOT_MACHINE_USE, max_curse_amount)
+
+ if(!COOLDOWN_FINISHED(src, spin_cooldown) || (signal_value & SLOT_MACHINE_USE_POSTPONE))
+ to_chat(user, span_danger("The machine doesn't engage. You get the compulsion to try again in a few seconds."))
+ return FALSE
+
+ if(signal_value & SLOT_MACHINE_USE_CANCEL) // failsafe in case we don't want to let the machine be used for some reason (like if we're maxed out on curses but not getting gibbed)
+ say("We're sorry, but we can no longer serve you at this establishment.")
+ return FALSE
+
+ in_use = TRUE
+ return TRUE
+
+/obj/structure/cursed_slot_machine/proc/determine_victor(mob/living/carbon/human/user)
icon_screen = initial(icon_screen)
update_appearance()
+
in_use = FALSE
COOLDOWN_START(src, spin_cooldown, cooldown_length)
+
if(!prob(win_prob))
if(status_effect_on_roll && isnull(user.has_status_effect(/datum/status_effect/grouped/cursed)))
user.apply_status_effect(/datum/status_effect/grouped/cursed)
diff --git a/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm b/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm
index 4fcc88b89bc..424e1db299e 100644
--- a/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm
+++ b/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm
@@ -112,9 +112,10 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999))
if(!storageTurf) //Blame subsystems for not allowing this to be in Initialize
if(!GLOB.hhStorageTurf)
var/datum/map_template/hilbertshotelstorage/storageTemp = new()
- var/datum/turf_reservation/storageReservation = SSmapping.RequestBlockReservation(3, 3)
- storageTemp.load(locate(storageReservation.bottom_left_coords[1], storageReservation.bottom_left_coords[2], storageReservation.bottom_left_coords[3]))
- GLOB.hhStorageTurf = locate(storageReservation.bottom_left_coords[1]+1, storageReservation.bottom_left_coords[2]+1, storageReservation.bottom_left_coords[3])
+ var/datum/turf_reservation/storageReservation = SSmapping.request_turf_block_reservation(1, 1, 1)
+ var/turf/storage_turf = storageReservation.bottom_left_turfs[1]
+ storageTemp.load(storage_turf)
+ GLOB.hhStorageTurf = storage_turf
else
storageTurf = GLOB.hhStorageTurf
if(tryActiveRoom(chosenRoomNumber, target))
@@ -127,20 +128,30 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999))
if(activeRooms["[roomNumber]"])
var/datum/turf_reservation/roomReservation = activeRooms["[roomNumber]"]
do_sparks(3, FALSE, get_turf(user))
- user.forceMove(locate(roomReservation.bottom_left_coords[1] + hotelRoomTemp.landingZoneRelativeX, roomReservation.bottom_left_coords[2] + hotelRoomTemp.landingZoneRelativeY, roomReservation.bottom_left_coords[3]))
+ var/turf/room_bottom_left = roomReservation.bottom_left_turfs[1]
+ user.forceMove(locate(
+ room_bottom_left.x + hotelRoomTemp.landingZoneRelativeX,
+ room_bottom_left.y + hotelRoomTemp.landingZoneRelativeY,
+ room_bottom_left.z,
+ ))
return TRUE
return FALSE
/obj/item/hilbertshotel/proc/tryStoredRoom(roomNumber, mob/user)
if(storedRooms["[roomNumber]"])
- var/datum/turf_reservation/roomReservation = SSmapping.RequestBlockReservation(hotelRoomTemp.width, hotelRoomTemp.height)
- hotelRoomTempEmpty.load(locate(roomReservation.bottom_left_coords[1], roomReservation.bottom_left_coords[2], roomReservation.bottom_left_coords[3]))
+ var/datum/turf_reservation/roomReservation = SSmapping.request_turf_block_reservation(hotelRoomTemp.width, hotelRoomTemp.height, 1)
+ var/turf/room_turf = roomReservation.bottom_left_turfs[1]
+ hotelRoomTempEmpty.load(room_turf)
var/turfNumber = 1
for(var/x in 0 to hotelRoomTemp.width-1)
for(var/y in 0 to hotelRoomTemp.height-1)
for(var/atom/movable/A in storedRooms["[roomNumber]"][turfNumber])
if(istype(A.loc, /obj/item/abstracthotelstorage))//Don't want to recall something thats been moved
- A.forceMove(locate(roomReservation.bottom_left_coords[1] + x, roomReservation.bottom_left_coords[2] + y, roomReservation.bottom_left_coords[3]))
+ A.forceMove(locate(
+ room_turf.x + x,
+ room_turf.y + y,
+ room_turf.z,
+ ))
turfNumber++
for(var/obj/item/abstracthotelstorage/S in storageTurf)
if((S.roomNumber == roomNumber) && (S.parentSphere == src))
@@ -149,29 +160,39 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999))
activeRooms["[roomNumber]"] = roomReservation
linkTurfs(roomReservation, roomNumber)
do_sparks(3, FALSE, get_turf(user))
- user.forceMove(locate(roomReservation.bottom_left_coords[1] + hotelRoomTemp.landingZoneRelativeX, roomReservation.bottom_left_coords[2] + hotelRoomTemp.landingZoneRelativeY, roomReservation.bottom_left_coords[3]))
+ user.forceMove(locate(
+ room_turf.x + hotelRoomTemp.landingZoneRelativeX,
+ room_turf.y + hotelRoomTemp.landingZoneRelativeY,
+ room_turf.z,
+ ))
return TRUE
return FALSE
-/obj/item/hilbertshotel/proc/sendToNewRoom(roomNumber, mob/user, chosen_room) //SKYRAT EDIT ADDITION - GHOST HOTEL UPDATE. Was sendToNewRoom(chosenRoomNumber, target)
- var/datum/turf_reservation/roomReservation = SSmapping.RequestBlockReservation(hotelRoomTemp.width, hotelRoomTemp.height)
+/obj/item/hilbertshotel/proc/sendToNewRoom(roomNumber, mob/user, chosen_room) //SKYRAT EDIT ADDITION - GHOST HOTEL UPDATE. Was sendToNewRoom(roomNumber, mob/user)
+ var/datum/turf_reservation/roomReservation = SSmapping.request_turf_block_reservation(hotelRoomTemp.width, hotelRoomTemp.height, 1)
+ var/turf/bottom_left = roomReservation.bottom_left_turfs[1]
+ var/datum/map_template/load_from = hotelRoomTemp
+
if(ruinSpawned && roomNumber == GLOB.hhMysteryRoomNumber)
- hotelRoomTempLore.load(locate(roomReservation.bottom_left_coords[1], roomReservation.bottom_left_coords[2], roomReservation.bottom_left_coords[3]))
- else
- //SKYRAT EDIT ADDITION - GHOST HOTEL UPDATE
- switch(chosen_room)
- if("Apartment")
- ghost_cafe_rooms_apartment.load(locate(roomReservation.bottom_left_coords[1], roomReservation.bottom_left_coords[2], roomReservation.bottom_left_coords[3]))
- else
- //SKYRAT EDIT END
- hotelRoomTemp.load(locate(roomReservation.bottom_left_coords[1], roomReservation.bottom_left_coords[2], roomReservation.bottom_left_coords[3]))
+ load_from = hotelRoomTempLore
+ //SKYRAT EDIT ADDITION START - GHOST HOTEL UPDATE
+ else if(chosen_room == "Apartment")
+ load_from = ghost_cafe_rooms_apartment
+ //SKYRAT EDIT ADDITION END
+
+ load_from.load(bottom_left)
activeRooms["[roomNumber]"] = roomReservation
linkTurfs(roomReservation, roomNumber)
do_sparks(3, FALSE, get_turf(user))
- user.forceMove(locate(roomReservation.bottom_left_coords[1] + hotelRoomTemp.landingZoneRelativeX, roomReservation.bottom_left_coords[2] + hotelRoomTemp.landingZoneRelativeY, roomReservation.bottom_left_coords[3]))
+ user.forceMove(locate(
+ bottom_left.x + hotelRoomTemp.landingZoneRelativeX,
+ bottom_left.y + hotelRoomTemp.landingZoneRelativeY,
+ bottom_left.z,
+ ))
/obj/item/hilbertshotel/proc/linkTurfs(datum/turf_reservation/currentReservation, currentRoomnumber)
- var/area/misc/hilbertshotel/currentArea = get_area(locate(currentReservation.bottom_left_coords[1], currentReservation.bottom_left_coords[2], currentReservation.bottom_left_coords[3]))
+ var/turf/room_bottom_left = currentReservation.bottom_left_turfs[1]
+ var/area/misc/hilbertshotel/currentArea = get_area(room_bottom_left)
currentArea.name = "Hilbert's Hotel Room [currentRoomnumber]"
currentArea.parentSphere = src
currentArea.storageTurf = storageTurf
@@ -187,9 +208,10 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999))
if(activeRooms.len)
for(var/x in activeRooms)
var/datum/turf_reservation/room = activeRooms[x]
+ var/turf/room_bottom_left = room.bottom_left_turfs[1]
for(var/i in 0 to hotelRoomTemp.width-1)
for(var/j in 0 to hotelRoomTemp.height-1)
- for(var/atom/movable/A in locate(room.bottom_left_coords[1] + i, room.bottom_left_coords[2] + j, room.bottom_left_coords[3]))
+ for(var/atom/movable/A in locate(room_bottom_left.x + i, room_bottom_left.y + j, room_bottom_left.z))
if(ismob(A))
var/mob/M = A
if(M.mind)
@@ -271,7 +293,7 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999))
icon_state = "bluespace"
base_icon_state = "bluespace"
baseturfs = /turf/open/space/bluespace
- flags_1 = NOJAUNT
+ turf_flags = NOJAUNT
explosive_resistance = INFINITY
var/obj/item/hilbertshotel/parentSphere
@@ -437,7 +459,11 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999))
storeRoom()
/area/misc/hilbertshotel/proc/storeRoom()
- var/roomSize = (reservation.top_right_coords[1]-reservation.bottom_left_coords[1]+1)*(reservation.top_right_coords[2]-reservation.bottom_left_coords[2]+1)
+ var/turf/room_bottom_left = reservation.bottom_left_turfs[1]
+ var/turf/room_top_right = reservation.top_right_turfs[1]
+ var/roomSize = \
+ ((room_top_right.x - room_bottom_left.x) + 1) * \
+ ((room_top_right.y - room_bottom_left.y) + 1)
var/storage[roomSize]
var/turfNumber = 1
var/obj/item/abstracthotelstorage/storageObj = new(storageTurf)
@@ -447,7 +473,7 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999))
for(var/x in 0 to parentSphere.hotelRoomTemp.width-1)
for(var/y in 0 to parentSphere.hotelRoomTemp.height-1)
var/list/turfContents = list()
- for(var/atom/movable/A in locate(reservation.bottom_left_coords[1] + x, reservation.bottom_left_coords[2] + y, reservation.bottom_left_coords[3]))
+ for(var/atom/movable/A in locate(room_bottom_left.x + x, room_bottom_left.y + y, room_bottom_left.z))
if(ismob(A) && !isliving(A))
continue //Don't want to store ghosts
turfContents += A
@@ -480,14 +506,14 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999))
entered_light.end_processing()
. = ..()
if(ismob(arrived))
- var/mob/M = arrived
- M.notransform = TRUE
+ var/mob/target = arrived
+ ADD_TRAIT(target, TRAIT_NO_TRANSFORM, REF(src))
/obj/item/abstracthotelstorage/Exited(atom/movable/gone, direction)
. = ..()
if(ismob(gone))
- var/mob/M = gone
- M.notransform = FALSE
+ var/mob/target = gone
+ REMOVE_TRAIT(target, TRAIT_NO_TRANSFORM, REF(src))
if(istype(gone, /obj/machinery/light))
var/obj/machinery/light/exited_light = gone
exited_light.begin_processing()
@@ -527,10 +553,10 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999))
to_chat(user, "No vacated rooms.")
return .
-/obj/effect/landmark/lift_id/hilbert/research
+/obj/effect/landmark/lift_id/hilbert
specific_lift_id = HILBERT_TRAM
-/obj/effect/landmark/tram/nav/hilbert/research
+/obj/effect/landmark/tram/nav/hilbert
name = HILBERT_TRAM
specific_lift_id = TRAM_NAV_BEACONS
diff --git a/code/modules/mapfluff/ruins/spaceruin_code/meateor.dm b/code/modules/mapfluff/ruins/spaceruin_code/meateor.dm
index 8af5d4e5a9d..fc79c82e780 100644
--- a/code/modules/mapfluff/ruins/spaceruin_code/meateor.dm
+++ b/code/modules/mapfluff/ruins/spaceruin_code/meateor.dm
@@ -13,8 +13,12 @@
/obj/effect/mob_spawn/corpse/human/tigercultist/perforated/special(mob/living/carbon/human/spawned_human)
. = ..()
- var/datum/wound/pierce/critical/exit_hole = new()
- exit_hole.apply_wound(spawned_human.get_bodypart(BODY_ZONE_CHEST))
+
+ var/obj/item/bodypart/chest/their_chest = spawned_human.get_bodypart(BODY_ZONE_CHEST)
+ if (!their_chest)
+ return
+
+ spawned_human.cause_wound_of_type_and_severity(WOUND_PIERCE, their_chest, WOUND_SEVERITY_CRITICAL)
/// A fun drink enjoyed by the tiger cooperative, might corrode your brain if you drink the whole bottle
/obj/item/reagent_containers/cup/glass/bottle/ritual_wine
diff --git a/code/modules/mapfluff/ruins/spaceruin_code/oldstation/oldstation_cytology.dm b/code/modules/mapfluff/ruins/spaceruin_code/oldstation/oldstation_cytology.dm
new file mode 100644
index 00000000000..72333ff67d1
--- /dev/null
+++ b/code/modules/mapfluff/ruins/spaceruin_code/oldstation/oldstation_cytology.dm
@@ -0,0 +1,29 @@
+/obj/item/petri_dish/oldstation
+ name = "molly's biopsy"
+ desc = "You can see a moldy piece of sandwich inside the dish. Maybe it helped to preserve the bacteria for that long."
+
+/obj/item/petri_dish/oldstation/Initialize(mapload)
+ . = ..()
+ sample = new
+ sample.GenerateSample(CELL_LINE_TABLE_COW, null, 1, 0)
+ var/datum/biological_sample/contamination = new
+ contamination.GenerateSample(CELL_LINE_TABLE_GRAPE, null, 1, 0)
+ sample.Merge(contamination)
+ sample.sample_color = COLOR_SAMPLE_BROWN
+ update_appearance()
+
+/obj/item/reagent_containers/cup/beaker/oldstation
+ name = "cultivation broth"
+ amount_per_transfer_from_this = 50
+ list_reagents = list(
+ // Required for CELL_LINE_TABLE_COW
+ /datum/reagent/consumable/nutriment/protein = 10,
+ /datum/reagent/consumable/nutriment = 5,
+ /datum/reagent/cellulose = 5,
+ // Required for CELL_LINE_TABLE_GRAPE
+ /datum/reagent/toxin/slimejelly = 5,
+ /datum/reagent/yuck = 5,
+ /datum/reagent/consumable/vitfro = 5,
+ // Supplementary for CELL_LINE_TABLE_GRAPE
+ /datum/reagent/consumable/liquidgibs = 5
+ )
diff --git a/code/modules/mapfluff/ruins/spaceruin_code/oldstation.dm b/code/modules/mapfluff/ruins/spaceruin_code/oldstation/oldstation_fluff.dm
similarity index 64%
rename from code/modules/mapfluff/ruins/spaceruin_code/oldstation.dm
rename to code/modules/mapfluff/ruins/spaceruin_code/oldstation/oldstation_fluff.dm
index 209b5798d53..a0b4adb9f75 100644
--- a/code/modules/mapfluff/ruins/spaceruin_code/oldstation.dm
+++ b/code/modules/mapfluff/ruins/spaceruin_code/oldstation/oldstation_fluff.dm
@@ -108,159 +108,3 @@
name = "DO NOT TOUCH!"
default_raw_text = "This is a spare pre-charged APC battery for emergencies ONLY. DO NOT use it for stun prods, Bob.
\
Note: Use crowbar to remove the APC cover and take out the malfunctioning battery."
-
-/obj/machinery/mod_installer
- name = "modular outerwear device installator"
- desc = "An ancient machine that mounts a MOD unit onto the occupant."
- icon = 'icons/obj/machines/mod_installer.dmi'
- icon_state = "mod_installer"
- base_icon_state = "mod_installer"
- layer = ABOVE_WINDOW_LAYER
- use_power = IDLE_POWER_USE
- anchored = TRUE
- density = TRUE
- obj_flags = BLOCKS_CONSTRUCTION // Becomes undense when the door is open
- idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.5
- active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 0.3
-
- var/busy = FALSE
- var/busy_icon_state
-
- var/obj/item/mod/control/mod_unit = /obj/item/mod/control/pre_equipped/prototype
-
- COOLDOWN_DECLARE(message_cooldown)
-
-/obj/machinery/mod_installer/Initialize(mapload)
- . = ..()
- occupant_typecache = typecacheof(/mob/living/carbon/human)
- if(ispath(mod_unit))
- mod_unit = new mod_unit()
-
-/obj/machinery/mod_installer/Destroy()
- QDEL_NULL(mod_unit)
- return ..()
-
-/obj/machinery/mod_installer/proc/set_busy(status, working_icon)
- busy = status
- busy_icon_state = working_icon
- update_appearance()
-
-/obj/machinery/mod_installer/proc/play_install_sound()
- playsound(src, 'sound/items/rped.ogg', 30, FALSE)
-
-/obj/machinery/mod_installer/update_icon_state()
- icon_state = busy ? busy_icon_state : "[base_icon_state][state_open ? "_open" : null]"
- return ..()
-
-/obj/machinery/mod_installer/update_overlays()
- var/list/overlays = ..()
- if(machine_stat & (NOPOWER|BROKEN))
- return overlays
- overlays += (busy || !mod_unit) ? "red" : "green"
- return overlays
-
-/obj/machinery/mod_installer/proc/start_process()
- if(machine_stat & (NOPOWER|BROKEN))
- return
- if(!occupant || !mod_unit || busy)
- return
- set_busy(TRUE, "[initial(icon_state)]_raising")
- addtimer(CALLBACK(src, PROC_REF(set_busy), TRUE, "[initial(icon_state)]_active"), 2.5 SECONDS)
- addtimer(CALLBACK(src, PROC_REF(play_install_sound)), 2.5 SECONDS)
- addtimer(CALLBACK(src, PROC_REF(set_busy), TRUE, "[initial(icon_state)]_falling"), 5 SECONDS)
- addtimer(CALLBACK(src, PROC_REF(complete_process)), 7.5 SECONDS)
-
-/obj/machinery/mod_installer/proc/complete_process()
- set_busy(FALSE)
- var/mob/living/carbon/human/human_occupant = occupant
- if(!istype(human_occupant))
- return
- if(!human_occupant.dropItemToGround(human_occupant.back))
- return
- if(!human_occupant.equip_to_slot_if_possible(mod_unit, mod_unit.slot_flags, qdel_on_fail = FALSE, disable_warning = TRUE))
- return
- human_occupant.update_action_buttons(TRUE)
- playsound(src, 'sound/machines/ping.ogg', 30, FALSE)
- if(!human_occupant.dropItemToGround(human_occupant.wear_suit) || !human_occupant.dropItemToGround(human_occupant.head))
- finish_completion()
- return
- mod_unit.quick_activation()
- finish_completion()
-
-/obj/machinery/mod_installer/proc/finish_completion()
- mod_unit = null
- open_machine()
-
-/obj/machinery/mod_installer/open_machine(drop = TRUE, density_to_set = FALSE)
- if(state_open)
- return FALSE
- ..()
- return TRUE
-
-/obj/machinery/mod_installer/close_machine(mob/living/carbon/user, density_to_set = TRUE)
- if(!state_open)
- return FALSE
- ..()
- addtimer(CALLBACK(src, PROC_REF(start_process)), 1 SECONDS)
- return TRUE
-
-/obj/machinery/mod_installer/relaymove(mob/living/user, direction)
- var/message
- if(busy)
- message = "it won't budge!"
- else if(user.stat != CONSCIOUS)
- message = "you don't have the energy!"
- if(!isnull(message))
- if (COOLDOWN_FINISHED(src, message_cooldown))
- COOLDOWN_START(src, message_cooldown, 5 SECONDS)
- balloon_alert(user, message)
- return
- open_machine()
-
-/obj/machinery/mod_installer/interact(mob/user)
- if(state_open)
- close_machine(null, user)
- return
- else if(busy)
- balloon_alert(user, "it's locked!")
- return
- open_machine()
-
-/obj/item/petri_dish/oldstation
- name = "molly's biopsy"
- desc = "You can see a moldy piece of sandwich inside the dish. Maybe it helped to preserve the bacteria for that long."
-
-/obj/item/petri_dish/oldstation/Initialize(mapload)
- . = ..()
- sample = new
- sample.GenerateSample(CELL_LINE_TABLE_COW, null, 1, 0)
- var/datum/biological_sample/contamination = new
- contamination.GenerateSample(CELL_LINE_TABLE_GRAPE, null, 1, 0)
- sample.Merge(contamination)
- sample.sample_color = COLOR_SAMPLE_BROWN
- update_appearance()
-
-/obj/item/reagent_containers/cup/beaker/oldstation
- name = "cultivation broth"
- amount_per_transfer_from_this = 60 // SKYRAT EDIT - Beakers capacity 50u -> 60u - ORIGINAL: amount_per_transfer_from_this = 50
- list_reagents = list(
- // Required for CELL_LINE_TABLE_COW
- /datum/reagent/consumable/nutriment/protein = 10,
- /datum/reagent/consumable/nutriment = 5,
- /datum/reagent/cellulose = 5,
- // Required for CELL_LINE_TABLE_GRAPE
- /datum/reagent/toxin/slimejelly = 5,
- /datum/reagent/yuck = 5,
- /datum/reagent/consumable/vitfro = 5,
- // Supplementary for CELL_LINE_TABLE_GRAPE
- /datum/reagent/consumable/liquidgibs = 5
- )
-
-/obj/machinery/computer/old
- name = "old computer"
- circuit = /obj/item/circuitboard/computer
-
-/obj/machinery/computer/old/Initialize(mapload)
- icon_keyboard = pick("generic_key", "med_key")
- icon_screen = pick("generic", "comm_monitor", "comm_logs")
- . = ..()
diff --git a/code/modules/mapfluff/ruins/spaceruin_code/oldstation/oldstation_machines.dm b/code/modules/mapfluff/ruins/spaceruin_code/oldstation/oldstation_machines.dm
new file mode 100644
index 00000000000..c2552b10744
--- /dev/null
+++ b/code/modules/mapfluff/ruins/spaceruin_code/oldstation/oldstation_machines.dm
@@ -0,0 +1,8 @@
+/obj/machinery/computer/old
+ name = "old computer"
+ circuit = /obj/item/circuitboard/computer
+
+/obj/machinery/computer/old/Initialize(mapload)
+ icon_keyboard = pick("generic_key", "med_key")
+ icon_screen = pick("generic", "comm_monitor", "comm_logs")
+ return ..()
diff --git a/code/modules/mapfluff/ruins/spaceruin_code/oldstation/oldstation_mod.dm b/code/modules/mapfluff/ruins/spaceruin_code/oldstation/oldstation_mod.dm
new file mode 100644
index 00000000000..ac026045674
--- /dev/null
+++ b/code/modules/mapfluff/ruins/spaceruin_code/oldstation/oldstation_mod.dm
@@ -0,0 +1,116 @@
+/obj/machinery/mod_installer
+ name = "modular outerwear device installator"
+ desc = "An ancient machine that mounts a MOD unit onto the occupant."
+ icon = 'icons/obj/machines/mod_installer.dmi'
+ icon_state = "mod_installer"
+ base_icon_state = "mod_installer"
+ layer = ABOVE_WINDOW_LAYER
+ use_power = IDLE_POWER_USE
+ anchored = TRUE
+ density = TRUE
+ obj_flags = BLOCKS_CONSTRUCTION // Becomes undense when the door is open
+ idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.5
+ active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 0.3
+
+ var/busy = FALSE
+ var/busy_icon_state
+
+ var/obj/item/mod/control/mod_unit = /obj/item/mod/control/pre_equipped/prototype
+
+ COOLDOWN_DECLARE(message_cooldown)
+
+/obj/machinery/mod_installer/Initialize(mapload)
+ . = ..()
+ occupant_typecache = typecacheof(/mob/living/carbon/human)
+ if(ispath(mod_unit))
+ mod_unit = new mod_unit()
+
+/obj/machinery/mod_installer/Destroy()
+ QDEL_NULL(mod_unit)
+ return ..()
+
+/obj/machinery/mod_installer/proc/set_busy(status, working_icon)
+ busy = status
+ busy_icon_state = working_icon
+ update_appearance()
+
+/obj/machinery/mod_installer/proc/play_install_sound()
+ playsound(src, 'sound/items/rped.ogg', 30, FALSE)
+
+/obj/machinery/mod_installer/update_icon_state()
+ icon_state = busy ? busy_icon_state : "[base_icon_state][state_open ? "_open" : null]"
+ return ..()
+
+/obj/machinery/mod_installer/update_overlays()
+ var/list/overlays = ..()
+ if(machine_stat & (NOPOWER|BROKEN))
+ return overlays
+ overlays += (busy || !mod_unit) ? "red" : "green"
+ return overlays
+
+/obj/machinery/mod_installer/proc/start_process()
+ if(machine_stat & (NOPOWER|BROKEN))
+ return
+ if(!occupant || !mod_unit || busy)
+ return
+ set_busy(TRUE, "[initial(icon_state)]_raising")
+ addtimer(CALLBACK(src, PROC_REF(set_busy), TRUE, "[initial(icon_state)]_active"), 2.5 SECONDS)
+ addtimer(CALLBACK(src, PROC_REF(play_install_sound)), 2.5 SECONDS)
+ addtimer(CALLBACK(src, PROC_REF(set_busy), TRUE, "[initial(icon_state)]_falling"), 5 SECONDS)
+ addtimer(CALLBACK(src, PROC_REF(complete_process)), 7.5 SECONDS)
+
+/obj/machinery/mod_installer/proc/complete_process()
+ set_busy(FALSE)
+ var/mob/living/carbon/human/human_occupant = occupant
+ if(!istype(human_occupant))
+ return
+ if(!human_occupant.dropItemToGround(human_occupant.back))
+ return
+ if(!human_occupant.equip_to_slot_if_possible(mod_unit, mod_unit.slot_flags, qdel_on_fail = FALSE, disable_warning = TRUE))
+ return
+ human_occupant.update_action_buttons(TRUE)
+ playsound(src, 'sound/machines/ping.ogg', 30, FALSE)
+ if(!human_occupant.dropItemToGround(human_occupant.wear_suit) || !human_occupant.dropItemToGround(human_occupant.head))
+ finish_completion()
+ return
+ mod_unit.quick_activation()
+ finish_completion()
+
+/obj/machinery/mod_installer/proc/finish_completion()
+ mod_unit = null
+ open_machine()
+
+/obj/machinery/mod_installer/open_machine(drop = TRUE, density_to_set = FALSE)
+ if(state_open)
+ return FALSE
+ ..()
+ return TRUE
+
+/obj/machinery/mod_installer/close_machine(mob/living/carbon/user, density_to_set = TRUE)
+ if(!state_open)
+ return FALSE
+ ..()
+ addtimer(CALLBACK(src, PROC_REF(start_process)), 1 SECONDS)
+ return TRUE
+
+/obj/machinery/mod_installer/relaymove(mob/living/user, direction)
+ var/message
+ if(busy)
+ message = "it won't budge!"
+ else if(user.stat != CONSCIOUS)
+ message = "you don't have the energy!"
+ if(!isnull(message))
+ if (COOLDOWN_FINISHED(src, message_cooldown))
+ COOLDOWN_START(src, message_cooldown, 5 SECONDS)
+ balloon_alert(user, message)
+ return
+ open_machine()
+
+/obj/machinery/mod_installer/interact(mob/user)
+ if(state_open)
+ close_machine(null, user)
+ return
+ else if(busy)
+ balloon_alert(user, "it's locked!")
+ return
+ open_machine()
diff --git a/code/modules/mapfluff/ruins/spaceruin_code/oldstation/oldstation_rnd.dm b/code/modules/mapfluff/ruins/spaceruin_code/oldstation/oldstation_rnd.dm
new file mode 100644
index 00000000000..58d14e0d041
--- /dev/null
+++ b/code/modules/mapfluff/ruins/spaceruin_code/oldstation/oldstation_rnd.dm
@@ -0,0 +1,29 @@
+/obj/machinery/rnd/server/oldstation
+ name = "\improper Ancient R&D Server"
+ circuit = /obj/item/circuitboard/machine/rdserver/oldstation
+ req_access = list(ACCESS_AWAY_SCIENCE)
+
+/obj/machinery/rnd/server/oldstation/Initialize(mapload)
+ register_context()
+ var/datum/techweb/oldstation_web = locate(/datum/techweb/oldstation) in SSresearch.techwebs
+ stored_research = oldstation_web
+ return ..()
+
+/obj/machinery/rnd/server/oldstation/add_context(atom/source, list/context, obj/item/held_item, mob/user)
+ if(held_item && istype(held_item, /obj/item/research_notes))
+ context[SCREENTIP_CONTEXT_LMB] = "Generate research points"
+ return CONTEXTUAL_SCREENTIP_SET
+
+/obj/machinery/rnd/server/oldstation/attackby(obj/item/attacking_item, mob/user, params)
+ if(istype(attacking_item, /obj/item/research_notes) && stored_research)
+ var/obj/item/research_notes/research_notes = attacking_item
+ stored_research.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = research_notes.value))
+ playsound(src, 'sound/machines/copier.ogg', 50, TRUE)
+ qdel(research_notes)
+ return
+ return ..()
+
+///Ancient computer that starts with dissection to tell players they have it.
+/obj/machinery/computer/operating/oldstation
+ name = "ancient operating computer"
+ advanced_surgeries = list(/datum/surgery/advanced/experimental_dissection)
diff --git a/code/modules/mapping/map_template.dm b/code/modules/mapping/map_template.dm
index 30477657ab5..237ae9f2d52 100644
--- a/code/modules/mapping/map_template.dm
+++ b/code/modules/mapping/map_template.dm
@@ -133,7 +133,15 @@
var/y = round((world.maxy - height) * 0.5) + 1
var/datum/space_level/level = SSmapping.add_new_zlevel(name, secret ? ZTRAITS_AWAY_SECRET : ZTRAITS_AWAY, contain_turfs = FALSE)
- var/datum/parsed_map/parsed = load_map(file(mappath), x, y, level.z_value, no_changeturf=(SSatoms.initialized == INITIALIZATION_INSSATOMS), placeOnTop=should_place_on_top, new_z = TRUE)
+ var/datum/parsed_map/parsed = load_map(
+ file(mappath),
+ x,
+ y,
+ level.z_value,
+ no_changeturf = (SSatoms.initialized == INITIALIZATION_INSSATOMS),
+ place_on_top = should_place_on_top,
+ new_z = TRUE,
+ )
var/list/bounds = parsed.bounds
if(!bounds)
return FALSE
@@ -177,7 +185,14 @@
UNSETEMPTY(turf_blacklist)
parsed.turf_blacklist = turf_blacklist
- if(!parsed.load(T.x, T.y, T.z, cropMap=TRUE, no_changeturf=(SSatoms.initialized == INITIALIZATION_INSSATOMS), placeOnTop=should_place_on_top))
+ if(!parsed.load(
+ T.x,
+ T.y,
+ T.z,
+ crop_map = TRUE,
+ no_changeturf = (SSatoms.initialized == INITIALIZATION_INSSATOMS),
+ place_on_top = should_place_on_top,
+ ))
return
var/list/bounds = parsed.bounds
diff --git a/code/modules/mapping/mapping_helpers.dm b/code/modules/mapping/mapping_helpers.dm
index d32bc6e5938..cec7932f4f5 100644
--- a/code/modules/mapping/mapping_helpers.dm
+++ b/code/modules/mapping/mapping_helpers.dm
@@ -840,8 +840,15 @@ INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava)
name = "Dead Body placer"
late = TRUE
icon_state = "deadbodyplacer"
+ ///if TRUE, was spawned out of mapload.
var/admin_spawned
- var/bodycount = 2 //number of bodies to spawn
+ ///number of bodies to spawn
+ var/bodycount = 3
+ /// These species IDs will be barred from spawning if morgue_cadaver_disable_nonhumans is disabled (In the future, we can also dehardcode this)
+ var/list/blacklisted_from_rng_placement = list(
+ SPECIES_ETHEREAL, // they revive on death which is bad juju
+ SPECIES_HUMAN, // already have a 50% chance of being selected
+ )
/obj/effect/mapping_helpers/dead_body_placer/Initialize(mapload)
. = ..()
@@ -850,23 +857,23 @@ INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava)
admin_spawned = TRUE
/obj/effect/mapping_helpers/dead_body_placer/LateInitialize()
- var/area/a = get_area(src)
- var/list/trays = list()
- for (var/i in a.contents)
- if (istype(i, /obj/structure/bodycontainer/morgue))
- if(admin_spawned)
- var/obj/structure/bodycontainer/morgue/early_morgue_tray = i
- if(early_morgue_tray.connected.loc != early_morgue_tray)
- continue
- trays += i
- if(!trays.len)
+ var/area/morgue_area = get_area(src)
+ var/list/obj/structure/bodycontainer/morgue/trays = list()
+ for(var/turf/area_turf as anything in morgue_area.get_contained_turfs())
+ var/obj/structure/bodycontainer/morgue/morgue_tray = locate() in area_turf
+ if(isnull(morgue_tray) || !morgue_tray.beeper || morgue_tray.connected.loc != morgue_tray)
+ continue
+ trays += morgue_tray
+
+ var/numtrays = length(trays)
+ if(numtrays == 0)
if(admin_spawned)
message_admins("[src] spawned at [ADMIN_VERBOSEJMP(src)] failed to find a closed morgue to spawn a body!")
else
log_mapping("[src] at [x],[y] could not find any morgues.")
return
- var/reuse_trays = (trays.len < bodycount) //are we going to spawn more trays than bodies?
+ var/reuse_trays = (numtrays < bodycount) //are we going to spawn more trays than bodies?
var/use_species = !(CONFIG_GET(flag/morgue_cadaver_disable_nonhumans))
var/species_probability = CONFIG_GET(number/morgue_cadaver_other_species_probability)
@@ -875,35 +882,39 @@ INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava)
if(use_species)
var/list/temp_list = get_selectable_species()
usable_races = temp_list.Copy()
- usable_races -= SPECIES_ETHEREAL //they revive on death which is bad juju
- LAZYREMOVE(usable_races, SPECIES_HUMAN)
- if(!usable_races)
+ LAZYREMOVE(usable_races, blacklisted_from_rng_placement)
+ if(!LAZYLEN(usable_races))
notice("morgue_cadaver_disable_nonhumans. There are no valid roundstart nonhuman races enabled. Defaulting to humans only!")
if(override_species)
warning("morgue_cadaver_override_species BEING OVERRIDEN since morgue_cadaver_disable_nonhumans is disabled.")
else if(override_species)
- usable_races += override_species
+ LAZYADD(usable_races, override_species)
- for (var/i = 1 to bodycount)
+ var/guaranteed_human_spawned = FALSE
+ for (var/i in 1 to bodycount)
var/obj/structure/bodycontainer/morgue/morgue_tray = reuse_trays ? pick(trays) : pick_n_take(trays)
var/obj/structure/closet/body_bag/body_bag = new(morgue_tray.loc)
- var/mob/living/carbon/human/new_human = new /mob/living/carbon/human(morgue_tray.loc, 1)
+ var/mob/living/carbon/human/new_human = new(morgue_tray.loc)
var/species_to_pick
- if(LAZYLEN(usable_races))
- if(!species_probability)
- species_probability = 50
- stack_trace("WARNING: morgue_cadaver_other_species_probability CONFIG SET TO 0% WHEN SPAWNING. DEFAULTING TO [species_probability]%.")
- if(prob(species_probability))
- species_to_pick = pick(usable_races)
- var/datum/species/new_human_species = GLOB.species_list[species_to_pick]
- if(new_human_species)
- new_human.set_species(new_human_species)
- new_human_species = new_human.dna.species
- new_human_species.randomize_features(new_human)
- new_human.fully_replace_character_name(new_human.real_name, new_human_species.random_name(new_human.gender, TRUE, TRUE))
- else
- stack_trace("failed to spawn cadaver with species ID [species_to_pick]") //if it's invalid they'll just be a human, so no need to worry too much aside from yelling at the server owner lol.
+
+ if(guaranteed_human_spawned && use_species)
+ if(LAZYLEN(usable_races))
+ if(!isnum(species_probability))
+ species_probability = 50
+ stack_trace("WARNING: morgue_cadaver_other_species_probability CONFIG SET TO 0% WHEN SPAWNING. DEFAULTING TO [species_probability]%.")
+ if(prob(species_probability))
+ species_to_pick = pick(usable_races)
+ var/datum/species/new_human_species = GLOB.species_list[species_to_pick]
+ if(new_human_species)
+ new_human.set_species(new_human_species)
+ new_human_species = new_human.dna.species
+ new_human_species.randomize_features(new_human)
+ new_human.fully_replace_character_name(new_human.real_name, new_human_species.random_name(new_human.gender, TRUE, TRUE))
+ else
+ stack_trace("failed to spawn cadaver with species ID [species_to_pick]") //if it's invalid they'll just be a human, so no need to worry too much aside from yelling at the server owner lol.
+ else
+ guaranteed_human_spawned = TRUE
body_bag.insert(new_human, TRUE)
body_bag.close()
@@ -911,18 +922,16 @@ INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava)
body_bag.forceMove(morgue_tray)
new_human.death() //here lies the mans, rip in pepperoni.
- for (var/part in new_human.organs) //randomly remove organs from each body, set those we keep to be in stasis
+ for (var/obj/item/organ/internal/part in new_human.organs) //randomly remove organs from each body, set those we keep to be in stasis
if (prob(40))
qdel(part)
else
- var/obj/item/organ/O = part
- O.organ_flags |= ORGAN_FROZEN
+ part.organ_flags |= ORGAN_FROZEN
morgue_tray.update_appearance()
qdel(src)
-
//On Ian's birthday, the hop's office is decorated.
/obj/effect/mapping_helpers/ianbirthday
name = "Ian's Bday Helper"
@@ -1350,3 +1359,19 @@ INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava)
engraved_wall.AddComponent(/datum/component/engraved, engraving["story"], FALSE, engraving["story_value"])
qdel(src)
+
+/// Apply to a wall (or floor, technically) to ensure it is instantly destroyed by any explosion, even if usually invulnerable
+/obj/effect/mapping_helpers/bombable_wall
+ name = "bombable wall helper"
+ icon = 'icons/turf/overlays.dmi'
+ icon_state = "explodable"
+
+/obj/effect/mapping_helpers/bombable_wall/Initialize(mapload)
+ . = ..()
+ if(!mapload)
+ log_mapping("[src] spawned outside of mapload!")
+ return
+
+ var/turf/our_turf = get_turf(src) // In case a locker ate us or something
+ our_turf.AddElement(/datum/element/bombable_turf)
+ return INITIALIZE_HINT_QDEL
diff --git a/code/modules/mapping/reader.dm b/code/modules/mapping/reader.dm
index 96b555457d7..14a8fdf6b94 100644
--- a/code/modules/mapping/reader.dm
+++ b/code/modules/mapping/reader.dm
@@ -114,26 +114,72 @@
var/turfsSkipped = 0
#endif
+/datum/parsed_map/proc/copy()
+ // Avoids duped work just in case
+ build_cache()
+ var/datum/parsed_map/newfriend = new()
+ newfriend.original_path = original_path
+ newfriend.map_format = map_format
+ newfriend.key_len = key_len
+ newfriend.line_len = line_len
+ newfriend.grid_models = grid_models.Copy()
+ newfriend.gridSets = gridSets.Copy()
+ newfriend.modelCache = modelCache.Copy()
+ newfriend.parsed_bounds = parsed_bounds.Copy()
+ // Copy parsed bounds to reset to initial values
+ newfriend.bounds = parsed_bounds.Copy()
+ newfriend.turf_blacklist = turf_blacklist?.Copy()
+ return newfriend
+
//text trimming (both directions) helper macro
#define TRIM_TEXT(text) (trim_reduced(text))
-/// Shortcut function to parse a map and apply it to the world.
-///
-/// - `dmm_file`: A .dmm file to load (Required).
-/// - `x_offset`, `y_offset`, `z_offset`: Positions representign where to load the map (Optional).
-/// - `cropMap`: When true, the map will be cropped to fit the existing world dimensions (Optional).
-/// - `measureOnly`: When true, no changes will be made to the world (Optional).
-/// - `no_changeturf`: When true, [/turf/proc/AfterChange] won't be called on loaded turfs
-/// - `x_lower`, `x_upper`, `y_lower`, `y_upper`: Coordinates (relative to the map) to crop to (Optional).
-/// - `placeOnTop`: Whether to use [/turf/proc/PlaceOnTop] rather than [/turf/proc/ChangeTurf] (Optional).
-/proc/load_map(dmm_file as file, x_offset as num, y_offset as num, z_offset as num, cropMap as num, measureOnly as num, no_changeturf as num, x_lower = -INFINITY as num, x_upper = INFINITY as num, y_lower = -INFINITY as num, y_upper = INFINITY as num, placeOnTop = FALSE as num, new_z)
- var/datum/parsed_map/parsed = new(dmm_file, x_lower, x_upper, y_lower, y_upper, measureOnly)
- if(parsed.bounds && !measureOnly)
- parsed.load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, new_z = new_z)
- return parsed
+/**
+ * Helper and recommened way to load a map file
+ * - dmm_file: The path to the map file
+ * - x_offset: The x offset to load the map at
+ * - y_offset: The y offset to load the map at
+ * - z_offset: The z offset to load the map at
+ * - crop_map: If true, the map will be cropped to the world bounds
+ * - measure_only: If true, the map will not be loaded, but the bounds will be calculated
+ * - no_changeturf: If true, the map will not call /turf/AfterChange
+ * - x_lower: The minimum x coordinate to load
+ * - x_upper: The maximum x coordinate to load
+ * - y_lower: The minimum y coordinate to load
+ * - y_upper: The maximum y coordinate to load
+ * - z_lower: The minimum z coordinate to load
+ * - z_upper: The maximum z coordinate to load
+ * - place_on_top: Whether to use /turf/proc/PlaceOnTop rather than /turf/proc/ChangeTurf
+ * - new_z: If true, a new z level will be created for the map
+ */
+/proc/load_map(
+ dmm_file,
+ x_offset = 0,
+ y_offset = 0,
+ z_offset = 0,
+ crop_map = FALSE,
+ measure_only = FALSE,
+ no_changeturf = FALSE,
+ x_lower = -INFINITY,
+ x_upper = INFINITY,
+ y_lower = -INFINITY,
+ y_upper = INFINITY,
+ z_lower = -INFINITY,
+ z_upper = INFINITY,
+ place_on_top = FALSE,
+ new_z = FALSE,
+)
+ if(!(dmm_file in GLOB.cached_maps))
+ GLOB.cached_maps[dmm_file] = new /datum/parsed_map(dmm_file)
+
+ var/datum/parsed_map/parsed_map = GLOB.cached_maps[dmm_file]
+ parsed_map = parsed_map.copy()
+ if(!measure_only && !isnull(parsed_map.bounds))
+ parsed_map.load(x_offset, y_offset, z_offset, crop_map, no_changeturf, x_lower, x_upper, y_lower, y_upper, z_lower, z_upper, place_on_top, new_z)
+ return parsed_map
/// Parse a map, possibly cropping it.
-/datum/parsed_map/New(tfile, x_lower = -INFINITY, x_upper = INFINITY, y_lower = -INFINITY, y_upper=INFINITY, measureOnly=FALSE)
+/datum/parsed_map/New(tfile, x_lower = -INFINITY, x_upper = INFINITY, y_lower = -INFINITY, y_upper=INFINITY, z_lower = -INFINITY, z_upper=INFINITY, measureOnly=FALSE)
// This proc sleeps for like 6 seconds. why?
// Is it file accesses? if so, can those be done ahead of time, async to save on time here? I wonder.
// Love ya :)
@@ -184,20 +230,26 @@
CRASH("Coords before model definition in DMM")
var/curr_x = text2num(regexOutput[3])
-
if(curr_x < x_lower || curr_x > x_upper)
continue
+ var/curr_y = text2num(regexOutput[4])
+ if(curr_y < y_lower || curr_y > y_upper)
+ continue
+
+ var/curr_z = text2num(regexOutput[5])
+ if(curr_z < z_lower || curr_z > z_upper)
+ continue
+
var/datum/grid_set/gridSet = new
gridSet.xcrd = curr_x
- //position of the currently processed square
- gridSet.ycrd = text2num(regexOutput[4])
- gridSet.zcrd = text2num(regexOutput[5])
+ gridSet.ycrd = curr_y
+ gridSet.zcrd = curr_z
bounds[MAP_MINX] = min(bounds[MAP_MINX], curr_x)
- bounds[MAP_MINZ] = min(bounds[MAP_MINZ], gridSet.zcrd)
- bounds[MAP_MAXZ] = max(bounds[MAP_MAXZ], gridSet.zcrd)
+ bounds[MAP_MINZ] = min(bounds[MAP_MINZ], curr_y)
+ bounds[MAP_MAXZ] = max(bounds[MAP_MAXZ], curr_z)
var/list/gridLines = splittext(regexOutput[6], "\n")
gridSet.gridLines = gridLines
@@ -238,16 +290,29 @@
bounds[MAP_MAXX] = clamp(bounds[MAP_MAXX], x_lower, x_upper)
bounds[MAP_MINY] = clamp(bounds[MAP_MINY], y_lower, y_upper)
bounds[MAP_MAXY] = clamp(bounds[MAP_MAXY], y_lower, y_upper)
+ bounds[MAP_MINZ] = clamp(bounds[MAP_MINZ], z_lower, z_upper)
+ bounds[MAP_MAXZ] = clamp(bounds[MAP_MAXZ], z_lower, z_upper)
parsed_bounds = src.bounds
src.key_len = key_len
src.line_len = line_len
-/// Load the parsed map into the world. See [/proc/load_map] for arguments.
-/datum/parsed_map/proc/load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, whitelist = FALSE, new_z)
+/// Iterates over all grid sets and returns ones with z values within the given bounds. Inclusive
+/datum/parsed_map/proc/filter_grid_sets_based_on_z_bounds(lower_z, upper_z)
+ var/list/filtered_sets = list()
+ for(var/datum/grid_set/grid_set as anything in gridSets)
+ if(grid_set.zcrd < lower_z)
+ continue
+ if(grid_set.zcrd > upper_z)
+ continue
+ filtered_sets += grid_set
+ return filtered_sets
+
+/// Load the parsed map into the world. You probably want [/proc/load_map]. Keep the signature the same.
+/datum/parsed_map/proc/load(x_offset = 0, y_offset = 0, z_offset = 0, crop_map = FALSE, no_changeturf = FALSE, x_lower = -INFINITY, x_upper = INFINITY, y_lower = -INFINITY, y_upper = INFINITY, z_lower = -INFINITY, z_upper = INFINITY, place_on_top = FALSE, new_z = FALSE)
//How I wish for RAII
Master.StartLoadingMap()
- . = _load_impl(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, new_z)
+ . = _load_impl(x_offset, y_offset, z_offset, crop_map, no_changeturf, x_lower, x_upper, y_lower, y_upper, z_lower, z_upper, place_on_top, new_z)
Master.StopLoadingMap()
#define MAPLOADING_CHECK_TICK \
@@ -262,7 +327,7 @@
}
// Do not call except via load() above.
-/datum/parsed_map/proc/_load_impl(x_offset = 1, y_offset = 1, z_offset = world.maxz + 1, cropMap = FALSE, no_changeturf = FALSE, x_lower = -INFINITY, x_upper = INFINITY, y_lower = -INFINITY, y_upper = INFINITY, placeOnTop = FALSE, new_z = FALSE)
+/datum/parsed_map/proc/_load_impl(x_offset, y_offset, z_offset, crop_map, no_changeturf, x_lower, x_upper, y_lower, y_upper, z_lower, z_upper, place_on_top, new_z)
PRIVATE_PROC(TRUE)
// Tell ss atoms that we're doing maploading
// We'll have to account for this in the following tick_checks so it doesn't overflow
@@ -275,9 +340,9 @@
var/sucessful = FALSE
switch(map_format)
if(MAP_TGM)
- sucessful = _tgm_load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, new_z)
+ sucessful = _tgm_load(x_offset, y_offset, z_offset, crop_map, no_changeturf, x_lower, x_upper, y_lower, y_upper, z_lower, z_upper, place_on_top, new_z)
else
- sucessful = _dmm_load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, new_z)
+ sucessful = _dmm_load(x_offset, y_offset, z_offset, crop_map, no_changeturf, x_lower, x_upper, y_lower, y_upper, z_lower, z_upper, place_on_top, new_z)
// And we are done lads, call it off
SSatoms.map_loader_stop(REF(src))
@@ -309,7 +374,7 @@
// In the tgm format, each gridset contains 255 lines, each line representing one tile, with 255 total gridsets
// In the dmm format, each gridset contains 255 lines, each line representing one row of tiles, containing 255 * line length characters, with one gridset per z
// You can think of dmm as storing maps in rows, whereas tgm stores them in columns
-/datum/parsed_map/proc/_tgm_load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, new_z)
+/datum/parsed_map/proc/_tgm_load(x_offset, y_offset, z_offset, crop_map, no_changeturf, x_lower, x_upper, y_lower, y_upper, z_lower, z_upper, place_on_top, new_z)
// setup
var/list/modelCache = build_cache(no_changeturf)
var/space_key = modelCache[SPACE_KEY]
@@ -330,12 +395,12 @@
var/relative_y = first_column.ycrd
var/highest_y = relative_y + y_relative_to_absolute
- if(!cropMap && highest_y > world.maxy)
+ if(!crop_map && highest_y > world.maxy)
if(new_z)
// Need to avoid improperly loaded area/turf_contents
- world.increaseMaxY(highest_y, max_zs_to_load = z_offset - 1)
+ world.increase_max_y(highest_y, map_load_z_cutoff = z_offset - 1)
else
- world.increaseMaxY(highest_y)
+ world.increase_max_y(highest_y)
expanded_y = TRUE
// Skip Y coords that are above the smallest of the three params
@@ -345,7 +410,6 @@
var/y_starting_skip = relative_y - y_skip_above
highest_y -= y_starting_skip
-
// Y is the LOWEST it will ever be here, so we can easily set a threshold for how low to go
var/line_count = length(first_column.gridLines)
var/lowest_y = relative_y - (line_count - 1) // -1 because we decrement at the end of the loop, not the start
@@ -353,7 +417,7 @@
// X setup
var/x_delta_with = x_upper
- if(cropMap)
+ if(crop_map)
// Take our smaller crop threshold yes?
x_delta_with = min(x_delta_with, world.maxx)
@@ -367,33 +431,51 @@
// If our relative x is greater then X upper, well then we've gotta limit our expansion
var/delta = max(final_x - x_delta_with, 0)
final_x -= delta
- if(final_x > world.maxx && !cropMap)
+ if(final_x > world.maxx && !crop_map)
if(new_z)
// Need to avoid improperly loaded area/turf_contents
- world.increaseMaxX(final_x, max_zs_to_load = z_offset - 1)
+ world.increase_max_x(final_x, map_load_z_cutoff = z_offset - 1)
else
- world.increaseMaxX(final_x)
+ world.increase_max_x(final_x)
expanded_x = TRUE
var/lowest_x = max(x_lower, 1 - x_relative_to_absolute)
+ // Amount we offset the grid zcrd to get the true zcrd
+ var/grid_z_offset = z_offset - 1
+ var/z_upper_set = z_upper < INFINITY
+ var/z_lower_set = z_lower > -INFINITY
+
// We make the assumption that the last block of turfs will have the highest embedded z in it
- var/highest_z = last_column.zcrd + z_offset - 1 // Lets not just make a new z level each time we increment maxz
+ // true max zcrd
+ var/map_bounds_z_max = last_column.zcrd
+ var/z_upper_parsed = map_bounds_z_max + z_offset - 1
+ if(z_upper_set)
+ z_upper_parsed -= map_bounds_z_max - z_upper
+ if(z_lower_set)
+ var/offset_amount = z_lower - 1
+ z_upper_parsed -= offset_amount
+ grid_z_offset -= offset_amount
+
+ var/list/target_grid_sets = gridSets
+ if(z_lower_set || z_upper_set) // bounds are set, filter out gridsets for z levels we don't want
+ target_grid_sets = filter_grid_sets_based_on_z_bounds(z_lower, z_upper)
+
var/z_threshold = world.maxz
- if(highest_z > z_threshold && cropMap)
- for(var/i in z_threshold + 1 to highest_z) //create a new z_level if needed
+ if(z_upper_parsed > z_threshold && crop_map)
+ for(var/i in z_threshold + 1 to z_upper_parsed) //create a new z_level if needed
world.incrementMaxZ()
if(!no_changeturf)
WARNING("Z-level expansion occurred without no_changeturf set, this may cause problems when /turf/AfterChange is called")
- for(var/datum/grid_set/gset as anything in gridSets)
+ for(var/datum/grid_set/gset as anything in target_grid_sets)
var/true_xcrd = gset.xcrd + x_relative_to_absolute
// any cutoff of x means we just shouldn't iterate this gridset
if(final_x < true_xcrd || lowest_x > gset.xcrd)
continue
- var/zcrd = gset.zcrd + z_offset - 1
+ var/zcrd = gset.zcrd + grid_z_offset
// If we're using changeturf, we disable it if we load into a z level we JUST created
var/no_afterchange = no_changeturf || zcrd > z_threshold
@@ -420,7 +502,7 @@
if(!cache)
SSatoms.map_loader_stop(REF(src))
CRASH("Undefined model key in DMM: [gset.gridLines[i]]")
- build_coordinate(cache, locate(true_xcrd, ycrd, zcrd), no_afterchange, placeOnTop, new_z)
+ build_coordinate(cache, locate(true_xcrd, ycrd, zcrd), no_afterchange, place_on_top, new_z)
// only bother with bounds that actually exist
if(!first_found)
@@ -444,7 +526,7 @@
/// Stanrdard loading, not used in production
/// Doesn't take advantage of any tgm optimizations, which makes it slower but also more general
/// Use this if for some reason your map format is messy
-/datum/parsed_map/proc/_dmm_load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, new_z)
+/datum/parsed_map/proc/_dmm_load(x_offset, y_offset, z_offset, crop_map, no_changeturf, x_lower, x_upper, y_lower, y_upper, z_lower, z_upper, place_on_top, new_z)
// setup
var/list/modelCache = build_cache(no_changeturf)
var/space_key = modelCache[SPACE_KEY]
@@ -455,23 +537,46 @@
var/y_relative_to_absolute = y_offset - 1
var/x_relative_to_absolute = x_offset - 1
var/line_len = src.line_len
- for(var/datum/grid_set/gset as anything in gridSets)
+
+ // Amount we offset the grid zcrd to get the true zcrd
+ var/grid_z_offset = z_offset - 1
+ var/z_upper_set = z_upper < INFINITY
+ var/z_lower_set = z_lower > -INFINITY
+
+ // we now need to find the maximum z, fun!
+ var/map_bounds_z_max = 1
+ for(var/datum/grid_set/grid_set as anything in gridSets)
+ map_bounds_z_max = max(map_bounds_z_max, grid_set.zcrd)
+
+ var/z_upper_parsed = map_bounds_z_max + z_offset - 1
+ if(z_upper_set)
+ z_upper_parsed -= map_bounds_z_max - z_upper
+ if(z_lower_set)
+ var/offset_amount = z_lower - 1
+ z_upper_parsed -= offset_amount
+ grid_z_offset -= offset_amount
+
+ var/list/target_grid_sets = gridSets
+ if(z_lower_set || z_upper_set) // bounds are set, filter out gridsets for z levels we don't want
+ target_grid_sets = filter_grid_sets_based_on_z_bounds(z_lower, z_upper)
+
+ for(var/datum/grid_set/gset as anything in target_grid_sets)
var/relative_x = gset.xcrd
var/relative_y = gset.ycrd
var/true_xcrd = relative_x + x_relative_to_absolute
var/ycrd = relative_y + y_relative_to_absolute
- var/zcrd = gset.zcrd + z_offset - 1
- if(!cropMap && ycrd > world.maxy)
+ var/zcrd = gset.zcrd + grid_z_offset
+ if(!crop_map && ycrd > world.maxy)
if(new_z)
// Need to avoid improperly loaded area/turf_contents
- world.increaseMaxY(ycrd, max_zs_to_load = z_offset - 1)
+ world.increase_max_y(ycrd, map_load_z_cutoff = z_offset - 1)
else
- world.increaseMaxY(ycrd)
+ world.increase_max_y(ycrd)
expanded_y = TRUE
var/zexpansion = zcrd > world.maxz
var/no_afterchange = no_changeturf
if(zexpansion)
- if(cropMap)
+ if(crop_map)
continue
else
while (zcrd > world.maxz) //create a new z_level if needed
@@ -508,7 +613,7 @@
var/x_step_count = ROUND_UP(x_target / key_len)
var/final_x = relative_x + (x_step_count - 1)
var/x_delta_with = x_upper
- if(cropMap)
+ if(crop_map)
// Take our smaller crop threshold yes?
x_delta_with = min(x_delta_with, world.maxx)
if(final_x > x_delta_with)
@@ -517,12 +622,12 @@
x_step_count -= delta
final_x -= delta
x_target = x_step_count * key_len
- if(final_x > world.maxx && !cropMap)
+ if(final_x > world.maxx && !crop_map)
if(new_z)
// Need to avoid improperly loaded area/turf_contents
- world.increaseMaxX(final_x, max_zs_to_load = z_offset - 1)
+ world.increase_max_x(final_x, map_load_z_cutoff = z_offset - 1)
else
- world.increaseMaxX(final_x)
+ world.increase_max_x(final_x)
expanded_x = TRUE
// We're gonna track the first and last pairs of coords we find
@@ -553,7 +658,7 @@
if(!cache)
SSatoms.map_loader_stop(REF(src))
CRASH("Undefined model key in DMM: [model_key]")
- build_coordinate(cache, locate(xcrd, ycrd, zcrd), no_afterchange, placeOnTop, new_z)
+ build_coordinate(cache, locate(xcrd, ycrd, zcrd), no_afterchange, place_on_top, new_z)
// only bother with bounds that actually exist
if(!first_found)
diff --git a/code/modules/mapping/ruins.dm b/code/modules/mapping/ruins.dm
index 01a91a10c2a..a7b9480a34e 100644
--- a/code/modules/mapping/ruins.dm
+++ b/code/modules/mapping/ruins.dm
@@ -51,10 +51,10 @@
return central_turf
/datum/map_template/ruin/proc/place_on_isolated_level(z)
- var/datum/turf_reservation/reservation = SSmapping.RequestBlockReservation(width, height, z) //Make the new level creation work with different traits.
+ var/datum/turf_reservation/reservation = SSmapping.request_turf_block_reservation(width, height, 1, z) //Make the new level creation work with different traits.
if(!reservation)
return
- var/turf/placement = locate(reservation.bottom_left_coords[1],reservation.bottom_left_coords[2],reservation.bottom_left_coords[3])
+ var/turf/placement = reservation.bottom_left_turfs[1]
load(placement)
loaded++
for(var/turf/T in get_affected_turfs(placement))
diff --git a/code/modules/mapping/space_management/multiz_helpers.dm b/code/modules/mapping/space_management/multiz_helpers.dm
index f2331eb5146..b0e2ff7fa06 100644
--- a/code/modules/mapping/space_management/multiz_helpers.dm
+++ b/code/modules/mapping/space_management/multiz_helpers.dm
@@ -1,10 +1,11 @@
/proc/get_step_multiz(ref, dir)
+ var/turf/us = get_turf(ref)
if(dir & UP)
dir &= ~UP
- return get_step(GET_TURF_ABOVE(get_turf(ref)), dir)
+ return get_step(GET_TURF_ABOVE(us), dir)
if(dir & DOWN)
dir &= ~DOWN
- return get_step(GET_TURF_BELOW(get_turf(ref)), dir)
+ return get_step(GET_TURF_BELOW(us), dir)
return get_step(ref, dir)
/proc/get_dir_multiz(turf/us, turf/them)
@@ -15,27 +16,21 @@
if(us.z == them.z)
return get_dir(us, them)
else
- var/turf/T = us.above()
+ var/turf/T = GET_TURF_ABOVE(us)
var/dir = NONE
if(T && (T.z == them.z))
dir = UP
else
- T = us.below()
+ T = GET_TURF_BELOW(us)
if(T && (T.z == them.z))
dir = DOWN
else
return get_dir(us, them)
return (dir | get_dir(us, them))
-/turf/proc/above()
- return GET_TURF_ABOVE(src)
-
-/turf/proc/below()
- return GET_TURF_BELOW(src)
-
/proc/get_lowest_turf(atom/ref)
var/turf/us = get_turf(ref)
- var/next = GET_TURF_BELOW(us)
+ var/turf/next = GET_TURF_BELOW(us)
while(next)
us = next
next = GET_TURF_BELOW(us)
@@ -44,7 +39,7 @@
// I wish this was lisp
/proc/get_highest_turf(atom/ref)
var/turf/us = get_turf(ref)
- var/next = GET_TURF_ABOVE(us)
+ var/turf/next = GET_TURF_ABOVE(us)
while(next)
us = next
next = GET_TURF_ABOVE(us)
diff --git a/code/modules/mapping/space_management/space_reservation.dm b/code/modules/mapping/space_management/space_reservation.dm
index 52ac76e343a..2809ae65e6c 100644
--- a/code/modules/mapping/space_management/space_reservation.dm
+++ b/code/modules/mapping/space_management/space_reservation.dm
@@ -1,16 +1,33 @@
//Yes, they can only be rectangular.
//Yes, I'm sorry.
/datum/turf_reservation
+ /// All turfs that we've reserved
var/list/reserved_turfs = list()
- ///Turfs around the reservation for cordoning
+
+ /// Turfs around the reservation for cordoning
var/list/cordon_turfs = list()
- ///Area of turfs next to the cordon to fill with pre_cordon_area's
+
+ /// Area of turfs next to the cordon to fill with pre_cordon_area's
var/list/pre_cordon_turfs = list()
+
+ /// The width of the reservation
var/width = 0
+
+ /// The height of the reservation
var/height = 0
- var/bottom_left_coords[3]
- var/top_right_coords[3]
+
+ /// The z stack size of the reservation. Note that reservations are ALWAYS reserved from the bottom up
+ var/z_size = 0
+
+ /// List of the bottom left turfs. Indexed by what their z index for this reservation is
+ var/list/bottom_left_turfs = list()
+
+ /// List of the top right turfs. Indexed by what their z index for this reservation is
+ var/list/top_right_turfs = list()
+
+ /// The turf type the reservation is initially made with
var/turf_type = /turf/open/space
+
///Distance away from the cordon where we can put a "sort-cordon" and run some extra code (see make_repel). 0 makes nothing happen
var/pre_cordon_distance = 0
@@ -19,6 +36,9 @@
pre_cordon_distance = 7
/datum/turf_reservation/proc/Release()
+ bottom_left_turfs.Cut()
+ top_right_turfs.Cut()
+
var/list/reserved_copy = reserved_turfs.Copy()
SSmapping.used_turfs -= reserved_turfs
reserved_turfs = list()
@@ -36,20 +56,20 @@
INVOKE_ASYNC(SSmapping, TYPE_PROC_REF(/datum/controller/subsystem/mapping, reserve_turfs), release_turfs)
/// Attempts to calaculate and store a list of turfs around the reservation for cordoning. Returns whether a valid cordon was calculated
-/datum/turf_reservation/proc/calculate_cordon_turfs(turf/BL, turf/TR)
- if(BL.x < 2 || BL.y < 2 || TR.x > (world.maxx - 2) || TR.y > (world.maxy - 2))
+/datum/turf_reservation/proc/calculate_cordon_turfs(turf/bottom_left, turf/top_right)
+ if(bottom_left.x < 2 || bottom_left.y < 2 || top_right.x > (world.maxx - 2) || top_right.y > (world.maxy - 2))
return FALSE // no space for a cordon here
- var/list/possible_turfs = CORNER_OUTLINE(BL, width, height)
+ var/list/possible_turfs = CORNER_OUTLINE(bottom_left, width, height)
+ // if they're our cordon turfs, accept them
+ possible_turfs -= cordon_turfs
for(var/turf/cordon_turf as anything in possible_turfs)
- if(!(cordon_turf.flags_1 & UNUSED_RESERVATION_TURF))
+ if(!(cordon_turf.turf_flags & UNUSED_RESERVATION_TURF))
return FALSE
- cordon_turfs = possible_turfs
-
- pre_cordon_turfs.Cut()
+ cordon_turfs |= possible_turfs
if(pre_cordon_distance)
- var/turf/offset_turf = locate(BL.x + pre_cordon_distance, BL.y + pre_cordon_distance, BL.z)
+ var/turf/offset_turf = locate(bottom_left.x + pre_cordon_distance, bottom_left.y + pre_cordon_distance, bottom_left.z)
var/list/to_add = CORNER_OUTLINE(offset_turf, width - pre_cordon_distance * 2, height - pre_cordon_distance * 2) //we step-by-stop move inwards from the outer cordon
for(var/turf/turf_being_added as anything in to_add)
pre_cordon_turfs |= turf_being_added //add one by one so we can filter out duplicates
@@ -64,10 +84,11 @@
old_area.turfs_to_uncontain += cordon_turf
cordon_area.contained_turfs += cordon_turf
cordon_area.contents += cordon_turf
+ // Its no longer unused, but its also not "used"
+ cordon_turf.turf_flags &= ~UNUSED_RESERVATION_TURF
cordon_turf.ChangeTurf(/turf/cordon, /turf/cordon)
-
- cordon_turf.flags_1 &= ~UNUSED_RESERVATION_TURF
SSmapping.unused_turfs["[cordon_turf.z]"] -= cordon_turf
+ // still gets linked to us though
SSmapping.used_turfs[cordon_turf] = src
//swap the area with the pre-cordoning area
@@ -113,7 +134,8 @@
if(!HAS_TRAIT(enterer, TRAIT_FREE_HYPERSPACE_SOFTCORDON_MOVEMENT))
space_dump(source, enterer)
-/datum/turf_reservation/proc/Reserve(width, height, zlevel)
+/// Internal proc which handles reserving the area for the reservation.
+/datum/turf_reservation/proc/_reserve_area(width, height, zlevel)
src.width = width
src.height = height
if(width > world.maxx || height > world.maxy || width < 1 || height < 1)
@@ -126,12 +148,12 @@
for(var/i in avail)
CHECK_TICK
BL = i
- if(!(BL.flags_1 & UNUSED_RESERVATION_TURF))
+ if(!(BL.turf_flags & UNUSED_RESERVATION_TURF))
continue
if(BL.x + width > world.maxx || BL.y + height > world.maxy)
continue
TR = locate(BL.x + width - 1, BL.y + height - 1, BL.z)
- if(!(TR.flags_1 & UNUSED_RESERVATION_TURF))
+ if(!(TR.turf_flags & UNUSED_RESERVATION_TURF))
continue
final = block(BL, TR)
if(!final)
@@ -139,7 +161,7 @@
passing = TRUE
for(var/I in final)
var/turf/checking = I
- if(!(checking.flags_1 & UNUSED_RESERVATION_TURF))
+ if(!(checking.turf_flags & UNUSED_RESERVATION_TURF))
passing = FALSE
break
if(passing) // found a potentially valid area, now try to calculate its cordon
@@ -149,18 +171,94 @@
break
if(!passing || !istype(BL) || !istype(TR))
return FALSE
- bottom_left_coords = list(BL.x, BL.y, BL.z)
- top_right_coords = list(TR.x, TR.y, TR.z)
for(var/i in final)
var/turf/T = i
reserved_turfs |= T
- T.flags_1 &= ~UNUSED_RESERVATION_TURF
SSmapping.unused_turfs["[T.z]"] -= T
SSmapping.used_turfs[T] = src
+ T.turf_flags = (T.turf_flags | RESERVATION_TURF) & ~UNUSED_RESERVATION_TURF
T.ChangeTurf(turf_type, turf_type)
+
+ bottom_left_turfs += BL
+ top_right_turfs += TR
+ return TRUE
+
+/datum/turf_reservation/proc/reserve(width, height, z_size, z_reservation)
+ src.z_size = z_size
+ var/failed_reservation = FALSE
+ for(var/_ in 1 to z_size)
+ if(!_reserve_area(width, height, z_reservation))
+ failed_reservation = TRUE
+ break
+
+ if(failed_reservation)
+ Release()
+ return FALSE
+
generate_cordon()
return TRUE
+/// Calculates the effective bounds information for the given turf. Returns a list of the information, or null if not applicable.
+/datum/turf_reservation/proc/calculate_turf_bounds_information(turf/target)
+ for(var/z_idx in 1 to z_size)
+ var/turf/bottom_left = bottom_left_turfs[z_idx]
+ var/turf/top_right = top_right_turfs[z_idx]
+ var/bl_x = bottom_left.x
+ var/bl_y = bottom_left.y
+ var/tr_x = top_right.x
+ var/tr_y = top_right.y
+
+ if(target.x < bl_x)
+ continue
+
+ if(target.y < bl_y)
+ continue
+
+ if(target.x > tr_x)
+ continue
+
+ if(target.y > tr_y)
+ continue
+
+ var/list/return_information = list()
+ return_information["z_idx"] = z_idx
+ return_information["offset_x"] = target.x - bl_x
+ return_information["offset_y"] = target.y - bl_y
+ return return_information
+ return null
+
+/// Gets the turf below the given target. Returns null if there is no turf below the target
+/datum/turf_reservation/proc/get_turf_below(turf/target)
+ var/list/bounds_info = calculate_turf_bounds_information(target)
+ if(isnull(bounds_info))
+ return null
+
+ var/z_idx = bounds_info["z_idx"]
+ // check what z level, if its the max, then there is no turf below
+ if(z_idx == z_size)
+ return null
+
+ var/offset_x = bounds_info["offset_x"]
+ var/offset_y = bounds_info["offset_y"]
+ var/turf/bottom_left = bottom_left_turfs[z_idx + 1]
+ return locate(bottom_left.x + offset_x, bottom_left.y + offset_y, bottom_left.z)
+
+/// Gets the turf above the given target. Returns null if there is no turf above the target
+/datum/turf_reservation/proc/get_turf_above(turf/target)
+ var/list/bounds_info = calculate_turf_bounds_information(target)
+ if(isnull(bounds_info))
+ return null
+
+ var/z_idx = bounds_info["z_idx"]
+ // check what z level, if its the min, then there is no turf above
+ if(z_idx == 1)
+ return null
+
+ var/offset_x = bounds_info["offset_x"]
+ var/offset_y = bounds_info["offset_y"]
+ var/turf/bottom_left = bottom_left_turfs[z_idx - 1]
+ return locate(bottom_left.x + offset_x, bottom_left.y + offset_y, bottom_left.z)
+
/datum/turf_reservation/New()
LAZYADD(SSmapping.turf_reservations, src)
diff --git a/code/modules/meteors/meteor_types.dm b/code/modules/meteors/meteor_types.dm
index 9f598f9809e..b258196ed24 100644
--- a/code/modules/meteors/meteor_types.dm
+++ b/code/modules/meteors/meteor_types.dm
@@ -56,7 +56,7 @@
var/turf/T = get_turf(loc)
ram_turf(T)
- if(prob(10) && !isspaceturf(T))//randomly takes a 'hit' from ramming
+ if(prob(10) && !ispassmeteorturf(T))//randomly takes a 'hit' from ramming
get_hit()
if(z != z_original || loc == get_turf(dest))
diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm
index 7f1348d54e6..a656aa467d6 100644
--- a/code/modules/mining/abandoned_crates.dm
+++ b/code/modules/mining/abandoned_crates.dm
@@ -185,7 +185,7 @@
if(63 to 64)
new /obj/item/clothing/shoes/kindle_kicks(src)
if(65 to 66)
- new /obj/item/clothing/suit/costume/ianshirt(src)
+ new /obj/item/clothing/suit/costume/wellworn_shirt/graphic/ian(src)
new /obj/item/clothing/suit/hooded/ian_costume(src)
if(67 to 68)
new /obj/item/toy/plush/awakenedplushie(src)
diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm
index a8e3b59df4a..caee1bbac8d 100644
--- a/code/modules/mining/equipment/kinetic_crusher.dm
+++ b/code/modules/mining/equipment/kinetic_crusher.dm
@@ -32,8 +32,13 @@
/obj/item/kinetic_crusher/Initialize(mapload)
. = ..()
- AddComponent(/datum/component/butchering, speed = 7 SECONDS, effectiveness = 40)
- AddComponent(/datum/component/two_handed, force_unwielded = 0, force_wielded = 20)
+ AddComponent(/datum/component/butchering, \
+ speed = 6 SECONDS, \
+ effectiveness = 110, \
+ )
+ //technically it's huge and bulky, but this provides an incentive to use it
+ AddComponent(/datum/component/two_handed, force_unwielded=0, force_wielded=20)
+ RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur))
/obj/item/kinetic_crusher/Destroy()
QDEL_LIST(trophies)
@@ -161,6 +166,10 @@
playsound(user, 'sound/weapons/empty.ogg', 100, TRUE)
update_appearance()
+/obj/item/kinetic_crusher/proc/on_saboteur(datum/source, disrupt_duration)
+ set_light_on(FALSE)
+ playsound(src, 'sound/weapons/empty.ogg', 100, TRUE)
+ return COMSIG_SABOTEUR_SUCCESS
/obj/item/kinetic_crusher/update_icon_state()
inhand_icon_state = "crusher[HAS_TRAIT(src, TRAIT_WIELDED)]" // this is not icon_state and not supported by 2hcomponent
diff --git a/code/modules/mining/equipment/mining_tools.dm b/code/modules/mining/equipment/mining_tools.dm
index 3b1d5233dbf..69903d77591 100644
--- a/code/modules/mining/equipment/mining_tools.dm
+++ b/code/modules/mining/equipment/mining_tools.dm
@@ -217,6 +217,9 @@
attack_verb_simple = list("bash", "bludgeon", "thrash", "whack")
wound_bonus = 10
+/obj/item/trench_tool/get_all_tool_behaviours()
+ return list(TOOL_MINING, TOOL_SHOVEL, TOOL_WRENCH)
+
/obj/item/trench_tool/Initialize(mapload)
. = ..()
AddElement(/datum/element/update_icon_updates_onmob)
@@ -320,6 +323,9 @@
/// Wether we knock down and launch away out enemies when we attack.
var/do_launch = TRUE
+/obj/item/shovel/giant_wrench/get_all_tool_behaviours()
+ return list(TOOL_SHOVEL, TOOL_WRENCH)
+
/datum/armor/giant_wrench
acid = 30
bomb = 100
diff --git a/code/modules/mining/equipment/monster_organs/monster_organ.dm b/code/modules/mining/equipment/monster_organs/monster_organ.dm
index 7898abd6dda..699564c9ed7 100644
--- a/code/modules/mining/equipment/monster_organs/monster_organ.dm
+++ b/code/modules/mining/equipment/monster_organs/monster_organ.dm
@@ -183,9 +183,9 @@
* Utility proc to find the associated monster organ action and trigger it.
* Call this instead of on_triggered_internal() if the action needs to trigger automatically, or the cooldown won't happen.
*/
-/obj/item/organ/internal/monster_core/proc/trigger_organ_action()
+/obj/item/organ/internal/monster_core/proc/trigger_organ_action(trigger_flags)
var/datum/action/cooldown/monster_core_action/action = locate() in actions
- action?.Trigger()
+ action?.Trigger(trigger_flags = trigger_flags)
/**
* Called when activated while implanted inside someone.
diff --git a/code/modules/mining/equipment/monster_organs/regenerative_core.dm b/code/modules/mining/equipment/monster_organs/regenerative_core.dm
index f8c95536258..cb224438c00 100644
--- a/code/modules/mining/equipment/monster_organs/regenerative_core.dm
+++ b/code/modules/mining/equipment/monster_organs/regenerative_core.dm
@@ -28,7 +28,7 @@
/obj/item/organ/internal/monster_core/regenerative_core/on_life(seconds_per_tick, times_fired)
. = ..()
if (owner.health <= owner.crit_threshold)
- trigger_organ_action()
+ trigger_organ_action(TRIGGER_FORCE_AVAILABLE)
/obj/item/organ/internal/monster_core/regenerative_core/on_triggered_internal()
owner.revive(HEAL_ALL)
@@ -60,4 +60,3 @@
desc = "Fully regenerate your body, consuming your regenerative core in the process. \
This process will trigger automatically if you are badly wounded."
button_icon_state = "legion_core_stable"
- check_flags = NONE
diff --git a/code/modules/mining/lavaland/megafauna_loot.dm b/code/modules/mining/lavaland/megafauna_loot.dm
index fed4f1ea517..65d3a1ad3b3 100644
--- a/code/modules/mining/lavaland/megafauna_loot.dm
+++ b/code/modules/mining/lavaland/megafauna_loot.dm
@@ -283,7 +283,7 @@
/obj/item/clothing/suit/hooded/hostile_environment/Initialize(mapload)
. = ..()
AddElement(/datum/element/radiation_protected_clothing)
- AddComponent(/datum/component/gags_recolorable)
+ AddElement(/datum/element/gags_recolorable)
/obj/item/clothing/suit/hooded/hostile_environment/process(seconds_per_tick)
. = ..()
@@ -330,7 +330,7 @@
butcher_callback = CALLBACK(src, PROC_REF(consume)), \
)
AddElement(/datum/element/radiation_protected_clothing)
- AddComponent(/datum/component/gags_recolorable)
+ AddElement(/datum/element/gags_recolorable)
/obj/item/clothing/head/hooded/hostile_environment/equipped(mob/user, slot, initial = FALSE)
. = ..()
@@ -643,9 +643,10 @@
spirits = list()
START_PROCESSING(SSobj, src)
SSpoints_of_interest.make_point_of_interest(src)
- AddComponent(/datum/component/butchering, \
- speed = 15 SECONDS, \
- effectiveness = 90, \
+ AddComponent(\
+ /datum/component/butchering, \
+ speed = 15 SECONDS, \
+ effectiveness = 90, \
)
/obj/item/melee/ghost_sword/Destroy()
diff --git a/code/modules/mining/lavaland/tendril_loot.dm b/code/modules/mining/lavaland/tendril_loot.dm
index d26b9f6d365..96e330825f1 100644
--- a/code/modules/mining/lavaland/tendril_loot.dm
+++ b/code/modules/mining/lavaland/tendril_loot.dm
@@ -421,7 +421,7 @@
return
user.status_flags &= ~GODMODE
- user.notransform = FALSE
+ REMOVE_TRAIT(user, TRAIT_NO_TRANSFORM, REF(src))
user.forceMove(get_turf(src))
user.visible_message(span_danger("[user] pops back into reality!"))
@@ -432,7 +432,7 @@
setDir(user.dir)
user.forceMove(src)
- user.notransform = TRUE
+ ADD_TRAIT(user, TRAIT_NO_TRANSFORM, REF(src))
user.status_flags |= GODMODE
user_ref = WEAKREF(user)
@@ -446,8 +446,8 @@
return
/obj/effect/immortality_talisman/relaymove(mob/living/user, direction)
- // Won't really come into play since our mob has notransform and cannot move,
- // but regardless block all relayed moves, becuase no, you cannot move in the void.
+ // Won't really come into play since our mob has TRAIT_NO_TRANSFORM and cannot move,
+ // but regardless block all relayed moves, because no, you cannot move in the void.
return
/obj/effect/immortality_talisman/singularity_pull()
diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm
index 4c0ca13dcd2..ce045a81298 100644
--- a/code/modules/mining/machine_redemption.dm
+++ b/code/modules/mining/machine_redemption.dm
@@ -370,7 +370,7 @@
var/amount = round(min(text2num(params["sheets"]), 50, can_smelt_alloy(alloy)))
if(amount < 1) //no negative mats
return
- materials.use_materials(alloy.materials, action = "released", name = "sheets")
+ materials.use_materials(alloy.materials, multiplier = amount, action = "released", name = "sheets")
var/output
if(ispath(alloy.build_path, /obj/item/stack/sheet))
output = new alloy.build_path(src, amount)
diff --git a/code/modules/mining/machine_silo.dm b/code/modules/mining/machine_silo.dm
index dc15e28a927..840c8e92900 100644
--- a/code/modules/mining/machine_silo.dm
+++ b/code/modules/mining/machine_silo.dm
@@ -165,8 +165,8 @@ GLOBAL_LIST_EMPTY(silo_access_logs)
/obj/machinery/ore_silo/multitool_act(mob/living/user, obj/item/multitool/I)
. = ..()
if (istype(I))
- to_chat(user, span_notice("You log [src] in the multitool's buffer."))
I.set_buffer(src)
+ balloon_alert(user, "saved to multitool buffer")
return TRUE
/**
diff --git a/code/modules/mining/machine_stacking.dm b/code/modules/mining/machine_stacking.dm
index d7381d48e66..286317a5d74 100644
--- a/code/modules/mining/machine_stacking.dm
+++ b/code/modules/mining/machine_stacking.dm
@@ -27,7 +27,7 @@
return
var/obj/item/multitool/M = I
M.set_buffer(src)
- to_chat(user, span_notice("You store linkage information in [I]'s buffer."))
+ balloon_alert(user, "saved to multitool buffer")
return TRUE
/obj/machinery/mineral/stacking_unit_console/ui_interact(mob/user, datum/tgui/ui)
diff --git a/code/modules/mining/minebot.dm b/code/modules/mining/minebot.dm
deleted file mode 100644
index f7a6c030d2c..00000000000
--- a/code/modules/mining/minebot.dm
+++ /dev/null
@@ -1,331 +0,0 @@
-/**********************Mining drone**********************/
-#define MINEDRONE_COLLECT 1
-#define MINEDRONE_ATTACK 2
-
-/mob/living/simple_animal/hostile/mining_drone
- name = "\improper Nanotrasen minebot"
- desc = "The instructions printed on the side read: This is a small robot used to support miners, can be set to search and collect loose ore, or to help fend off wildlife."
- gender = NEUTER
- icon = 'icons/mob/silicon/aibots.dmi'
- icon_state = "mining_drone"
- icon_living = "mining_drone"
- status_flags = CANSTUN|CANKNOCKDOWN|CANPUSH
- mouse_opacity = MOUSE_OPACITY_ICON
- faction = list(FACTION_NEUTRAL)
- combat_mode = TRUE
- atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
- minbodytemp = 0
- move_to_delay = 10
- health = 125
- maxHealth = 125
- melee_damage_lower = 15
- melee_damage_upper = 15
- obj_damage = 10
- environment_smash = ENVIRONMENT_SMASH_NONE
- check_friendly_fire = TRUE
- stop_automated_movement_when_pulled = TRUE
- attack_verb_continuous = "drills"
- attack_verb_simple = "drill"
- attack_sound = 'sound/weapons/circsawhit.ogg'
- sentience_type = SENTIENCE_MINEBOT
- speak_emote = list("states")
- wanted_objects = list(/obj/item/stack/ore/diamond, /obj/item/stack/ore/gold, /obj/item/stack/ore/silver,
- /obj/item/stack/ore/plasma, /obj/item/stack/ore/uranium, /obj/item/stack/ore/iron,
- /obj/item/stack/ore/bananium, /obj/item/stack/ore/titanium)
- mob_biotypes = MOB_ROBOTIC
- loot = list(/obj/effect/decal/cleanable/robot_debris)
- del_on_death = TRUE
- light_system = MOVABLE_LIGHT
- light_range = 6
- light_on = FALSE
- var/mode = MINEDRONE_COLLECT
- var/obj/item/gun/energy/recharge/kinetic_accelerator/minebot/stored_gun
-
-/mob/living/simple_animal/hostile/mining_drone/Initialize(mapload)
- . = ..()
-
- AddElement(/datum/element/footstep, FOOTSTEP_OBJ_ROBOT, 1, -6, sound_vary = TRUE)
-
- stored_gun = new(src)
- var/datum/action/innate/minedrone/toggle_light/toggle_light_action = new()
- toggle_light_action.Grant(src)
- var/datum/action/innate/minedrone/toggle_meson_vision/toggle_meson_vision_action = new()
- toggle_meson_vision_action.Grant(src)
- var/datum/action/innate/minedrone/toggle_mode/toggle_mode_action = new()
- toggle_mode_action.Grant(src)
- var/datum/action/innate/minedrone/dump_ore/dump_ore_action = new()
- dump_ore_action.Grant(src)
- var/obj/item/implant/radio/mining/imp = new(src)
- imp.implant(src)
-
- access_card = new /obj/item/card/id/advanced/gold(src)
- SSid_access.apply_trim_to_card(access_card, /datum/id_trim/job/shaft_miner)
-
- SetCollectBehavior()
-
-/mob/living/simple_animal/hostile/mining_drone/Destroy()
- QDEL_NULL(stored_gun)
- for (var/datum/action/innate/minedrone/action in actions)
- qdel(action)
- return ..()
-
-/mob/living/simple_animal/hostile/mining_drone/sentience_act()
- ..()
- check_friendly_fire = 0
-
-/mob/living/simple_animal/hostile/mining_drone/examine(mob/user)
- . = ..()
- var/t_He = p_They()
- var/t_him = p_them()
- var/t_s = p_s()
- if(health < maxHealth)
- if(health >= maxHealth * 0.5)
- . += span_warning("[t_He] look[t_s] slightly dented.")
- else
- . += span_boldwarning("[t_He] look[t_s] severely dented!")
- . += {"Using a mining scanner on [t_him] will instruct [t_him] to drop stored ore. [max(0, LAZYLEN(contents) - 1)] Stored Ore\n
- Field repairs can be done with a welder."}
- if(stored_gun?.max_mod_capacity)
- . += "[stored_gun.get_remaining_mod_capacity()]% mod capacity remaining."
- for(var/obj/item/borg/upgrade/modkit/modkit as anything in stored_gun.modkits)
- . += span_notice("There is \a [modkit] installed, using [modkit.cost]% capacity.")
-
-/mob/living/simple_animal/hostile/mining_drone/welder_act(mob/living/user, obj/item/welder)
- ..()
- . = TRUE
- if(mode == MINEDRONE_ATTACK)
- to_chat(user, span_warning("[src] can't be repaired while in attack mode!"))
- return
-
- if(maxHealth == health)
- to_chat(user, span_info("[src] is at full integrity."))
- return
-
- if(welder.use_tool(src, user, 0, volume=40))
- adjustBruteLoss(-15)
- to_chat(user, span_info("You repair some of the armor on [src]."))
-
-/mob/living/simple_animal/hostile/mining_drone/attackby(obj/item/item_used, mob/user, params)
- if(istype(item_used, /obj/item/mining_scanner) || istype(item_used, /obj/item/t_scanner/adv_mining_scanner))
- to_chat(user, span_info("You instruct [src] to drop any collected ore."))
- DropOre()
- return
- if(item_used.tool_behaviour == TOOL_CROWBAR || istype(item_used, /obj/item/borg/upgrade/modkit))
- item_used.melee_attack_chain(user, stored_gun, params)
- return
- ..()
-
-/mob/living/simple_animal/hostile/mining_drone/death()
- DropOre()
- if(stored_gun)
- for(var/obj/item/borg/upgrade/modkit/modkit as anything in stored_gun.modkits)
- modkit.uninstall(stored_gun)
- death_message = "blows apart!"
- ..()
-
-/mob/living/simple_animal/hostile/mining_drone/attack_hand(mob/living/carbon/human/user, list/modifiers)
- . = ..()
- if(.)
- return
- if(!user.combat_mode)
- toggle_mode()
- switch(mode)
- if(MINEDRONE_COLLECT)
- to_chat(user, span_info("[src] has been set to search and store loose ore."))
- if(MINEDRONE_ATTACK)
- to_chat(user, span_info("[src] has been set to attack hostile wildlife."))
- return
-
-/mob/living/simple_animal/hostile/mining_drone/CanAllowThrough(atom/movable/mover, border_dir)
- . = ..()
- if(istype(mover, /obj/projectile/kinetic))
- var/obj/projectile/kinetic/projectile = mover
- if(projectile.kinetic_gun)
- if (locate(/obj/item/borg/upgrade/modkit/minebot_passthrough) in projectile.kinetic_gun.modkits)
- return TRUE
- else if(istype(mover, /obj/projectile/destabilizer))
- return TRUE
-
-/mob/living/simple_animal/hostile/mining_drone/proc/SetCollectBehavior()
- mode = MINEDRONE_COLLECT
- vision_range = 9
- search_objects = 2
- wander = TRUE
- ranged = FALSE
- minimum_distance = 1
- retreat_distance = null
- icon_state = "mining_drone"
- to_chat(src, span_info("You are set to collect mode. You can now collect loose ore."))
-
-/mob/living/simple_animal/hostile/mining_drone/proc/SetOffenseBehavior()
- mode = MINEDRONE_ATTACK
- vision_range = 7
- search_objects = 0
- wander = FALSE
- ranged = TRUE
- retreat_distance = 2
- minimum_distance = 1
- icon_state = "mining_drone_offense"
- to_chat(src, span_info("You are set to attack mode. You can now attack from range."))
-
-/mob/living/simple_animal/hostile/mining_drone/AttackingTarget()
- if(istype(target, /obj/item/stack/ore) && mode == MINEDRONE_COLLECT)
- CollectOre()
- return
- if(isliving(target))
- SetOffenseBehavior()
- return ..()
-
-/mob/living/simple_animal/hostile/mining_drone/OpenFire(atom/target)
- if(CheckFriendlyFire(target))
- return
- stored_gun.afterattack(target, src) //of the possible options to allow minebots to have KA mods, would you believe this is the best?
-
-/mob/living/simple_animal/hostile/mining_drone/proc/CollectOre()
- for(var/obj/item/stack/ore/O in range(1, src))
- O.forceMove(src)
-
-/mob/living/simple_animal/hostile/mining_drone/proc/DropOre(message = 1)
- if(!contents.len)
- if(message)
- to_chat(src, span_warning("You attempt to dump your stored ore, but you have none!"))
- return
- if(message)
- to_chat(src, span_notice("You dump your stored ore."))
- for(var/obj/item/stack/ore/O in contents)
- O.forceMove(drop_location())
-
-/mob/living/simple_animal/hostile/mining_drone/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
- if(mode != MINEDRONE_ATTACK && amount > 0)
- SetOffenseBehavior()
- . = ..()
-
-/datum/action/innate/minedrone/toggle_meson_vision
- name = "Toggle Meson Vision"
- button_icon_state = "meson"
-
-/datum/action/innate/minedrone/toggle_meson_vision/Activate()
- var/mob/living/simple_animal/hostile/mining_drone/user = owner
- if(user.sight & SEE_TURFS)
- user.clear_sight(SEE_TURFS)
- user.lighting_cutoff_red += 5
- user.lighting_cutoff_green += 15
- user.lighting_cutoff_blue += 5
- else
- user.add_sight(SEE_TURFS)
- user.lighting_cutoff_red -= 5
- user.lighting_cutoff_green -= 15
- user.lighting_cutoff_blue -= 5
-
- user.sync_lighting_plane_cutoff()
-
- to_chat(user, span_notice("You toggle your meson vision [(user.sight & SEE_TURFS) ? "on" : "off"]."))
-
-
-/mob/living/simple_animal/hostile/mining_drone/proc/toggle_mode()
- switch(mode)
- if(MINEDRONE_ATTACK)
- SetCollectBehavior()
- else
- SetOffenseBehavior()
-
-//Actions for sentient minebots
-
-/datum/action/innate/minedrone
- check_flags = AB_CHECK_CONSCIOUS
- button_icon = 'icons/mob/actions/actions_mecha.dmi'
- background_icon_state = "bg_default"
- overlay_icon_state = "bg_default_border"
-
-/datum/action/innate/minedrone/toggle_light
- name = "Toggle Light"
- button_icon_state = "mech_lights_off"
-
-
-/datum/action/innate/minedrone/toggle_light/Activate()
- var/mob/living/simple_animal/hostile/mining_drone/user = owner
- user.set_light_on(!user.light_on)
- to_chat(user, span_notice("You toggle your light [user.light_on ? "on" : "off"]."))
-
-
-/datum/action/innate/minedrone/toggle_mode
- name = "Toggle Mode"
- button_icon_state = "mech_cycle_equip_off"
-
-/datum/action/innate/minedrone/toggle_mode/Activate()
- var/mob/living/simple_animal/hostile/mining_drone/user = owner
- user.toggle_mode()
-
-/datum/action/innate/minedrone/dump_ore
- name = "Dump Ore"
- button_icon_state = "mech_eject"
-
-/datum/action/innate/minedrone/dump_ore/Activate()
- var/mob/living/simple_animal/hostile/mining_drone/user = owner
- user.DropOre()
-
-
-/**********************Minebot Upgrades**********************/
-
-//Melee
-
-/obj/item/mine_bot_upgrade
- name = "minebot melee upgrade"
- desc = "A minebot upgrade."
- icon_state = "door_electronics"
- icon = 'icons/obj/assemblies/module.dmi'
-
-/obj/item/mine_bot_upgrade/afterattack(mob/living/simple_animal/hostile/mining_drone/minebot, mob/user, proximity)
- . = ..()
- if(!istype(minebot) || !proximity)
- return
- upgrade_bot(minebot, user)
-
-/obj/item/mine_bot_upgrade/proc/upgrade_bot(mob/living/simple_animal/hostile/mining_drone/minebot, mob/user)
- if(minebot.melee_damage_upper != initial(minebot.melee_damage_upper))
- to_chat(user, span_warning("[minebot] already has a combat upgrade installed!"))
- return
- minebot.melee_damage_lower += 7
- minebot.melee_damage_upper += 7
- to_chat(user, "You increase the close-quarter combat abilities of [minebot].")
- qdel(src)
-
-//Health
-
-/obj/item/mine_bot_upgrade/health
- name = "minebot armor upgrade"
-
-/obj/item/mine_bot_upgrade/health/upgrade_bot(mob/living/simple_animal/hostile/mining_drone/minebot, mob/user)
- if(minebot.maxHealth != initial(minebot.maxHealth))
- to_chat(user, span_warning("[minebot] already has reinforced armor!"))
- return
- minebot.maxHealth += 45
- minebot.updatehealth()
- to_chat(user, "You reinforce the armor of [minebot].")
- qdel(src)
-
-//AI
-
-/obj/item/slimepotion/slime/sentience/mining
- name = "minebot AI upgrade"
- desc = "Can be used to grant sentience to minebots. It's incompatible with minebot armor and melee upgrades, and will override them."
- icon_state = "door_electronics"
- icon = 'icons/obj/assemblies/module.dmi'
- sentience_type = SENTIENCE_MINEBOT
- var/base_health_add = 5 //sentient minebots are penalized for beign sentient; they have their stats reset to normal plus these values
- var/base_damage_add = 1 //this thus disables other minebot upgrades
- var/base_speed_add = 1
- var/base_cooldown_add = 10 //base cooldown isn't reset to normal, it's just added on, since it's not practical to disable the cooldown module
-
-/obj/item/slimepotion/slime/sentience/mining/after_success(mob/living/user, mob/living/simple_animal/simple_mob)
- if(!istype(simple_mob, /mob/living/simple_animal/hostile/mining_drone))
- return
- var/mob/living/simple_animal/hostile/mining_drone/minebot = simple_mob
- minebot.maxHealth = initial(minebot.maxHealth) + base_health_add
- minebot.melee_damage_lower = initial(minebot.melee_damage_lower) + base_damage_add
- minebot.melee_damage_upper = initial(minebot.melee_damage_upper) + base_damage_add
- minebot.move_to_delay = initial(minebot.move_to_delay) + base_speed_add
- minebot.stored_gun?.recharge_time += base_cooldown_add
-
-#undef MINEDRONE_COLLECT
-#undef MINEDRONE_ATTACK
diff --git a/code/modules/mining/voucher_sets.dm b/code/modules/mining/voucher_sets.dm
index 86c6e407d67..071a8f11536 100644
--- a/code/modules/mining/voucher_sets.dm
+++ b/code/modules/mining/voucher_sets.dm
@@ -62,7 +62,7 @@
icon = 'icons/mob/silicon/aibots.dmi'
icon_state = "mining_drone"
set_items = list(
- /mob/living/simple_animal/hostile/mining_drone,
+ /mob/living/basic/mining_drone,
/obj/item/weldingtool/hugetank,
/obj/item/clothing/head/utility/welding,
/obj/item/borg/upgrade/modkit/minebot_passthrough,
diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm
index b68edb67e26..8d7db7f8e85 100644
--- a/code/modules/mob/dead/dead.dm
+++ b/code/modules/mob/dead/dead.dm
@@ -46,11 +46,13 @@ INITIALIZE_IMMEDIATE(/mob/dead)
. += "Players Ready: [SSticker.totalPlayersReady]"
. += "Admins Ready: [SSticker.total_admins_ready] / [length(GLOB.admins)]"
+#define SERVER_HOPPER_TRAIT "server_hopper"
+
/mob/dead/proc/server_hop()
set category = "OOC"
set name = "Server Hop"
set desc= "Jump to the other server"
- if(notransform)
+ if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM)) // in case the round is ending and a cinematic is already playing we don't wanna clash with that (yes i know)
return
var/list/our_id = CONFIG_GET(string/cross_comms_name)
var/list/csa = CONFIG_GET(keyed_list/cross_server) - our_id
@@ -76,9 +78,9 @@ INITIALIZE_IMMEDIATE(/mob/dead)
to_chat(C, span_notice("Sending you to [pick]."))
new /atom/movable/screen/splash(null, null, C)
- notransform = TRUE
+ ADD_TRAIT(src, TRAIT_NO_TRANSFORM, SERVER_HOPPER_TRAIT)
sleep(2.9 SECONDS) //let the animation play
- notransform = FALSE
+ REMOVE_TRAIT(src, TRAIT_NO_TRANSFORM, SERVER_HOPPER_TRAIT)
if(!C)
return
@@ -87,6 +89,8 @@ INITIALIZE_IMMEDIATE(/mob/dead)
C << link("[addr]")
+#undef SERVER_HOPPER_TRAIT
+
/mob/dead/proc/update_z(new_z) // 1+ to register, null to unregister
if (registered_z != new_z)
if (registered_z)
diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm
index 03f88cf9e6a..a38fe171174 100644
--- a/code/modules/mob/dead/new_player/new_player.dm
+++ b/code/modules/mob/dead/new_player/new_player.dm
@@ -125,13 +125,15 @@
if(JOB_NOT_VETERAN)
return "You need to be veteran to join as [jobtitle]."
if(JOB_UNAVAILABLE_QUIRK)
- return "[jobtitle] is restricted from your quirks."
+ return "[jobtitle] is restricted due to your selected quirks."
if(JOB_UNAVAILABLE_LANGUAGE)
- return "[jobtitle] is restricted from your languages."
+ return "[jobtitle] is restricted due to your selected languages."
if(JOB_UNAVAILABLE_SPECIES)
- return "[jobtitle] is restricted from your species."
+ return "[jobtitle] is restricted due to your selected species."
if(JOB_UNAVAILABLE_FLAVOUR)
return "[jobtitle] requires you to have flavour text for your character."
+ if(JOB_UNAVAILABLE_AUGMENT)
+ return "[jobtitle] is restricted due to your selected body augments."
//SKYRAT EDIT END
if(JOB_UNAVAILABLE_ANTAG_INCOMPAT)
return "[jobtitle] is not compatible with some antagonist role assigned to you."
@@ -214,14 +216,16 @@
#define IS_ACTING_CAPTAIN 1
#define IS_FULL_CAPTAIN 2
var/is_captain = IS_NOT_CAPTAIN
+ var/captain_sound = 'sound/misc/notice2.ogg'
// If we already have a captain, are they a "Captain" rank and are we allowing multiple of them to be assigned?
if(is_captain_job(job))
is_captain = IS_FULL_CAPTAIN
+ captain_sound = ANNOUNCER_DEPARTMENTAL // SKYRAT EDIT CHANGE - Announcer Sounds
// If we don't have an assigned cap yet, check if this person qualifies for some from of captaincy.
else if(!SSjob.assigned_captain && ishuman(character) && SSjob.chain_of_command[rank] && !is_banned_from(ckey, list(JOB_CAPTAIN)))
is_captain = IS_ACTING_CAPTAIN
if(is_captain != IS_NOT_CAPTAIN)
- minor_announce(job.get_captaincy_announcement(character))
+ minor_announce(job.get_captaincy_announcement(character), sound_override = captain_sound)
SSjob.promote_to_captain(character, is_captain == IS_ACTING_CAPTAIN)
#undef IS_NOT_CAPTAIN
#undef IS_ACTING_CAPTAIN
diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm
index 9b8a192260f..a1c7c0371b0 100644
--- a/code/modules/mob/dead/new_player/preferences_setup.dm
+++ b/code/modules/mob/dead/new_player/preferences_setup.dm
@@ -25,6 +25,7 @@
/datum/preferences/proc/hardcore_random_setup(mob/living/carbon/human/character)
var/next_hardcore_score = select_hardcore_quirks()
character.hardcore_survival_score = next_hardcore_score ** 1.2 //30 points would be about 60 score
+ log_admin("[character] started hardcore random with [english_list(all_quirks)], for a score of [next_hardcore_score].")
//Add a sixpack because honestly
var/obj/item/bodypart/chest/chest = character.get_bodypart(BODY_ZONE_CHEST)
diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm
index ff2e414dd70..0688778b048 100644
--- a/code/modules/mob/emote.dm
+++ b/code/modules/mob/emote.dm
@@ -117,7 +117,7 @@
return
if(user.get_timed_status_effect_duration(/datum/status_effect/confusion) > BEYBLADE_PUKE_THRESHOLD)
- user.vomit(BEYBLADE_PUKE_NUTRIENT_LOSS, distance = 0)
+ user.vomit(VOMIT_CATEGORY_KNOCKDOWN, lost_nutrition = BEYBLADE_PUKE_NUTRIENT_LOSS, distance = 0)
return
if(prob(BEYBLADE_DIZZINESS_PROBABILITY))
diff --git a/code/modules/mob/living/basic/basic.dm b/code/modules/mob/living/basic/basic.dm
index 5a9ccacf6e3..7b65e6600a7 100644
--- a/code/modules/mob/living/basic/basic.dm
+++ b/code/modules/mob/living/basic/basic.dm
@@ -11,7 +11,7 @@
var/basic_mob_flags = NONE
- ///Defines how fast the basic mob can move. This is a multiplier
+ ///Defines how fast the basic mob can move. This is not a multiplier
var/speed = 1
///How much stamina the mob recovers per second
var/stamina_recovery = 5
@@ -35,6 +35,8 @@
var/attack_vis_effect
///Played when someone punches the creature.
var/attacked_sound = SFX_PUNCH //This should be an element
+ /// How often can you melee attack?
+ var/melee_attack_cooldown = 2 SECONDS
/// Variable maintained for compatibility with attack_animal procs until simple animals can be refactored away. Use element instead of setting manually.
var/environment_smash = ENVIRONMENT_SMASH_STRUCTURES
@@ -141,6 +143,19 @@
health = 0
look_dead()
+/mob/living/basic/gib()
+ if(butcher_results || guaranteed_butcher_results)
+ var/list/butcher_loot = list()
+ if(butcher_results)
+ butcher_loot += butcher_results
+ if(guaranteed_butcher_results)
+ butcher_loot += guaranteed_butcher_results
+ var/atom/loot_destination = drop_location()
+ for(var/path in butcher_loot)
+ for(var/i in 1 to butcher_loot[path])
+ new path(loot_destination)
+ return ..()
+
/**
* Apply the appearance and properties this mob has when it dies
* This is called by the mob pretending to be dead too so don't put loot drops in here or something
@@ -178,8 +193,10 @@
return
. += span_deadsay("Upon closer examination, [p_they()] appear[p_s()] to be [HAS_TRAIT(user.mind, TRAIT_NAIVE) ? "asleep" : "dead"].")
-/mob/living/basic/proc/melee_attack(atom/target, list/modifiers)
+/mob/living/basic/proc/melee_attack(atom/target, list/modifiers, ignore_cooldown = FALSE)
face_atom(target)
+ if (!ignore_cooldown)
+ changeNext_move(melee_attack_cooldown)
if(SEND_SIGNAL(src, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, target) & COMPONENT_HOSTILE_NO_ATTACK)
return FALSE //but more importantly return before attack_animal called
var/result = target.attack_basic_mob(src, modifiers)
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm b/code/modules/mob/living/basic/clown/clown.dm
similarity index 62%
rename from code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm
rename to code/modules/mob/living/basic/clown/clown.dm
index 529c3025479..78715361356 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm
+++ b/code/modules/mob/living/basic/clown/clown.dm
@@ -1,4 +1,4 @@
-/mob/living/simple_animal/hostile/retaliate/clown
+/mob/living/basic/clown
name = "Clown"
desc = "A denizen of clown planet."
icon = 'icons/mob/simple/clown_mobs.dmi'
@@ -8,73 +8,517 @@
icon_gib = "clown_gib"
health_doll_icon = "clown" //if >32x32, it will use this generic. for all the huge clown mobs that subtype from this
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
- turns_per_move = 5
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
response_harm_continuous = "robusts"
response_harm_simple = "robust"
- speak = list("HONK", "Honk!", "Welcome to clown planet!")
- emote_see = list("honks", "squeaks")
- speak_chance = 1
combat_mode = TRUE
maxHealth = 75
health = 75
- speed = 1
- harm_intent_damage = 8
melee_damage_lower = 10
melee_damage_upper = 10
attack_sound = 'sound/items/bikehorn.ogg'
- obj_damage = 0
+ attacked_sound = 'sound/items/bikehorn.ogg'
environment_smash = ENVIRONMENT_SMASH_NONE
- del_on_death = 1
- loot = list(/obj/effect/mob_spawn/corpse/human/clown)
+ basic_mob_flags = DEL_ON_DEATH
initial_language_holder = /datum/language_holder/clown
- atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
- minbodytemp = 270
- maxbodytemp = 370
+ habitable_atmos = list("min_oxy" = 5, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
+ minimum_survivable_temperature = T0C
+ maximum_survivable_temperature = (T0C + 100)
unsuitable_atmos_damage = 10
unsuitable_heat_damage = 15
- footstep_type = FOOTSTEP_MOB_SHOE
faction = list(FACTION_CLOWN)
- var/attack_reagent
+ ai_controller = /datum/ai_controller/basic_controller/clown
+ speed = 1.4 //roughly close to simpleanimal clowns
+ ///list of stuff we drop on death
+ var/list/loot = list(/obj/effect/mob_spawn/corpse/human/clown)
+ ///blackboard emote list
+ var/list/emotes = list(
+ BB_EMOTE_SAY = list("HONK", "Honk!", "Welcome to clown planet!"),
+ BB_EMOTE_HEAR = list("honks", "squeaks"),
+ BB_EMOTE_SOUND = list('sound/items/bikehorn.ogg'), //WE LOVE TO PARTY
+ BB_EMOTE_CHANCE = 5,
+ )
+ ///do we waddle (honk)
+ var/waddles = TRUE
-/mob/living/simple_animal/hostile/retaliate/clown/Initialize(mapload)
+/mob/living/basic/clown/Initialize(mapload)
. = ..()
- if(attack_reagent)
- var/static/list/injection_range
- if(!injection_range)
- injection_range = string_numbers_list(list(1, 5))
- AddElement(/datum/element/venomous, attack_reagent, injection_range)
+ AddElement(/datum/element/footstep, footstep_type = FOOTSTEP_MOB_SHOE)
+ AddComponent(/datum/component/ai_retaliate_advanced, CALLBACK(src, PROC_REF(retaliate_callback)))
+ ai_controller.set_blackboard_key(BB_BASIC_MOB_SPEAK_LINES, emotes)
+ //im not putting dynamic humans or whatever its called here because this is the base path of nonhuman clownstrosities
+ if(waddles)
+ AddElement(/datum/element/waddling)
+ if(length(loot))
+ loot = string_list(loot)
+ AddElement(/datum/element/death_drops, loot)
-/mob/living/simple_animal/hostile/retaliate/clown/attack_hand(mob/living/carbon/human/user, list/modifiers)
- ..()
- playsound(loc, 'sound/items/bikehorn.ogg', 50, TRUE)
+/mob/living/basic/clown/proc/retaliate_callback(mob/living/attacker)
+ if (!istype(attacker))
+ return
+ for (var/mob/living/basic/clown/harbringer in oview(src, 7))
+ harbringer.ai_controller.insert_blackboard_key_lazylist(BB_BASIC_MOB_RETALIATE_LIST, attacker)
-/mob/living/simple_animal/hostile/retaliate/clown/AttackingTarget(atom/attacked_target)
- if(!istype(attacked_target, /obj/item/food/grown/banana/bunch))
+/mob/living/basic/clown/melee_attack(atom/target, list/modifiers, ignore_cooldown = FALSE)
+ if(!istype(target, /obj/item/food/grown/banana/bunch))
return ..()
- var/obj/item/food/grown/banana/bunch/unripe_bunch = attacked_target
+ var/obj/item/food/grown/banana/bunch/unripe_bunch = target
unripe_bunch.start_ripening()
- log_combat(src, attacked_target, "honksposivley ripened")
+ log_combat(src, target, "explosively ripened")
-/mob/living/simple_animal/hostile/retaliate/clown/lube
+/mob/living/basic/clown/lube
name = "Living Lube"
desc = "A puddle of lube brought to life by the honkmother."
icon_state = "lube"
icon_living = "lube"
- turns_per_move = 1
response_help_continuous = "dips a finger into"
response_help_simple = "dip a finger into"
response_disarm_continuous = "gently scoops and pours aside"
response_disarm_simple = "gently scoop and pour aside"
- emote_see = list("bubbles", "oozes")
- loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/particle_effect/fluid/foam)
+ emotes = list(
+ BB_EMOTE_SAY = list("HONK", "Honk!", "Welcome to clown planet!"),
+ BB_EMOTE_HEAR = list("bubbles", "oozes"),
+ )
+ waddles = FALSE
+ loot = list(
+ /obj/effect/spawner/foam_starter/small,
+ /obj/item/clothing/mask/gas/clown_hat,
+ )
-/mob/living/simple_animal/hostile/retaliate/clown/lube/Initialize(mapload)
+/mob/living/basic/clown/lube/Initialize(mapload)
. = ..()
AddElement(/datum/element/snailcrawl)
-/mob/living/simple_animal/hostile/retaliate/clown/banana
+/mob/living/basic/clown/honkling
+ name = "Honkling"
+ desc = "A divine being sent by the Honkmother to spread joy. It's not dangerous, but it's a bit of a nuisance."
+ icon_state = "honkling"
+ icon_living = "honkling"
+ speed = 1.1
+ melee_damage_lower = 1
+ melee_damage_upper = 1
+ attack_verb_continuous = "cheers up"
+ attack_verb_simple = "cheer up"
+ loot = list(
+ /obj/item/clothing/mask/gas/clown_hat,
+ /obj/effect/gibspawner/human,
+ /obj/item/soap,
+ /obj/item/seeds/banana/bluespace,
+ )
+
+/mob/living/basic/clown/honkling/Initialize(mapload)
+ . = ..()
+ var/static/list/injection_range
+ if(!injection_range)
+ injection_range = string_numbers_list(list(1, 5))
+ AddElement(/datum/element/venomous, /datum/reagent/consumable/laughter, injection_range)
+
+/mob/living/basic/clown/fleshclown
+ name = "Fleshclown"
+ desc = "A being forged out of the pure essence of pranking, cursed into existence by a cruel maker."
+ icon_state = "fleshclown"
+ icon_living = "fleshclown"
+ response_help_continuous = "reluctantly pokes"
+ response_help_simple = "reluctantly poke"
+ response_disarm_continuous = "sinks his hands into the spongy flesh of"
+ response_disarm_simple = "sink your hands into the spongy flesh of"
+ response_harm_continuous = "cleanses the world of"
+ response_harm_simple = "cleanse the world of"
+ maxHealth = 140
+ health = 140
+ speed = 1
+ melee_damage_upper = 15
+ attack_verb_continuous = "limply slaps"
+ attack_verb_simple = "limply slap"
+ obj_damage = 5
+ loot = list(
+ /obj/effect/gibspawner/human,
+ /obj/item/clothing/mask/gas/clown_hat,
+ /obj/item/soap,
+ /obj/item/clothing/suit/hooded/bloated_human,
+ )
+ emotes = list(
+ BB_EMOTE_SAY = list(
+ "HONK",
+ "Honk!",
+ "I didn't ask for this",
+ "I feel constant and horrible pain",
+ "I was born out of mirthful pranking but I live in suffering",
+ "This body is a merciless and unforgiving prison",
+ "YA-HONK!!!",
+ ),
+ BB_EMOTE_HEAR = list("honks", "contemplates its existence"),
+ BB_EMOTE_SEE = list("sweats", "jiggles"),
+ BB_EMOTE_CHANCE = 5,
+ )
+
+/mob/living/basic/clown/fleshclown/Initialize(mapload)
+ . = ..()
+ ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
+
+/mob/living/basic/clown/longface
+ name = "Longface"
+ desc = "Often found walking into the bar."
+ icon_state = "long face"
+ icon_living = "long face"
+ move_resist = INFINITY
+ response_help_continuous = "tries to awkwardly hug"
+ response_help_simple = "try to awkwardly hug"
+ response_disarm_continuous = "pushes the unwieldy frame of"
+ response_disarm_simple = "push the unwieldy frame of"
+ response_harm_continuous = "tries to shut up"
+ response_harm_simple = "try to shut up"
+ maxHealth = 150
+ health = 150
+ pixel_x = -16
+ base_pixel_x = -16
+ speed = 3
+ melee_damage_lower = 5
+ attack_verb_continuous = "YA-HONKs"
+ attack_verb_simple = "YA-HONK"
+ loot = list(
+ /obj/effect/gibspawner/human,
+ /obj/item/soap,
+ /obj/item/clothing/mask/gas/clown_hat,
+ )
+ emotes = list(
+ BB_EMOTE_SAY = list("YA-HONK!!!"),
+ BB_EMOTE_HEAR = list("honks", "squeaks"),
+ BB_EMOTE_CHANCE = 60,
+ )
+
+/mob/living/basic/clown/clownhulk
+ name = "Honk Hulk"
+ desc = "A cruel and fearsome clown. Don't make him angry."
+ icon_state = "honkhulk"
+ icon_living = "honkhulk"
+ move_resist = INFINITY
+ gender = MALE
+ response_help_continuous = "tries desperately to appease"
+ response_help_simple = "try desperately to appease"
+ response_disarm_continuous = "foolishly pushes"
+ response_disarm_simple = "foolishly push"
+ response_harm_continuous = "angers"
+ response_harm_simple = "anger"
+ maxHealth = 400
+ health = 400
+ pixel_x = -16
+ base_pixel_x = -16
+ speed = 2
+ melee_damage_lower = 15
+ melee_damage_upper = 20
+ attack_verb_continuous = "pummels"
+ attack_verb_simple = "pummel"
+ obj_damage = 30
+ environment_smash = ENVIRONMENT_SMASH_WALLS
+ loot = list(
+ /obj/effect/gibspawner/human,
+ /obj/item/soap,
+ /obj/item/clothing/mask/gas/clown_hat,
+ )
+ emotes = list(
+ BB_EMOTE_SAY = list("HONK", "Honk!", "HAUAUANK!!!", "GUUURRRRAAAHHH!!!"),
+ BB_EMOTE_HEAR = list("honks", "grunts"),
+ BB_EMOTE_SEE = list("sweats"),
+ BB_EMOTE_CHANCE = 5,
+ )
+
+/mob/living/basic/clown/clownhulk/chlown
+ name = "Chlown"
+ desc = "A real lunkhead who somehow gets all the girls."
+ icon_state = "chlown"
+ icon_living = "chlown"
+ gender = MALE
+ response_help_continuous = "submits to"
+ response_help_simple = "submit to"
+ response_disarm_continuous = "tries to assert dominance over"
+ response_disarm_simple = "try to assert dominance over"
+ response_harm_continuous = "makes a weak beta attack at"
+ response_harm_simple = "make a weak beta attack at"
+ maxHealth = 500
+ health = 500
+ speed = -2 //ridicilously fast but i dont even know what this is used for
+ armour_penetration = 20
+ attack_verb_continuous = "steals the girlfriend of"
+ attack_verb_simple = "steal the girlfriend of"
+ attack_sound = 'sound/items/airhorn2.ogg'
+ loot = list(
+ /obj/effect/gibspawner/human,
+ /obj/effect/spawner/foam_starter/small,
+ /obj/item/soap,
+ /obj/item/clothing/mask/gas/clown_hat,
+ )
+ emotes = list(
+ BB_EMOTE_SAY = list("HONK", "Honk!", "Bruh", "cheeaaaahhh?"),
+ BB_EMOTE_SEE = list("asserts his dominance", "emasculates everyone implicitly"),
+ BB_EMOTE_CHANCE = 5,
+ )
+
+/mob/living/basic/clown/clownhulk/honkmunculus
+ name = "Honkmunculus"
+ desc = "A slender wiry figure of alchemical origin."
+ icon_state = "honkmunculus"
+ icon_living = "honkmunculus"
+ response_help_continuous = "skeptically pokes"
+ response_help_simple = "skeptically poke"
+ response_disarm_continuous = "pushes the unwieldy frame of"
+ response_disarm_simple = "push the unwieldy frame of"
+ maxHealth = 200
+ health = 200
+ speed = 1
+ melee_damage_lower = 5
+ melee_damage_upper = 10
+ attack_verb_continuous = "ferociously mauls"
+ attack_verb_simple = "ferociously maul"
+ environment_smash = ENVIRONMENT_SMASH_NONE
+ loot = list(
+ /obj/effect/gibspawner/xeno/bodypartless,
+ /obj/effect/spawner/foam_starter/small,
+ /obj/item/soap,
+ /obj/item/clothing/mask/gas/clown_hat,
+ )
+ emotes = list(
+ BB_EMOTE_SAY = list("honk"),
+ BB_EMOTE_SEE = list("squirms", "writhes"),
+ )
+
+/mob/living/basic/clown/clownhulk/honkmunculus/Initialize(mapload)
+ . = ..()
+ var/static/list/injection_range
+ if(!injection_range)
+ injection_range = string_numbers_list(list(1, 5))
+ AddElement(/datum/element/venomous, /datum/reagent/peaceborg/confuse, injection_range)
+
+/mob/living/basic/clown/clownhulk/destroyer
+ name = "The Destroyer"
+ desc = "An ancient being born of arcane honking."
+ icon_state = "destroyer"
+ icon_living = "destroyer"
+ response_disarm_continuous = "bounces off of"
+ response_harm_continuous = "bounces off of"
+ maxHealth = 400
+ health = 400
+ speed = 5
+ melee_damage_lower = 20
+ melee_damage_upper = 40
+ armour_penetration = 30
+ attack_verb_continuous = "acts out divine vengeance on"
+ attack_verb_simple = "act out divine vengeance on"
+ obj_damage = 50
+ environment_smash = ENVIRONMENT_SMASH_RWALLS
+ ai_controller = /datum/ai_controller/basic_controller/clown/murder
+ loot = list(
+ /obj/effect/gibspawner/human,
+ /obj/effect/spawner/foam_starter/small,
+ /obj/item/soap,
+ /obj/item/clothing/mask/gas/clown_hat,
+ )
+ emotes = list(
+ BB_EMOTE_SAY = list("HONK!!!", "The Honkmother is merciful, so I must act out her wrath.", "parce mihi ad beatus honkmother placet mihi ut peccata committere,", "DIE!!!"),
+ BB_EMOTE_HEAR = list("honks", "grunts"),
+ BB_EMOTE_SEE = list("sweats"),
+ BB_EMOTE_CHANCE = 5,
+ )
+
+/mob/living/basic/clown/mutant
+ name = "Unknown"
+ desc = "Kill it for its own sake."
+ icon_state = "mutant"
+ icon_living = "mutant"
+ move_resist = INFINITY
+ response_help_continuous = "reluctantly sinks a finger into"
+ response_help_simple = "reluctantly sink a finger into"
+ response_disarm_continuous = "squishes into"
+ response_disarm_simple = "squish into"
+ response_harm_continuous = "squishes into"
+ response_harm_simple = "squish into"
+ maxHealth = 130
+ health = 130
+ pixel_x = -16
+ base_pixel_x = -16
+ speed = -5
+ melee_damage_lower = 10
+ melee_damage_upper = 20
+ attack_verb_continuous = "awkwardly flails at"
+ attack_verb_simple = "awkwardly flail at"
+ loot = list(
+ /obj/effect/gibspawner/generic,
+ /obj/effect/gibspawner/generic/animal,
+ /obj/effect/gibspawner/human,
+ /obj/effect/gibspawner/human/bodypartless,
+ /obj/effect/gibspawner/xeno/bodypartless,
+ /obj/item/soap,
+ /obj/item/clothing/mask/gas/clown_hat,
+ )
+ emotes = list(
+ BB_EMOTE_SAY = list("aaaaaahhhhuuhhhuhhhaaaaa", "AAAaaauuuaaAAAaauuhhh", "huuuuuh... hhhhuuuooooonnnnkk", "HuaUAAAnKKKK"),
+ BB_EMOTE_SEE = list("squirms", "writhes", "pulsates", "froths", "oozes"),
+ BB_EMOTE_CHANCE = 10,
+ )
+
+/mob/living/basic/clown/mutant/slow
+ speed = 20
+
+/mob/living/basic/clown/mutant/glutton
+ name = "banana glutton"
+ desc = "Something that was once a clown"
+ icon_state = "glutton"
+ icon_living = "glutton"
+ health = 200
+ mob_size = MOB_SIZE_LARGE
+ speed = 1
+ melee_damage_lower = 10
+ melee_damage_upper = 15
+ force_threshold = 10 //lots of fat to cushion blows.
+ damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 2, STAMINA = 0, OXY = 1)
+ attack_verb_continuous = "slams"
+ attack_verb_simple = "slam"
+ loot = list(
+ /obj/effect/gibspawner/generic,
+ /obj/effect/gibspawner/generic/animal,
+ /obj/effect/gibspawner/human/bodypartless,
+ /obj/effect/gibspawner/xeno/bodypartless,
+ )
+ emotes = list(
+ BB_EMOTE_SAY = list("hey, buddy", "HONK!!!", "H-h-h-H-HOOOOONK!!!!", "HONKHONKHONK!!!", "HEY, BUCKO, GET BACK HERE!!!", "HOOOOOOOONK!!!"),
+ BB_EMOTE_SEE = list("jiggles", "wobbles"),
+ )
+ death_sound = 'sound/misc/sadtrombone.ogg'
+ waddles = FALSE
+ ///This is the list of items we are ready to regurgitate,
+ var/list/prank_pouch = list()
+
+/mob/living/basic/clown/mutant/glutton/Initialize(mapload)
+ . = ..()
+ var/datum/action/cooldown/regurgitate/spit = new(src)
+ spit.Grant(src)
+
+ AddElement(/datum/element/swabable, CELL_LINE_TABLE_GLUTTON, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
+ AddComponent(/datum/component/tameable, food_types = list(/obj/item/food/cheesiehonkers, /obj/item/food/cornchips), tame_chance = 30, bonus_tame_chance = 0, after_tame = CALLBACK(src, PROC_REF(tamed)))
+
+
+/mob/living/basic/clown/mutant/glutton/attacked_by(obj/item/item, mob/living/user)
+ if(!check_edible(item))
+ return ..()
+ eat_atom(item)
+
+/mob/living/basic/clown/mutant/glutton/melee_attack(atom/target, list/modifiers, ignore_cooldown = FALSE)
+ if(!check_edible(target))
+ return ..()
+ eat_atom(target)
+
+/mob/living/basic/clown/mutant/glutton/UnarmedAttack(atom/victim, proximity_flag, list/modifiers)
+ if(!check_edible(victim))
+ return ..()
+ eat_atom(victim)
+
+///Returns whether or not the supplied movable atom is edible.
+/mob/living/basic/clown/mutant/glutton/proc/check_edible(atom/movable/potential_food)
+ if(isliving(potential_food))
+ var/mob/living/living_morsel = potential_food
+ if(living_morsel.mob_size > MOB_SIZE_SMALL)
+ return FALSE
+ else
+ return TRUE
+
+ if(IS_EDIBLE(potential_food))
+ if(prank_pouch.len >= 8)
+ to_chat(src, span_warning("Your prank pouch is filled to the brim! You don't think you can swallow any more morsels right now."))
+ return FALSE
+ return TRUE
+
+///This proc eats the atom, certain funny items are stored directly in the prank pouch while bananas grant a heal based on their potency and the peels are retained in the pouch.
+/mob/living/basic/clown/mutant/glutton/proc/eat_atom(atom/movable/eaten_atom)
+
+ var/static/funny_items = list(
+ /obj/item/food/pie/cream,
+ /obj/item/food/grown/tomato,
+ /obj/item/food/meatclown,
+ )
+
+ visible_message(span_warning("[src] eats [eaten_atom]!"), span_notice("You eat [eaten_atom]."))
+ if(is_type_in_list(eaten_atom, funny_items))
+ eaten_atom.forceMove(src)
+ prank_pouch += eaten_atom
+
+ else
+ if(istype(eaten_atom, /obj/item/food/grown/banana))
+ var/obj/item/food/grown/banana/banana_morsel = eaten_atom
+ adjustBruteLoss(-banana_morsel.seed.potency * 0.25)
+ prank_pouch += banana_morsel.generate_trash(src)
+
+ qdel(eaten_atom)
+
+ playsound(loc,'sound/items/eatfood.ogg', rand(30,50), TRUE)
+ flick("glutton_mouth", src)
+
+/mob/living/basic/clown/mutant/glutton/proc/tamed(mob/living/tamer)
+ buckle_lying = 0
+ AddElement(/datum/element/ridable, /datum/component/riding/creature/glutton)
+
+/mob/living/basic/clown/mutant/glutton/Exited(atom/movable/gone, direction)
+ . = ..()
+ prank_pouch -= gone
+
+///This ability will let you fire one random item from your pouch,
+/datum/action/cooldown/regurgitate
+ name = "Regurgitate"
+ desc = "Regurgitates a single item from the depths of your pouch."
+ background_icon_state = "bg_changeling"
+ overlay_icon_state = "bg_changeling_border"
+ button_icon = 'icons/mob/actions/actions_animal.dmi'
+ button_icon_state = "regurgitate"
+ check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_INCAPACITATED
+ melee_cooldown_time = 0 SECONDS
+ click_to_activate = TRUE
+
+/datum/action/cooldown/regurgitate/set_click_ability(mob/on_who)
+ . = ..()
+ if(!.)
+ return
+
+ to_chat(on_who, span_notice("Your throat muscles tense up. Left-click to regurgitate a funny morsel!"))
+ on_who.icon_state = "glutton_tongue"
+ on_who.update_appearance(UPDATE_ICON)
+
+/datum/action/cooldown/regurgitate/unset_click_ability(mob/on_who, refund_cooldown = TRUE)
+ . = ..()
+ if(!.)
+ return
+
+ if(refund_cooldown)
+ to_chat(on_who, span_notice("Your throat muscles relax."))
+ on_who.icon_state = initial(on_who.icon_state)
+ on_who.update_appearance(UPDATE_ICON)
+
+/datum/action/cooldown/regurgitate/IsAvailable(feedback = FALSE)
+ . = ..()
+ if(!.)
+ return FALSE
+
+ // Hardcoded to only work with gluttons. Come back next year
+ return istype(owner, /mob/living/basic/clown/mutant/glutton)
+
+/datum/action/cooldown/regurgitate/Activate(atom/spit_at)
+ StartCooldown(cooldown_time / 4)
+
+ var/mob/living/basic/clown/mutant/glutton/pouch_owner = owner
+ if(!length(pouch_owner.prank_pouch))
+ pouch_owner.icon_state = initial(pouch_owner.icon_state)
+ to_chat(pouch_owner, span_notice("Your prank pouch is empty."))
+ return TRUE
+
+ var/obj/item/projected_morsel = pick(pouch_owner.prank_pouch)
+ projected_morsel.forceMove(pouch_owner.loc)
+ projected_morsel.throw_at(spit_at, 8, 2, pouch_owner)
+ flick("glutton_mouth", pouch_owner)
+ playsound(pouch_owner, 'sound/misc/soggy.ogg', 75)
+
+ StartCooldown()
+ return TRUE
+
+/mob/living/basic/clown/banana
name = "Clownana"
desc = "A fusion of clown and banana DNA birthed from a botany experiment gone wrong."
icon_state = "banana tree"
@@ -83,26 +527,33 @@
response_disarm_simple = "peel"
response_harm_continuous = "peels"
response_harm_simple = "peel"
- turns_per_move = 1
- speak = list("HONK", "Honk!", "YA-HONK!!!")
- emote_see = list("honks", "bites into the banana", "plucks a banana off its head", "photosynthesizes")
maxHealth = 120
health = 120
speed = -1
- loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/item/soap, /obj/item/seeds/banana)
+ loot = list(
+ /obj/effect/gibspawner/human,
+ /obj/item/seeds/banana,
+ /obj/item/soap,
+ /obj/item/clothing/mask/gas/clown_hat,
+ )
+ emotes = list(
+ BB_EMOTE_SAY = list("HONK", "Honk!", "YA-HONK!!!"),
+ BB_EMOTE_SEE = list("bites into the banana", "plucks a banana off its head", "photosynthesizes"),
+ BB_EMOTE_SOUND = list('sound/items/bikehorn.ogg'),
+ )
///Our peel dropping ability
var/datum/action/cooldown/rustle/banana_rustle
///Our banana bunch spawning ability
var/datum/action/cooldown/exquisite_bunch/banana_bunch
-/mob/living/simple_animal/hostile/retaliate/clown/banana/Initialize(mapload)
+/mob/living/basic/clown/banana/Initialize(mapload)
. = ..()
banana_rustle = new()
banana_rustle.Grant(src)
banana_bunch = new()
banana_bunch.Grant(src)
-/mob/living/simple_animal/hostile/retaliate/clown/banana/Destroy()
+/mob/living/basic/clown/banana/Destroy()
. = ..()
QDEL_NULL(banana_rustle)
QDEL_NULL(banana_bunch)
@@ -176,358 +627,3 @@
playsound(owner, 'sound/items/bikehorn.ogg', 60)
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(playsound), owner, 'sound/creatures/clown/hohoho.ogg', 100, 1), 1 SECONDS)
StartCooldown()
-
-/mob/living/simple_animal/hostile/retaliate/clown/honkling
- name = "Honkling"
- desc = "A divine being sent by the Honkmother to spread joy. It's not dangerous, but it's a bit of a nuisance."
- icon_state = "honkling"
- icon_living = "honkling"
- turns_per_move = 1
- speed = -10
- harm_intent_damage = 1
- melee_damage_lower = 1
- melee_damage_upper = 1
- attack_verb_continuous = "cheers up"
- attack_verb_simple = "cheer up"
- loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/item/soap, /obj/item/seeds/banana/bluespace)
- attack_reagent = /datum/reagent/consumable/laughter
-
-/mob/living/simple_animal/hostile/retaliate/clown/fleshclown
- name = "Fleshclown"
- desc = "A being forged out of the pure essence of pranking, cursed into existence by a cruel maker."
- icon_state = "fleshclown"
- icon_living = "fleshclown"
- response_help_continuous = "reluctantly pokes"
- response_help_simple = "reluctantly poke"
- response_disarm_continuous = "sinks his hands into the spongy flesh of"
- response_disarm_simple = "sink your hands into the spongy flesh of"
- response_harm_continuous = "cleanses the world of"
- response_harm_simple = "cleanse the world of"
- speak = list("HONK", "Honk!", "I didn't ask for this", "I feel constant and horrible pain", "YA-HONK!!!", "this body is a merciless and unforgiving prison", "I was born out of mirthful pranking but I live in suffering")
- emote_see = list("honks", "sweats", "jiggles", "contemplates its existence")
- speak_chance = 5
- dextrous = TRUE
- hud_type = /datum/hud/dextrous
- maxHealth = 140
- health = 140
- speed = -5
- melee_damage_upper = 15
- attack_verb_continuous = "limply slaps"
- attack_verb_simple = "limply slap"
- obj_damage = 5
- loot = list(/obj/item/clothing/suit/hooded/bloated_human, /obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/item/soap)
-
-/mob/living/simple_animal/hostile/retaliate/clown/fleshclown/Initialize(mapload)
- . = ..()
- ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
-
-/mob/living/simple_animal/hostile/retaliate/clown/longface
- name = "Longface"
- desc = "Often found walking into the bar."
- icon_state = "long face"
- icon_living = "long face"
- move_resist = INFINITY
- turns_per_move = 10
- response_help_continuous = "tries to awkwardly hug"
- response_help_simple = "try to awkwardly hug"
- response_disarm_continuous = "pushes the unwieldy frame of"
- response_disarm_simple = "push the unwieldy frame of"
- response_harm_continuous = "tries to shut up"
- response_harm_simple = "try to shut up"
- speak = list("YA-HONK!!!")
- emote_see = list("honks", "squeaks")
- speak_chance = 60
- maxHealth = 150
- health = 150
- pixel_x = -16
- base_pixel_x = -16
- speed = 10
- harm_intent_damage = 5
- melee_damage_lower = 5
- attack_verb_continuous = "YA-HONKs"
- attack_verb_simple = "YA-HONK"
- loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/item/soap)
-
-/mob/living/simple_animal/hostile/retaliate/clown/clownhulk
- name = "Honk Hulk"
- desc = "A cruel and fearsome clown. Don't make him angry."
- icon_state = "honkhulk"
- icon_living = "honkhulk"
- move_resist = INFINITY
- gender = MALE
- response_help_continuous = "tries desperately to appease"
- response_help_simple = "try desperately to appease"
- response_disarm_continuous = "foolishly pushes"
- response_disarm_simple = "foolishly push"
- response_harm_continuous = "angers"
- response_harm_simple = "anger"
- speak = list("HONK", "Honk!", "HAUAUANK!!!", "GUUURRRRAAAHHH!!!")
- emote_see = list("honks", "sweats", "grunts")
- speak_chance = 5
- maxHealth = 400
- health = 400
- pixel_x = -16
- base_pixel_x = -16
- speed = 2
- harm_intent_damage = 15
- melee_damage_lower = 15
- melee_damage_upper = 20
- attack_verb_continuous = "pummels"
- attack_verb_simple = "pummel"
- obj_damage = 30
- environment_smash = ENVIRONMENT_SMASH_WALLS
- loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/item/soap)
-
-/mob/living/simple_animal/hostile/retaliate/clown/clownhulk/chlown
- name = "Chlown"
- desc = "A real lunkhead who somehow gets all the girls."
- icon_state = "chlown"
- icon_living = "chlown"
- gender = MALE
- response_help_continuous = "submits to"
- response_help_simple = "submit to"
- response_disarm_continuous = "tries to assert dominance over"
- response_disarm_simple = "try to assert dominance over"
- response_harm_continuous = "makes a weak beta attack at"
- response_harm_simple = "make a weak beta attack at"
- speak = list("HONK", "Honk!", "Bruh", "cheeaaaahhh?")
- emote_see = list("asserts his dominance", "emasculates everyone implicitly")
- maxHealth = 500
- health = 500
- speed = -2
- armour_penetration = 20
- attack_verb_continuous = "steals the girlfriend of"
- attack_verb_simple = "steal the girlfriend of"
- attack_sound = 'sound/items/airhorn2.ogg'
- loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/effect/particle_effect/fluid/foam, /obj/item/soap)
-
-/mob/living/simple_animal/hostile/retaliate/clown/clownhulk/honcmunculus
- name = "Honkmunculus"
- desc = "A slender wiry figure of alchemical origin."
- icon_state = "honkmunculus"
- icon_living = "honkmunculus"
- response_help_continuous = "skeptically pokes"
- response_help_simple = "skeptically poke"
- response_disarm_continuous = "pushes the unwieldy frame of"
- response_disarm_simple = "push the unwieldy frame of"
- speak = list("honk")
- emote_see = list("squirms", "writhes")
- speak_chance = 1
- maxHealth = 200
- health = 200
- speed = -5
- harm_intent_damage = 5
- melee_damage_lower = 5
- melee_damage_upper = 10
- attack_verb_continuous = "ferociously mauls"
- attack_verb_simple = "ferociously maul"
- environment_smash = ENVIRONMENT_SMASH_NONE
- loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/xeno/bodypartless, /obj/effect/particle_effect/fluid/foam, /obj/item/soap)
- attack_reagent = /datum/reagent/peaceborg/confuse
-
-/mob/living/simple_animal/hostile/retaliate/clown/clownhulk/destroyer
- name = "The Destroyer"
- desc = "An ancient being born of arcane honking."
- icon_state = "destroyer"
- icon_living = "destroyer"
- response_disarm_continuous = "bounces off of"
- response_harm_continuous = "bounces off of"
- speak = list("HONK!!!", "The Honkmother is merciful, so I must act out her wrath.", "parce mihi ad beatus honkmother placet mihi ut peccata committere,", "DIE!!!")
- maxHealth = 400
- health = 400
- speed = 5
- harm_intent_damage = 30
- melee_damage_lower = 20
- melee_damage_upper = 40
- armour_penetration = 30
- stat_attack = HARD_CRIT
- attack_verb_continuous = "acts out divine vengeance on"
- attack_verb_simple = "act out divine vengeance on"
- obj_damage = 50
- environment_smash = ENVIRONMENT_SMASH_RWALLS
- loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/effect/particle_effect/fluid/foam, /obj/item/soap)
-
-/mob/living/simple_animal/hostile/retaliate/clown/mutant
- name = "Unknown"
- desc = "Kill it for its own sake."
- icon_state = "mutant"
- icon_living = "mutant"
- move_resist = INFINITY
- turns_per_move = 10
- response_help_continuous = "reluctantly sinks a finger into"
- response_help_simple = "reluctantly sink a finger into"
- response_disarm_continuous = "squishes into"
- response_disarm_simple = "squish into"
- response_harm_continuous = "squishes into"
- response_harm_simple = "squish into"
- speak = list("aaaaaahhhhuuhhhuhhhaaaaa", "AAAaaauuuaaAAAaauuhhh", "huuuuuh... hhhhuuuooooonnnnkk", "HuaUAAAnKKKK")
- emote_see = list("squirms", "writhes", "pulsates", "froths", "oozes")
- speak_chance = 10
- maxHealth = 130
- health = 130
- pixel_x = -16
- base_pixel_x = -16
- speed = -5
- harm_intent_damage = 10
- melee_damage_lower = 10
- melee_damage_upper = 20
- attack_verb_continuous = "awkwardly flails at"
- attack_verb_simple = "awkwardly flail at"
- loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/xeno/bodypartless, /obj/item/soap, /obj/effect/gibspawner/generic, /obj/effect/gibspawner/generic/animal, /obj/effect/gibspawner/human/bodypartless, /obj/effect/gibspawner/human)
-
-/mob/living/simple_animal/hostile/retaliate/clown/mutant/slow
- speed = 20
- move_to_delay = 60
-
-/mob/living/simple_animal/hostile/retaliate/clown/mutant/glutton
- name = "banana glutton"
- desc = "Something that was once a clown"
- icon_state = "glutton"
- icon_living = "glutton"
- speak = list("hey, buddy", "HONK!!!", "H-h-h-H-HOOOOONK!!!!", "HONKHONKHONK!!!", "HEY, BUCKO, GET BACK HERE!!!", "HOOOOOOOONK!!!")
- emote_see = list("jiggles", "wobbles")
- health = 200
- mob_size = MOB_SIZE_LARGE
- speed = 1
- melee_damage_lower = 10
- melee_damage_upper = 15
- force_threshold = 10 //lots of fat to cushion blows.
- damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 2, STAMINA = 0, OXY = 1)
- attack_verb_continuous = "slams"
- attack_verb_simple = "slam"
- loot = list(/obj/effect/gibspawner/xeno/bodypartless, /obj/effect/gibspawner/generic, /obj/effect/gibspawner/generic/animal, /obj/effect/gibspawner/human/bodypartless)
- death_sound = 'sound/misc/sadtrombone.ogg'
- ///This is the list of items we are ready to regurgitate,
- var/list/prank_pouch = list()
-
-/mob/living/simple_animal/hostile/retaliate/clown/mutant/glutton/Initialize(mapload)
- . = ..()
- var/datum/action/cooldown/regurgitate/spit = new(src)
- spit.Grant(src)
-
- add_cell_sample()
- AddComponent(/datum/component/tameable, food_types = list(/obj/item/food/cheesiehonkers, /obj/item/food/cornchips), tame_chance = 30, bonus_tame_chance = 0, after_tame = CALLBACK(src, PROC_REF(tamed)))
-
-
-/mob/living/simple_animal/hostile/retaliate/clown/mutant/glutton/attacked_by(obj/item/I, mob/living/user)
- if(!check_edible(I))
- return ..()
- eat_atom(I)
-
-/mob/living/simple_animal/hostile/retaliate/clown/mutant/glutton/AttackingTarget(atom/attacked_target)
- if(!check_edible(attacked_target))
- return ..()
- eat_atom(attacked_target)
-
-/mob/living/simple_animal/hostile/retaliate/clown/mutant/glutton/UnarmedAttack(atom/A, proximity_flag, list/modifiers)
- if(!check_edible(A))
- return ..()
- eat_atom(A)
-
-///Returns whether or not the supplied movable atom is edible.
-/mob/living/simple_animal/hostile/retaliate/clown/mutant/glutton/proc/check_edible(atom/movable/potential_food)
- if(isliving(potential_food))
- var/mob/living/living_morsel = potential_food
- if(living_morsel.mob_size > MOB_SIZE_SMALL)
- return FALSE
- else
- return TRUE
-
- if(IS_EDIBLE(potential_food))
- if(prank_pouch.len >= 8)
- to_chat(src, span_warning("Your prank pouch is filled to the brim! You don't think you can swallow any more morsels right now."))
- return FALSE
- return TRUE
-
-///This proc eats the atom, certain funny items are stored directly in the prank pouch while bananas grant a heal based on their potency and the peels are retained in the pouch.
-/mob/living/simple_animal/hostile/retaliate/clown/mutant/glutton/proc/eat_atom(atom/movable/eaten_atom)
-
- var/static/funny_items = list(
- /obj/item/food/pie/cream,
- /obj/item/food/grown/tomato,
- /obj/item/food/meatclown,
- )
-
- visible_message(span_warning("[src] eats [eaten_atom]!"), span_notice("You eat [eaten_atom]."))
- if(is_type_in_list(eaten_atom, funny_items))
- eaten_atom.forceMove(src)
- prank_pouch += eaten_atom
-
- else
- if(istype(eaten_atom, /obj/item/food/grown/banana))
- var/obj/item/food/grown/banana/banana_morsel = eaten_atom
- adjustBruteLoss(-banana_morsel.seed.potency * 0.25)
- prank_pouch += banana_morsel.generate_trash(src)
-
- qdel(eaten_atom)
-
- playsound(loc,'sound/items/eatfood.ogg', rand(30,50), TRUE)
- flick("glutton_mouth", src)
-
-/mob/living/simple_animal/hostile/retaliate/clown/mutant/glutton/proc/tamed(mob/living/tamer)
- buckle_lying = 0
- AddElement(/datum/element/ridable, /datum/component/riding/creature/glutton)
-
-/mob/living/simple_animal/hostile/retaliate/clown/mutant/glutton/add_cell_sample()
- AddElement(/datum/element/swabable, CELL_LINE_TABLE_GLUTTON, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
-
-/mob/living/simple_animal/hostile/retaliate/clown/mutant/glutton/Exited(atom/movable/gone, direction)
- . = ..()
- prank_pouch -= gone
-
-///This ability will let you fire one random item from your pouch,
-/datum/action/cooldown/regurgitate
- name = "Regurgitate"
- desc = "Regurgitates a single item from the depths of your pouch."
- background_icon_state = "bg_changeling"
- overlay_icon_state = "bg_changeling_border"
- button_icon = 'icons/mob/actions/actions_animal.dmi'
- button_icon_state = "regurgitate"
- check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_INCAPACITATED
- melee_cooldown_time = 0 SECONDS
- click_to_activate = TRUE
-
-/datum/action/cooldown/regurgitate/set_click_ability(mob/on_who)
- . = ..()
- if(!.)
- return
-
- to_chat(on_who, span_notice("Your throat muscles tense up. Left-click to regurgitate a funny morsel!"))
- on_who.icon_state = "glutton_tongue"
- on_who.update_appearance(UPDATE_ICON)
-
-/datum/action/cooldown/regurgitate/unset_click_ability(mob/on_who, refund_cooldown = TRUE)
- . = ..()
- if(!.)
- return
-
- if(refund_cooldown)
- to_chat(on_who, span_notice("Your throat muscles relax."))
- on_who.icon_state = initial(on_who.icon_state)
- on_who.update_appearance(UPDATE_ICON)
-
-/datum/action/cooldown/regurgitate/IsAvailable(feedback = FALSE)
- . = ..()
- if(!.)
- return FALSE
-
- // Hardcoded to only work with gluttons. Come back next year
- return istype(owner, /mob/living/simple_animal/hostile/retaliate/clown/mutant/glutton)
-
-/datum/action/cooldown/regurgitate/Activate(atom/spit_at)
- StartCooldown(cooldown_time / 4)
-
- var/mob/living/simple_animal/hostile/retaliate/clown/mutant/glutton/pouch_owner = owner
- if(!length(pouch_owner.prank_pouch))
- pouch_owner.icon_state = initial(pouch_owner.icon_state)
- to_chat(pouch_owner, span_notice("Your prank pouch is empty."))
- return TRUE
-
- var/obj/item/projected_morsel = pick(pouch_owner.prank_pouch)
- projected_morsel.forceMove(pouch_owner.loc)
- projected_morsel.throw_at(spit_at, 8, 2, pouch_owner)
- flick("glutton_mouth", pouch_owner)
- playsound(pouch_owner, 'sound/misc/soggy.ogg', 75)
-
- StartCooldown()
- return TRUE
diff --git a/code/modules/mob/living/basic/clown/clown_ai.dm b/code/modules/mob/living/basic/clown/clown_ai.dm
new file mode 100644
index 00000000000..b2e6418dde7
--- /dev/null
+++ b/code/modules/mob/living/basic/clown/clown_ai.dm
@@ -0,0 +1,19 @@
+/datum/ai_controller/basic_controller/clown
+ blackboard = list(
+ BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
+ BB_BASIC_MOB_SPEAK_LINES = null,
+ )
+
+ 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/basic_melee_attack_subtree,
+ /datum/ai_planning_subtree/random_speech/blackboard,
+ )
+
+/datum/ai_controller/basic_controller/clown/murder
+ blackboard = list(
+ BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/attack_until_dead,
+ BB_BASIC_MOB_SPEAK_LINES = null,
+ )
diff --git a/code/modules/mob/living/basic/farm_animals/bee/_bee.dm b/code/modules/mob/living/basic/farm_animals/bee/_bee.dm
index a175deacb93..655d08aa864 100644
--- a/code/modules/mob/living/basic/farm_animals/bee/_bee.dm
+++ b/code/modules/mob/living/basic/farm_animals/bee/_bee.dm
@@ -258,6 +258,9 @@
var/datum/reagent/chemical = needle.reagents.get_master_reagent()
if(isnull(chemical))
return
+ if(!(chemical.chemical_flags & REAGENT_CAN_BE_SYNTHESIZED))
+ to_chat(user, span_warning("[chemical.name] cannot be inserted into a bee's genome!"))
+ return
if(chemical.type == queen.beegent?.type)
to_chat(user, span_warning("[queen] already has this chemical!"))
return
diff --git a/code/modules/mob/living/basic/farm_animals/bee/bee_ai_behavior.dm b/code/modules/mob/living/basic/farm_animals/bee/bee_ai_behavior.dm
index 137de67dfc6..017eac3cb51 100644
--- a/code/modules/mob/living/basic/farm_animals/bee/bee_ai_behavior.dm
+++ b/code/modules/mob/living/basic/farm_animals/bee/bee_ai_behavior.dm
@@ -1,3 +1,5 @@
+/// if we have a hive, this will be our aggro distance
+#define AGGRO_DISTANCE_FROM_HIVE 2
/datum/ai_behavior/hunt_target/pollinate
always_reset_target = TRUE
@@ -89,5 +91,20 @@
. = ..()
if(!.)
return FALSE
+
var/mob/living/mob_target = target
+
+ if(mob_target.mob_biotypes & MOB_PLANT)
+ return FALSE
+
+ var/datum/ai_controller/basic_controller/bee_ai = owner.ai_controller
+ if(isnull(bee_ai))
+ return FALSE
+
+ var/atom/bee_hive = bee_ai.blackboard[BB_CURRENT_HOME]
+ if(bee_hive && get_dist(target, bee_hive) > AGGRO_DISTANCE_FROM_HIVE)
+ return FALSE
+
return !(mob_target.bee_friendly())
+
+#undef AGGRO_DISTANCE_FROM_HIVE
diff --git a/code/modules/mob/living/basic/farm_animals/chicken/chicken.dm b/code/modules/mob/living/basic/farm_animals/chicken/chicken.dm
index b3eb18e0cd4..89f5174f15e 100644
--- a/code/modules/mob/living/basic/farm_animals/chicken/chicken.dm
+++ b/code/modules/mob/living/basic/farm_animals/chicken/chicken.dm
@@ -49,7 +49,7 @@ GLOBAL_VAR_INIT(chicken_count, 0)
AddElement(/datum/element/animal_variety, "chicken", pick("brown", "black", "white"), modify_pixels = TRUE)
AddComponent(\
/datum/component/egg_layer,\
- /obj/item/food/egg,\
+ /obj/item/food/egg/organic,\
list(/obj/item/food/grown/wheat),\
feed_messages = list("She clucks contently."),\
lay_messages = EGG_LAYING_MESSAGES,\
diff --git a/code/modules/mob/living/basic/farm_animals/cow/_cow.dm b/code/modules/mob/living/basic/farm_animals/cow/_cow.dm
index 949a3cd0c34..8777cf5a4d1 100644
--- a/code/modules/mob/living/basic/farm_animals/cow/_cow.dm
+++ b/code/modules/mob/living/basic/farm_animals/cow/_cow.dm
@@ -11,7 +11,7 @@
mob_biotypes = MOB_ORGANIC | MOB_BEAST
speak_emote = list("moos","moos hauntingly")
speed = 1.1
- butcher_results = list(/obj/item/food/meat/slab = 6)
+ butcher_results = list(/obj/item/food/meat/slab/grassfed = 6)
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
diff --git a/code/modules/mob/living/basic/farm_animals/deer.dm b/code/modules/mob/living/basic/farm_animals/deer.dm
index a656426e3ba..445ad831e59 100644
--- a/code/modules/mob/living/basic/farm_animals/deer.dm
+++ b/code/modules/mob/living/basic/farm_animals/deer.dm
@@ -7,7 +7,7 @@
gender = FEMALE
mob_biotypes = MOB_ORGANIC|MOB_BEAST
speak_emote = list("grunts", "grunts lowly")
- butcher_results = list(/obj/item/food/meat/slab = 3)
+ butcher_results = list(/obj/item/food/meat/slab/grassfed = 3)
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently nudges"
diff --git a/code/modules/mob/living/basic/farm_animals/pony.dm b/code/modules/mob/living/basic/farm_animals/pony.dm
index 434caa5ef51..4bc09391cb7 100644
--- a/code/modules/mob/living/basic/farm_animals/pony.dm
+++ b/code/modules/mob/living/basic/farm_animals/pony.dm
@@ -62,7 +62,7 @@
if (prob(33))
whinny_angrily()
-/mob/living/basic/pony/melee_attack(atom/target, list/modifiers)
+/mob/living/basic/pony/melee_attack(atom/target, list/modifiers, ignore_cooldown = FALSE)
. = ..()
if (!.)
diff --git a/code/modules/mob/living/basic/farm_animals/rabbit.dm b/code/modules/mob/living/basic/farm_animals/rabbit.dm
index fd95b7ef83b..92d40e0228e 100644
--- a/code/modules/mob/living/basic/farm_animals/rabbit.dm
+++ b/code/modules/mob/living/basic/farm_animals/rabbit.dm
@@ -32,7 +32,7 @@
response_harm_simple = "kick"
attack_verb_continuous = "kicks"
attack_verb_simple = "kick"
- butcher_results = list(/obj/item/food/meat/slab = 1)
+ butcher_results = list(/obj/item/food/meat/slab/grassfed = 1)
unsuitable_cold_damage = 0.5 // Cold damage is 0.5 here to account for low health on the rabbit.
unsuitable_heat_damage = 0.5 // Heat damage is 0.5 here to account for low health on the rabbit.
ai_controller = /datum/ai_controller/basic_controller/rabbit
diff --git a/code/modules/mob/living/basic/farm_animals/sheep.dm b/code/modules/mob/living/basic/farm_animals/sheep.dm
index 4102bd83fdf..691f1db14e3 100644
--- a/code/modules/mob/living/basic/farm_animals/sheep.dm
+++ b/code/modules/mob/living/basic/farm_animals/sheep.dm
@@ -9,7 +9,7 @@
mob_biotypes = MOB_ORGANIC | MOB_BEAST
speak_emote = list("baas","bleats")
speed = 1.1
- butcher_results = list(/obj/item/food/meat/slab = 3)
+ butcher_results = list(/obj/item/food/meat/slab/grassfed = 3)
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
diff --git a/code/modules/mob/living/basic/heretic/star_gazer.dm b/code/modules/mob/living/basic/heretic/star_gazer.dm
index e4450aa5dbf..b739da0831a 100644
--- a/code/modules/mob/living/basic/heretic/star_gazer.dm
+++ b/code/modules/mob/living/basic/heretic/star_gazer.dm
@@ -6,7 +6,7 @@
icon_living = "star_gazer"
pixel_x = -32
base_pixel_x = -32
- mob_biotypes = MOB_HUMANOID | MOB_EPIC
+ mob_biotypes = MOB_HUMANOID | MOB_SPECIAL
response_help_continuous = "passes through"
response_help_simple = "pass through"
speed = -0.2
@@ -22,6 +22,7 @@
attack_verb_simple = "ravage"
attack_vis_effect = ATTACK_EFFECT_SLASH
attack_sound = 'sound/weapons/bladeslice.ogg'
+ melee_attack_cooldown = 0.6 SECONDS
speak_emote = list("growls")
damage_coeff = list(BRUTE = 1, BURN = 0.5, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
death_sound = 'sound/magic/cosmic_expansion.ogg'
@@ -30,6 +31,7 @@
move_force = MOVE_FORCE_OVERPOWERING
move_resist = MOVE_FORCE_OVERPOWERING
pull_force = MOVE_FORCE_OVERPOWERING
+ can_buckle_to = FALSE
mob_size = MOB_SIZE_HUGE
layer = LARGE_MOB_LAYER
plane = GAME_PLANE_UPPER_FOV_HIDDEN
@@ -56,6 +58,24 @@
ADD_TRAIT(src, TRAIT_NO_FLOATING_ANIM, INNATE_TRAIT)
set_light(4, l_color = "#dcaa5b")
+// Star gazer attacks everything around itself applies a spooky mark
+/mob/living/basic/heretic_summon/star_gazer/melee_attack(mob/living/target, list/modifiers, ignore_cooldown)
+ . = ..()
+ if (!. || !isliving(target))
+ return
+
+ target.apply_status_effect(/datum/status_effect/star_mark)
+ target.apply_damage(damage = 5, damagetype = CLONE)
+ var/datum/targetting_datum/target_confirmer = ai_controller.blackboard[BB_TARGETTING_DATUM]
+ for(var/mob/living/nearby_mob in range(1, src))
+ if(target == nearby_mob || !target_confirmer?.can_attack(src, nearby_mob))
+ continue
+ nearby_mob.apply_status_effect(/datum/status_effect/star_mark)
+ nearby_mob.apply_damage(10)
+ to_chat(nearby_mob, span_userdanger("\The [src] [attack_verb_continuous] you!"))
+ do_attack_animation(nearby_mob, ATTACK_EFFECT_SLASH)
+ log_combat(src, nearby_mob, "slashed")
+
/datum/ai_controller/basic_controller/star_gazer
blackboard = list(
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/star_gazer(),
@@ -69,39 +89,12 @@
/datum/ai_planning_subtree/pet_planning,
/datum/ai_planning_subtree/simple_find_target,
/datum/ai_planning_subtree/attack_obstacle_in_path/star_gazer,
- /datum/ai_planning_subtree/basic_melee_attack_subtree/star_gazer,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
)
/datum/targetting_datum/basic/star_gazer
stat_attack = HARD_CRIT
-/datum/ai_planning_subtree/basic_melee_attack_subtree/star_gazer
- melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/star_gazer
-
-/datum/ai_behavior/basic_melee_attack/star_gazer
- action_cooldown = 0.6 SECONDS
-
-/datum/ai_behavior/basic_melee_attack/star_gazer/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
- . = ..()
- var/atom/target = controller.blackboard[target_key]
- var/mob/living/living_pawn = controller.pawn
-
- if(!isliving(target))
- return
- var/mob/living/living_target = target
- living_target.apply_status_effect(/datum/status_effect/star_mark)
- living_target.apply_damage_type(damage = 5, damagetype = CLONE)
- if(living_target.pulledby != living_pawn)
- if(living_pawn.Adjacent(living_target) && isturf(living_target.loc) && living_target.stat == SOFT_CRIT)
- living_target.grabbedby(living_pawn)
- for(var/mob/living/nearby_mob in range(1, living_pawn))
- if(nearby_mob.stat == DEAD || living_target == nearby_mob || faction_check(nearby_mob.faction, list(FACTION_HERETIC)))
- continue
- nearby_mob.apply_status_effect(/datum/status_effect/star_mark)
- nearby_mob.adjustBruteLoss(10)
- living_pawn.do_attack_animation(nearby_mob, ATTACK_EFFECT_SLASH)
- log_combat(living_pawn, nearby_mob, "slashed")
-
/datum/ai_planning_subtree/attack_obstacle_in_path/star_gazer
attack_behaviour = /datum/ai_behavior/attack_obstructions/star_gazer
@@ -118,4 +111,4 @@
command_feedback = "stares!"
pointed_reaction = "stares intensely!"
refuse_reaction = "..."
- attack_behaviour = /datum/ai_behavior/basic_melee_attack/star_gazer
+ attack_behaviour = /datum/ai_behavior/basic_melee_attack
diff --git a/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp.dm b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp.dm
index 465d724944b..292766be07b 100644
--- a/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp.dm
+++ b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp.dm
@@ -69,6 +69,7 @@
INVOKE_ASYNC(src, PROC_REF(cannibalize_victim), victim)
return COMPONENT_HOSTILE_NO_ATTACK
+/// Carve a stone into a beautiful self-portrait
/mob/living/basic/mining/ice_whelp/proc/create_sculpture(atom/target)
balloon_alert(src, "sculpting...")
if(!do_after(src, 5 SECONDS, target = target))
@@ -80,7 +81,9 @@
dragon_statue.set_anchored(TRUE)
qdel(target)
+/// Gib and consume our fellow ice drakes
/mob/living/basic/mining/ice_whelp/proc/cannibalize_victim(mob/living/target)
+ start_pulling(target)
balloon_alert(src, "devouring...")
if(!do_after(src, 5 SECONDS, target))
return
diff --git a/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm
index 08c5fda3fd8..5951bd6b7fe 100644
--- a/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm
+++ b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm
@@ -58,7 +58,6 @@
finish_action(controller, FALSE)
return
- living_pawn.start_pulling(target)
living_pawn.melee_attack(target)
finish_action(controller, TRUE)
@@ -70,14 +69,10 @@
/datum/ai_planning_subtree/sculpt_statues
/datum/ai_planning_subtree/sculpt_statues/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
- var/obj/target = controller.blackboard[BB_TARGET_ROCK]
-
- if(QDELETED(target))
- controller.queue_behavior(/datum/ai_behavior/find_and_set, BB_TARGET_ROCK, /obj/structure/flora/rock/icy)
- return
-
- controller.queue_behavior(/datum/ai_behavior/sculpt_statue, BB_TARGET_ROCK)
- return SUBTREE_RETURN_FINISH_PLANNING
+ if(controller.blackboard_key_exists(BB_TARGET_ROCK))
+ controller.queue_behavior(/datum/ai_behavior/sculpt_statue, BB_TARGET_ROCK)
+ return SUBTREE_RETURN_FINISH_PLANNING
+ controller.queue_behavior(/datum/ai_behavior/find_and_set, BB_TARGET_ROCK, /obj/structure/flora/rock/icy)
/datum/ai_behavior/sculpt_statue
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
@@ -136,16 +131,13 @@
/datum/ai_planning_subtree/burn_trees/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
var/datum/action/cooldown/using_action = controller.blackboard[BB_WHELP_STRAIGHTLINE_FIRE]
- if (!using_action.IsAvailable())
+ if (!using_action?.IsAvailable())
return
- var/obj/structure/target = controller.blackboard[BB_TARGET_TREE]
- if(QDELETED(target))
- controller.queue_behavior(/datum/ai_behavior/set_target_tree, BB_TARGET_TREE)
- return
-
- controller.queue_behavior(/datum/ai_behavior/targeted_mob_ability/and_clear_target/burn_trees, BB_WHELP_STRAIGHTLINE_FIRE, BB_TARGET_TREE)
- return SUBTREE_RETURN_FINISH_PLANNING
+ if(controller.blackboard_key_exists(BB_TARGET_TREE))
+ controller.queue_behavior(/datum/ai_behavior/targeted_mob_ability/and_clear_target/burn_trees, BB_WHELP_STRAIGHTLINE_FIRE, BB_TARGET_TREE)
+ return SUBTREE_RETURN_FINISH_PLANNING
+ controller.queue_behavior(/datum/ai_behavior/set_target_tree, BB_TARGET_TREE)
/datum/ai_behavior/set_target_tree
diff --git a/code/modules/mob/living/basic/jungle/seedling/seedling.dm b/code/modules/mob/living/basic/jungle/seedling/seedling.dm
new file mode 100644
index 00000000000..998f693d6da
--- /dev/null
+++ b/code/modules/mob/living/basic/jungle/seedling/seedling.dm
@@ -0,0 +1,348 @@
+#define SEEDLING_STATE_NEUTRAL 0
+#define SEEDLING_STATE_WARMUP 1
+#define SEEDLING_STATE_ACTIVE 2
+
+/**
+ * A mobile plant with a rapid ranged attack.
+ * It can pick up watering cans and look after plants.
+ */
+/mob/living/basic/seedling
+ name = "seedling"
+ desc = "This oversized, predatory flower conceals what can only be described as an organic energy cannon."
+ icon = 'icons/mob/simple/jungle/seedling.dmi'
+ icon_state = "seedling"
+ icon_living = "seedling"
+ icon_dead = "seedling_dead"
+ habitable_atmos = list("min_oxy" = 2, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
+ minimum_survivable_temperature = 0
+ maximum_survivable_temperature = 450
+ mob_biotypes = MOB_ORGANIC | MOB_PLANT
+ maxHealth = 100
+ health = 100
+ pixel_y = -14
+ base_pixel_y = -14
+ pixel_x = -14
+ base_pixel_x = -14
+ response_harm_continuous = "strikes"
+ response_harm_simple = "strike"
+ melee_damage_lower = 30
+ melee_damage_upper = 30
+ lighting_cutoff_green = 20
+ lighting_cutoff_blue = 25
+ mob_size = MOB_SIZE_LARGE
+ attack_sound = 'sound/weapons/bladeslice.ogg'
+ attack_vis_effect = ATTACK_EFFECT_SLASH
+ ai_controller = /datum/ai_controller/basic_controller/seedling
+ ///the state of combat we are in
+ var/combatant_state = SEEDLING_STATE_NEUTRAL
+ ///the colors our petals can have
+ var/static/list/possible_colors = list(COLOR_RED, COLOR_YELLOW, COLOR_OLIVE, COLOR_CYAN)
+ ///appearance when we are in our normal state
+ var/mutable_appearance/petal_neutral
+ ///appearance when we are in our warmup state
+ var/mutable_appearance/petal_warmup
+ ///appearance when we are in the firing state
+ var/mutable_appearance/petal_active
+ ///appearance when we are dead
+ var/mutable_appearance/petal_dead
+ ///the bucket we carry
+ var/obj/item/reagent_containers/cup/held_can
+ ///commands we follow
+ var/list/seedling_commands = list(
+ /datum/pet_command/idle,
+ /datum/pet_command/free,
+ /datum/pet_command/follow,
+ )
+
+/mob/living/basic/seedling/Initialize(mapload)
+ . = ..()
+ var/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/seedling/seed_attack = new(src)
+ seed_attack.Grant(src)
+ ai_controller.set_blackboard_key(BB_RAPIDSEEDS_ABILITY, seed_attack)
+ var/datum/action/cooldown/mob_cooldown/solarbeam/beam_attack = new(src)
+ beam_attack.Grant(src)
+ ai_controller.set_blackboard_key(BB_SOLARBEAM_ABILITY, beam_attack)
+
+ var/petal_color = pick(possible_colors)
+
+ petal_neutral = mutable_appearance(icon, "[icon_state]_overlay")
+ petal_neutral.color = petal_color
+
+ petal_warmup = mutable_appearance(icon, "[icon_state]_charging_overlay")
+ petal_warmup.color = petal_color
+
+ petal_active = mutable_appearance(icon, "[icon_state]_fire_overlay")
+ petal_active.color = petal_color
+
+ petal_dead = mutable_appearance(icon, "[icon_state]_dead_overlay")
+ petal_dead.color = petal_color
+
+ AddElement(/datum/element/wall_smasher)
+ AddComponent(/datum/component/obeys_commands, seedling_commands)
+ RegisterSignal(src, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(pre_attack))
+ RegisterSignal(src, COMSIG_KB_MOB_DROPITEM_DOWN, PROC_REF(drop_can))
+ update_appearance()
+
+/mob/living/basic/seedling/proc/pre_attack(mob/living/puncher, atom/target)
+ SIGNAL_HANDLER
+
+ if(istype(target, /obj/machinery/hydroponics))
+ treat_hydro_tray(target)
+ return COMPONENT_HOSTILE_NO_ATTACK
+
+ if(isnull(held_can))
+ return
+
+ if(istype(target, /obj/structure/sink) || istype(target, /obj/structure/reagent_dispensers))
+ INVOKE_ASYNC(held_can, TYPE_PROC_REF(/obj/item, melee_attack_chain), src, target)
+ return COMPONENT_HOSTILE_NO_ATTACK
+
+
+///seedlings can water trays, remove weeds, or remove dead plants
+/mob/living/basic/seedling/proc/treat_hydro_tray(obj/machinery/hydroponics/hydro)
+
+ if(hydro.plant_status == HYDROTRAY_PLANT_DEAD)
+ balloon_alert(src, "dead plant removed")
+ hydro.set_seed(null)
+ return
+
+ if(hydro.weedlevel > 0)
+ balloon_alert(src, "weeds uprooted")
+ hydro.set_weedlevel(0)
+ return
+
+ var/list/can_reagents = held_can?.reagents.reagent_list
+
+ if(!length(can_reagents))
+ return
+
+ if((locate(/datum/reagent/water) in can_reagents) && (hydro.waterlevel < hydro.maxwater))
+ INVOKE_ASYNC(held_can, TYPE_PROC_REF(/obj/item, melee_attack_chain), src, hydro)
+ return
+
+/mob/living/basic/seedling/UnarmedAttack(atom/attack_target, proximity_flag, list/modifiers)
+ . = ..()
+
+ if(!. || !proximity_flag || held_can)
+ return
+
+ if(!istype(attack_target, /obj/item/reagent_containers/cup/watering_can))
+ return
+
+ var/obj/item/can_target = attack_target
+ can_target.forceMove(src)
+
+/mob/living/basic/seedling/proc/change_combatant_state(state)
+ combatant_state = state
+ update_appearance()
+
+/mob/living/basic/seedling/attackby(obj/item/can, mob/living/carbon/human/user, list/modifiers)
+ if(istype(can, /obj/item/reagent_containers/cup/watering_can) && isnull(held_can))
+ can.forceMove(src)
+ return
+
+ return ..()
+
+/mob/living/basic/seedling/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs)
+ if(istype(arrived, /obj/item/reagent_containers/cup/watering_can))
+ held_can = arrived
+ update_appearance()
+
+ return ..()
+
+/mob/living/basic/seedling/update_overlays()
+ . = ..()
+ if(stat == DEAD)
+ . += petal_dead
+ return
+
+ switch(combatant_state)
+ if(SEEDLING_STATE_NEUTRAL)
+ . += petal_neutral
+ if(held_can)
+ . += mutable_appearance(icon, "seedling_can_overlay")
+ if(SEEDLING_STATE_WARMUP)
+ . += petal_warmup
+ if(SEEDLING_STATE_ACTIVE)
+ . += petal_active
+
+/mob/living/basic/seedling/update_icon_state()
+ . = ..()
+ if(stat == DEAD)
+ return
+ switch(combatant_state)
+ if(SEEDLING_STATE_NEUTRAL)
+ icon_state = "seedling"
+ if(SEEDLING_STATE_WARMUP)
+ icon_state = "seedling_charging"
+ if(SEEDLING_STATE_ACTIVE)
+ icon_state = "seedling_fire"
+
+/mob/living/basic/seedling/proc/drop_can(mob/living/user)
+ SIGNAL_HANDLER
+
+ if(isnull(held_can))
+ return
+ dropItemToGround(held_can)
+ return COMSIG_KB_ACTIVATED
+
+/mob/living/basic/seedling/Exited(atom/movable/gone, direction)
+ . = ..()
+ if(gone != held_can)
+ return
+ held_can = null
+ update_appearance()
+
+/mob/living/basic/seedling/death(gibbed)
+ . = ..()
+ if(isnull(held_can))
+ return
+ held_can.forceMove(drop_location())
+
+/mob/living/basic/seedling/Destroy()
+ QDEL_NULL(held_can)
+ return ..()
+
+/mob/living/basic/seedling/meanie
+ maxHealth = 400
+ health = 400
+ faction = list(FACTION_JUNGLE)
+ ai_controller = /datum/ai_controller/basic_controller/seedling/meanie
+ seedling_commands = list(
+ /datum/pet_command/idle,
+ /datum/pet_command/free,
+ /datum/pet_command/follow,
+ /datum/pet_command/point_targetting/attack,
+ /datum/pet_command/point_targetting/use_ability/solarbeam,
+ /datum/pet_command/point_targetting/use_ability/rapidseeds,
+ )
+
+//abilities
+/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/seedling
+ name = "Solar Energy"
+ button_icon = 'icons/obj/weapons/guns/projectiles.dmi'
+ button_icon_state = "seedling"
+ desc = "Fire small beams of solar energy."
+ cooldown_time = 10 SECONDS
+ projectile_type = /obj/projectile/seedling
+ default_projectile_spread = 10
+ shot_count = 10
+ shot_delay = 0.2 SECONDS
+ melee_cooldown_time = 0 SECONDS
+ shared_cooldown = NONE
+ ///how long we must charge up before firing off
+ var/charge_up_timer = 3 SECONDS
+ ///is the owner of this ability a seedling?
+ var/is_seedling = FALSE
+
+/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/seedling/Grant(mob/grant_to)
+ . = ..()
+ if(isnull(owner))
+ return
+ is_seedling = istype(owner, /mob/living/basic/seedling)
+
+/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/seedling/IsAvailable(feedback)
+ . = ..()
+ if(!.)
+ return FALSE
+ if(!is_seedling)
+ return TRUE
+ var/mob/living/basic/seedling/seed_owner = owner
+ if(seed_owner.combatant_state != SEEDLING_STATE_NEUTRAL)
+ if(feedback)
+ seed_owner.balloon_alert(seed_owner, "charging!")
+ return FALSE
+ return TRUE
+
+/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/seedling/Activate(atom/target)
+ if(is_seedling)
+ var/mob/living/basic/seedling/seed_owner = owner
+ seed_owner.change_combatant_state(state = SEEDLING_STATE_WARMUP)
+ addtimer(CALLBACK(src, PROC_REF(attack_sequence), owner, target), charge_up_timer)
+ StartCooldown()
+ return TRUE
+
+/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/seedling/attack_sequence(mob/living/firer, atom/target)
+ if(is_seedling)
+ var/mob/living/basic/seedling/seed_owner = owner
+ seed_owner.change_combatant_state(state = SEEDLING_STATE_ACTIVE)
+ addtimer(CALLBACK(seed_owner, TYPE_PROC_REF(/mob/living/basic/seedling, change_combatant_state), SEEDLING_STATE_NEUTRAL), 4 SECONDS)
+
+ return ..()
+
+
+/datum/action/cooldown/mob_cooldown/solarbeam
+ name = "Solar Beam"
+ button_icon = 'icons/effects/beam.dmi'
+ button_icon_state = "solar_beam"
+ desc = "Concentrate the power of the sun onto your target!"
+ cooldown_time = 30 SECONDS
+ shared_cooldown = NONE
+ ///how long will it take for us to charge up the beam
+ var/beam_charge_up = 3 SECONDS
+ ///is the owner of this ability a seedling?
+ var/is_seedling = FALSE
+
+/datum/action/cooldown/mob_cooldown/solarbeam/Grant(mob/grant_to)
+ . = ..()
+ if(isnull(owner))
+ return
+ is_seedling = istype(owner, /mob/living/basic/seedling)
+
+/datum/action/cooldown/mob_cooldown/solarbeam/IsAvailable(feedback)
+ . = ..()
+ if(!.)
+ return FALSE
+ if(!is_seedling)
+ return TRUE
+ var/mob/living/basic/seedling/seed_owner = owner
+ if(seed_owner.combatant_state != SEEDLING_STATE_NEUTRAL)
+ if(feedback)
+ seed_owner.balloon_alert(seed_owner, "charging!")
+ return FALSE
+ return TRUE
+
+/datum/action/cooldown/mob_cooldown/solarbeam/Activate(atom/target)
+ if(is_seedling)
+ var/mob/living/basic/seedling/seed_owner = owner
+ seed_owner.change_combatant_state(state = SEEDLING_STATE_WARMUP)
+
+ var/turf/target_turf = get_turf(target)
+ playsound(owner, 'sound/effects/seedling_chargeup.ogg', 100, FALSE)
+
+ var/obj/effect/temp_visual/solarbeam_killsat/owner_beam = new(get_turf(owner))
+ animate(owner_beam, transform = matrix().Scale(1, 32), alpha = 255, time = beam_charge_up)
+
+ var/obj/effect/temp_visual/solarbeam_killsat/target_beam = new(target_turf)
+ animate(target_beam, transform = matrix().Scale(2, 1), alpha = 255, time = beam_charge_up)
+
+ addtimer(CALLBACK(src, PROC_REF(launch_beam), owner, target_turf), beam_charge_up)
+ StartCooldown()
+ return TRUE
+
+///the solarbeam will damage people, otherwise it will heal plants
+/datum/action/cooldown/mob_cooldown/solarbeam/proc/launch_beam(mob/living/firer, turf/target_turf)
+ for(var/atom/target_atom as anything in target_turf)
+
+ if(istype(target_atom, /obj/machinery/hydroponics))
+ var/obj/machinery/hydroponics/hydro = target_atom
+ hydro.adjust_plant_health(10)
+ new /obj/effect/temp_visual/heal(target_turf, COLOR_HEALING_CYAN)
+
+ if(!isliving(target_atom))
+ continue
+
+ var/mob/living/living_target = target_atom
+ living_target.adjust_fire_stacks(0.2)
+ living_target.ignite_mob()
+ living_target.adjustFireLoss(30)
+
+ playsound(target_turf, 'sound/magic/lightningbolt.ogg', 50, TRUE)
+ if(!is_seedling)
+ return
+ var/mob/living/basic/seedling/seed_firer = firer
+ seed_firer.change_combatant_state(state = SEEDLING_STATE_NEUTRAL)
+
+#undef SEEDLING_STATE_NEUTRAL
+#undef SEEDLING_STATE_WARMUP
+#undef SEEDLING_STATE_ACTIVE
diff --git a/code/modules/mob/living/basic/jungle/seedling/seedling_ai.dm b/code/modules/mob/living/basic/jungle/seedling/seedling_ai.dm
new file mode 100644
index 00000000000..4d67a71d4d4
--- /dev/null
+++ b/code/modules/mob/living/basic/jungle/seedling/seedling_ai.dm
@@ -0,0 +1,178 @@
+/datum/ai_controller/basic_controller/seedling
+ blackboard = list(
+ BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
+ BB_PET_TARGETTING_DATUM = new /datum/targetting_datum/not_friends,
+ BB_WEEDLEVEL_THRESHOLD = 3,
+ BB_WATERLEVEL_THRESHOLD = 90,
+ )
+
+ ai_movement = /datum/ai_movement/basic_avoidance
+ idle_behavior = /datum/idle_behavior/idle_random_walk
+ planning_subtrees = list(
+ /datum/ai_planning_subtree/pet_planning,
+ /datum/ai_planning_subtree/find_and_hunt_target/watering_can,
+ /datum/ai_planning_subtree/find_and_hunt_target/fill_watercan,
+ /datum/ai_planning_subtree/find_and_hunt_target/treat_hydroplants,
+ /datum/ai_planning_subtree/find_and_hunt_target/beamable_hydroplants,
+ )
+
+/datum/ai_planning_subtree/find_and_hunt_target/watering_can
+ target_key = BB_WATERCAN_TARGET
+ finding_behavior = /datum/ai_behavior/find_hunt_target
+ hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target
+ hunt_targets = list(/obj/item/reagent_containers/cup/watering_can)
+ hunt_range = 7
+
+/datum/ai_planning_subtree/find_and_hunt_target/watering_can/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
+ var/mob/living/living_pawn = controller.pawn
+ if(locate(/obj/item/reagent_containers/cup/watering_can) in living_pawn) //we already have what we came for!
+ return
+ return ..()
+
+/datum/ai_planning_subtree/find_and_hunt_target/treat_hydroplants
+ target_key = BB_HYDROPLANT_TARGET
+ finding_behavior = /datum/ai_behavior/find_and_set/treatable_hydro
+ hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/treat_hydroplant
+ hunt_targets = list(/obj/machinery/hydroponics)
+ hunt_range = 7
+
+/datum/ai_behavior/find_and_set/treatable_hydro
+
+/datum/ai_behavior/find_and_set/treatable_hydro/search_tactic(datum/ai_controller/controller, locate_path, search_range)
+ var/list/possible_trays = list()
+ var/mob/living/living_pawn = controller.pawn
+ var/waterlevel_threshold = controller.blackboard[BB_WATERLEVEL_THRESHOLD]
+ var/weedlevel_threshold = controller.blackboard[BB_WEEDLEVEL_THRESHOLD]
+ var/watering_can = locate(/obj/item/reagent_containers/cup/watering_can) in living_pawn
+
+ for(var/obj/machinery/hydroponics/hydro in oview(search_range, controller.pawn))
+ if(isnull(hydro.myseed))
+ continue
+ if(hydro.waterlevel < waterlevel_threshold && watering_can)
+ possible_trays += hydro
+ continue
+ if(hydro.weedlevel > weedlevel_threshold || hydro.plant_status == HYDROTRAY_PLANT_DEAD)
+ possible_trays += hydro
+ continue
+
+ if(possible_trays.len)
+ return pick(possible_trays)
+
+/datum/ai_behavior/hunt_target/unarmed_attack_target/treat_hydroplant
+ hunt_cooldown = 2 SECONDS
+ always_reset_target = TRUE
+
+/datum/ai_behavior/hunt_target/unarmed_attack_target/treat_hydroplant/target_caught(mob/living/living_pawn, obj/machinery/hydroponics/hydro_target)
+ if(QDELETED(hydro_target) || QDELETED(hydro_target.myseed))
+ return
+
+ if(hydro_target.plant_status == HYDROTRAY_PLANT_DEAD)
+ living_pawn.manual_emote("weeps...") //weep over the dead plants
+ return ..()
+
+
+/datum/ai_planning_subtree/find_and_hunt_target/beamable_hydroplants
+ target_key = BB_BEAMABLE_HYDROPLANT_TARGET
+ finding_behavior = /datum/ai_behavior/find_and_set/beamable_hydroplants
+ hunting_behavior = /datum/ai_behavior/hunt_target/use_ability_on_target/solarbeam
+ hunt_targets = list(/obj/machinery/hydroponics)
+ hunt_range = 7
+
+/datum/ai_planning_subtree/find_and_hunt_target/beamable_hydroplants/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
+ var/datum/action/cooldown/solar_ability = controller.blackboard[BB_SOLARBEAM_ABILITY]
+ if(QDELETED(solar_ability) || !solar_ability.IsAvailable())
+ return
+ return ..()
+
+/datum/ai_behavior/hunt_target/use_ability_on_target/solarbeam
+ behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
+ required_distance = 2
+ action_cooldown = 1 MINUTES
+ ability_key = BB_SOLARBEAM_ABILITY
+
+/datum/ai_behavior/hunt_target/use_ability_on_target/solarbeam/setup(datum/ai_controller/controller, target_key, ability_key)
+ . = ..()
+ var/obj/target = controller.blackboard[target_key]
+ if(QDELETED(target))
+ return FALSE
+ set_movement_target(controller, target)
+
+/datum/ai_behavior/find_and_set/beamable_hydroplants/search_tactic(datum/ai_controller/controller, locate_path, search_range)
+ var/list/possible_trays = list()
+
+ for(var/obj/machinery/hydroponics/hydro in oview(search_range, controller.pawn))
+ if(isnull(hydro.myseed))
+ continue
+ if(hydro.plant_health < hydro.myseed.endurance)
+ possible_trays += hydro
+
+ if(possible_trays.len)
+ return pick(possible_trays)
+
+/datum/ai_planning_subtree/find_and_hunt_target/fill_watercan
+ target_key = BB_LOW_PRIORITY_HUNTING_TARGET
+ finding_behavior = /datum/ai_behavior/find_hunt_target/suitable_dispenser
+ hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/water_source
+ hunt_targets = list(/obj/structure/sink, /obj/structure/reagent_dispensers)
+ hunt_range = 7
+
+/datum/ai_planning_subtree/find_and_hunt_target/fill_watercan/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
+ var/mob/living/living_pawn = controller.pawn
+ var/obj/item/reagent_containers/can = locate(/obj/item/reagent_containers/cup/watering_can) in living_pawn
+
+ if(isnull(can))
+ return
+ if(locate(/datum/reagent/water) in can.reagents.reagent_list)
+ return
+
+ return ..()
+
+/datum/ai_behavior/find_hunt_target/suitable_dispenser
+
+/datum/ai_behavior/find_hunt_target/suitable_dispenser/valid_dinner(mob/living/source, obj/structure/water_source, radius)
+ if(!(locate(/datum/reagent/water) in water_source.reagents.reagent_list))
+ return FALSE
+
+ return can_see(source, water_source, radius)
+
+/datum/ai_behavior/hunt_target/unarmed_attack_target/water_source
+ behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
+ hunt_cooldown = 5 SECONDS
+
+/datum/ai_controller/basic_controller/seedling/meanie
+ blackboard = list(
+ BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
+ BB_PET_TARGETTING_DATUM = new /datum/targetting_datum/not_friends,
+ )
+ planning_subtrees = list(
+ /datum/ai_planning_subtree/pet_planning,
+ /datum/ai_planning_subtree/simple_find_target,
+ /datum/ai_planning_subtree/targeted_mob_ability/seedling_rapid,
+ /datum/ai_planning_subtree/targeted_mob_ability/solarbeam,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
+ )
+
+/datum/ai_planning_subtree/targeted_mob_ability/seedling_rapid
+ ability_key = BB_RAPIDSEEDS_ABILITY
+ finish_planning = FALSE
+
+/datum/ai_planning_subtree/targeted_mob_ability/solarbeam
+ ability_key = BB_SOLARBEAM_ABILITY
+ finish_planning = FALSE
+
+///pet commands
+/datum/pet_command/point_targetting/use_ability/solarbeam
+ command_name = "Launch solarbeam"
+ command_desc = "Command your pet to launch a solarbeam at your target!"
+ radial_icon = 'icons/effects/beam.dmi'
+ radial_icon_state = "solar_beam"
+ speech_commands = list("beam", "solar")
+ pet_ability_key = BB_SOLARBEAM_ABILITY
+
+/datum/pet_command/point_targetting/use_ability/rapidseeds
+ command_name = "Rapid seeds"
+ command_desc = "Command your pet to launch a volley of seeds at your target!"
+ radial_icon = 'icons/obj/weapons/guns/projectiles.dmi'
+ radial_icon_state = "seedling"
+ speech_commands = list("rapid", "seeds", "volley")
+ pet_ability_key = BB_RAPIDSEEDS_ABILITY
diff --git a/code/modules/mob/living/basic/jungle/seedling/seedling_projectiles.dm b/code/modules/mob/living/basic/jungle/seedling/seedling_projectiles.dm
new file mode 100644
index 00000000000..726b8105933
--- /dev/null
+++ b/code/modules/mob/living/basic/jungle/seedling/seedling_projectiles.dm
@@ -0,0 +1,32 @@
+/obj/projectile/seedling
+ name = "solar energy"
+ icon_state = "seedling"
+ damage = 10
+ damage_type = BURN
+ light_range = 2
+ armor_flag = ENERGY
+ light_color = LIGHT_COLOR_DIM_YELLOW
+ speed = 1.6
+ hitsound = 'sound/weapons/sear.ogg'
+ hitsound_wall = 'sound/weapons/effects/searwall.ogg'
+ nondirectional_sprite = TRUE
+
+/obj/projectile/seedling/on_hit(atom/target)
+ if(!isliving(target))
+ return ..()
+
+ var/mob/living/living_target = target
+ if(FACTION_JUNGLE in living_target.faction)
+ return
+
+ return ..()
+
+/obj/effect/temp_visual/solarbeam_killsat
+ name = "beam of solar energy"
+ icon_state = "solar_beam"
+ icon = 'icons/effects/beam.dmi'
+ plane = LIGHTING_PLANE
+ layer = LIGHTING_PRIMARY_LAYER
+ duration = 3 SECONDS
+ alpha = 200
+ randomdir = FALSE
diff --git a/code/modules/mob/living/basic/lavaland/bileworm/bileworm_actions.dm b/code/modules/mob/living/basic/lavaland/bileworm/bileworm_actions.dm
index c3e753d992e..b6f7468697a 100644
--- a/code/modules/mob/living/basic/lavaland/bileworm/bileworm_actions.dm
+++ b/code/modules/mob/living/basic/lavaland/bileworm/bileworm_actions.dm
@@ -117,7 +117,7 @@
to_chat(devourer, span_warning("Someone stole your dinner!"))
return
to_chat(target, span_userdanger("You are consumed by [devourer]!"))
- devourer.visible_message("[devourer] consumes [target]!")
+ devourer.visible_message(span_warning("[devourer] consumes [target]!"))
devourer.fully_heal()
playsound(devourer, 'sound/effects/splat.ogg', 50, TRUE)
//to be recieved on death
diff --git a/code/modules/mob/living/basic/lavaland/bileworm/bileworm_ai.dm b/code/modules/mob/living/basic/lavaland/bileworm/bileworm_ai.dm
index 11d7168776b..0093e69220c 100644
--- a/code/modules/mob/living/basic/lavaland/bileworm/bileworm_ai.dm
+++ b/code/modules/mob/living/basic/lavaland/bileworm/bileworm_ai.dm
@@ -15,9 +15,7 @@
/datum/ai_planning_subtree/bileworm_attack
/datum/ai_planning_subtree/bileworm_attack/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
-
- var/mob/living/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]
- if(QDELETED(target))
+ if (!controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET))
return
var/datum/action/cooldown/mob_cooldown/resurface = controller.blackboard[BB_BILEWORM_RESURFACE]
diff --git a/code/modules/mob/living/basic/lavaland/brimdemon/brimbeam.dm b/code/modules/mob/living/basic/lavaland/brimdemon/brimbeam.dm
new file mode 100644
index 00000000000..29a3de60029
--- /dev/null
+++ b/code/modules/mob/living/basic/lavaland/brimdemon/brimbeam.dm
@@ -0,0 +1,126 @@
+/// Fires a bloody beam. Brimdemon Blast!
+/datum/action/cooldown/mob_cooldown/brimbeam
+ name = "brimstone blast"
+ desc = "Unleash a barrage of infernal energies in the targeted direction."
+ button_icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
+ button_icon_state = "brimdemon_firing"
+ background_icon_state = "bg_demon"
+ overlay_icon_state = "bg_demon_border"
+ click_to_activate = TRUE
+ cooldown_time = 5 SECONDS
+ melee_cooldown_time = 0
+ check_flags = AB_CHECK_CONSCIOUS | AB_CHECK_INCAPACITATED
+ /// How far does our beam go?
+ var/beam_range = 10
+ /// How long does our beam last?
+ var/beam_duration = 2 SECONDS
+ /// How long do we wind up before firing?
+ var/charge_duration = 1 SECONDS
+ /// Overlay we show when we're about to fire
+ var/static/image/direction_overlay = image('icons/mob/simple/lavaland/lavaland_monsters.dmi', "brimdemon_telegraph_dir")
+ /// A list of all the beam parts.
+ var/list/beam_parts = list()
+
+/datum/action/cooldown/mob_cooldown/brimbeam/Destroy()
+ extinguish_laser()
+ return ..()
+
+/datum/action/cooldown/mob_cooldown/brimbeam/Activate(atom/target)
+ StartCooldown(360 SECONDS)
+
+ owner.face_atom(target)
+ owner.move_resist = MOVE_FORCE_VERY_STRONG
+ owner.add_overlay(direction_overlay)
+ owner.balloon_alert_to_viewers("charging...")
+
+ var/fully_charged = do_after(owner, delay = charge_duration, target = owner)
+ owner.cut_overlay(direction_overlay)
+ if (!fully_charged)
+ StartCooldown()
+ return TRUE
+
+ if (!fire_laser())
+ var/static/list/fail_emotes = list("coughs.", "wheezes.", "belches out a puff of black smoke.")
+ owner.manual_emote(pick(fail_emotes))
+ StartCooldown()
+ return TRUE
+
+ do_after(owner, delay = beam_duration, target = owner)
+ extinguish_laser()
+ StartCooldown()
+ return TRUE
+
+/// Create a laser in the direction we are facing
+/datum/action/cooldown/mob_cooldown/brimbeam/proc/fire_laser()
+ owner.visible_message(span_danger("[owner] fires a brimbeam!"))
+ playsound(owner, 'sound/creatures/brimdemon.ogg', 150, FALSE, 0, 3)
+ var/turf/target_turf = get_ranged_target_turf(owner, owner.dir, beam_range)
+ var/turf/origin_turf = get_turf(owner)
+ var/list/affected_turfs = get_line(origin_turf, target_turf) - origin_turf
+ for(var/turf/affected_turf in affected_turfs)
+ if(affected_turf.opacity)
+ break
+ var/blocked = FALSE
+ for(var/obj/potential_block in affected_turf.contents)
+ if(potential_block.opacity)
+ blocked = TRUE
+ break
+ if(blocked)
+ break
+ var/atom/new_brimbeam = new /obj/effect/brimbeam(affected_turf)
+ new_brimbeam.dir = owner.dir
+ beam_parts += new_brimbeam
+ for(var/mob/living/hit_mob in affected_turf.contents)
+ hit_mob.apply_damage(damage = 25, damagetype = BURN)
+ to_chat(hit_mob, span_userdanger("You're blasted by [owner]'s brimbeam!"))
+ RegisterSignal(new_brimbeam, COMSIG_QDELETING, PROC_REF(extinguish_laser)) // In case idk a singularity eats it or something
+ if(!length(beam_parts))
+ return FALSE
+ var/atom/last_brimbeam = beam_parts[length(beam_parts)]
+ last_brimbeam.icon_state = "brimbeam_end"
+ var/atom/first_brimbeam = beam_parts[1]
+ first_brimbeam.icon_state = "brimbeam_start"
+ return TRUE
+
+/// Get rid of our laser when we are done with it
+/datum/action/cooldown/mob_cooldown/brimbeam/proc/extinguish_laser()
+ if(!length(beam_parts))
+ return FALSE
+ owner.move_resist = initial(owner.move_resist)
+ for(var/obj/effect/brimbeam/beam in beam_parts)
+ beam.disperse()
+ beam_parts = list()
+
+/// Segments of the actual beam, these hurt if you stand in them
+/obj/effect/brimbeam
+ name = "brimbeam"
+ icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
+ icon_state = "brimbeam_mid"
+ layer = ABOVE_MOB_LAYER
+ plane = ABOVE_GAME_PLANE
+ mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ light_color = LIGHT_COLOR_BLOOD_MAGIC
+ light_power = 3
+ light_range = 2
+
+/obj/effect/brimbeam/Initialize(mapload)
+ . = ..()
+ START_PROCESSING(SSfastprocess, src)
+
+/obj/effect/brimbeam/Destroy()
+ STOP_PROCESSING(SSfastprocess, src)
+ return ..()
+
+/obj/effect/brimbeam/process()
+ for(var/mob/living/hit_mob in get_turf(src))
+ damage(hit_mob)
+
+/// Hurt the passed mob
+/obj/effect/brimbeam/proc/damage(mob/living/hit_mob)
+ hit_mob.apply_damage(damage = 5, damagetype = BURN)
+ to_chat(hit_mob, span_danger("You're damaged by [src]!"))
+
+/// Disappear
+/obj/effect/brimbeam/proc/disperse()
+ animate(src, time = 0.5 SECONDS, alpha = 0)
+ QDEL_IN(src, 0.5 SECONDS)
diff --git a/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon.dm b/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon.dm
new file mode 100644
index 00000000000..2c22977d9c6
--- /dev/null
+++ b/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon.dm
@@ -0,0 +1,87 @@
+/// Lavaland mob which tries to line up with its target and fire a laser
+/mob/living/basic/mining/brimdemon
+ name = "brimdemon"
+ desc = "A volatile creature resembling an enormous horned skull. Its response to almost any stimulus is to unleash a beam of infernal energy."
+ icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
+ icon_state = "brimdemon"
+ icon_living = "brimdemon"
+ icon_dead = "brimdemon_dead"
+ speed = 3
+ maxHealth = 250
+ health = 250
+ friendly_verb_continuous = "scratches at"
+ friendly_verb_simple = "scratch at"
+ speak_emote = list("cackles")
+ melee_damage_lower = 7.5
+ melee_damage_upper = 7.5
+ attack_sound = 'sound/weapons/bite.ogg'
+ melee_attack_cooldown = 0.6 SECONDS
+ attack_vis_effect = ATTACK_EFFECT_BITE
+ attack_verb_continuous = "bites"
+ attack_verb_simple = "bite"
+ death_message = "wails as infernal energy escapes from its wounds, leaving it an empty husk."
+ death_sound = 'sound/magic/demon_dies.ogg'
+ light_color = LIGHT_COLOR_BLOOD_MAGIC
+ light_power = 5
+ light_range = 1.4
+
+ ai_controller = /datum/ai_controller/basic_controller/brimdemon
+
+ crusher_loot = /obj/item/crusher_trophy/brimdemon_fang
+ butcher_results = list(
+ /obj/item/food/meat/slab = 2,
+ /obj/effect/decal/cleanable/brimdust = 1,
+ /obj/item/organ/internal/monster_core/brimdust_sac = 1,
+ )
+ /// How we get blasting
+ var/datum/action/cooldown/mob_cooldown/brimbeam/beam
+
+/mob/living/basic/mining/brimdemon/Initialize(mapload)
+ . = ..()
+ AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW)
+ beam = new(src)
+ beam.Grant(src)
+ ai_controller.set_blackboard_key(BB_TARGETTED_ACTION, beam)
+
+/mob/living/basic/mining/brimdemon/Destroy()
+ QDEL_NULL(beam)
+ return ..()
+
+/mob/living/basic/mining/brimdemon/RangedAttack(atom/target, modifiers)
+ beam.Trigger(target = target)
+
+/mob/living/basic/mining/brimdemon/death(gibbed)
+ . = ..()
+ if (gibbed)
+ return
+ var/obj/effect/temp_visual/brim_burst/bang = new(loc)
+ forceMove(bang)
+
+/// Show a funny animation before doing an explosion
+/obj/effect/temp_visual/brim_burst
+ name = "bursting brimdemon"
+ icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
+ icon_state = "brimdemon_dead"
+ duration = 1.9 SECONDS
+
+/obj/effect/temp_visual/brim_burst/Initialize(mapload)
+ . = ..()
+ addtimer(CALLBACK(src, PROC_REF(bang)), duration - (1 DECISECONDS), TIMER_DELETE_ME)
+ animate(src, color = "#ff8888", transform = matrix().Scale(1.1), time = 0.7 SECONDS)
+ animate(color = "#ffffff", transform = matrix(), time = 0.2 SECONDS)
+ animate(color = "#ff4444", transform = matrix().Scale(1.3), time = 0.5 SECONDS)
+ animate(color = "#ffffff", transform = matrix(), time = 0.2 SECONDS)
+ animate(color = "#ff0000", transform = matrix().Scale(1.5), time = 0.3 SECONDS)
+
+/// Make an explosion
+/obj/effect/temp_visual/brim_burst/proc/bang()
+ var/turf/origin_turf = get_turf(src)
+ playsound(origin_turf, 'sound/effects/pop_expl.ogg', 50)
+ new /obj/effect/temp_visual/explosion/fast(origin_turf)
+ var/list/possible_targets = range(1, origin_turf)
+ for(var/mob/living/target in possible_targets)
+ var/armor = target.run_armor_check(attack_flag = BOMB)
+ target.apply_damage(20, damagetype = BURN, blocked = armor, spread_damage = TRUE)
+
+ for (var/atom/movable/thing as anything in contents)
+ thing.forceMove(loc)
diff --git a/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_ai.dm b/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_ai.dm
new file mode 100644
index 00000000000..e5d793fa150
--- /dev/null
+++ b/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_ai.dm
@@ -0,0 +1,50 @@
+/**
+ * Slap someone who is nearby, line up with target, blast with a beam
+ */
+/datum/ai_controller/basic_controller/brimdemon
+ blackboard = list(
+ BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/brimdemon,
+ )
+
+ ai_traits = PAUSE_DURING_DO_AFTER
+ ai_movement = /datum/ai_movement/basic_avoidance
+ idle_behavior = /datum/idle_behavior/idle_random_walk/no_target
+ planning_subtrees = list(
+ /datum/ai_planning_subtree/simple_find_target,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree/opportunistic,
+ /datum/ai_planning_subtree/move_to_cardinal/brimdemon,
+ /datum/ai_planning_subtree/targeted_mob_ability/brimbeam,
+ )
+
+/datum/targetting_datum/basic/brimdemon
+ stat_attack = HARD_CRIT
+
+/datum/ai_planning_subtree/move_to_cardinal/brimdemon
+ move_behaviour = /datum/ai_behavior/move_to_cardinal/brimdemon
+
+/datum/ai_behavior/move_to_cardinal/brimdemon
+ minimum_distance = 2
+
+/datum/ai_behavior/move_to_cardinal/brimdemon/finish_action(datum/ai_controller/controller, succeeded, target_key)
+ . = ..()
+ if (!succeeded)
+ return
+ var/mob/living/target = controller.blackboard[target_key]
+ var/datum/action/cooldown/ability = controller.blackboard[BB_TARGETTED_ACTION]
+ if(!ability?.IsAvailable())
+ return
+ ability.InterceptClickOn(caller = controller.pawn, target = target)
+
+/datum/ai_planning_subtree/targeted_mob_ability/brimbeam
+ use_ability_behaviour = /datum/ai_behavior/targeted_mob_ability/brimbeam
+
+/datum/ai_behavior/targeted_mob_ability/brimbeam
+ /// Don't shoot if too far away
+ var/max_target_distance = 9
+
+/datum/ai_behavior/targeted_mob_ability/brimbeam/perform(seconds_per_tick, datum/ai_controller/controller, ability_key, target_key)
+ var/mob/living/target = controller.blackboard[target_key]
+ if (QDELETED(target) || !(get_dir(controller.pawn, target) in GLOB.cardinals) || get_dist(controller.pawn, target) > max_target_distance)
+ finish_action(controller, succeeded = FALSE, ability_key = ability_key, target_key = target_key)
+ return
+ return ..()
diff --git a/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_loot.dm b/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_loot.dm
new file mode 100644
index 00000000000..9a45ed99e1c
--- /dev/null
+++ b/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_loot.dm
@@ -0,0 +1,56 @@
+/// Brimdemon crusher trophy, it... makes a funny sound?
+/obj/item/crusher_trophy/brimdemon_fang
+ name = "brimdemon's fang"
+ icon_state = "brimdemon_fang"
+ desc = "A fang from a brimdemon's corpse."
+ denied_type = /obj/item/crusher_trophy/brimdemon_fang
+ /// Cartoon punching vfx
+ var/static/list/comic_phrases = list("BOOM", "BANG", "KABLOW", "KAPOW", "OUCH", "BAM", "KAPOW", "WHAM", "POW", "KABOOM")
+
+/obj/item/crusher_trophy/brimdemon_fang/effect_desc()
+ return "mark detonation creates visual and audiosensory effects on the target"
+
+/obj/item/crusher_trophy/brimdemon_fang/on_mark_detonation(mob/living/target, mob/living/user)
+ target.balloon_alert_to_viewers("[pick(comic_phrases)]!")
+ playsound(target, 'sound/lavaland/brimdemon_crush.ogg', 100)
+
+/// Reagent pool left by dying brimdemon
+/obj/effect/decal/cleanable/brimdust
+ name = "brimdust"
+ desc = "Dust from a brimdemon. It is considered valuable for its' botanical abilities."
+ icon_state = "brimdust"
+ icon = 'icons/obj/mining.dmi'
+ layer = FLOOR_CLEAN_LAYER
+ mergeable_decal = FALSE
+
+/obj/effect/decal/cleanable/brimdust/Initialize(mapload)
+ . = ..()
+ reagents.add_reagent(/datum/reagent/brimdust, 15)
+
+/// Ashwalker ore sensor crafted from brimdemon ash
+/obj/item/ore_sensor
+ name = "ore sensor"
+ desc = "Using demonic frequencies, this ear-mounted tool detects ores in the nearby terrain."
+ icon_state = "oresensor"
+ icon = 'icons/obj/mining.dmi'
+ slot_flags = ITEM_SLOT_EARS
+ var/range = 5
+ var/cooldown = 4 SECONDS //between the standard and the advanced ore scanner in strength
+ COOLDOWN_DECLARE(ore_sensing_cooldown)
+
+/obj/item/ore_sensor/equipped(mob/user, slot, initial)
+ . = ..()
+ if(slot & ITEM_SLOT_EARS)
+ START_PROCESSING(SSobj, src)
+ else
+ STOP_PROCESSING(SSobj, src)
+
+/obj/item/ore_sensor/dropped(mob/user, silent)
+ . = ..()
+ STOP_PROCESSING(SSobj, src)
+
+/obj/item/ore_sensor/process(seconds_per_tick)
+ if(!COOLDOWN_FINISHED(src, ore_sensing_cooldown))
+ return
+ COOLDOWN_START(src, ore_sensing_cooldown, cooldown)
+ mineral_scan_pulse(get_turf(src), range)
diff --git a/code/modules/mob/living/basic/lavaland/goldgrub/goldgrub_ai.dm b/code/modules/mob/living/basic/lavaland/goldgrub/goldgrub_ai.dm
index 12e7d4c8ff1..58efaf1f81b 100644
--- a/code/modules/mob/living/basic/lavaland/goldgrub/goldgrub_ai.dm
+++ b/code/modules/mob/living/basic/lavaland/goldgrub/goldgrub_ai.dm
@@ -108,10 +108,15 @@
if(!dig_ability.IsAvailable())
return
- var/mob/living/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]
+ var/has_target = controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET)
//a storm is coming or someone is nearby, its time to escape
- if(currently_underground || !currently_underground && storm_approaching || !QDELETED(target))
+ if(currently_underground)
+ if(has_target)
+ return
+ controller.queue_behavior(/datum/ai_behavior/use_mob_ability/burrow, BB_BURROW_ABILITY)
+ return SUBTREE_RETURN_FINISH_PLANNING
+ if(storm_approaching || has_target)
controller.queue_behavior(/datum/ai_behavior/use_mob_ability/burrow, BB_BURROW_ABILITY)
return SUBTREE_RETURN_FINISH_PLANNING
@@ -122,48 +127,10 @@
/datum/ai_planning_subtree/grub_mine
/datum/ai_planning_subtree/grub_mine/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
- var/turf/target_wall = controller.blackboard[BB_TARGET_MINERAL_WALL]
-
- if(QDELETED(target_wall))
- controller.queue_behavior(/datum/ai_behavior/find_mineral_wall, BB_TARGET_MINERAL_WALL)
- return
-
- controller.queue_behavior(/datum/ai_behavior/mine_wall, BB_TARGET_MINERAL_WALL)
- return SUBTREE_RETURN_FINISH_PLANNING
-
-
-/datum/ai_behavior/find_mineral_wall
-
-/datum/ai_behavior/find_mineral_wall/perform(seconds_per_tick, datum/ai_controller/controller, found_wall_key)
- . = ..()
-
- var/mob/living_pawn = controller.pawn
-
- for(var/turf/closed/mineral/potential_wall in oview(9, living_pawn))
- if(!check_if_mineable(living_pawn, potential_wall)) //check if its surrounded by walls
- continue
- controller.set_blackboard_key(found_wall_key, potential_wall) //closest wall first!
- finish_action(controller, TRUE)
- return
-
- finish_action(controller, FALSE)
-
-/datum/ai_behavior/find_mineral_wall/proc/check_if_mineable(mob/living/source, turf/target_wall)
- var/direction_to_turf = get_dir(target_wall, source)
- if(!ISDIAGONALDIR(direction_to_turf))
- return TRUE
- var/list/directions_to_check = list()
- for(var/direction_check in GLOB.cardinals)
- if(direction_check & direction_to_turf)
- directions_to_check += direction_check
-
- for(var/direction in directions_to_check)
- var/turf/test_turf = get_step(target_wall, direction)
- if(isnull(test_turf))
- continue
- if(!test_turf.is_blocked_turf(ignore_atoms = list(source)))
- return TRUE
- return FALSE
+ if(controller.blackboard_key_exists(BB_TARGET_MINERAL_WALL))
+ controller.queue_behavior(/datum/ai_behavior/mine_wall, BB_TARGET_MINERAL_WALL)
+ return SUBTREE_RETURN_FINISH_PLANNING
+ controller.queue_behavior(/datum/ai_behavior/find_mineral_wall, BB_TARGET_MINERAL_WALL)
/datum/ai_behavior/mine_wall
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
@@ -202,7 +169,7 @@
/datum/pet_command/grub_spit/execute_action(datum/ai_controller/controller)
var/datum/action/cooldown/spit_ability = controller.blackboard[BB_SPIT_ABILITY]
- if(QDELETED(spit_ability) || !spit_ability.IsAvailable())
+ if(!spit_ability?.IsAvailable())
return
controller.queue_behavior(/datum/ai_behavior/use_mob_ability, BB_SPIT_ABILITY)
controller.clear_blackboard_key(BB_ACTIVE_PET_COMMAND)
diff --git a/code/modules/mob/living/basic/lavaland/goliath/goliath_ai.dm b/code/modules/mob/living/basic/lavaland/goliath/goliath_ai.dm
index 83369de8862..7e723f5d93a 100644
--- a/code/modules/mob/living/basic/lavaland/goliath/goliath_ai.dm
+++ b/code/modules/mob/living/basic/lavaland/goliath/goliath_ai.dm
@@ -9,7 +9,7 @@
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/target_retaliate/check_faction,
/datum/ai_planning_subtree/simple_find_target,
/datum/ai_planning_subtree/find_food,
/datum/ai_planning_subtree/targeted_mob_ability/goliath_tentacles,
@@ -96,8 +96,7 @@
var/target_key = BB_GOLIATH_HOLE_TARGET
/datum/ai_planning_subtree/goliath_dig/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
- var/turf/target_turf = controller.blackboard[target_key]
- if (QDELETED(target_turf))
+ if (!controller.blackboard_key_exists(target_key))
return
controller.queue_behavior(/datum/ai_behavior/goliath_dig, target_key)
return SUBTREE_RETURN_FINISH_PLANNING
diff --git a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm
index 6463fc94979..18cd7321936 100644
--- a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm
+++ b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm
@@ -18,6 +18,7 @@
attack_verb_simple = "snip"
attack_sound = 'sound/weapons/bite.ogg'
attack_vis_effect = ATTACK_EFFECT_BITE // Closer than a scratch to a crustacean pinching effect
+ melee_attack_cooldown = 1 SECONDS
butcher_results = list(
/obj/item/food/meat/crab = 2,
/obj/item/stack/sheet/bone = 2,
@@ -35,6 +36,7 @@
/mob/living/basic/mining/lobstrosity/Initialize(mapload)
. = ..()
ADD_TRAIT(src, TRAIT_SNOWSTORM_IMMUNE, INNATE_TRAIT)
+ AddElement(/datum/element/mob_grabber)
AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW)
AddElement(/datum/element/basic_eating, food_types = target_foods)
AddElement(\
@@ -73,7 +75,7 @@
return
var/mob/living/basic/basic_source = source
var/mob/living/living_target = target
- basic_source.melee_attack(living_target)
+ basic_source.melee_attack(living_target, ignore_cooldown = TRUE)
basic_source.ai_controller?.set_blackboard_key(BB_BASIC_MOB_FLEEING, FALSE)
basic_source.start_pulling(living_target)
diff --git a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm
index dcbeb1e670c..8e4dfe9e294 100644
--- a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm
+++ b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm
@@ -36,7 +36,6 @@
return ..()
/datum/ai_behavior/basic_melee_attack/lobster
- action_cooldown = 1 SECONDS
/datum/ai_behavior/basic_melee_attack/lobster/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
var/mob/living/target = controller.blackboard[target_key]
@@ -53,9 +52,6 @@
if (controller.blackboard[BB_BASIC_MOB_FLEEING])
finish_action(controller = controller, succeeded = TRUE, target_key = target_key) // We don't want to clear our target
return
- var/mob/living/living_pawn = controller.pawn
- if (target.stat != CONSCIOUS)
- living_pawn.start_pulling(target) // No crawling away
return ..()
/datum/ai_planning_subtree/flee_target/lobster
@@ -75,6 +71,10 @@
finish_action(controller, succeeded = FALSE)
return
+ var/mob/living/us = controller.pawn
+ if (us.pulling == target)
+ us.stop_pulling() // If we're running away from someone, best not to bring them with us
+
return ..()
/// Don't use charge ability on an adjacent target, and make sure you're visible before you start
diff --git a/code/modules/mob/living/basic/lavaland/watcher/watcher.dm b/code/modules/mob/living/basic/lavaland/watcher/watcher.dm
index b94ba914298..28ed712d061 100644
--- a/code/modules/mob/living/basic/lavaland/watcher/watcher.dm
+++ b/code/modules/mob/living/basic/lavaland/watcher/watcher.dm
@@ -1,4 +1,4 @@
-/// A floating eyeball which keeps its distance and plays red light/green light with you.
+/// A floating eyeball which keeps its distance and sometimes make you look away.
/mob/living/basic/mining/watcher
name = "watcher"
desc = "A levitating, monocular creature held aloft by wing-like veins. A sharp spine of crystal protrudes from its body."
@@ -59,14 +59,10 @@
)
update_appearance(UPDATE_OVERLAYS)
- var/datum/action/cooldown/mob_cooldown/watcher_overwatch/overwatch = new(src)
- overwatch.Grant(src)
- overwatch.projectile_type = projectile_type
- ai_controller.set_blackboard_key(BB_WATCHER_OVERWATCH, overwatch)
-
var/datum/action/cooldown/mob_cooldown/watcher_gaze/gaze = new gaze_attack(src)
gaze.Grant(src)
- ai_controller.set_blackboard_key(BB_WATCHER_GAZE, gaze)
+ ai_controller.set_blackboard_key(BB_GENERIC_ACTION, gaze)
+ AddComponent(/datum/component/revenge_ability, gaze, targetting = ai_controller.blackboard[BB_TARGETTING_DATUM])
/mob/living/basic/mining/watcher/update_overlays()
. = ..()
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 b08245963f4..1f310ac229f 100644
--- a/code/modules/mob/living/basic/lavaland/watcher/watcher_ai.dm
+++ b/code/modules/mob/living/basic/lavaland/watcher/watcher_ai.dm
@@ -3,44 +3,27 @@
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
)
+ ai_traits = PAUSE_DURING_DO_AFTER
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/target_retaliate/check_faction,
/datum/ai_planning_subtree/simple_find_target,
/datum/ai_planning_subtree/use_mob_ability/gaze,
- /datum/ai_planning_subtree/targeted_mob_ability/overwatch,
/datum/ai_planning_subtree/ranged_skirmish/watcher,
/datum/ai_planning_subtree/maintain_distance,
)
-/datum/ai_planning_subtree/targeted_mob_ability/overwatch
- ability_key = BB_WATCHER_OVERWATCH
- operational_datums = list(/datum/component/ai_target_timer)
-
-/datum/ai_planning_subtree/targeted_mob_ability/overwatch/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
- var/mob/living/living_pawn = controller.pawn
- if (living_pawn.do_after_count())
- return // Don't interrupt our other ability
- var/atom/target = controller.blackboard[target_key]
- if (QDELETED(target) || HAS_TRAIT(target, TRAIT_OVERWATCH_IMMUNE))
- return // We should probably let miners move sometimes
- var/time_on_target = controller.blackboard[BB_BASIC_MOB_HAS_TARGET_TIME] || 0
- if (time_on_target < 5 SECONDS)
- return // We need to spend some time acquiring our target first
- return ..()
-
/datum/ai_planning_subtree/use_mob_ability/gaze
- ability_key = BB_WATCHER_GAZE
finish_planning = TRUE
/datum/ai_planning_subtree/use_mob_ability/gaze/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
- var/mob/living/watcher = controller.pawn
- if (watcher.health > watcher.maxHealth * 0.66) // When we're a little hurt
- return
var/mob/living/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]
if (!isliving(target))
return // Don't do this if there's nothing hostile around or if our target is a mech
+ var/time_on_target = controller.blackboard[BB_BASIC_MOB_HAS_TARGET_TIME] || 0
+ if (time_on_target < 5 SECONDS)
+ return // We need to spend some time acquiring our target first
return ..()
/datum/ai_planning_subtree/ranged_skirmish/watcher
diff --git a/code/modules/mob/living/basic/lavaland/watcher/watcher_gaze.dm b/code/modules/mob/living/basic/lavaland/watcher/watcher_gaze.dm
index e4eb9562f53..9426db41cca 100644
--- a/code/modules/mob/living/basic/lavaland/watcher/watcher_gaze.dm
+++ b/code/modules/mob/living/basic/lavaland/watcher/watcher_gaze.dm
@@ -8,7 +8,7 @@
button_icon_state = "gaze"
background_icon_state = "bg_demon"
overlay_icon_state = "bg_demon_border"
- cooldown_time = 30 SECONDS
+ cooldown_time = 20 SECONDS
check_flags = AB_CHECK_CONSCIOUS | AB_CHECK_INCAPACITATED
click_to_activate = FALSE
shared_cooldown = NONE
diff --git a/code/modules/mob/living/basic/lavaland/watcher/watcher_overwatch.dm b/code/modules/mob/living/basic/lavaland/watcher/watcher_overwatch.dm
index 36ad2d61b4c..0c8194c524a 100644
--- a/code/modules/mob/living/basic/lavaland/watcher/watcher_overwatch.dm
+++ b/code/modules/mob/living/basic/lavaland/watcher/watcher_overwatch.dm
@@ -1,5 +1,6 @@
/**
* Automatically shoot at a target if they do anything while this is active on them.
+ * Currently not given to any mob, but retained so admins can use it.
*/
/datum/action/cooldown/mob_cooldown/watcher_overwatch
name = "Overwatch"
diff --git a/code/modules/mob/living/basic/minebots/minebot.dm b/code/modules/mob/living/basic/minebots/minebot.dm
new file mode 100644
index 00000000000..061c9a624f7
--- /dev/null
+++ b/code/modules/mob/living/basic/minebots/minebot.dm
@@ -0,0 +1,175 @@
+/mob/living/basic/mining_drone
+ name = "\improper Nanotrasen minebot"
+ desc = "The instructions printed on the side read: This is a small robot used to support miners, can be set to search and collect loose ore, or to help fend off wildlife. Insert any type of ore into it to make it start listening to your commands!"
+ gender = NEUTER
+ icon = 'icons/mob/silicon/aibots.dmi'
+ icon_state = "mining_drone"
+ icon_living = "mining_drone"
+ basic_mob_flags = DEL_ON_DEATH
+ status_flags = CANSTUN|CANKNOCKDOWN|CANPUSH
+ mouse_opacity = MOUSE_OPACITY_ICON
+ combat_mode = TRUE
+ habitable_atmos = list("min_oxy" = 0, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
+ minimum_survivable_temperature = 0
+ health = 125
+ maxHealth = 125
+ melee_damage_lower = 15
+ melee_damage_upper = 15
+ obj_damage = 10
+ attack_verb_continuous = "drills"
+ attack_verb_simple = "drill"
+ attack_sound = 'sound/weapons/circsawhit.ogg'
+ sentience_type = SENTIENCE_MINEBOT
+ speak_emote = list("states")
+ mob_biotypes = MOB_ROBOTIC
+ death_message = "blows apart!"
+ light_system = MOVABLE_LIGHT
+ light_range = 6
+ light_on = FALSE
+ combat_mode = FALSE
+ ai_controller = /datum/ai_controller/basic_controller/minebot
+ ///the access card we use to access mining
+ var/obj/item/card/id/access_card
+ ///the gun we use to kill
+ var/obj/item/gun/energy/recharge/kinetic_accelerator/minebot/stored_gun
+ ///the commands our owner can give us
+ var/list/pet_commands = list(
+ /datum/pet_command/idle/minebot,
+ /datum/pet_command/minebot_ability/light,
+ /datum/pet_command/minebot_ability/dump,
+ /datum/pet_command/automate_mining,
+ /datum/pet_command/free/minebot,
+ /datum/pet_command/follow,
+ /datum/pet_command/point_targetting/attack/minebot,
+ )
+
+/mob/living/basic/mining_drone/Initialize(mapload)
+ . = ..()
+
+ var/static/list/death_drops = list(/obj/effect/decal/cleanable/robot_debris/old)
+ AddElement(/datum/element/death_drops, death_drops)
+ add_traits(list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE), INNATE_TRAIT)
+ AddElement(/datum/element/footstep, FOOTSTEP_OBJ_ROBOT, 1, -6, sound_vary = TRUE)
+ AddComponent(\
+ /datum/component/tameable,\
+ food_types = list(/obj/item/stack/ore),\
+ tame_chance = 100,\
+ bonus_tame_chance = 5,\
+ after_tame = CALLBACK(src, PROC_REF(activate_bot)),\
+ )
+
+ var/datum/action/cooldown/mob_cooldown/minedrone/toggle_light/toggle_light_action = new(src)
+ var/datum/action/cooldown/mob_cooldown/minedrone/toggle_meson_vision/toggle_meson_vision_action = new(src)
+ var/datum/action/cooldown/mob_cooldown/minedrone/dump_ore/dump_ore_action = new(src)
+ toggle_light_action.Grant(src)
+ toggle_meson_vision_action.Grant(src)
+ dump_ore_action.Grant(src)
+ ai_controller.set_blackboard_key(BB_MINEBOT_LIGHT_ABILITY, toggle_light_action)
+ ai_controller.set_blackboard_key(BB_MINEBOT_DUMP_ABILITY, dump_ore_action)
+
+ stored_gun = new(src)
+ var/obj/item/implant/radio/mining/comms = new(src)
+ comms.implant(src)
+ access_card = new /obj/item/card/id/advanced/gold(src)
+ SSid_access.apply_trim_to_card(access_card, /datum/id_trim/job/shaft_miner)
+
+ RegisterSignal(src, COMSIG_MOB_TRIED_ACCESS, PROC_REF(attempt_access))
+
+/mob/living/basic/mining_drone/set_combat_mode(new_mode, silent = TRUE)
+ . = ..()
+ icon_state = combat_mode ? "mining_drone_offense" : "mining_drone"
+ balloon_alert(src, "now [combat_mode ? "attacking" : "collecting"]")
+
+/mob/living/basic/mining_drone/examine(mob/user)
+ . = ..()
+ if(health < maxHealth)
+ if(health >= maxHealth * 0.5)
+ . += span_warning("[p_They()] look slightly dented.")
+ else
+ . += span_boldwarning("[p_They()] look severely dented!")
+
+ if(isnull(stored_gun) || !stored_gun.max_mod_capacity)
+ return
+
+ . += "[stored_gun.get_remaining_mod_capacity()]% mod capacity remaining."
+
+ for(var/obj/item/borg/upgrade/modkit/modkit as anything in stored_gun.modkits)
+ . += span_notice("There is \a [modkit] installed, using [modkit.cost]% capacity.")
+
+
+/mob/living/basic/mining_drone/welder_act(mob/living/user, obj/item/welder)
+ if(user.combat_mode)
+ return FALSE
+ if(combat_mode)
+ user.balloon_alert(user, "can't repair in attack mode!")
+ return TRUE
+ if(maxHealth == health)
+ user.balloon_alert(user, "at full integrity!")
+ return TRUE
+ if(welder.use_tool(src, user, 0, volume=40))
+ adjustBruteLoss(-15)
+ user.balloon_alert(user, "successfully repaired!")
+ return TRUE
+
+/mob/living/basic/mining_drone/attackby(obj/item/item_used, mob/user, params)
+ if(item_used.tool_behaviour == TOOL_CROWBAR || istype(item_used, /obj/item/borg/upgrade/modkit))
+ item_used.melee_attack_chain(user, stored_gun, params)
+ return
+
+ return ..()
+
+/mob/living/basic/mining_drone/attack_hand(mob/living/carbon/human/user, list/modifiers)
+ . = ..()
+
+ if(. || user.combat_mode)
+ return
+ set_combat_mode(!combat_mode)
+ balloon_alert(user, "now [combat_mode ? "attacking wildlife" : "collecting loose ore"]")
+
+/mob/living/basic/mining_drone/RangedAttack(atom/target)
+ if(!combat_mode)
+ return
+ stored_gun.afterattack(target, src)
+
+
+/mob/living/basic/mining_drone/UnarmedAttack(atom/attack_target, proximity_flag, list/modifiers)
+ . = ..()
+
+ if(!. || !proximity_flag || combat_mode)
+ return
+
+ if(istype(attack_target, /obj/item/stack/ore))
+ var/obj/item/target_ore = attack_target
+ target_ore.forceMove(src)
+
+/mob/living/basic/mining_drone/proc/drop_ore()
+ to_chat(src, span_notice("You dump your stored ore."))
+ for(var/obj/item/stack/ore/dropped_item in contents)
+ dropped_item.forceMove(get_turf(src))
+
+/mob/living/basic/mining_drone/proc/attempt_access(mob/drone, obj/door_attempt)
+ SIGNAL_HANDLER
+
+ if(door_attempt.check_access(access_card))
+ return ACCESS_ALLOWED
+ return ACCESS_DISALLOWED
+
+/mob/living/basic/mining_drone/proc/activate_bot()
+ AddComponent(/datum/component/obeys_commands, pet_commands)
+
+/mob/living/basic/mining_drone/death(gibbed)
+ drop_ore()
+
+ if(isnull(stored_gun))
+ return ..()
+
+ for(var/obj/item/borg/upgrade/modkit/modkit as anything in stored_gun.modkits)
+ modkit.uninstall(stored_gun)
+
+ return ..()
+
+/mob/living/basic/mining_drone/Destroy()
+ QDEL_NULL(stored_gun)
+ QDEL_NULL(access_card)
+ return ..()
+
diff --git a/code/modules/mob/living/basic/minebots/minebot_abilities.dm b/code/modules/mob/living/basic/minebots/minebot_abilities.dm
new file mode 100644
index 00000000000..4f119fd9b66
--- /dev/null
+++ b/code/modules/mob/living/basic/minebots/minebot_abilities.dm
@@ -0,0 +1,51 @@
+
+/datum/action/cooldown/mob_cooldown/minedrone
+ button_icon = 'icons/mob/actions/actions_mecha.dmi'
+ background_icon_state = "bg_default"
+ overlay_icon_state = "bg_default_border"
+ click_to_activate = FALSE
+
+/datum/action/cooldown/mob_cooldown/minedrone/toggle_light
+ name = "Toggle Light"
+ button_icon_state = "mech_lights_off"
+
+/datum/action/cooldown/mob_cooldown/minedrone/Activate()
+ owner.set_light_on(!owner.light_on)
+ owner.balloon_alert(owner, "lights [owner.light_on ? "on" : "off"]!")
+
+/datum/action/cooldown/mob_cooldown/minedrone/dump_ore
+ name = "Dump Ore"
+ button_icon_state = "mech_eject"
+
+/datum/action/cooldown/mob_cooldown/minedrone/dump_ore/IsAvailable(feedback = TRUE)
+ if(locate(/obj/item/stack/ore) in owner.contents)
+ return TRUE
+
+ if(feedback)
+ owner.balloon_alert(owner, "no ore!")
+ return FALSE
+
+/datum/action/cooldown/mob_cooldown/minedrone/dump_ore/Activate()
+ var/mob/living/basic/mining_drone/user = owner
+ user.drop_ore()
+
+/datum/action/cooldown/mob_cooldown/minedrone/toggle_meson_vision
+ name = "Toggle Meson Vision"
+ button_icon_state = "meson"
+
+/datum/action/cooldown/mob_cooldown/minedrone/toggle_meson_vision/Activate()
+ if(owner.sight & SEE_TURFS)
+ owner.clear_sight(SEE_TURFS)
+ owner.lighting_cutoff_red += 5
+ owner.lighting_cutoff_green += 15
+ owner.lighting_cutoff_blue += 5
+ else
+ owner.add_sight(SEE_TURFS)
+ owner.lighting_cutoff_red -= 5
+ owner.lighting_cutoff_green -= 15
+ owner.lighting_cutoff_blue -= 5
+
+ owner.sync_lighting_plane_cutoff()
+
+ to_chat(owner, span_notice("You toggle your meson vision [(owner.sight & SEE_TURFS) ? "on" : "off"]."))
+
diff --git a/code/modules/mob/living/basic/minebots/minebot_ai.dm b/code/modules/mob/living/basic/minebots/minebot_ai.dm
new file mode 100644
index 00000000000..897cddb1401
--- /dev/null
+++ b/code/modules/mob/living/basic/minebots/minebot_ai.dm
@@ -0,0 +1,217 @@
+/datum/ai_controller/basic_controller/minebot
+ blackboard = list(
+ BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
+ BB_PET_TARGETTING_DATUM = new /datum/targetting_datum/not_friends,
+ BB_BLACKLIST_MINERAL_TURFS = list(/turf/closed/mineral/gibtonite),
+ BB_AUTOMATED_MINING = FALSE,
+ )
+
+ 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/pet_planning,
+ /datum/ai_planning_subtree/basic_ranged_attack_subtree/minebot,
+ /datum/ai_planning_subtree/find_and_hunt_target/consume_ores/minebot,
+ /datum/ai_planning_subtree/minebot_mining,
+ /datum/ai_planning_subtree/locate_dead_humans,
+ )
+
+///find dead humans and report their location on the radio
+/datum/ai_planning_subtree/locate_dead_humans/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
+ if(controller.blackboard_key_exists(BB_NEARBY_DEAD_MINER))
+ controller.queue_behavior(/datum/ai_behavior/send_sos_message, BB_NEARBY_DEAD_MINER)
+ return SUBTREE_RETURN_FINISH_PLANNING
+ controller.queue_behavior(/datum/ai_behavior/find_and_set/unconscious_human, BB_NEARBY_DEAD_MINER, /mob/living/carbon/human)
+
+/datum/ai_behavior/find_and_set/unconscious_human/search_tactic(datum/ai_controller/controller, locate_path, search_range)
+ for(var/mob/living/carbon/human/target in oview(search_range, controller.pawn))
+ if(target.stat >= UNCONSCIOUS && target.mind)
+ return target
+
+/datum/ai_behavior/send_sos_message
+ behavior_flags = AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
+ action_cooldown = 2 MINUTES
+
+/datum/ai_behavior/send_sos_message/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
+ . = ..()
+ var/mob/living/carbon/target = controller.blackboard[target_key]
+ var/mob/living/living_pawn = controller.pawn
+ if(QDELETED(target) || is_station_level(target.z))
+ finish_action(controller, FALSE, target_key)
+ return
+ var/turf/target_turf = get_turf(target)
+ var/obj/item/implant/radio/radio_implant = locate(/obj/item/implant/radio) in living_pawn.contents
+ if(!radio_implant)
+ finish_action(controller, FALSE, target_key)
+ return
+ var/message = "ALERT, [target] in need of help at coordinates: [target_turf.x], [target_turf.y], [target_turf.z]!"
+ radio_implant.radio.talk_into(living_pawn, message, RADIO_CHANNEL_SUPPLY)
+ finish_action(controller, TRUE, target_key)
+
+/datum/ai_behavior/send_sos_message/finish_action(datum/ai_controller/controller, success, target_key)
+ . = ..()
+ controller.clear_blackboard_key(target_key)
+
+///operational datums is null because we dont use a ranged component, we use a gun in our contents
+/datum/ai_planning_subtree/basic_ranged_attack_subtree/minebot
+ operational_datums = null
+ ranged_attack_behavior = /datum/ai_behavior/basic_ranged_attack/minebot
+
+/datum/ai_behavior/basic_ranged_attack/minebot
+ behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT
+
+/datum/ai_planning_subtree/basic_ranged_attack_subtree/minebot/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
+ var/mob/living/living_pawn = controller.pawn
+ if(!living_pawn.combat_mode) //we are not on attack mode
+ return
+ return ..()
+
+///mine walls if we are on automated mining mode
+/datum/ai_planning_subtree/minebot_mining/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
+ if(!controller.blackboard[BB_AUTOMATED_MINING])
+ return
+ if(controller.blackboard_key_exists(BB_TARGET_MINERAL_TURF))
+ controller.queue_behavior(/datum/ai_behavior/minebot_mine_turf, BB_TARGET_MINERAL_TURF)
+ return SUBTREE_RETURN_FINISH_PLANNING
+ controller.queue_behavior(/datum/ai_behavior/find_mineral_wall/minebot, BB_TARGET_MINERAL_TURF)
+
+/datum/ai_behavior/find_mineral_wall/minebot
+
+/datum/ai_behavior/find_mineral_wall/minebot/check_if_mineable(datum/ai_controller/controller, turf/target_wall)
+ var/list/forbidden_turfs = controller.blackboard[BB_BLACKLIST_MINERAL_TURFS]
+ var/turf/previous_unreachable_wall = controller.blackboard[BB_PREVIOUS_UNREACHABLE_WALL]
+ if(is_type_in_list(target_wall, forbidden_turfs) || target_wall == previous_unreachable_wall)
+ return FALSE
+ controller.clear_blackboard_key(BB_PREVIOUS_UNREACHABLE_WALL)
+ return ..()
+
+/datum/ai_behavior/minebot_mine_turf
+ behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
+ required_distance = 2
+ action_cooldown = 3 SECONDS
+
+/datum/ai_behavior/minebot_mine_turf/setup(datum/ai_controller/controller, target_key)
+ . = ..()
+ var/turf/target = controller.blackboard[target_key]
+ if(isnull(target))
+ return FALSE
+ set_movement_target(controller, target)
+
+/datum/ai_behavior/minebot_mine_turf/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
+ . = ..()
+ var/mob/living/basic/living_pawn = controller.pawn
+ var/turf/target = controller.blackboard[target_key]
+
+ if(QDELETED(target))
+ finish_action(controller, FALSE, target_key)
+ return
+
+ if(check_obstacles_in_path(controller, target))
+ finish_action(controller, FALSE, target_key)
+ return
+
+ if(!living_pawn.combat_mode)
+ living_pawn.set_combat_mode(TRUE)
+
+ living_pawn.RangedAttack(target)
+ finish_action(controller, TRUE, target_key)
+ return
+
+/datum/ai_behavior/minebot_mine_turf/proc/check_obstacles_in_path(datum/ai_controller/controller, turf/target)
+ var/mob/living/source = controller.pawn
+ var/list/turfs_in_path = get_line(source, target) - target
+ for(var/turf/turf in turfs_in_path)
+ if(turf.is_blocked_turf(ignore_atoms = list(source)))
+ controller.set_blackboard_key(BB_PREVIOUS_UNREACHABLE_WALL, target)
+ return TRUE
+ return FALSE
+
+/datum/ai_behavior/minebot_mine_turf/finish_action(datum/ai_controller/controller, success, target_key)
+ . = ..()
+ controller.clear_blackboard_key(target_key)
+
+///store ores in our body
+/datum/ai_planning_subtree/find_and_hunt_target/consume_ores/minebot
+ hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/consume_ores/minebot
+ hunt_chance = 100
+
+/datum/ai_planning_subtree/find_and_hunt_target/consume_ores/minebot/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
+ var/automated_mining = controller.blackboard[BB_AUTOMATED_MINING]
+ var/mob/living/living_pawn = controller.pawn
+
+ if(!automated_mining && living_pawn.combat_mode) //are we not on automated mining or collect mode?
+ return
+
+ return ..()
+
+/datum/ai_behavior/hunt_target/unarmed_attack_target/consume_ores/minebot
+ hunt_cooldown = 2 SECONDS
+
+/datum/ai_behavior/hunt_target/unarmed_attack_target/consume_ores/minebot/target_caught(mob/living/hunter, obj/item/stack/ore/hunted)
+ if(hunter.combat_mode)
+ hunter.set_combat_mode(FALSE)
+ return ..()
+
+///pet commands
+/datum/pet_command/free/minebot
+
+/datum/pet_command/free/minebot/execute_action(datum/ai_controller/controller)
+ controller.set_blackboard_key(BB_AUTOMATED_MINING, FALSE)
+ return ..()
+
+/datum/pet_command/automate_mining
+ command_name = "Automate mining"
+ command_desc = "Make your minebot automatically mine!"
+ radial_icon = 'icons/obj/mining.dmi'
+ radial_icon_state = "pickaxe"
+ speech_commands = list("mine")
+
+/datum/pet_command/automate_mining/execute_action(datum/ai_controller/controller)
+ controller.set_blackboard_key(BB_AUTOMATED_MINING, TRUE)
+ controller.clear_blackboard_key(BB_ACTIVE_PET_COMMAND)
+
+/datum/pet_command/minebot_ability
+ command_name = "Minebot ability"
+ command_desc = "Make your minebot use one of its abilities."
+ radial_icon = 'icons/mob/actions/actions_mecha.dmi'
+ ///the ability we will use
+ var/ability_key
+
+/datum/pet_command/minebot_ability/execute_action(datum/ai_controller/controller)
+ var/datum/action/cooldown/ability = controller.blackboard[ability_key]
+ if(!ability?.IsAvailable())
+ return
+ controller.queue_behavior(/datum/ai_behavior/use_mob_ability, ability_key)
+ controller.clear_blackboard_key(BB_ACTIVE_PET_COMMAND)
+ return SUBTREE_RETURN_FINISH_PLANNING
+
+/datum/pet_command/minebot_ability/light
+ command_name = "Toggle lights"
+ command_desc = "Make your minebot toggle its lights."
+ speech_commands = list("light")
+ radial_icon_state = "mech_lights_off"
+ ability_key = BB_MINEBOT_LIGHT_ABILITY
+
+/datum/pet_command/minebot_ability/dump
+ command_name = "Dump ore"
+ command_desc = "Make your minebot dump all its ore!"
+ speech_commands = list("dump", "ore")
+ radial_icon_state = "mech_eject"
+ ability_key = BB_MINEBOT_DUMP_ABILITY
+
+/datum/pet_command/point_targetting/attack/minebot
+ attack_behaviour = /datum/ai_behavior/basic_ranged_attack/minebot
+
+/datum/pet_command/point_targetting/attack/minebot/execute_action(datum/ai_controller/controller)
+ controller.set_blackboard_key(BB_AUTOMATED_MINING, FALSE)
+ var/mob/living/living_pawn = controller.pawn
+ if(!living_pawn.combat_mode)
+ living_pawn.set_combat_mode(TRUE)
+ return ..()
+
+/datum/pet_command/idle/minebot
+
+/datum/pet_command/idle/minebot/execute_action(datum/ai_controller/controller)
+ controller.set_blackboard_key(BB_AUTOMATED_MINING, FALSE)
+ return ..()
diff --git a/code/modules/mob/living/basic/minebots/minebot_upgrades.dm b/code/modules/mob/living/basic/minebots/minebot_upgrades.dm
new file mode 100644
index 00000000000..6f5d43af1af
--- /dev/null
+++ b/code/modules/mob/living/basic/minebots/minebot_upgrades.dm
@@ -0,0 +1,60 @@
+/obj/item/mine_bot_upgrade
+ name = "minebot melee upgrade"
+ desc = "A minebot upgrade."
+ icon_state = "door_electronics"
+ icon = 'icons/obj/assemblies/module.dmi'
+
+/obj/item/mine_bot_upgrade/afterattack(mob/living/basic/mining_drone/minebot, mob/user, proximity)
+ . = ..()
+ if(!istype(minebot) || !proximity)
+ return
+ upgrade_bot(minebot, user)
+
+/obj/item/mine_bot_upgrade/proc/upgrade_bot(mob/living/basic/mining_drone/minebot, mob/user)
+ if(minebot.melee_damage_upper != initial(minebot.melee_damage_upper))
+ user.balloon_alert(user, "already has armor!")
+ return
+ minebot.melee_damage_lower += 7
+ minebot.melee_damage_upper += 7
+ to_chat(user, span_notice("You increase the close-quarter combat abilities of [minebot]."))
+ qdel(src)
+
+//Health
+
+/obj/item/mine_bot_upgrade/health
+ name = "minebot armor upgrade"
+
+/obj/item/mine_bot_upgrade/health/upgrade_bot(mob/living/basic/mining_drone/minebot, mob/user)
+ if(minebot.maxHealth != initial(minebot.maxHealth))
+ to_chat(user, span_warning("[minebot] already has reinforced armor!"))
+ return
+ minebot.maxHealth += 45
+ minebot.updatehealth()
+ to_chat(user, span_notice("You reinforce the armor of [minebot]."))
+ qdel(src)
+
+//AI
+
+/obj/item/slimepotion/slime/sentience/mining
+ name = "minebot AI upgrade"
+ desc = "Can be used to grant sentience to minebots. It's incompatible with minebot armor and melee upgrades, and will override them."
+ icon_state = "door_electronics"
+ icon = 'icons/obj/assemblies/module.dmi'
+ sentience_type = SENTIENCE_MINEBOT
+ ///health boost to add
+ var/base_health_add = 5
+ ///damage boost to add
+ var/base_damage_add = 1
+ ///speed boost to add
+ var/base_speed_add = 1
+ ///cooldown boost to add
+ var/base_cooldown_add = 10
+
+/obj/item/slimepotion/slime/sentience/mining/after_success(mob/living/user, mob/living/basic_mob)
+ if(!istype(basic_mob, /mob/living/basic/mining_drone))
+ return
+ var/mob/living/basic/mining_drone/minebot = basic_mob
+ minebot.maxHealth = initial(minebot.maxHealth) + base_health_add
+ minebot.melee_damage_lower = initial(minebot.melee_damage_lower) + base_damage_add
+ minebot.melee_damage_upper = initial(minebot.melee_damage_upper) + base_damage_add
+ minebot.stored_gun?.recharge_time += base_cooldown_add
diff --git a/code/modules/mob/living/basic/pets/dog/_dog.dm b/code/modules/mob/living/basic/pets/dog/_dog.dm
index 93947173cd9..dd3b3b3a463 100644
--- a/code/modules/mob/living/basic/pets/dog/_dog.dm
+++ b/code/modules/mob/living/basic/pets/dog/_dog.dm
@@ -33,6 +33,7 @@
attack_verb_simple = "bite"
attack_sound = 'sound/weapons/bite.ogg'
attack_vis_effect = ATTACK_EFFECT_BITE
+ melee_attack_cooldown = 0.8 SECONDS
/// Instructions you can give to dogs
var/static/list/pet_commands = list(
/datum/pet_command/idle,
diff --git a/code/modules/mob/living/basic/pets/dog/corgi.dm b/code/modules/mob/living/basic/pets/dog/corgi.dm
index d072a1c897e..cb0df08d198 100644
--- a/code/modules/mob/living/basic/pets/dog/corgi.dm
+++ b/code/modules/mob/living/basic/pets/dog/corgi.dm
@@ -44,27 +44,29 @@
/mob/living/basic/pet/dog/corgi/Exited(atom/movable/gone, direction)
. = ..()
+ var/dropped_something = FALSE
if(gone == inventory_head)
+ dropped_something = TRUE
inventory_head = null
- update_corgi_fluff()
- update_appearance(UPDATE_OVERLAYS)
if(gone == inventory_back)
+ dropped_something = TRUE
inventory_back = null
+ if(dropped_something)
update_corgi_fluff()
update_appearance(UPDATE_OVERLAYS)
/mob/living/basic/pet/dog/corgi/gib()
- if(inventory_head)
- inventory_head.forceMove(drop_location())
- inventory_head = null
- if(inventory_back)
- inventory_back.forceMove(drop_location())
- inventory_back = null
+ undress_dog()
if(access_card)
access_card.forceMove(drop_location())
access_card = null
return ..()
+/// Removes the hat and shirt (but not ID) of this corgi
+/mob/living/basic/pet/dog/corgi/proc/undress_dog()
+ inventory_head?.forceMove(drop_location())
+ inventory_back?.forceMove(drop_location())
+
/mob/living/basic/pet/dog/corgi/examine(mob/user)
. = ..()
if(access_card)
@@ -194,44 +196,42 @@
/mob/living/basic/pet/dog/corgi/proc/place_on_head(obj/item/item_to_add, mob/living/user)
if(inventory_head)
if(user)
- to_chat(user, span_warning("You can't put more than one hat on [src]!"))
- return
- if(!item_to_add)
- user.visible_message(span_notice("[user] pets [src]."), span_notice("You rest your hand on [src]'s head for a moment."))
- if(flags_1 & HOLOGRAM_1)
- return
- user.add_mood_event(REF(src), /datum/mood_event/pet_animal, src)
- return
+ balloon_alert(user, "already wearing a hat!")
+ return FALSE
+
+ if(isnull(item_to_add))
+ if (!isnull(user))
+ user.visible_message(span_notice("[user] pets [src]."), span_notice("You rest your hand on [src]'s head for a moment."))
+ if(flags_1 & HOLOGRAM_1)
+ return
+ user.add_mood_event(REF(src), /datum/mood_event/pet_animal, src)
+ return FALSE
if(user && !user.temporarilyRemoveItemFromInventory(item_to_add))
to_chat(user, span_warning("\The [item_to_add] is stuck to your hand, you cannot put it on [src]'s head!"))
- return
-
- var/valid = FALSE
- if(ispath(item_to_add.dog_fashion, /datum/dog_fashion/head))
- valid = TRUE
+ return FALSE
//Various hats and items (worn on his head) change Ian's behaviour. His attributes are reset when a hat is removed.
-
- if(valid)
- if(user && (stat == DEAD || HAS_TRAIT(src, TRAIT_FAKEDEATH)))
- to_chat(user, span_notice("There is merely a dull, lifeless look in [real_name]'s eyes as you put \the [item_to_add] on [p_them()]."))
- else if(user)
- user.visible_message(span_notice("[user] puts [item_to_add] on [real_name]'s head. [src] looks at [user] and barks once."),
- span_notice("You put [item_to_add] on [real_name]'s head. [src] gives you a peculiar look, then wags [p_their()] tail once and barks."),
- span_hear("You hear a friendly-sounding bark."))
- item_to_add.forceMove(src)
- inventory_head = item_to_add
- update_corgi_fluff()
- update_appearance(UPDATE_OVERLAYS)
- else
+ if(!ispath(item_to_add.dog_fashion, /datum/dog_fashion/head))
to_chat(user, span_warning("You set [item_to_add] on [src]'s head, but it falls off!"))
item_to_add.forceMove(drop_location())
if(prob(25))
step_rand(item_to_add)
dance_rotate(src, set_original_dir = TRUE)
+ return FALSE
- return valid
+ if (user)
+ if(stat == DEAD || HAS_TRAIT(src, TRAIT_FAKEDEATH))
+ to_chat(user, span_notice("There is merely a dull, lifeless look in [real_name]'s eyes as you put \the [item_to_add] on [p_them()]."))
+ else
+ user.visible_message(span_notice("[user] puts [item_to_add] on [real_name]'s head. [src] looks at [user] and barks once."),
+ span_notice("You put [item_to_add] on [real_name]'s head. [src] gives you a peculiar look, then wags [p_their()] tail once and barks."),
+ span_hear("You hear a friendly-sounding bark."))
+ item_to_add.forceMove(src)
+ inventory_head = item_to_add
+ update_corgi_fluff()
+ update_appearance(UPDATE_OVERLAYS)
+ return TRUE
/mob/living/basic/pet/dog/corgi/proc/update_corgi_fluff()
// First, change back to defaults
@@ -380,6 +380,14 @@
Write_Memory(TRUE)
return ..()
+/mob/living/basic/pet/dog/corgi/ian/revive(full_heal_flags, excess_healing, force_grab_ghost)
+ . = ..()
+ if (!.)
+ return
+ if (!istype(inventory_head, /obj/item/clothing/glasses/eyepatch))
+ inventory_head?.forceMove(drop_location())
+ place_on_head(new /obj/item/clothing/glasses/eyepatch/medical)
+
/mob/living/basic/pet/dog/corgi/ian/narsie_act()
playsound(src, 'sound/magic/demon_dies.ogg', 75, TRUE)
var/mob/living/basic/pet/dog/corgi/narsie/narsIan = new(loc)
@@ -453,30 +461,30 @@
can_be_shaved = FALSE
unique_pet = TRUE
held_state = "narsian"
+ /// Mobs we will consume in the name of Nar'Sie
+ var/static/list/edible_types = list(/mob/living/simple_animal/pet, /mob/living/basic/pet)
-//this could maybe be turned into an element
-/mob/living/basic/pet/dog/corgi/narsie/Life(seconds_per_tick = SSMOBS_DT, times_fired)
+/mob/living/basic/pet/dog/corgi/narsie/Initialize(mapload)
. = ..()
- //consume simple_animal pets
- for(var/mob/living/simple_animal/pet/simple_pet in range(1, src))
- if(simple_pet != src && !istype(simple_pet, /mob/living/basic/pet/dog/corgi/narsie))
- visible_message(span_warning("Dark magic resonating from [src] devours [simple_pet]!"), \
- "DELICIOUS SOULS")
- playsound(src, 'sound/magic/demon_attack1.ogg', 75, TRUE)
- new /obj/effect/temp_visual/cult/sac(get_turf(simple_pet))
- narsie_act()
- simple_pet.investigate_log("has been gibbed by [src].", INVESTIGATE_DEATHS)
- simple_pet.gib()
- //consume basic pets
- for(var/mob/living/basic/pet/basic_pet in range(1, src))
- if(basic_pet != src && !istype(basic_pet, /mob/living/basic/pet/dog/corgi/narsie))
- visible_message(span_warning("Dark magic resonating from [src] devours [basic_pet]!"), \
- "DELICIOUS SOULS")
- playsound(src, 'sound/magic/demon_attack1.ogg', 75, TRUE)
- new /obj/effect/temp_visual/cult/sac(get_turf(basic_pet))
- narsie_act()
- basic_pet.investigate_log("has been gibbed by [src].", INVESTIGATE_DEATHS)
- basic_pet.gib()
+ var/static/list/connections = list(COMSIG_ATOM_ENTERED = PROC_REF(on_prey_approached))
+ AddComponent(/datum/component/connect_range, tracked = src, connections = connections, range = 1, works_in_containers = FALSE)
+
+/// Attempt to eat a pet we get near
+/mob/living/basic/pet/dog/corgi/narsie/proc/on_prey_approached(atom/movable/dog, atom/movable/prey)
+ SIGNAL_HANDLER
+ if (!is_type_in_list(prey, edible_types) || istype(prey, type))
+ return
+ visible_message(span_warning("Dark magic resonating from [src] devours [prey]!"), \
+ "DELICIOUS SOULS")
+ playsound(src, 'sound/magic/demon_attack1.ogg', 75, TRUE)
+ new /obj/effect/temp_visual/cult/sac(get_turf(prey))
+ narsie_act()
+ prey.investigate_log("has been sacrificed by [src].", INVESTIGATE_DEATHS)
+ if (isliving(prey))
+ var/mob/living/living_sacrifice = prey
+ living_sacrifice.gib()
+ else
+ qdel(prey)
/mob/living/basic/pet/dog/corgi/narsie/update_corgi_fluff()
. = ..()
diff --git a/code/modules/mob/living/basic/ruin_defender/stickman.dm b/code/modules/mob/living/basic/ruin_defender/stickman.dm
index 8d0a5ab0cde..107973135c7 100644
--- a/code/modules/mob/living/basic/ruin_defender/stickman.dm
+++ b/code/modules/mob/living/basic/ruin_defender/stickman.dm
@@ -13,6 +13,7 @@
attack_verb_simple = "punch"
melee_damage_lower = 10
melee_damage_upper = 10
+ melee_attack_cooldown = 1.5 SECONDS
attack_sound = 'sound/weapons/punch1.ogg'
combat_mode = TRUE
faction = list(FACTION_STICKMAN)
@@ -39,15 +40,9 @@
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/stickman
+ /datum/ai_planning_subtree/basic_melee_attack_subtree
)
-/datum/ai_planning_subtree/basic_melee_attack_subtree/stickman
- melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/stickman
-
-/datum/ai_behavior/basic_melee_attack/stickman
- action_cooldown = 1.5 SECONDS
-
/mob/living/basic/stickman/dog
name = "Angry Stick Dog"
desc = "Stickman's best friend, if he could see him at least."
diff --git a/code/modules/mob/living/basic/space_fauna/bear/bear_ai_behavior.dm b/code/modules/mob/living/basic/space_fauna/bear/bear_ai_behavior.dm
index 6e716ddf411..7c57349524f 100644
--- a/code/modules/mob/living/basic/space_fauna/bear/bear_ai_behavior.dm
+++ b/code/modules/mob/living/basic/space_fauna/bear/bear_ai_behavior.dm
@@ -1,6 +1,3 @@
-/datum/ai_behavior/basic_melee_attack/bear
- action_cooldown = 2 SECONDS
-
/datum/ai_behavior/find_hunt_target/find_hive
/datum/ai_behavior/find_hunt_target/find_hive/valid_dinner(mob/living/source, obj/structure/beebox/hive, radius)
diff --git a/code/modules/mob/living/basic/space_fauna/bear/bear_ai_subtree.dm b/code/modules/mob/living/basic/space_fauna/bear/bear_ai_subtree.dm
index 244c600d89f..851c0bb8029 100644
--- a/code/modules/mob/living/basic/space_fauna/bear/bear_ai_subtree.dm
+++ b/code/modules/mob/living/basic/space_fauna/bear/bear_ai_subtree.dm
@@ -8,16 +8,13 @@
planning_subtrees = list(
/datum/ai_planning_subtree/target_retaliate,
/datum/ai_planning_subtree/simple_find_target,
- /datum/ai_planning_subtree/basic_melee_attack_subtree/bear,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
/datum/ai_planning_subtree/climb_trees,
/datum/ai_planning_subtree/find_and_hunt_target/find_hive,
/datum/ai_planning_subtree/find_and_hunt_target/find_honeycomb,
/datum/ai_planning_subtree/random_speech/bear,
)
-/datum/ai_planning_subtree/basic_melee_attack_subtree/bear
- melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/bear
-
/datum/ai_planning_subtree/find_and_hunt_target/find_hive
target_key = BB_FOUND_HONEY
hunting_behavior = /datum/ai_behavior/hunt_target/find_hive
diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp.dm b/code/modules/mob/living/basic/space_fauna/carp/carp.dm
index 6ce40d8c1a3..9a4b149fd1a 100644
--- a/code/modules/mob/living/basic/space_fauna/carp/carp.dm
+++ b/code/modules/mob/living/basic/space_fauna/carp/carp.dm
@@ -32,6 +32,7 @@
attack_vis_effect = ATTACK_EFFECT_BITE
attack_verb_continuous = "bites"
attack_verb_simple = "bite"
+ melee_attack_cooldown = 1.5 SECONDS
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
@@ -57,7 +58,7 @@
/datum/pet_command/idle,
/datum/pet_command/free,
/datum/pet_command/follow,
- /datum/pet_command/point_targetting/attack/carp
+ /datum/pet_command/point_targetting/attack
)
/// Carp want to eat raw meat
var/static/list/desired_food = list(/obj/item/food/meat/slab, /obj/item/food/meat/rawcutlet)
diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp_ai_actions.dm b/code/modules/mob/living/basic/space_fauna/carp/carp_ai_actions.dm
index c0f5143f18c..b1343a7aeed 100644
--- a/code/modules/mob/living/basic/space_fauna/carp/carp_ai_actions.dm
+++ b/code/modules/mob/living/basic/space_fauna/carp/carp_ai_actions.dm
@@ -1,17 +1,8 @@
#define MAGICARP_SPELL_TARGET_SEEK_RANGE 4
-/datum/pet_command/point_targetting/attack/carp
- attack_behaviour = /datum/ai_behavior/basic_melee_attack/carp
-
/datum/pet_command/point_targetting/use_ability/magicarp
pet_ability_key = BB_MAGICARP_SPELL
-/datum/ai_planning_subtree/basic_melee_attack_subtree/carp
- melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/carp
-
-/datum/ai_behavior/basic_melee_attack/carp
- action_cooldown = 1.5 SECONDS
-
/datum/ai_planning_subtree/attack_obstacle_in_path/carp
attack_behaviour = /datum/ai_behavior/attack_obstructions/carp
@@ -20,12 +11,12 @@
/// As basic attack tree but interrupt if your health gets low or if your spell is off cooldown
/datum/ai_planning_subtree/basic_melee_attack_subtree/magicarp
- melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/carp/magic
+ melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/magicarp
/// Interrupt your attack chain if: you have a spell, it's not on cooldown, and it has a target
-/datum/ai_behavior/basic_melee_attack/carp/magic
+/datum/ai_behavior/basic_melee_attack/magicarp
-/datum/ai_behavior/basic_melee_attack/carp/magic/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key, health_ratio_key)
+/datum/ai_behavior/basic_melee_attack/magicarp/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key, health_ratio_key)
var/datum/action/cooldown/using_action = controller.blackboard[BB_MAGICARP_SPELL]
if (QDELETED(using_action))
return ..()
@@ -43,9 +34,7 @@
/datum/ai_planning_subtree/find_nearest_magicarp_spell_target/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
var/datum/action/cooldown/using_action = controller.blackboard[BB_MAGICARP_SPELL]
- if (QDELETED(using_action))
- return
- if (!using_action.IsAvailable())
+ if (!using_action?.IsAvailable())
return
var/spell_targetting = controller.blackboard[BB_MAGICARP_SPELL_SPECIAL_TARGETTING]
diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp_ai_rift_actions.dm b/code/modules/mob/living/basic/space_fauna/carp/carp_ai_rift_actions.dm
index 88a9f6706f2..d220325ca15 100644
--- a/code/modules/mob/living/basic/space_fauna/carp/carp_ai_rift_actions.dm
+++ b/code/modules/mob/living/basic/space_fauna/carp/carp_ai_rift_actions.dm
@@ -12,9 +12,10 @@
if (!rift_behaviour)
CRASH("Forgot to specify rift behaviour for [src]")
- var/mob/living/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]
+ if (!controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET))
+ return
var/datum/action/cooldown/using_action = controller.blackboard[BB_CARP_RIFT]
- if (QDELETED(target) || QDELETED(using_action) || !using_action.IsAvailable())
+ if (!using_action?.IsAvailable())
return
controller.queue_behavior(rift_behaviour, BB_CARP_RIFT, BB_BASIC_MOB_CURRENT_TARGET)
diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp_controllers.dm b/code/modules/mob/living/basic/space_fauna/carp/carp_controllers.dm
index f4c446d088b..b3097014535 100644
--- a/code/modules/mob/living/basic/space_fauna/carp/carp_controllers.dm
+++ b/code/modules/mob/living/basic/space_fauna/carp/carp_controllers.dm
@@ -25,7 +25,7 @@
/datum/ai_planning_subtree/attack_obstacle_in_path/carp,
/datum/ai_planning_subtree/shortcut_to_target_through_carp_rift,
/datum/ai_planning_subtree/make_carp_rift/aggressive_teleport,
- /datum/ai_planning_subtree/basic_melee_attack_subtree/carp,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
/datum/ai_planning_subtree/carp_migration,
)
@@ -48,7 +48,7 @@
/datum/ai_planning_subtree/attack_obstacle_in_path/carp,
/datum/ai_planning_subtree/shortcut_to_target_through_carp_rift,
/datum/ai_planning_subtree/make_carp_rift/aggressive_teleport,
- /datum/ai_planning_subtree/basic_melee_attack_subtree/carp,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
)
/**
@@ -91,6 +91,6 @@
/datum/ai_planning_subtree/attack_obstacle_in_path/carp,
/datum/ai_planning_subtree/shortcut_to_target_through_carp_rift,
/datum/ai_planning_subtree/make_carp_rift/aggressive_teleport,
- /datum/ai_planning_subtree/basic_melee_attack_subtree/carp,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
/datum/ai_planning_subtree/carp_migration,
)
diff --git a/code/modules/mob/living/basic/space_fauna/carp/magicarp.dm b/code/modules/mob/living/basic/space_fauna/carp/magicarp.dm
index 5051335a557..32f02b880db 100644
--- a/code/modules/mob/living/basic/space_fauna/carp/magicarp.dm
+++ b/code/modules/mob/living/basic/space_fauna/carp/magicarp.dm
@@ -56,7 +56,7 @@ GLOBAL_LIST_INIT(magicarp_spell_colours, list(
/datum/pet_command/idle,
/datum/pet_command/free,
/datum/pet_command/follow,
- /datum/pet_command/point_targetting/attack/carp,
+ /datum/pet_command/point_targetting/attack,
/datum/pet_command/point_targetting/use_ability/magicarp,
)
/// List of all projectiles we can fire.
diff --git a/code/modules/mob/living/basic/space_fauna/eyeball/eyeball_ai_subtree.dm b/code/modules/mob/living/basic/space_fauna/eyeball/eyeball_ai_subtree.dm
index d20873f0ce9..a3c8e22071d 100644
--- a/code/modules/mob/living/basic/space_fauna/eyeball/eyeball_ai_subtree.dm
+++ b/code/modules/mob/living/basic/space_fauna/eyeball/eyeball_ai_subtree.dm
@@ -17,14 +17,10 @@
/datum/ai_planning_subtree/heal_the_blind
/datum/ai_planning_subtree/heal_the_blind/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
- var/mob/living/carbon/target = controller.blackboard[BB_BLIND_TARGET]
-
- if(QDELETED(target))
- controller.queue_behavior(/datum/ai_behavior/find_the_blind, BB_BLIND_TARGET, BB_EYE_DAMAGE_THRESHOLD)
- return
-
- controller.queue_behavior(/datum/ai_behavior/heal_eye_damage, BB_BLIND_TARGET)
- return SUBTREE_RETURN_FINISH_PLANNING
+ if(controller.blackboard_key_exists(BB_BLIND_TARGET))
+ controller.queue_behavior(/datum/ai_behavior/heal_eye_damage, BB_BLIND_TARGET)
+ return SUBTREE_RETURN_FINISH_PLANNING
+ controller.queue_behavior(/datum/ai_behavior/find_the_blind, BB_BLIND_TARGET, BB_EYE_DAMAGE_THRESHOLD)
/datum/targetting_datum/basic/eyeball/can_attack(mob/living/owner, atom/target)
. = ..()
diff --git a/code/modules/mob/living/basic/space_fauna/faithless.dm b/code/modules/mob/living/basic/space_fauna/faithless.dm
index b279856412c..c1dc297ea46 100644
--- a/code/modules/mob/living/basic/space_fauna/faithless.dm
+++ b/code/modules/mob/living/basic/space_fauna/faithless.dm
@@ -18,6 +18,7 @@
attack_verb_continuous = "grips"
attack_verb_simple = "grip"
attack_sound = 'sound/hallucinations/growl1.ogg'
+ melee_attack_cooldown = 1 SECONDS
speak_emote = list("growls")
unsuitable_atmos_damage = 0
@@ -29,12 +30,29 @@
ai_controller = /datum/ai_controller/basic_controller/faithless
+ /// What are the odds we paralyze a target on attack
+ var/paralyze_chance = 12
+ /// How long do we paralyze a target for if we attack them
+ var/paralyze_duration = 2 SECONDS
+
/mob/living/basic/faithless/Initialize(mapload)
. = ..()
ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT)
AddElement(/datum/element/footstep, FOOTSTEP_MOB_SHOE)
+ AddElement(/datum/element/mob_grabber, steal_from_others = FALSE)
AddComponent(/datum/component/pry_open_door)
+/mob/living/basic/faithless/melee_attack(atom/target, list/modifiers, ignore_cooldown)
+ . = ..()
+ if (!. || !isliving(target))
+ return
+
+ var/mob/living/living_target = target
+ if (prob(paralyze_chance))
+ living_target.Paralyze(paralyze_duration)
+ living_target.visible_message(span_danger("\The [src] knocks \the [target] down!"), \
+ span_userdanger("\The [src] knocks you down!"))
+
/datum/ai_controller/basic_controller/faithless
blackboard = list(
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/faithless(),
@@ -47,37 +65,10 @@
/datum/ai_planning_subtree/simple_find_target,
/datum/ai_planning_subtree/attack_obstacle_in_path,
/datum/ai_planning_subtree/attack_obstacle_in_path/low_priority_target,
- /datum/ai_planning_subtree/basic_melee_attack_subtree/faithless,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
/datum/ai_planning_subtree/find_and_hunt_target/look_for_light_fixtures,
/datum/ai_planning_subtree/random_speech/faithless,
)
/datum/targetting_datum/basic/faithless
stat_attack = UNCONSCIOUS
-
-/datum/ai_planning_subtree/basic_melee_attack_subtree/faithless
- melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/faithless
-
-/datum/ai_behavior/basic_melee_attack/faithless
- action_cooldown = 1 SECONDS
- /// What are the odds we paralyze a target
- var/paralyze_chance = 12
- /// How long do we paralyze a target for if we attack them
- var/paralyze_duration = 2 SECONDS
-
-/datum/ai_behavior/basic_melee_attack/faithless/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
- . = ..()
- var/atom/target = controller.blackboard[target_key]
- var/mob/living/living_pawn = controller.pawn
-
- if(!isliving(target))
- return
- var/mob/living/living_target = target
- if(living_target.pulledby != living_pawn && !HAS_AI_CONTROLLER_TYPE(living_target.pulledby, /datum/ai_controller/basic_controller/faithless)) //Dont steal from my fellow faithless.
- if(living_pawn.Adjacent(living_target) && isturf(living_target.loc) && living_target.stat == SOFT_CRIT)
- living_target.grabbedby(living_pawn) //Drag their bodies around as a menace.
- if(prob(paralyze_chance) && iscarbon(target))
- var/mob/living/carbon/carbon_target = target
- carbon_target.Paralyze(paralyze_duration)
- carbon_target.visible_message(span_danger("\The [living_pawn] knocks down \the [carbon_target]!"), \
- span_userdanger("\The [living_pawn] knocks you down!"))
diff --git a/code/modules/mob/living/basic/space_fauna/garden_gnome.dm b/code/modules/mob/living/basic/space_fauna/garden_gnome.dm
index 9b57eba8fe2..d9dfc3c5343 100644
--- a/code/modules/mob/living/basic/space_fauna/garden_gnome.dm
+++ b/code/modules/mob/living/basic/space_fauna/garden_gnome.dm
@@ -17,6 +17,7 @@
attack_verb_continuous = "punches"
attack_verb_simple = "punch"
attack_sound = 'sound/weapons/punch1.ogg'
+ melee_attack_cooldown = 1.2 SECONDS
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1)
speak_emote = list("announces")
@@ -132,12 +133,6 @@
planning_subtrees = list(
/datum/ai_planning_subtree/target_retaliate,
/datum/ai_planning_subtree/attack_obstacle_in_path,
- /datum/ai_planning_subtree/basic_melee_attack_subtree/garden_gnome,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
/datum/ai_planning_subtree/random_speech/garden_gnome,
)
-
-/datum/ai_planning_subtree/basic_melee_attack_subtree/garden_gnome
- melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/garden_gnome
-
-/datum/ai_behavior/basic_melee_attack/garden_gnome
- action_cooldown = 1.2 SECONDS
diff --git a/code/modules/mob/living/basic/space_fauna/headslug.dm b/code/modules/mob/living/basic/space_fauna/headslug.dm
index b0fba4fadc1..a417b6c1394 100644
--- a/code/modules/mob/living/basic/space_fauna/headslug.dm
+++ b/code/modules/mob/living/basic/space_fauna/headslug.dm
@@ -18,6 +18,7 @@
attack_verb_simple = "chomp"
attack_sound = 'sound/weapons/bite.ogg'
attack_vis_effect = ATTACK_EFFECT_BITE
+ mob_biotypes = MOB_ORGANIC|MOB_SPECIAL
faction = list(FACTION_CREATURE)
obj_damage = 0
environment_smash = ENVIRONMENT_SMASH_NONE
@@ -39,10 +40,11 @@
/mob/living/basic/headslug/examine(mob/user)
. = ..()
- if(isnull(client))
- . += span_notice("It appears to be moving around listlessly.")
- else
- . += span_warning("It's moving around intelligently!")
+ if(stat != DEAD)
+ if(isnull(client))
+ . += span_notice("It appears to be moving around listlessly.")
+ else
+ . += span_warning("It's moving around intelligently!")
if (egg_lain)
. += span_notice("Its reproductive equipment appears to have withered.")
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 c5173e3d7f9..347219d0ef0 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
@@ -54,14 +54,10 @@
if(!SPT_PROB(relay_chance, seconds_per_tick))
return
- var/mob/hive_target = controller.blackboard[BB_HIVE_PARTNER]
-
- if(QDELETED(hive_target))
- controller.queue_behavior(/datum/ai_behavior/find_and_set/hive_partner, BB_HIVE_PARTNER, /mob/living/basic/hivebot)
- return
-
- controller.queue_behavior(/datum/ai_behavior/relay_message, BB_HIVE_PARTNER)
- return SUBTREE_RETURN_FINISH_PLANNING
+ if (controller.blackboard_key_exists(BB_HIVE_PARTNER))
+ controller.queue_behavior(/datum/ai_behavior/relay_message, BB_HIVE_PARTNER)
+ return SUBTREE_RETURN_FINISH_PLANNING
+ controller.queue_behavior(/datum/ai_behavior/find_and_set/hive_partner, BB_HIVE_PARTNER, /mob/living/basic/hivebot)
/datum/ai_planning_subtree/find_and_hunt_target/repair_machines
target_key = BB_MACHINE_TARGET
diff --git a/code/modules/mob/living/basic/space_fauna/lightgeist.dm b/code/modules/mob/living/basic/space_fauna/lightgeist.dm
index 28debb6c0a1..c70588f4502 100644
--- a/code/modules/mob/living/basic/space_fauna/lightgeist.dm
+++ b/code/modules/mob/living/basic/space_fauna/lightgeist.dm
@@ -21,6 +21,7 @@
health = 2
melee_damage_lower = 5
melee_damage_upper = 5
+ melee_attack_cooldown = 5 SECONDS
friendly_verb_continuous = "taps"
friendly_verb_simple = "tap"
density = FALSE
@@ -65,10 +66,10 @@
complete_text = "%TARGET%'s wounds mend together.",\
)
-/mob/living/basic/lightgeist/melee_attack(atom/target, list/modifiers)
- if (isliving(target))
+/mob/living/basic/lightgeist/melee_attack(atom/target, list/modifiers, ignore_cooldown = FALSE)
+ . = ..()
+ if (. && isliving(target))
faction |= REF(target) // Anyone we heal will treat us as a friend
- return ..()
/mob/living/basic/lightgeist/ghost()
. = ..()
@@ -86,7 +87,7 @@
planning_subtrees = list(
/datum/ai_planning_subtree/simple_find_target,
- /datum/ai_planning_subtree/basic_melee_attack_subtree/lightgeist, // We heal things by attacking them
+ /datum/ai_planning_subtree/basic_melee_attack_subtree, // We heal things by attacking them
)
/// Attack only mobs who have damage that we can heal, I think this is specific enough not to be a generic type
@@ -111,9 +112,3 @@
continue
return TRUE
return FALSE
-
-/datum/ai_planning_subtree/basic_melee_attack_subtree/lightgeist
- melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/lightgeist
-
-/datum/ai_behavior/basic_melee_attack/lightgeist
- action_cooldown = 5 SECONDS
diff --git a/code/modules/mob/living/basic/space_fauna/mushroom.dm b/code/modules/mob/living/basic/space_fauna/mushroom.dm
index 5e52dabae75..e6d47e2db5c 100644
--- a/code/modules/mob/living/basic/space_fauna/mushroom.dm
+++ b/code/modules/mob/living/basic/space_fauna/mushroom.dm
@@ -64,7 +64,7 @@
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/mushroom,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
/datum/ai_planning_subtree/find_and_hunt_target/mushroom_food,
)
@@ -76,13 +76,6 @@
/datum/targetting_datum/basic/mushroom/faction_check(mob/living/living_mob, mob/living/the_target)
return !living_mob.faction_check_mob(the_target, exact_match = check_factions_exactly)
-
-/datum/ai_planning_subtree/basic_melee_attack_subtree/mushroom
- melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/mushroom
-
-/datum/ai_behavior/basic_melee_attack/mushroom
- action_cooldown = 2 SECONDS
-
/datum/ai_planning_subtree/find_and_hunt_target/mushroom_food
target_key = BB_LOW_PRIORITY_HUNTING_TARGET
hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/mushroom_food
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 35d597e53ca..5a7bb075f19 100644
--- a/code/modules/mob/living/basic/space_fauna/netherworld/blankbody.dm
+++ b/code/modules/mob/living/basic/space_fauna/netherworld/blankbody.dm
@@ -14,6 +14,7 @@
attack_verb_simple = "punch"
attack_sound = 'sound/weapons/bladeslice.ogg'
attack_vis_effect = ATTACK_EFFECT_SLASH
+ melee_attack_cooldown = 1 SECONDS
faction = list(FACTION_NETHER)
speak_emote = list("screams")
death_message = "falls apart into a fine dust."
@@ -42,5 +43,5 @@
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/average_speed,
+ /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 5fabbf2afb2..b38ada0f6e1 100644
--- a/code/modules/mob/living/basic/space_fauna/netherworld/creature.dm
+++ b/code/modules/mob/living/basic/space_fauna/netherworld/creature.dm
@@ -15,6 +15,7 @@
gold_core_spawnable = HOSTILE_SPAWN
attack_sound = 'sound/weapons/bite.ogg'
attack_vis_effect = ATTACK_EFFECT_BITE
+ melee_attack_cooldown = 1 SECONDS
faction = list(FACTION_NETHER)
speak_emote = list("screams")
death_message = "gets his head split open."
@@ -111,5 +112,5 @@
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/average_speed,
+ /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 57d90da264a..18dca95013e 100644
--- a/code/modules/mob/living/basic/space_fauna/netherworld/migo.dm
+++ b/code/modules/mob/living/basic/space_fauna/netherworld/migo.dm
@@ -12,6 +12,7 @@
speed = 1
attack_verb_continuous = "lacerates"
attack_verb_simple = "lacerate"
+ melee_attack_cooldown = 1 SECONDS
gold_core_spawnable = HOSTILE_SPAWN
attack_sound = 'sound/weapons/bladeslice.ogg'
attack_vis_effect = ATTACK_EFFECT_SLASH
@@ -81,5 +82,5 @@
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/average_speed,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
)
diff --git a/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm b/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm
index 609d80fc4df..7a30f88b4c2 100644
--- a/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm
+++ b/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm
@@ -161,6 +161,7 @@
nearby_roach.melee_damage_upper += 4
nearby_roach.obj_damage += 5
nearby_roach.ai_controller = new /datum/ai_controller/basic_controller/cockroach/sewer(nearby_roach)
+ nearby_roach.melee_attack_cooldown = 0.8 SECONDS
nearby_roach.icon_state += "_sewer"
nearby_roach.maxHealth += 1
@@ -232,7 +233,7 @@
if (istype(victim) && !(FACTION_RAT in victim.faction))
to_chat(victim, span_userdanger("With this last sip, you feel your body convulsing horribly from the contents you've ingested. As you contemplate your actions, you sense an awakened kinship with rat-kind and their newly risen leader!"))
victim.faction |= FACTION_RAT
- victim.vomit()
+ victim.vomit(VOMIT_CATEGORY_DEFAULT)
metabolization_rate = 10 * REAGENTS_METABOLISM
/datum/reagent/rat_spit/on_mob_life(mob/living/carbon/C)
@@ -243,8 +244,8 @@
to_chat(C, span_warning("That food does not sit up well!"))
C.adjust_disgust(5)
else if(prob(5))
- C.vomit()
+ C.vomit(VOMIT_CATEGORY_DEFAULT)
return ..()
/datum/pet_command/protect_owner/glockroach
- protect_behavior = /datum/ai_planning_subtree/basic_ranged_attack_subtree/glockroach
+ protect_behavior = /datum/ai_behavior/basic_ranged_attack/glockroach
diff --git a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_ai.dm b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_ai.dm
index 6838f3ba1ab..f998b7b53cd 100644
--- a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_ai.dm
+++ b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_ai.dm
@@ -4,7 +4,7 @@
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic(),
)
- ai_traits = STOP_MOVING_WHEN_PULLED
+ ai_traits = STOP_MOVING_WHEN_PULLED | PAUSE_DURING_DO_AFTER
ai_movement = /datum/ai_movement/basic_avoidance
idle_behavior = /datum/idle_behavior/idle_random_walk/less_walking
diff --git a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_subtrees.dm b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_subtrees.dm
index 4b65138b041..56aacb11a96 100644
--- a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_subtrees.dm
+++ b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_subtrees.dm
@@ -62,12 +62,9 @@
var/target_key = BB_SPIDER_WEB_TARGET
/datum/ai_planning_subtree/spin_web/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
- var/datum/action/cooldown/using_action = controller.blackboard[action_key]
- var/turf/target_turf = controller.blackboard[target_key]
- if (QDELETED(using_action) || QDELETED(target_turf))
- return
- controller.queue_behavior(/datum/ai_behavior/spin_web, action_key, target_key)
- return SUBTREE_RETURN_FINISH_PLANNING
+ if (controller.blackboard_key_exists(action_key) && controller.blackboard_key_exists(target_key))
+ controller.queue_behavior(/datum/ai_behavior/spin_web, action_key, target_key)
+ return SUBTREE_RETURN_FINISH_PLANNING
/// Move to an unwebbed nearby turf and web it up
/datum/ai_behavior/spin_web
diff --git a/code/modules/mob/living/basic/space_fauna/statue/statue.dm b/code/modules/mob/living/basic/space_fauna/statue/statue.dm
index 7d13ee9a1ab..bce35146ecf 100644
--- a/code/modules/mob/living/basic/space_fauna/statue/statue.dm
+++ b/code/modules/mob/living/basic/space_fauna/statue/statue.dm
@@ -27,6 +27,7 @@
attack_verb_simple = "claw"
attack_sound = 'sound/hallucinations/growl1.ogg'
attack_vis_effect = ATTACK_EFFECT_CLAW
+ melee_attack_cooldown = 1 SECONDS
faction = list(FACTION_STATUE)
speak_emote = list("screams")
@@ -147,16 +148,10 @@
ai_movement = /datum/ai_movement/basic_avoidance
planning_subtrees = list(
/datum/ai_planning_subtree/simple_find_target,
- /datum/ai_planning_subtree/basic_melee_attack_subtree/statue,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
/datum/ai_planning_subtree/find_and_hunt_target/look_for_light_fixtures,
)
-/datum/ai_planning_subtree/basic_melee_attack_subtree/statue
- melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/statue
-
-/datum/ai_behavior/basic_melee_attack/statue
- action_cooldown = 1 SECONDS
-
/mob/living/basic/statue/frosty
name = "Frosty"
desc = "Just a snowman. Just a snowman. Oh god, it's just a snowman."
diff --git a/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_ai.dm b/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_ai.dm
index f632a38dc1b..9d3a09c5348 100644
--- a/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_ai.dm
+++ b/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_ai.dm
@@ -1,5 +1,3 @@
-#define WUMBO_ATTACK_COOLDOWN 2.5 SECONDS
-
/// Cowardly when small, aggressive when big. Tries to transform whenever possible.
/datum/ai_controller/basic_controller/wumborian_fugu
blackboard = list(
@@ -15,23 +13,15 @@
/datum/ai_planning_subtree/targeted_mob_ability/inflate,
/datum/ai_planning_subtree/flee_target,
/datum/ai_planning_subtree/attack_obstacle_in_path/wumborian_fugu,
- /datum/ai_planning_subtree/basic_melee_attack_subtree/wumborian_fugu,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
)
-/datum/ai_planning_subtree/basic_melee_attack_subtree/wumborian_fugu
- melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/wumborian_fugu
-
-/datum/ai_behavior/basic_melee_attack/wumborian_fugu
- action_cooldown = WUMBO_ATTACK_COOLDOWN
-
/datum/ai_planning_subtree/attack_obstacle_in_path/wumborian_fugu
attack_behaviour = /datum/ai_behavior/attack_obstructions/wumborian_fugu
/datum/ai_behavior/attack_obstructions/wumborian_fugu
can_attack_turfs = TRUE
- action_cooldown = WUMBO_ATTACK_COOLDOWN
+ action_cooldown = 2.5 SECONDS
/datum/ai_planning_subtree/targeted_mob_ability/inflate
ability_key = BB_FUGU_INFLATE
-
-#undef WUMBO_ATTACK_COOLDOWN
diff --git a/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_fugu.dm b/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_fugu.dm
index e13bef35482..bf8be2051d8 100644
--- a/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_fugu.dm
+++ b/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_fugu.dm
@@ -29,6 +29,7 @@
melee_damage_upper = 0
attack_sound = 'sound/weapons/punch1.ogg'
attack_vis_effect = ATTACK_EFFECT_BITE
+ melee_attack_cooldown = 2.5 SECONDS
attack_verb_continuous = "chomps"
attack_verb_simple = "chomp"
friendly_verb_continuous = "floats near"
diff --git a/code/modules/mob/living/basic/syndicate/syndicate.dm b/code/modules/mob/living/basic/syndicate/syndicate.dm
index 549dbf476d0..a4fd0981198 100644
--- a/code/modules/mob/living/basic/syndicate/syndicate.dm
+++ b/code/modules/mob/living/basic/syndicate/syndicate.dm
@@ -15,6 +15,7 @@
attack_verb_continuous = "punches"
attack_verb_simple = "punch"
attack_sound = 'sound/weapons/punch1.ogg'
+ melee_attack_cooldown = 1.2 SECONDS
combat_mode = TRUE
unsuitable_atmos_damage = 7.5
unsuitable_cold_damage = 7.5
@@ -138,12 +139,20 @@
var/casingtype = /obj/item/ammo_casing/c9mm
/// Sound to play when firing weapon
var/projectilesound = 'sound/weapons/gun/pistol/shot.ogg'
+ /// number of burst shots
+ var/burst_shots
/// Time between taking shots
var/ranged_cooldown = 1 SECONDS
/mob/living/basic/syndicate/ranged/Initialize(mapload)
. = ..()
- AddComponent(/datum/component/ranged_attacks, casing_type = casingtype, projectile_sound = projectilesound, cooldown_time = ranged_cooldown)
+ AddComponent(\
+ /datum/component/ranged_attacks,\
+ casing_type = casingtype,\
+ projectile_sound = projectilesound,\
+ cooldown_time = ranged_cooldown,\
+ burst_shots = burst_shots,\
+ )
/mob/living/basic/syndicate/ranged/infiltrator //shuttle loan event
projectilesound = 'sound/weapons/gun/smg/shot_suppressed.ogg'
@@ -172,6 +181,7 @@
casingtype = /obj/item/ammo_casing/c45
projectilesound = 'sound/weapons/gun/smg/shot.ogg'
ai_controller = /datum/ai_controller/basic_controller/syndicate/ranged/burst
+ burst_shots = 3
ranged_cooldown = 3 SECONDS
r_hand = /obj/item/gun/ballistic/automatic/c20r
@@ -203,6 +213,7 @@
casingtype = /obj/item/ammo_casing/shotgun/buckshot //buckshot (up to 72.5 brute) fired in a two-round burst
ai_controller = /datum/ai_controller/basic_controller/syndicate/ranged/shotgunner
ranged_cooldown = 3 SECONDS
+ burst_shots = 2
r_hand = /obj/item/gun/ballistic/shotgun/bulldog
/mob/living/basic/syndicate/ranged/shotgun/space
diff --git a/code/modules/mob/living/basic/syndicate/syndicate_ai.dm b/code/modules/mob/living/basic/syndicate/syndicate_ai.dm
index c38e4f132ad..be84c1a5685 100644
--- a/code/modules/mob/living/basic/syndicate/syndicate_ai.dm
+++ b/code/modules/mob/living/basic/syndicate/syndicate_ai.dm
@@ -1,6 +1,6 @@
/datum/ai_controller/basic_controller/syndicate
blackboard = list(
- BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/syndicate()
+ BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/attack_until_dead
)
ai_movement = /datum/ai_movement/basic_avoidance
@@ -8,12 +8,9 @@
planning_subtrees = list(
/datum/ai_planning_subtree/simple_find_target,
/datum/ai_planning_subtree/attack_obstacle_in_path/syndicate,
- /datum/ai_planning_subtree/basic_melee_attack_subtree/syndicate
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
)
-/datum/targetting_datum/basic/syndicate
- stat_attack = HARD_CRIT
-
/datum/ai_planning_subtree/basic_melee_attack_subtree/syndicate
melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/syndicate
@@ -49,7 +46,6 @@
ranged_attack_behavior = /datum/ai_behavior/basic_ranged_attack/syndicate_burst
/datum/ai_behavior/basic_ranged_attack/syndicate_burst
- shots = 3
action_cooldown = 3 SECONDS
/datum/ai_controller/basic_controller/syndicate/ranged/shotgunner
@@ -62,8 +58,6 @@
ranged_attack_behavior = /datum/ai_behavior/basic_ranged_attack/syndicate_shotgun
/datum/ai_behavior/basic_ranged_attack/syndicate_shotgun
- shots = 2
- burst_interval = 0.6 SECONDS
action_cooldown = 3 SECONDS
required_distance = 1
diff --git a/code/modules/mob/living/basic/tree.dm b/code/modules/mob/living/basic/tree.dm
index f93ab14a37f..2a0806b105c 100644
--- a/code/modules/mob/living/basic/tree.dm
+++ b/code/modules/mob/living/basic/tree.dm
@@ -74,7 +74,7 @@
our_turf.air.gases[/datum/gas/carbon_dioxide][MOLES] -= amt
our_turf.atmos_spawn_air("[GAS_O2]=[amt]")
-/mob/living/basic/tree/melee_attack(atom/target, list/modifiers)
+/mob/living/basic/tree/melee_attack(atom/target, list/modifiers, ignore_cooldown = FALSE)
. = ..()
if(!.)
@@ -107,12 +107,6 @@
idle_behavior = /datum/idle_behavior/idle_random_walk/less_walking
planning_subtrees = list(
/datum/ai_planning_subtree/simple_find_target,
- /datum/ai_planning_subtree/basic_melee_attack_subtree/tree,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
/datum/ai_planning_subtree/random_speech/tree,
)
-
-/datum/ai_planning_subtree/basic_melee_attack_subtree/tree
- melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/tree
-
-/datum/ai_behavior/basic_melee_attack/tree
- action_cooldown = 2 SECONDS
diff --git a/code/modules/mob/living/basic/vermin/cockroach.dm b/code/modules/mob/living/basic/vermin/cockroach.dm
index 90e5bd53d2d..5c69ad90447 100644
--- a/code/modules/mob/living/basic/vermin/cockroach.dm
+++ b/code/modules/mob/living/basic/vermin/cockroach.dm
@@ -93,10 +93,19 @@
faction = list(FACTION_HOSTILE, FACTION_MAINT_CREATURES)
ai_controller = /datum/ai_controller/basic_controller/cockroach/glockroach
cockroach_cell_line = CELL_LINE_TABLE_GLOCKROACH
+ ///number of burst shots
+ var/burst_shots
+ ///cooldown between attacks
+ var/ranged_cooldown = 1 SECONDS
/mob/living/basic/cockroach/glockroach/Initialize(mapload)
. = ..()
- AddComponent(/datum/component/ranged_attacks, casing_type = /obj/item/ammo_casing/glockroach, cooldown_time = 1 SECONDS)
+ AddComponent(\
+ /datum/component/ranged_attacks,\
+ casing_type = /obj/item/ammo_casing/glockroach,\
+ burst_shots = burst_shots,\
+ cooldown_time = ranged_cooldown,\
+ )
/datum/ai_controller/basic_controller/cockroach/glockroach
planning_subtrees = list(
@@ -122,6 +131,7 @@
melee_damage_lower = 2.5
melee_damage_upper = 10
obj_damage = 10
+ melee_attack_cooldown = 1 SECONDS
gold_core_spawnable = HOSTILE_SPAWN
attack_sound = 'sound/weapons/bladeslice.ogg'
attack_vis_effect = ATTACK_EFFECT_SLASH
@@ -156,36 +166,26 @@
/datum/ai_planning_subtree/pet_planning,
/datum/ai_planning_subtree/random_speech/insect,
/datum/ai_planning_subtree/simple_find_target,
- /datum/ai_planning_subtree/basic_melee_attack_subtree/hauberoach, //If we are attacking someone, this will prevent us from hunting
+ /datum/ai_planning_subtree/basic_melee_attack_subtree, //If we are attacking someone, this will prevent us from hunting
/datum/ai_planning_subtree/find_and_hunt_target/roach,
)
-/datum/ai_planning_subtree/basic_melee_attack_subtree/hauberoach
- melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/hauberoach
-
-/datum/ai_behavior/basic_melee_attack/hauberoach //Slightly slower, as this is being made in feature freeze ;)
- action_cooldown = 1 SECONDS
-
/datum/ai_controller/basic_controller/cockroach/sewer
planning_subtrees = list(
/datum/ai_planning_subtree/pet_planning,
/datum/ai_planning_subtree/random_speech/insect,
/datum/ai_planning_subtree/simple_find_target,
- /datum/ai_planning_subtree/basic_melee_attack_subtree/sewer,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
/datum/ai_planning_subtree/find_and_hunt_target/roach,
)
-/datum/ai_planning_subtree/basic_melee_attack_subtree/sewer
- melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/sewer
-
-/datum/ai_behavior/basic_melee_attack/sewer
- action_cooldown = 0.8 SECONDS
-
/mob/living/basic/cockroach/glockroach/mobroach
name = "mobroach"
desc = "WE'RE FUCKED, THAT GLOCKROACH HAS A TOMMYGUN!"
icon_state = "mobroach"
ai_controller = /datum/ai_controller/basic_controller/cockroach/mobroach
+ burst_shots = 4
+ ranged_cooldown = 2 SECONDS
/datum/ai_controller/basic_controller/cockroach/mobroach
planning_subtrees = list(
@@ -200,5 +200,4 @@
ranged_attack_behavior = /datum/ai_behavior/basic_ranged_attack/mobroach
/datum/ai_behavior/basic_ranged_attack/mobroach
- shots = 4
action_cooldown = 2 SECONDS
diff --git a/code/modules/mob/living/basic/vermin/frog.dm b/code/modules/mob/living/basic/vermin/frog.dm
index 282ed17b00c..191ea12b4df 100644
--- a/code/modules/mob/living/basic/vermin/frog.dm
+++ b/code/modules/mob/living/basic/vermin/frog.dm
@@ -17,6 +17,7 @@
obj_damage = 10
attack_verb_continuous = "bites"
attack_verb_simple = "bite"
+ melee_attack_cooldown = 2.5 SECONDS
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "pokes"
@@ -85,19 +86,13 @@
planning_subtrees = list(
/datum/ai_planning_subtree/target_retaliate,
/datum/ai_planning_subtree/random_speech/frog,
- /datum/ai_planning_subtree/basic_melee_attack_subtree/frog,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
)
-/datum/ai_planning_subtree/basic_melee_attack_subtree/frog
- melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/frog
-
-/datum/ai_behavior/basic_melee_attack/frog
- action_cooldown = 2.5 SECONDS
-
/datum/ai_controller/basic_controller/frog/trash
planning_subtrees = list(
/datum/ai_planning_subtree/pet_planning,
/datum/ai_planning_subtree/random_speech/frog,
/datum/ai_planning_subtree/simple_find_target,
- /datum/ai_planning_subtree/basic_melee_attack_subtree/frog,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
)
diff --git a/code/modules/mob/living/basic/vermin/mouse.dm b/code/modules/mob/living/basic/vermin/mouse.dm
index d70b24f048d..0b3645b3e0f 100644
--- a/code/modules/mob/living/basic/vermin/mouse.dm
+++ b/code/modules/mob/living/basic/vermin/mouse.dm
@@ -57,6 +57,7 @@
)
AddElement(/datum/element/connect_loc, loc_connections)
make_tameable()
+ AddComponent(/datum/component/swarming, 16, 16) //max_x, max_y
/mob/living/basic/mouse/proc/make_tameable()
if (tame)
@@ -116,7 +117,8 @@
. = ..(TRUE)
// Now if we were't ACTUALLY gibbed, spawn the dead mouse
if(!gibbed)
- var/obj/item/food/deadmouse/mouse = new(loc, src)
+ var/obj/item/food/deadmouse/mouse = new(loc)
+ mouse.copy_corpse(src)
if(HAS_TRAIT(src, TRAIT_BEING_SHOCKED))
mouse.desc = "They're toast."
mouse.add_atom_colour("#3A3A3A", FIXED_COLOUR_PRIORITY)
@@ -301,16 +303,18 @@
var/body_color = "gray"
var/critter_type = /mob/living/basic/mouse
-/obj/item/food/deadmouse/Initialize(mapload, mob/living/basic/mouse/dead_critter)
+/obj/item/food/deadmouse/Initialize(mapload)
. = ..()
- if(dead_critter)
- body_color = dead_critter.body_color
- critter_type = dead_critter.type
- name = dead_critter.name
- icon_state = dead_critter.icon_dead
AddElement(/datum/element/swabable, CELL_LINE_TABLE_MOUSE, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 10)
RegisterSignal(src, COMSIG_ATOM_ON_LAZARUS_INJECTOR, PROC_REF(use_lazarus))
+/// Copy properties from an imminently dead mouse
+/obj/item/food/deadmouse/proc/copy_corpse(mob/living/basic/mouse/dead_critter)
+ body_color = dead_critter.body_color
+ critter_type = dead_critter.type
+ name = dead_critter.name
+ icon_state = dead_critter.icon_dead
+
/obj/item/food/deadmouse/examine(mob/user)
. = ..()
if (reagents?.has_reagent(/datum/reagent/yuck) || reagents?.has_reagent(/datum/reagent/fuel))
diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm
index 9608db4d4c6..9354f02e2b2 100644
--- a/code/modules/mob/living/blood.dm
+++ b/code/modules/mob/living/blood.dm
@@ -88,7 +88,7 @@
//Makes a blood drop, leaking amt units of blood from the mob
/mob/living/carbon/proc/bleed(amt)
- if(!blood_volume)
+ if(!blood_volume || (status_flags & GODMODE))
return
blood_volume = max(blood_volume - amt, 0)
diff --git a/code/modules/mob/living/brain/MMI.dm b/code/modules/mob/living/brain/MMI.dm
index 3dc3d08d399..e182c51f54f 100644
--- a/code/modules/mob/living/brain/MMI.dm
+++ b/code/modules/mob/living/brain/MMI.dm
@@ -57,7 +57,7 @@
if(newbrain.suicided)
to_chat(user, span_warning("[newbrain] is completely useless."))
return
- if(!newbrain.brainmob?.mind || !newbrain.brainmob)
+ if(!newbrain.brainmob)
var/install = tgui_alert(user, "[newbrain] is inactive, slot it in anyway?", "Installing Brain", list("Yes", "No"))
if(install != "Yes")
return
@@ -73,7 +73,7 @@
if(!user.transferItemToLoc(O, src))
return
var/mob/living/brain/B = newbrain.brainmob
- if(!B.key)
+ if(!B.key && !newbrain.decoy_override)
B.notify_ghost_cloning("Someone has put your brain in a MMI!", source = src)
user.visible_message(span_notice("[user] sticks \a [newbrain] into [src]."), span_notice("[src]'s indicator light turn on as you insert [newbrain]."))
@@ -241,14 +241,23 @@
. = ..()
if(radio)
. += span_notice("There is a switch to toggle the radio system [radio.is_on() ? "off" : "on"].[brain ? " It is currently being covered by [brain]." : null]")
- if(brainmob)
- var/mob/living/brain/B = brainmob
- if(!B.key || !B.mind || B.stat == DEAD)
- . += span_warning("\The [src] indicates that the brain is completely unresponsive.")
- else if(!B.client)
- . += span_warning("\The [src] indicates that the brain is currently inactive; it might change.")
+
+ if(!isnull(brain))
+ // It's dead, show it as much
+ if((brain.organ_flags & ORGAN_FAILING) || brainmob?.stat == DEAD)
+ if(brain.suicided || (brainmob && HAS_TRAIT(brainmob, TRAIT_SUICIDED)))
+ . += span_warning("[src] indicator light is red.")
+ else
+ . += span_warning("[src] indicator light is yellow - perhaps you should check the brain for damage.")
+ // If we have a client, OR it's a decoy brain, show as active
+ else if(brain.decoy_override || brainmob?.client)
+ . += span_notice("[src] indicates that the brain is active.")
+ // If we have a brainmob and it has a mind, it may just be DC'd
+ else if(brainmob?.mind)
+ . += span_warning("[src] indicates that the brain is currently inactive; it might change.")
+ // No brainmob, no mind, and not a decoy, it's a dead brain
else
- . += span_notice("\The [src] indicates that the brain is active.")
+ . += span_warning("[src] indicates that the brain is completely unresponsive.")
/obj/item/mmi/relaymove(mob/living/user, direction)
return //so that the MMI won't get a warning about not being able to move if it tries to move
@@ -259,6 +268,10 @@
if(user)
to_chat(user, span_warning("\The [src] indicates that there is no mind present!"))
return FALSE
+ if(brain.decoy_override)
+ if(user)
+ to_chat(user, span_warning("This [name] does not seem to fit!"))
+ return FALSE
if(!B.key || !B.mind)
if(user)
to_chat(user, span_warning("\The [src] indicates that their mind is completely unresponsive!"))
diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm
index ac8f503df45..4bd275b5df1 100644
--- a/code/modules/mob/living/brain/brain_item.dm
+++ b/code/modules/mob/living/brain/brain_item.dm
@@ -54,17 +54,23 @@
brain_owner.update_body_parts()
return
- // Not a ling? Now you get to assume direct control.
if(brainmob)
- if(brain_owner.key)
- brain_owner.ghostize()
+ // If it's a ling decoy brain, nothing to transfer, just throw it out
+ if(decoy_override)
+ if(brainmob?.key)
+ stack_trace("Decoy override brain with a key assigned - This should never happen.")
- if(brainmob.mind)
- brainmob.mind.transfer_to(brain_owner)
+ // Not a ling - assume direct control
else
- brain_owner.key = brainmob.key
+ if(brain_owner.key)
+ brain_owner.ghostize()
- brain_owner.set_suicide(HAS_TRAIT(brainmob, TRAIT_SUICIDED))
+ if(brainmob.mind)
+ brainmob.mind.transfer_to(brain_owner)
+ else
+ brain_owner.key = brainmob.key
+
+ brain_owner.set_suicide(HAS_TRAIT(brainmob, TRAIT_SUICIDED))
QDEL_NULL(brainmob)
else
@@ -126,8 +132,13 @@
/obj/item/organ/internal/brain/proc/transfer_identity(mob/living/L)
name = "[L.name]'s [initial(name)]"
- if(brainmob || decoy_override)
- return
+ if(brainmob)
+ if(!decoy_override)
+ return
+
+ // it's just a dummy, throw it out
+ QDEL_NULL(brainmob)
+
if(!L.mind)
return
brainmob = new(src)
@@ -146,9 +157,10 @@
// Hack, fucked dna needs to follow the brain to prevent memes, so we need to copy over the trait sources and shit
for(var/source in GET_TRAIT_SOURCES(L, TRAIT_BADDNA))
ADD_TRAIT(brainmob, TRAIT_BADDNA, source)
- if(L.mind && L.mind.current)
+
+ if(L.mind && L.mind.current && !decoy_override)
L.mind.transfer_to(brainmob)
- to_chat(brainmob, span_notice("You feel slightly disoriented. That's normal when you're just a brain."))
+ to_chat(brainmob, span_notice("You feel slightly disoriented. That's normal when you're just a brain."))
/obj/item/organ/internal/brain/attackby(obj/item/O, mob/user, params)
user.changeNext_move(CLICK_CD_MELEE)
@@ -214,7 +226,7 @@
if(suicided)
. += span_info("It's started turning slightly grey. They must not have been able to handle the stress of it all.")
return
- if((brainmob && (brainmob.client || brainmob.get_ghost())) || decoy_override)
+ if(brainmob && (decoy_override || brainmob.client || brainmob.get_ghost()))
if(organ_flags & ORGAN_FAILING)
. += span_info("It seems to still have a bit of energy within it, but it's rather damaged... You may be able to restore it with some mannitol.")
else if(damage >= BRAIN_DAMAGE_DEATH*0.5)
@@ -262,13 +274,11 @@
..()
/obj/item/organ/internal/brain/Destroy() //copypasted from MMIs.
- if(brainmob)
- QDEL_NULL(brainmob)
+ QDEL_NULL(brainmob)
QDEL_LIST(traumas)
destroy_all_skillchips()
- if(owner?.mind) //You aren't allowed to return to brains that don't exist
- owner.mind.set_current(null)
+ owner?.mind?.set_current(null) //You aren't allowed to return to brains that don't exist
return ..()
/obj/item/organ/internal/brain/on_life(seconds_per_tick, times_fired)
diff --git a/code/modules/mob/living/brain/life.dm b/code/modules/mob/living/brain/life.dm
index 54888f26533..9bebeac70ec 100644
--- a/code/modules/mob/living/brain/life.dm
+++ b/code/modules/mob/living/brain/life.dm
@@ -1,8 +1,6 @@
/mob/living/brain/Life(seconds_per_tick = SSMOBS_DT, times_fired)
- if (notransform)
- return
- if(!loc)
+ if(isnull(loc) || HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
return
if(!isnull(container))
diff --git a/code/modules/mob/living/brain/posibrain.dm b/code/modules/mob/living/brain/posibrain.dm
index bb2077dbd83..b9080a8673a 100644
--- a/code/modules/mob/living/brain/posibrain.dm
+++ b/code/modules/mob/living/brain/posibrain.dm
@@ -124,20 +124,20 @@ GLOBAL_VAR(posibrain_notify_cooldown)
brainmob.set_suicide(FALSE)
transfer_personality(user)
-/obj/item/mmi/posibrain/transfer_identity(mob/living/carbon/transfered_user)
- name = "[initial(name)] ([transfered_user])"
- brainmob.name = transfered_user.real_name
- brainmob.real_name = transfered_user.real_name
- if(transfered_user.has_dna())
+/obj/item/mmi/posibrain/transfer_identity(mob/living/carbon/transferred_user)
+ name = "[initial(name)] ([transferred_user])"
+ brainmob.name = transferred_user.real_name
+ brainmob.real_name = transferred_user.real_name
+ if(transferred_user.has_dna())
if(!brainmob.stored_dna)
brainmob.stored_dna = new /datum/dna/stored(brainmob)
- transfered_user.dna.copy_dna(brainmob.stored_dna)
- brainmob.timeofdeath = transfered_user.timeofdeath
+ transferred_user.dna.copy_dna(brainmob.stored_dna)
+ brainmob.timeofdeath = transferred_user.timeofdeath
brainmob.set_stat(CONSCIOUS)
if(brainmob.mind)
brainmob.mind.set_assigned_role(SSjob.GetJobType(posibrain_job_path))
- if(transfered_user.mind)
- transfered_user.mind.transfer_to(brainmob)
+ if(transferred_user.mind)
+ transferred_user.mind.transfer_to(brainmob)
brainmob.mind.remove_all_antag_datums()
brainmob.mind.wipe_memory()
diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm
index 325e2b10742..2e2674e14e7 100644
--- a/code/modules/mob/living/carbon/alien/larva/life.dm
+++ b/code/modules/mob/living/carbon/alien/larva/life.dm
@@ -1,7 +1,7 @@
/mob/living/carbon/alien/larva/Life(seconds_per_tick = SSMOBS_DT, times_fired)
- if (notransform)
+ if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
return
if(!..() || IS_IN_STASIS(src) || (amount_grown >= max_grown))
return // We're dead, in stasis, or already grown.
diff --git a/code/modules/mob/living/carbon/alien/organs.dm b/code/modules/mob/living/carbon/alien/organs.dm
index 00c8a617c64..5ef9b23c418 100644
--- a/code/modules/mob/living/carbon/alien/organs.dm
+++ b/code/modules/mob/living/carbon/alien/organs.dm
@@ -51,21 +51,24 @@
actions_types = list(/datum/action/cooldown/alien/transfer)
/obj/item/organ/internal/alien/plasmavessel/on_life(seconds_per_tick, times_fired)
+ var/delta_time = DELTA_WORLD_TIME(SSmobs)
+ //Instantly healing to max health in a single tick would be silly. If it takes 8 seconds to fire, then something's fucked.
+ var/delta_time_capped = min(delta_time, 8)
//If there are alien weeds on the ground then heal if needed or give some plasma
if(locate(/obj/structure/alien/weeds) in owner.loc)
if(owner.health >= owner.maxHealth)
- owner.adjustPlasma(plasma_rate * seconds_per_tick)
+ owner.adjustPlasma(plasma_rate * delta_time)
else
var/heal_amt = heal_rate
if(!isalien(owner))
heal_amt *= 0.2
- owner.adjustPlasma(0.5 * plasma_rate * seconds_per_tick)
- owner.adjustBruteLoss(-heal_amt * seconds_per_tick)
- owner.adjustFireLoss(-heal_amt * seconds_per_tick)
- owner.adjustOxyLoss(-heal_amt * seconds_per_tick)
- owner.adjustCloneLoss(-heal_amt * seconds_per_tick)
+ owner.adjustPlasma(0.5 * plasma_rate * delta_time_capped)
+ owner.adjustBruteLoss(-heal_amt * delta_time_capped)
+ owner.adjustFireLoss(-heal_amt * delta_time_capped)
+ owner.adjustOxyLoss(-heal_amt * delta_time_capped)
+ owner.adjustCloneLoss(-heal_amt * delta_time_capped)
else
- owner.adjustPlasma(0.1 * plasma_rate * seconds_per_tick)
+ owner.adjustPlasma(0.1 * plasma_rate * delta_time)
/obj/item/organ/internal/alien/plasmavessel/on_insert(mob/living/carbon/organ_owner)
. = ..()
diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
index fa56f624a4d..37fb827f3a5 100644
--- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
+++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
@@ -111,8 +111,7 @@
var/mob/living/carbon/alien/larva/new_xeno = new(xeno_loc)
new_xeno.key = ghost.key
SEND_SOUND(new_xeno, sound('sound/voice/hiss5.ogg',0,0,0,100)) //To get the player's attention
- new_xeno.add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), type) //so we don't move during the bursting animation
- new_xeno.notransform = 1
+ new_xeno.add_traits(list(TRAIT_HANDS_BLOCKED, TRAIT_IMMOBILIZED, TRAIT_NO_TRANSFORM), type) //so we don't move during the bursting animation
new_xeno.invisibility = INVISIBILITY_MAXIMUM
sleep(0.6 SECONDS)
@@ -121,10 +120,8 @@
qdel(new_xeno)
CRASH("AttemptGrow failed due to the early qdeletion of source or owner.")
- if(new_xeno)
- REMOVE_TRAIT(new_xeno, TRAIT_IMMOBILIZED, type)
- REMOVE_TRAIT(new_xeno, TRAIT_HANDS_BLOCKED, type)
- new_xeno.notransform = 0
+ if(!isnull(new_xeno))
+ new_xeno.remove_traits(list(TRAIT_HANDS_BLOCKED, TRAIT_IMMOBILIZED, TRAIT_NO_TRANSFORM), type)
new_xeno.invisibility = 0
if(gib_on_success)
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 9c0789a9caf..92981770948 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -416,53 +416,76 @@
return 0
return ..()
-/mob/living/carbon/proc/vomit(lost_nutrition = 10, blood = FALSE, stun = TRUE, distance = 1, message = TRUE, vomit_type = VOMIT_TOXIC, harm = TRUE, force = FALSE, purge_ratio = 0.1)
+/// Proc that compels the mob to throw up. Returns TRUE if the mob actually threw up.
+/mob/living/carbon/proc/vomit(vomit_flags = VOMIT_CATEGORY_DEFAULT, vomit_type = /obj/effect/decal/cleanable/vomit/toxic, lost_nutrition = 10, distance = 1, purge_ratio = 0.1)
+ var/force = (vomit_flags & MOB_VOMIT_FORCE)
if((HAS_TRAIT(src, TRAIT_NOHUNGER) || HAS_TRAIT(src, TRAIT_TOXINLOVER)) && !force)
return TRUE
SEND_SIGNAL(src, COMSIG_CARBON_VOMITED, distance, force)
+
+ // cache some stuff that we'll need later (at least multiple times)
var/starting_dir = dir
- if(nutrition < 100 && !blood && !force)
+ var/message = (vomit_flags & MOB_VOMIT_MESSAGE)
+ var/stun = (vomit_flags & MOB_VOMIT_STUN)
+ var/knockdown = (vomit_flags & MOB_VOMIT_KNOCKDOWN)
+ var/blood = (vomit_flags & MOB_VOMIT_BLOOD)
+
+ if(!force && !blood && (nutrition < 100))
if(message)
- visible_message(span_warning("[src] dry heaves!"), \
- span_userdanger("You try to throw up, but there's nothing in your stomach!"))
+ visible_message(
+ span_warning("[src] dry heaves!"),
+ span_userdanger("You try to throw up, but there's nothing in your stomach!"),
+ )
if(stun)
Stun(20 SECONDS)
+ if(knockdown)
+ Knockdown(20 SECONDS)
return TRUE
if(is_mouth_covered()) //make this add a blood/vomit overlay later it'll be hilarious
if(message)
- visible_message(span_danger("[src] throws up all over [p_them()]self!"), \
- span_userdanger("You throw up all over yourself!"))
+ visible_message(
+ span_danger("[src] throws up all over [p_them()]self!"),
+ span_userdanger("You throw up all over yourself!"),
+ )
add_mood_event("vomit", /datum/mood_event/vomitself)
distance = 0
else
if(message)
- visible_message(span_danger("[src] throws up!"), span_userdanger("You throw up!"))
+ visible_message(
+ span_danger("[src] throws up!"),
+ span_userdanger("You throw up!"),
+ )
if(!isflyperson(src))
add_mood_event("vomit", /datum/mood_event/vomit)
if(stun)
Stun(8 SECONDS)
+ if(knockdown)
+ Knockdown(8 SECONDS)
playsound(get_turf(src), 'sound/effects/splat.ogg', 50, TRUE)
- var/turf/T = get_turf(src)
+
+ var/turf/location = get_turf(src)
if(!blood)
adjust_nutrition(-lost_nutrition)
adjustToxLoss(-3)
- for(var/i=0 to distance)
+ for(var/i = 0 to distance)
if(blood)
- if(T)
- add_splatter_floor(T)
- if(harm)
+ if(location)
+ add_splatter_floor(location)
+ if(vomit_flags & MOB_VOMIT_HARM)
adjustBruteLoss(3)
else
- if(T)
- T.add_vomit_floor(src, vomit_type, purge_ratio) //toxic barf looks different || call purge when doing detoxicfication to pump more chems out of the stomach.
- T = get_step(T, starting_dir)
- if (T?.is_blocked_turf())
+ if(location)
+ location.add_vomit_floor(src, vomit_type, vomit_flags, purge_ratio) // call purge when doing detoxicfication to pump more chems out of the stomach.
+
+ location = get_step(location, starting_dir)
+ if (location?.is_blocked_turf())
break
+
return TRUE
/**
@@ -481,7 +504,7 @@
var/turf/floor = get_turf(src)
var/obj/effect/decal/cleanable/vomit/spew = new(floor, get_static_viruses())
- bite.reagents.trans_to(spew, amount, transfered_by = src)
+ bite.reagents.trans_to(spew, amount, transferred_by = src)
/mob/living/carbon/proc/spew_organ(power = 5, amt = 1)
for(var/i in 1 to amt)
@@ -1179,7 +1202,7 @@
/mob/living/carbon/proc/hypnosis_vulnerable()
if(HAS_TRAIT(src, TRAIT_MINDSHIELD))
return FALSE
- if(has_status_effect(/datum/status_effect/hallucination))
+ if(has_status_effect(/datum/status_effect/hallucination) || has_status_effect(/datum/status_effect/drugginess))
return TRUE
if(IsSleeping() || IsUnconscious())
return TRUE
@@ -1267,12 +1290,17 @@
else
wound_type = forced_type
else
- wound_type = pick(GLOB.global_all_wound_types)
+ for (var/datum/wound/path as anything in shuffle(GLOB.all_wound_pregen_data))
+ var/datum/wound_pregen_data/pregen_data = GLOB.all_wound_pregen_data[path]
+ if (pregen_data.can_be_applied_to(scar_part, random_roll = TRUE))
+ wound_type = path
+ break
- var/datum/wound/phantom_wound = new wound_type
- scaries.generate(scar_part, phantom_wound)
- scaries.fake = TRUE
- QDEL_NULL(phantom_wound)
+ if (wound_type) // can feasibly happen, if its an inorganic limb/cant be wounded/scarred
+ var/datum/wound/phantom_wound = new wound_type
+ scaries.generate(scar_part, phantom_wound)
+ scaries.fake = TRUE
+ QDEL_NULL(phantom_wound)
/mob/living/carbon/is_face_visible()
return !(wear_mask?.flags_inv & HIDEFACE) && !(head?.flags_inv & HIDEFACE)
@@ -1432,27 +1460,3 @@
our_splatter.blood_dna_info = get_blood_dna_list()
var/turf/targ = get_ranged_target_turf(src, splatter_direction, splatter_strength)
our_splatter.fly_towards(targ, splatter_strength)
-
-/mob/living/carbon/update_fire_overlay(stacks, on_fire, last_icon_state, suffix = "")
- var/fire_icon = "generic_burning[suffix]"
-
- if(!GLOB.fire_appearances[fire_icon])
- var/mutable_appearance/new_fire_overlay = mutable_appearance('icons/mob/effects/onfire.dmi', fire_icon, -FIRE_LAYER)
- new_fire_overlay.appearance_flags = RESET_COLOR
- GLOB.fire_appearances[fire_icon] = new_fire_overlay
-
- if((stacks > 0 && on_fire) || HAS_TRAIT(src, TRAIT_PERMANENTLY_ONFIRE))
- if(fire_icon == last_icon_state)
- return last_icon_state
-
- remove_overlay(FIRE_LAYER)
- overlays_standing[FIRE_LAYER] = GLOB.fire_appearances[fire_icon]
- apply_overlay(FIRE_LAYER)
- return fire_icon
-
- if(!last_icon_state)
- return last_icon_state
-
- remove_overlay(FIRE_LAYER)
- apply_overlay(FIRE_LAYER)
- return null
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index 172bb5b8313..8d87eff6882 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -31,7 +31,7 @@
/mob/living/carbon/is_mouth_covered(check_flags = ALL)
if((check_flags & ITEM_SLOT_HEAD) && head && (head.flags_cover & HEADCOVERSMOUTH))
return head
- if((check_flags & ITEM_SLOT_MASK) && wear_mask && (wear_mask.flags_cover & HEADCOVERSMOUTH))
+ if((check_flags & ITEM_SLOT_MASK) && wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH))
return wear_mask
return null
@@ -102,7 +102,7 @@
if(I.force)
var/attack_direction = get_dir(user, src)
apply_damage(I.force, I.damtype, affecting, wound_bonus = I.wound_bonus, bare_wound_bonus = I.bare_wound_bonus, sharpness = I.get_sharpness(), attack_direction = attack_direction, attacking_item = I)
- if(I.damtype == BRUTE && IS_ORGANIC_LIMB(affecting))
+ if(I.damtype == BRUTE && affecting.can_bleed())
if(prob(33))
I.add_mob_blood(src)
var/turf/location = get_turf(src)
@@ -140,22 +140,35 @@
//SKYRAT EDIT ADDITION END
var/extra_wound_details = ""
+
if(I.damtype == BRUTE && hit_bodypart.can_dismember())
+
var/mangled_state = hit_bodypart.get_mangled_state()
- var/bio_state = hit_bodypart.biological_state
- if((mangled_state & BODYPART_MANGLED_FLESH) && (mangled_state & BODYPART_MANGLED_BONE))
+
+ var/bio_status = hit_bodypart.get_bio_state_status()
+
+ var/has_exterior = ((bio_status & ANATOMY_EXTERIOR))
+ var/has_interior = ((bio_status & ANATOMY_INTERIOR))
+
+ var/exterior_ready_to_dismember = (!has_exterior || ((mangled_state & BODYPART_MANGLED_EXTERIOR)))
+ var/interior_ready_to_dismember = (!has_interior || ((mangled_state & BODYPART_MANGLED_INTERIOR)))
+
+ var/dismemberable = ((hit_bodypart.dismemberable_by_wound()) || hit_bodypart.dismemberable_by_total_damage())
+ if (dismemberable)
extra_wound_details = ", threatening to sever it entirely"
- else if((mangled_state & BODYPART_MANGLED_FLESH && I.get_sharpness()) || ((mangled_state & BODYPART_MANGLED_BONE) && (bio_state & BIO_BONE) && !(bio_state & BIO_FLESH)))
- extra_wound_details = ", [I.get_sharpness() == SHARP_EDGED ? "slicing" : "piercing"] through to the bone"
- else if((mangled_state & BODYPART_MANGLED_BONE && I.get_sharpness()) || ((mangled_state & BODYPART_MANGLED_FLESH) && (bio_state & BIO_FLESH) && !(bio_state & BIO_BONE)))
- extra_wound_details = ", [I.get_sharpness() == SHARP_EDGED ? "slicing" : "piercing"] at the remaining tissue"
+ else if((has_interior && (has_exterior && exterior_ready_to_dismember) && I.get_sharpness()))
+ var/bone_text = hit_bodypart.get_internal_description()
+ extra_wound_details = ", [I.get_sharpness() == SHARP_EDGED ? "slicing" : "piercing"] through to the [bone_text]"
+ else if(has_exterior && ((has_interior && interior_ready_to_dismember) && I.get_sharpness()))
+ var/tissue_text = hit_bodypart.get_external_description()
+ extra_wound_details = ", [I.get_sharpness() == SHARP_EDGED ? "slicing" : "piercing"] at the remaining [tissue_text]"
var/message_hit_area = ""
if(hit_area)
message_hit_area = " in the [hit_area]"
var/attack_message_spectator = "[src] [message_verb_continuous][message_hit_area] with [I][extra_wound_details]!"
var/attack_message_victim = "You're [message_verb_continuous][message_hit_area] with [I][extra_wound_details]!"
- var/attack_message_attacker = "You [message_verb_simple] [src][message_hit_area] with [I]!"
+ var/attack_message_attacker = "You [message_verb_simple] [src][message_hit_area] with [I][extra_wound_details]!"
if(user in viewers(src, null))
attack_message_spectator = "[user] [message_verb_continuous] [src][message_hit_area] with [I][extra_wound_details]!"
attack_message_victim = "[user] [message_verb_continuous] you[message_hit_area] with [I][extra_wound_details]!"
@@ -431,7 +444,7 @@
bodypart.emp_act(severity)
///Adds to the parent by also adding functionality to propagate shocks through pulling and doing some fluff effects.
-/mob/living/carbon/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
+/mob/living/carbon/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE, jitter_time = 20 SECONDS, stutter_time = 4 SECONDS, stun_duration = 4 SECONDS)
. = ..()
if(!.)
return
@@ -452,24 +465,32 @@
//Found our victims, now lets shock them all
for(var/victim in shocking_queue)
var/mob/living/carbon/C = victim
- C.electrocute_act(shock_damage*0.75, src, 1, flags)
+ C.electrocute_act(shock_damage*0.75, src, 1, flags, jitter_time, stutter_time, stun_duration)
//Stun
var/should_stun = (!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && !(flags & SHOCK_NOSTUN)
- if(should_stun)
- StaminaKnockdown(10, TRUE)
- //Paralyze(40) - SKYRAT EDIT REMOVAL
+ var/paralyze = !(flags & SHOCK_KNOCKDOWN)
+ var/immediately_stun = should_stun && !(flags & SHOCK_DELAY_STUN)
+ if (immediately_stun)
+ if (paralyze)
+ //Paralyze(40) - SKYRAT EDIT REMOVAL
+ StaminaKnockdown(10, TRUE) // SKYRAT EDIT ADDITION
+ else
+ Knockdown(stun_duration)
//Jitter and other fluff.
do_jitter_animation(300)
- adjust_jitter(20 SECONDS)
- adjust_stutter(4 SECONDS)
- addtimer(CALLBACK(src, PROC_REF(secondary_shock), should_stun), 2 SECONDS)
+ adjust_jitter(jitter_time)
+ adjust_stutter(stutter_time)
+ if (should_stun)
+ addtimer(CALLBACK(src, PROC_REF(secondary_shock), paralyze, stun_duration * 1.5), 2 SECONDS)
return shock_damage
///Called slightly after electrocute act to apply a secondary stun.
-/mob/living/carbon/proc/secondary_shock(should_stun)
- if(should_stun)
+/mob/living/carbon/proc/secondary_shock(paralyze, stun_duration)
+ if (paralyze)
//Paralyze(60) - SKYRAT EDIT REMOVAL
StaminaKnockdown(10, TRUE) //SKYRAT EDIT ADDITION
+ else
+ Knockdown(stun_duration)
/mob/living/carbon/proc/help_shake_act(mob/living/carbon/helper)
var/nosound = FALSE //SKYRAT EDIT ADDITION - EMOTES
@@ -775,16 +796,17 @@
return ..()
var/obj/item/bodypart/grasped_part = get_bodypart(zone_selected)
- //SKYRAT EDIT CHANGE BEGIN - MEDICAL
/*
- if(!grasped_part?.get_modified_bleed_rate())
+ if(!grasped_part?.can_be_grasped())
return
var/starting_hand_index = active_hand_index
if(starting_hand_index == grasped_part.held_index)
to_chat(src, span_danger("You can't grasp your [grasped_part.name] with itself!"))
return
- to_chat(src, span_warning("You try grasping at your [grasped_part.name], trying to stop the bleeding..."))
+ var/bleed_rate = grasped_part.get_modified_bleed_rate()
+ var/bleeding_text = (bleed_rate ? ", trying to stop the bleeding" : "")
+ to_chat(src, span_warning("You try grasping at your [grasped_part.name][bleeding_text]..."))
if(!do_after(src, 0.75 SECONDS))
to_chat(src, span_danger("You fail to grasp your [grasped_part.name]."))
return
@@ -795,9 +817,19 @@
QDEL_NULL(grasp)
return
grasp.grasp_limb(grasped_part)
- */
+ */ // SKYRAT EDIT REMOVAL - MODULARIZED INTO grasp.dm's self_grasp_bleeding_limb !! IF THIS PROC IS UPDATED, PUT IT IN THERE !!
self_grasp_bleeding_limb(grasped_part, supress_message)
- //SKYRAT EDIT CHANGE END
+
+/// If TRUE, the owner of this bodypart can try grabbing it to slow bleeding, as well as various other effects.
+/obj/item/bodypart/proc/can_be_grasped()
+ if (get_modified_bleed_rate())
+ return TRUE
+
+ for (var/datum/wound/iterated_wound as anything in wounds)
+ if (iterated_wound.wound_flags & CAN_BE_GRASPED)
+ return TRUE
+
+ return FALSE
/// an abstract item representing you holding your own limb to staunch the bleeding, see [/mob/living/carbon/proc/grabbedby] will probably need to find somewhere else to put this.
/obj/item/hand_item/self_grasp
@@ -843,7 +875,9 @@
RegisterSignal(user, COMSIG_QDELETING, PROC_REF(qdel_void))
RegisterSignals(grasped_part, list(COMSIG_CARBON_REMOVE_LIMB, COMSIG_QDELETING), PROC_REF(qdel_void))
- user.visible_message(span_danger("[user] grasps at [user.p_their()] [grasped_part.name], trying to stop the bleeding."), span_notice("You grab hold of your [grasped_part.name] tightly."), vision_distance=COMBAT_MESSAGE_RANGE)
+ var/bleed_rate = grasped_part.get_modified_bleed_rate()
+ var/bleeding_text = (bleed_rate ? ", trying to stop the bleeding" : "")
+ user.visible_message(span_danger("[user] grasps at [user.p_their()] [grasped_part.name][bleeding_text]."), span_notice("You grab hold of your [grasped_part.name] tightly."), vision_distance=COMBAT_MESSAGE_RANGE)
playsound(get_turf(src), 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1)
return TRUE
diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm
index 722f4282543..bcf5f495715 100644
--- a/code/modules/mob/living/carbon/carbon_defines.dm
+++ b/code/modules/mob/living/carbon/carbon_defines.dm
@@ -11,8 +11,8 @@
usable_hands = 0 //Populated on init through list/bodyparts
mobility_flags = MOBILITY_FLAGS_CARBON_DEFAULT
blocks_emissive = EMISSIVE_BLOCK_NONE
- ///List of [/obj/item/organ/internal] in the mob. They don't go in the contents for some reason I don't want to know.
- var/list/obj/item/organ/internal/organs = list()
+ ///List of [/obj/item/organ]s in the mob. They don't go in the contents for some reason I don't want to know.
+ var/list/obj/item/organ/organs = list()
///Same as [above][/mob/living/carbon/var/organs], but stores "slot ID" - "organ" pairs for easy access.
var/list/organs_slot = list()
///How many dream images we have left to send
@@ -104,6 +104,9 @@
/// All of the scars a carbon has afflicted throughout their limbs
var/list/all_scars
+ /// Assoc list of BODY_ZONE -> wounding_type. Set when a limb is dismembered, unset when one is attached. Used for determining what scar to add when it comes time to generate them.
+ var/list/body_zone_dismembered_by
+
/// Simple modifier for whether this mob can handle greater or lesser skillchip complexity. See /datum/mutation/human/biotechcompat/ for example.
var/skillchip_complexity_modifier = 0
diff --git a/code/modules/mob/living/carbon/carbon_update_icons.dm b/code/modules/mob/living/carbon/carbon_update_icons.dm
index 31429c28aaa..2aab0a5e2bb 100644
--- a/code/modules/mob/living/carbon/carbon_update_icons.dm
+++ b/code/modules/mob/living/carbon/carbon_update_icons.dm
@@ -272,8 +272,8 @@
#undef NEXT_PARENT_COMMAND
/mob/living/carbon/regenerate_icons()
- if(notransform)
- return 1
+ if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
+ return
icon_render_keys = list() //Clear this bad larry out
update_held_items()
update_worn_handcuffs()
diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm
index 98827ae3ce3..6e0c7cef867 100644
--- a/code/modules/mob/living/carbon/damage_procs.dm
+++ b/code/modules/mob/living/carbon/damage_procs.dm
@@ -1,4 +1,4 @@
-/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, attacking_item)
+/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = 0, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, attacking_item)
SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMAGE, damage, damagetype, def_zone)
var/hit_percent = (100-blocked)/100
if(!damage || (!forced && hit_percent <= 0))
@@ -157,12 +157,14 @@
////////////////////////////////////////////
///Returns a list of damaged bodyparts
-/mob/living/carbon/proc/get_damaged_bodyparts(brute = FALSE, burn = FALSE, required_bodytype)
+/mob/living/carbon/proc/get_damaged_bodyparts(brute = FALSE, burn = FALSE, required_bodytype = NONE, target_zone = null)
var/list/obj/item/bodypart/parts = list()
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
if(required_bodytype && !(BP.bodytype & required_bodytype))
continue
+ if(!isnull(target_zone) && BP.body_zone != target_zone)
+ continue
if((brute && BP.brute_dam) || (burn && BP.burn_dam))
parts += BP
return parts
@@ -197,8 +199,8 @@
*
* It automatically updates health status
*/
-/mob/living/carbon/heal_bodypart_damage(brute = 0, burn = 0, updating_health = TRUE, required_bodytype)
- var/list/obj/item/bodypart/parts = get_damaged_bodyparts(brute, burn, required_bodytype)
+/mob/living/carbon/heal_bodypart_damage(brute = 0, burn = 0, updating_health = TRUE, required_bodytype = NONE, target_zone = null)
+ var/list/obj/item/bodypart/parts = get_damaged_bodyparts(brute, burn, required_bodytype, target_zone)
if(!parts.len)
return
var/obj/item/bodypart/picked = pick(parts)
diff --git a/code/modules/mob/living/carbon/death.dm b/code/modules/mob/living/carbon/death.dm
index 41eb4d518ba..87602d87f60 100644
--- a/code/modules/mob/living/carbon/death.dm
+++ b/code/modules/mob/living/carbon/death.dm
@@ -40,14 +40,14 @@
/mob/living/carbon/spill_organs(no_brain, no_organs, no_bodyparts)
var/atom/Tsec = drop_location()
if(!no_bodyparts)
- if(no_organs)//so the organs don't get transfered inside the bodyparts we'll drop.
+ if(no_organs)//so the organs don't get transferred inside the bodyparts we'll drop.
for(var/organ in organs)
if(no_brain || !istype(organ, /obj/item/organ/internal/brain))
qdel(organ)
else //we're going to drop all bodyparts except chest, so the only organs that needs spilling are those inside it.
for(var/obj/item/organ/organ as anything in organs)
if(no_brain && istype(organ, /obj/item/organ/internal/brain))
- qdel(organ) //so the brain isn't transfered to the head when the head drops.
+ qdel(organ) //so the brain isn't transferred to the head when the head drops.
continue
var/org_zone = check_zone(organ.zone) //both groin and chest organs.
if(org_zone == BODY_ZONE_CHEST && organ.drop_when_organ_spilling) //Zubbers change, checks for drop_when_organ_spilling
diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm
index 3d1e08f8151..75a31925c33 100644
--- a/code/modules/mob/living/carbon/examine.dm
+++ b/code/modules/mob/living/carbon/examine.dm
@@ -154,7 +154,7 @@
SEND_SIGNAL(src, COMSIG_ATOM_EXAMINE, user, .)
-//SKYRAT EDIT REMOVAL - MOVED - MEDICAL
+//SKYRAT EDIT REMOVAL - MOVED - MEDICAL - carbon_examine.dm
/*
/mob/living/carbon/examine_more(mob/user)
. = ..()
diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm
index 676a6dfc01f..395651d8d3e 100644
--- a/code/modules/mob/living/carbon/human/_species.dm
+++ b/code/modules/mob/living/carbon/human/_species.dm
@@ -198,6 +198,9 @@ GLOBAL_LIST_EMPTY(features_by_species)
**/
var/properly_gained = FALSE
+ ///A list containing outfits that will be overridden in the species_equip_outfit proc. [Key = Typepath passed in] [Value = Typepath of outfit you want to equip for this specific species instead].
+ var/list/outfit_override_registry = list()
+
///////////
// PROCS //
///////////
@@ -508,6 +511,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
C.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()
SEND_SIGNAL(C, COMSIG_SPECIES_GAIN, src, old_species)
@@ -841,6 +845,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
human_mob.undershirt = random_undershirt(human_mob.gender)
human_mob.underwear = random_underwear(human_mob.gender)
human_mob.socks = random_socks(human_mob.gender)
+ human_mob.bra = random_bra(human_mob.gender) //SKYRAT EDIT ADDITION - Underwear and Bra split
///Proc that will randomise the underwear (i.e. top, pants and socks) of a species' associated mob
/datum/species/proc/randomize_active_underwear(mob/living/carbon/human/human_mob)
@@ -1083,7 +1088,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
to_chat(source, span_danger("You feel weak."))
if(time_since_irradiated > RAD_MOB_VOMIT && SPT_PROB(RAD_MOB_VOMIT_PROB, seconds_per_tick))
- source.vomit(10, TRUE)
+ source.vomit(VOMIT_CATEGORY_BLOOD, lost_nutrition = 10)
if(time_since_irradiated > RAD_MOB_MUTATE && SPT_PROB(RAD_MOB_MUTATE_PROB, seconds_per_tick))
to_chat(source, span_danger("You mutate!"))
@@ -1324,7 +1329,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
if(!(prob(25 + (weapon.force * 2))))
return TRUE
- if(IS_ORGANIC_LIMB(affecting))
+ if(affecting.can_bleed())
weapon.add_mob_blood(human) //Make the weapon bloody, not the person.
if(prob(weapon.force * 2)) //blood spatter!
bloody = TRUE
@@ -1703,19 +1708,26 @@ GLOBAL_LIST_EMPTY(features_by_species)
// Lets pick a random body part and check for an existing burn
var/obj/item/bodypart/bodypart = pick(humi.bodyparts)
- var/datum/wound/burn/existing_burn = locate(/datum/wound/burn) in bodypart.wounds
-
+ var/datum/wound/existing_burn
+ for (var/datum/wound/iterated_wound as anything in bodypart.wounds)
+ var/datum/wound_pregen_data/pregen_data = iterated_wound.get_pregen_data()
+ if (pregen_data.wound_series in GLOB.wounding_types_to_series[WOUND_BURN])
+ existing_burn = iterated_wound
+ break
// If we have an existing burn try to upgrade it
+ var/severity
if(existing_burn)
switch(existing_burn.severity)
if(WOUND_SEVERITY_MODERATE)
if(humi.bodytemperature > BODYTEMP_HEAT_WOUND_LIMIT + 400) // 800k
- bodypart.force_wound_upwards(/datum/wound/burn/severe, wound_source = "hot temperatures")
+ severity = WOUND_SEVERITY_SEVERE
if(WOUND_SEVERITY_SEVERE)
if(humi.bodytemperature > BODYTEMP_HEAT_WOUND_LIMIT + 2800) // 3200k
- bodypart.force_wound_upwards(/datum/wound/burn/critical, wound_source = "hot temperatures")
+ severity = WOUND_SEVERITY_CRITICAL
else // If we have no burn apply the lowest level burn
- bodypart.force_wound_upwards(/datum/wound/burn/moderate, wound_source = "hot temperatures")
+ severity = WOUND_SEVERITY_MODERATE
+
+ humi.cause_wound_of_type_and_severity(WOUND_BURN, bodypart, severity, wound_source = "hot temperatures")
// always take some burn damage
var/burn_damage = HEAT_DAMAGE_LEVEL_1
diff --git a/code/modules/mob/living/carbon/human/damage_procs.dm b/code/modules/mob/living/carbon/human/damage_procs.dm
index 47cbbe12188..d4fc0b40365 100644
--- a/code/modules/mob/living/carbon/human/damage_procs.dm
+++ b/code/modules/mob/living/carbon/human/damage_procs.dm
@@ -1,4 +1,4 @@
/// depending on the species, it will run the corresponding apply_damage code there
-/mob/living/carbon/human/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, attacking_item)
+/mob/living/carbon/human/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = 0, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, attacking_item)
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src, forced, spread_damage, wound_bonus, bare_wound_bonus, sharpness, attack_direction, attacking_item)
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index ab05de68686..811c013d3b5 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -515,10 +515,10 @@
//Temporary flavor text addition:
if(temporary_flavor_text)
- if(length_char(temporary_flavor_text) <= 40)
+ if(length_char(temporary_flavor_text) < TEMPORARY_FLAVOR_PREVIEW_LIMIT)
. += span_notice("They look different than usual: [temporary_flavor_text]")
else
- . += span_notice("They look different than usual: [copytext_char(temporary_flavor_text, 1, 37)]... More...")
+ . += span_notice("They look different than usual: [copytext_char(temporary_flavor_text, 1, TEMPORARY_FLAVOR_PREVIEW_LIMIT)]... More...")
. += ""
SEND_SIGNAL(src, COMSIG_ATOM_EXAMINE, user, .)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 427d9cf1003..40e4bf095d5 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -741,15 +741,21 @@
return ..()
-/mob/living/carbon/human/vomit(lost_nutrition = 10, blood = FALSE, stun = TRUE, distance = 1, message = TRUE, vomit_type = VOMIT_TOXIC, harm = TRUE, force = FALSE, purge_ratio = 0.1)
- if(blood && HAS_TRAIT(src, TRAIT_NOBLOOD) && !HAS_TRAIT(src, TRAIT_TOXINLOVER))
- if(message)
- visible_message(span_warning("[src] dry heaves!"), \
- span_userdanger("You try to throw up, but there's nothing in your stomach!"))
- if(stun)
- Stun(20 SECONDS)
- return 1
- ..()
+/mob/living/carbon/human/vomit(vomit_flags = VOMIT_CATEGORY_DEFAULT, vomit_type = /obj/effect/decal/cleanable/vomit/toxic, lost_nutrition = 10, distance = 1, purge_ratio = 0.1)
+ if(!((vomit_flags & MOB_VOMIT_BLOOD) && HAS_TRAIT(src, TRAIT_NOBLOOD) && !HAS_TRAIT(src, TRAIT_TOXINLOVER)))
+ return ..()
+
+ if(vomit_flags & MOB_VOMIT_MESSAGE)
+ visible_message(
+ span_warning("[src] dry heaves!"),
+ span_userdanger("You try to throw up, but there's nothing in your stomach!"),
+ )
+ if(vomit_flags & MOB_VOMIT_STUN)
+ Stun(20 SECONDS)
+ if(vomit_flags & MOB_VOMIT_KNOCKDOWN)
+ Knockdown(20 SECONDS)
+
+ return TRUE
/mob/living/carbon/human/vv_edit_var(var_name, var_value)
if(var_name == NAMEOF(src, mob_height))
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index b8d21e60daa..bc951d49bb7 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -484,7 +484,7 @@
///Calculates the siemens coeff based on clothing and species, can also restart hearts.
-/mob/living/carbon/human/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
+/mob/living/carbon/human/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE, jitter_time = 20 SECONDS, stutter_time = 4 SECONDS, stun_duration = 4 SECONDS)
//Calculates the siemens coeff based on clothing. Completely ignores the arguments
if(flags & SHOCK_TESLA) //I hate this entire block. This gets the siemens_coeff for tesla shocks
if(gloves && gloves.siemens_coefficient <= 0)
@@ -521,7 +521,8 @@
var/obj/item/organ/internal/heart/heart = get_organ_slot(ORGAN_SLOT_HEART)
if(heart.Restart() && stat == CONSCIOUS)
to_chat(src, span_notice("You feel your heart beating again!"))
- electrocution_animation(40)
+ if (!(flags & SHOCK_NO_HUMAN_ANIM))
+ electrocution_animation(4 SECONDS)
/mob/living/carbon/human/acid_act(acidpwr, acid_volume, bodyzone_hit) //todo: update this to utilize check_obscured_slots() //and make sure it's check_obscured_slots(TRUE) to stop aciding through visors etc
var/list/damaged = list()
@@ -705,11 +706,7 @@
//SKYRAT EDIT ADDITION BEGIN - MEDICAL
if(body_part.current_gauze)
- var/datum/bodypart_aid/current_gauze = body_part.current_gauze
- combined_msg += "\t [span_notice("Your [body_part.name] is [current_gauze.desc_prefix] with [current_gauze.get_description()].")]"
- if(body_part.current_splint)
- var/datum/bodypart_aid/current_splint = body_part.current_splint
- combined_msg += "\t [span_notice("Your [body_part.name] is [current_splint.desc_prefix] with [current_splint.get_description()].")]"
+ combined_msg += "\t [span_notice("Your [body_part.name] is [body_part.current_gauze.get_gauze_usage_prefix()] with [body_part.current_gauze.get_gauze_description()].")]"
//SKYRAT EDIT END
for(var/t in missing)
diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm
index 41273946aa5..62fc77bc6ce 100644
--- a/code/modules/mob/living/carbon/human/human_helpers.dm
+++ b/code/modules/mob/living/carbon/human/human_helpers.dm
@@ -169,13 +169,15 @@
if(LAZYLEN(scar_data) != SCAR_SAVE_LENGTH)
return // invalid, should delete
var/version = text2num(scar_data[SCAR_SAVE_VERS])
- if(!version || version < SCAR_CURRENT_VERSION) // get rid of old scars
+ if(!version || version != SCAR_CURRENT_VERSION) // get rid of scars using a incompatable version
return
if(specified_char_index && (mind?.original_character_slot_index != specified_char_index))
return
+ if (isnull(text2num(scar_data[SCAR_SAVE_BIOLOGY])))
+ return
var/obj/item/bodypart/the_part = get_bodypart("[scar_data[SCAR_SAVE_ZONE]]")
var/datum/scar/scaries = new
- return scaries.load(the_part, scar_data[SCAR_SAVE_VERS], scar_data[SCAR_SAVE_DESC], scar_data[SCAR_SAVE_PRECISE_LOCATION], text2num(scar_data[SCAR_SAVE_SEVERITY]), text2num(scar_data[SCAR_SAVE_BIOLOGY]), text2num(scar_data[SCAR_SAVE_CHAR_SLOT]))
+ return scaries.load(the_part, scar_data[SCAR_SAVE_VERS], scar_data[SCAR_SAVE_DESC], scar_data[SCAR_SAVE_PRECISE_LOCATION], text2num(scar_data[SCAR_SAVE_SEVERITY]), text2num(scar_data[SCAR_SAVE_BIOLOGY]), text2num(scar_data[SCAR_SAVE_CHAR_SLOT]), text2num(scar_data[SCAR_SAVE_CHECK_ANY_BIO]))
/// Read all the scars we have for the designated character/scar slots, verify they're good/dump them if they're old/wrong format, create them on the user, and write the scars that passed muster back to the file
/mob/living/carbon/human/proc/load_persistent_scars()
@@ -245,7 +247,6 @@
destination.socks = socks
destination.jumpsuit_style = jumpsuit_style
-
/// Fully randomizes everything according to the given flags.
/mob/living/carbon/human/proc/randomize_human_appearance(randomize_flags = ALL)
var/datum/preferences/preferences = new(new /datum/client_interface)
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index 84ba816d3c4..aed1beafd16 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -405,6 +405,22 @@
return O.equip(src, visualsOnly)
+///A version of equipOutfit that overrides passed in outfits with their entry on the species' outfit override registry
+/mob/living/carbon/human/proc/equip_species_outfit(outfit, visualsOnly = FALSE)
+ var/datum/outfit/outfit_to_equip
+
+ var/override_outfit_path = dna?.species.outfit_override_registry[outfit]
+ if(override_outfit_path)
+ outfit_to_equip = new override_outfit_path
+ else
+ outfit_to_equip = new outfit
+
+ if(isnull(outfit_to_equip))
+ return FALSE
+
+ return outfit_to_equip.equip(src, visualsOnly)
+
+
//delete all equipment without dropping anything
/mob/living/carbon/human/proc/delete_equipment()
for(var/slot in get_all_worn_items())//order matters, dependant slots go first
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 8c7c8fd61f7..c91fc7d6638 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -19,7 +19,7 @@
#define THERMAL_PROTECTION_HAND_RIGHT 0.025
/mob/living/carbon/human/Life(seconds_per_tick = SSMOBS_DT, times_fired)
- if(notransform)
+ if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
return
. = ..()
@@ -279,7 +279,7 @@
lastpuke += SPT_PROB(30, seconds_per_tick)
if(lastpuke >= 50) // about 25 second delay I guess // This is actually closer to 150 seconds
- vomit(20)
+ vomit(VOMIT_CATEGORY_DEFAULT, lost_nutrition = 20)
lastpuke = 0
diff --git a/code/modules/mob/living/carbon/human/species_types/abductors.dm b/code/modules/mob/living/carbon/human/species_types/abductors.dm
index 182027e1ea4..f3439891c2e 100644
--- a/code/modules/mob/living/carbon/human/species_types/abductors.dm
+++ b/code/modules/mob/living/carbon/human/species_types/abductors.dm
@@ -9,6 +9,8 @@
TRAIT_VIRUSIMMUNE,
TRAIT_NOBLOOD,
TRAIT_CHUNKYFINGERS_IGNORE_BATON,
+ TRAIT_NODISMEMBER,
+ TRAIT_NEVER_WOUNDED
)
mutanttongue = /obj/item/organ/internal/tongue/abductor
mutantstomach = null
diff --git a/code/modules/mob/living/carbon/human/species_types/ethereal.dm b/code/modules/mob/living/carbon/human/species_types/ethereal.dm
index 6ed5d951006..ec7beae093f 100644
--- a/code/modules/mob/living/carbon/human/species_types/ethereal.dm
+++ b/code/modules/mob/living/carbon/human/species_types/ethereal.dm
@@ -68,6 +68,7 @@
RegisterSignal(ethereal, COMSIG_ATOM_EMAG_ACT, PROC_REF(on_emag_act))
RegisterSignal(ethereal, COMSIG_ATOM_EMP_ACT, PROC_REF(on_emp_act))
RegisterSignal(ethereal, COMSIG_LIGHT_EATER_ACT, PROC_REF(on_light_eater))
+ RegisterSignal(ethereal, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur))
ethereal_light = ethereal.mob_light(light_type = /obj/effect/dummy/lighting_obj/moblight/species)
spec_updatehealth(ethereal)
new_ethereal.set_safe_hunger_level()
@@ -84,6 +85,7 @@
UnregisterSignal(former_ethereal, COMSIG_ATOM_EMAG_ACT)
UnregisterSignal(former_ethereal, COMSIG_ATOM_EMP_ACT)
UnregisterSignal(former_ethereal, COMSIG_LIGHT_EATER_ACT)
+ UnregisterSignal(former_ethereal, COMSIG_HIT_BY_SABOTEUR)
QDEL_NULL(ethereal_light)
return ..()
@@ -147,6 +149,16 @@
if(EMP_HEAVY)
addtimer(CALLBACK(src, PROC_REF(stop_emp), H), 20 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) //We're out for 20 seconds
+/datum/species/ethereal/proc/on_saboteur(datum/source, disrupt_duration)
+ SIGNAL_HANDLER
+ var/mob/living/carbon/human/our_target = source
+ EMPeffect = TRUE
+ spec_updatehealth(our_target)
+ to_chat(our_target, span_warning("Something inside of you crackles in a bad way."))
+ our_target.take_bodypart_damage(burn = 3, wound_bonus = CANT_WOUND)
+ addtimer(CALLBACK(src, PROC_REF(stop_emp), our_target), disrupt_duration, TIMER_UNIQUE|TIMER_OVERRIDE)
+ return COMSIG_SABOTEUR_SUCCESS
+
/datum/species/ethereal/proc/on_emag_act(mob/living/carbon/human/H, mob/user)
SIGNAL_HANDLER
if(emageffect)
diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm
index cf16c236605..3f5f46edf6c 100644
--- a/code/modules/mob/living/carbon/human/species_types/golems.dm
+++ b/code/modules/mob/living/carbon/human/species_types/golems.dm
@@ -7,7 +7,6 @@
TRAIT_GENELESS,
TRAIT_LAVA_IMMUNE,
TRAIT_NOBREATH,
- TRAIT_NODISMEMBER,
TRAIT_NOBLOOD,
TRAIT_NOFIRE,
TRAIT_PIERCEIMMUNE,
@@ -15,6 +14,8 @@
TRAIT_NO_DNA_COPY,
TRAIT_NO_TRANSFORMATION_STING,
TRAIT_NO_AUGMENTS,
+ TRAIT_NODISMEMBER,
+ TRAIT_NEVER_WOUNDED
)
mutantheart = null
mutantlungs = null
diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
index 31d42874b82..82f0e88c2bd 100644
--- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
@@ -277,12 +277,12 @@
if(!isslimeperson(H))
return
CHECK_DNA_AND_SPECIES(H)
- H.visible_message("[owner] gains a look of \
- concentration while standing perfectly still.",
- "You focus intently on moving your body while \
- standing perfectly still...")
+ H.visible_message(
+ span_notice("[owner] gains a look of concentration while standing perfectly still."),
+ span_notice("You focus intently on moving your body while standing perfectly still..."),
+ )
- H.notransform = TRUE
+ ADD_TRAIT(src, TRAIT_NO_TRANSFORM, REF(src))
if(do_after(owner, delay = 6 SECONDS, target = owner, timed_action_flags = IGNORE_HELD_ITEM))
if(H.blood_volume >= BLOOD_VOLUME_SLIME_SPLIT)
@@ -292,7 +292,7 @@
else
to_chat(H, span_warning("...but fail to stand perfectly still!"))
- H.notransform = FALSE
+ REMOVE_TRAIT(src, TRAIT_NO_TRANSFORM, REF(src))
/datum/action/innate/split_body/proc/make_dupe()
var/mob/living/carbon/human/H = owner
@@ -311,7 +311,7 @@
spare.Move(get_step(H.loc, pick(NORTH,SOUTH,EAST,WEST)))
H.blood_volume *= 0.45
- H.notransform = 0
+ REMOVE_TRAIT(H, TRAIT_NO_TRANSFORM, REF(src))
var/datum/species/jelly/slime/origin_datum = H.dna.species
origin_datum.bodies |= spare
@@ -321,10 +321,10 @@
H.transfer_quirk_datums(spare)
H.mind.transfer_to(spare)
- spare.visible_message("[H] distorts as a new body \
- \"steps out\" of [H.p_them()].",
- "...and after a moment of disorentation, \
- you're besides yourself!")
+ spare.visible_message(
+ span_warning("[H] distorts as a new body \"steps out\" of [H.p_them()]."),
+ span_notice("...and after a moment of disorentation, you're besides yourself!"),
+ )
/datum/action/innate/swap_body
diff --git a/code/modules/mob/living/carbon/human/species_types/monkeys.dm b/code/modules/mob/living/carbon/human/species_types/monkeys.dm
index ce276fd7db2..db600946e2b 100644
--- a/code/modules/mob/living/carbon/human/species_types/monkeys.dm
+++ b/code/modules/mob/living/carbon/human/species_types/monkeys.dm
@@ -49,13 +49,13 @@
/datum/species/monkey/on_species_gain(mob/living/carbon/human/H, datum/species/old_species)
. = ..()
- H.pass_flags |= PASSTABLE
+ passtable_on(H, SPECIES_TRAIT)
H.dna.add_mutation(/datum/mutation/human/race, MUT_NORMAL)
H.dna.activate_mutation(/datum/mutation/human/race)
/datum/species/monkey/on_species_loss(mob/living/carbon/C)
. = ..()
- C.pass_flags = initial(C.pass_flags)
+ passtable_off(C, SPECIES_TRAIT)
C.dna.remove_mutation(/datum/mutation/human/race)
/datum/species/monkey/spec_unarmedattack(mob/living/carbon/human/user, atom/target, modifiers)
diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
index cf4f33f5ea8..de1daa1b557 100644
--- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
+++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
@@ -51,6 +51,13 @@
ass_image = 'icons/ass/assplasma.png'
+ outfit_override_registry = list(
+ /datum/outfit/syndicate = /datum/outfit/syndicate/plasmaman,
+ /datum/outfit/syndicate/full = /datum/outfit/syndicate/full/plasmaman,
+ /datum/outfit/syndicate/leader = /datum/outfit/syndicate/leader/plasmaman,
+ /datum/outfit/syndicate/reinforcement = /datum/outfit/syndicate/reinforcement/plasmaman,
+ )
+
/// If the bones themselves are burning clothes won't help you much
var/internal_fire = FALSE
diff --git a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
index d7b8fdf34db..a8b1be203a3 100644
--- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
@@ -10,6 +10,8 @@
TRAIT_RADIMMUNE,
TRAIT_VIRUSIMMUNE,
TRAIT_NOBLOOD,
+ TRAIT_NODISMEMBER,
+ TRAIT_NEVER_WOUNDED
)
inherent_factions = list(FACTION_FAITHLESS)
changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index 2f8ca84a59e..e66d72a2c44 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -1,5 +1,5 @@
/mob/living/carbon/Life(seconds_per_tick = SSMOBS_DT, times_fired)
- if(notransform)
+ if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
return
//SKYRAT EDIT ADDITION
@@ -124,8 +124,8 @@
failed_last_breath = FALSE
clear_alert("not_enough_oxy")
return FALSE
- adjustOxyLoss(3)
- failed_last_breath = TRUE
+ breath = null // uh oh where'd the air go
+ check_breath(breath)
if(oxyloss <= OXYGEN_DAMAGE_CHOKING_THRESHOLD && stat == CONSCIOUS)
to_chat(src, "You hold in your breath!")
else
@@ -375,13 +375,13 @@
if(prob(5))
to_chat(src, span_warning("The stench of rotting carcasses is unbearable!"))
add_mood_event("smell", /datum/mood_event/disgust/nauseating_stench)
- vomit()
+ vomit(VOMIT_CATEGORY_DEFAULT)
if(30 to INFINITY)
//Higher chance to vomit. Let the horror start
if(prob(25))
to_chat(src, span_warning("The stench of rotting carcasses is unbearable!"))
add_mood_event("smell", /datum/mood_event/disgust/nauseating_stench)
- vomit()
+ vomit(VOMIT_CATEGORY_DEFAULT)
else
clear_mood_event("smell")
@@ -719,7 +719,7 @@
var/datum/reagent/bits = bile
if(istype(bits, /datum/reagent/consumable))
var/datum/reagent/consumable/goodbit = bile
- fullness += goodbit.nutriment_factor * goodbit.volume / goodbit.metabolization_rate
+ fullness += goodbit.get_nutriment_factor() * goodbit.volume / goodbit.metabolization_rate
continue
fullness += 0.6 * bits.volume / bits.metabolization_rate //not food takes up space
diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm
index 439101151c6..dfae5d2baf1 100644
--- a/code/modules/mob/living/damage_procs.dm
+++ b/code/modules/mob/living/damage_procs.dm
@@ -14,7 +14,7 @@
*
* Returns TRUE if damage applied
*/
-/mob/living/proc/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, attacking_item)
+/mob/living/proc/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = 0, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, attacking_item)
SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMAGE, damage, damagetype, def_zone)
var/hit_percent = (100-blocked)/100
if(!damage || (!forced && hit_percent <= 0))
@@ -323,7 +323,7 @@
*
* needs to return amount healed in order to calculate things like tend wounds xp gain
*/
-/mob/living/proc/heal_bodypart_damage(brute = 0, burn = 0, updating_health = TRUE, required_bodytype)
+/mob/living/proc/heal_bodypart_damage(brute = 0, burn = 0, updating_health = TRUE, required_bodytype = NONE, target_zone = null)
. = (adjustBruteLoss(-brute, FALSE) + adjustFireLoss(-burn, FALSE)) //zero as argument for no instant health update
if(updating_health)
updatehealth()
diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm
index 356438ed536..cb4d4a8241a 100644
--- a/code/modules/mob/living/emote.dm
+++ b/code/modules/mob/living/emote.dm
@@ -554,6 +554,8 @@
key_third_person = "yawns"
message = "yawns."
message_mime = "acts out an exaggerated silent yawn."
+ message_robot = "symphathetically yawns."
+ message_AI = "symphathetically yawns."
emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
cooldown = 5 SECONDS
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index 95b7da5b9da..aacdc60b56a 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -34,9 +34,7 @@
log_game("Z-TRACKING: [src] of type [src.type] has a Z-registration despite not having a client.")
update_z(null)
- if (notransform)
- return
- if(!loc)
+ if(isnull(loc) || HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
return
if(!IS_IN_STASIS(src))
@@ -49,8 +47,6 @@
handle_diseases(seconds_per_tick, times_fired)// DEAD check is in the proc itself; we want it to spread even if the mob is dead, but to handle its disease-y properties only if you're not.
- handle_wounds(seconds_per_tick, times_fired)
-
if (QDELETED(src)) // diseases can qdel the mob via transformations
return
@@ -65,6 +61,8 @@
handle_gravity(seconds_per_tick, times_fired)
+ handle_wounds(seconds_per_tick, times_fired)
+
if(machine)
machine.check_eye(src)
@@ -116,7 +114,7 @@
for(var/bile in reagents.reagent_list)
var/datum/reagent/consumable/bits = bile
if(bits)
- fullness += bits.nutriment_factor * bits.volume / bits.metabolization_rate
+ fullness += bits.get_nutriment_factor() * bits.volume / bits.metabolization_rate
return fullness
/**
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index fcad88fdf4d..c6a587ec2e2 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -1329,7 +1329,7 @@
to_chat(src, span_warning("You don't have the physical ability to do this!"))
return FALSE
- if(!Adjacent(target) && (target.loc != src))
+ if(!Adjacent(target) && (target.loc != src) && !recursive_loc_check(src, target))
if(issilicon(src) && !ispAI(src))
if(!(action_bitflags & ALLOW_SILICON_REACH)) // silicons can ignore range checks (except pAIs)
to_chat(src, span_warning("You are too far away!"))
@@ -1392,14 +1392,13 @@
* Returns a mob (what our mob turned into) or null (if we failed).
*/
/mob/living/proc/wabbajack(what_to_randomize, change_flags = WABBAJACK)
- if(stat == DEAD || notransform || (GODMODE & status_flags))
+ if(stat == DEAD || (GODMODE & status_flags) || HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
return
if(SEND_SIGNAL(src, COMSIG_LIVING_PRE_WABBAJACKED, what_to_randomize) & STOP_WABBAJACK)
return
- notransform = TRUE
- add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), MAGIC_TRAIT)
+ add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED, TRAIT_NO_TRANSFORM), MAGIC_TRAIT)
icon = null
cut_overlays()
invisibility = INVISIBILITY_ABSTRACT
@@ -2534,7 +2533,7 @@ GLOBAL_LIST_EMPTY(fire_appearances)
mob_mood.clear_mood_event(mood_events[chosen])
/// Adds a mood event to the mob
-/mob/living/proc/add_mood_event(category, type, ...)
+/mob/living/proc/add_mood_event(category, type, timeout_mod, ...)
if(QDELETED(mob_mood))
return
mob_mood.add_mood_event(arglist(args))
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 6c3f397f6ba..c157603ea83 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -131,6 +131,8 @@
for (var/law in laws.inherent)
lawcheck += law
+ create_eye()
+
if(target_ai.mind)
target_ai.mind.transfer_to(src)
if(mind.special_role)
@@ -152,8 +154,6 @@
job = "AI"
- create_eye()
-
create_modularInterface()
// /mob/living/silicon/ai/apply_prefs_job() uses these to set these procs at mapload
@@ -205,10 +205,6 @@
interaction_range = 1
sprint = 5
-/mob/living/silicon/ai/weak_syndie/Initialize(mapload, datum/ai_laws/L, mob/target_ai)
- . = ..()
- laws = new /datum/ai_laws/syndicate_override
-
/mob/living/silicon/ai/key_down(_key, client/user)
if(findtext(_key, "numpad")) //if it's a numpad number, we can convert it to just the number
_key = _key[7] //strings, lists, same thing really
@@ -866,24 +862,25 @@
/mob/living/silicon/ai/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card)
if(!..())
return
- if(interaction == AI_TRANS_TO_CARD)//The only possible interaction. Upload AI mob to a card.
- if(!can_be_carded)
- to_chat(user, span_boldwarning("Transfer failed."))
- return
- disconnect_shell() //If the AI is controlling a borg, force the player back to core!
- if(!mind)
- to_chat(user, span_warning("No intelligence patterns detected."))
- return
- ShutOffDoomsdayDevice()
- var/obj/structure/ai_core/new_core = new /obj/structure/ai_core/deactivated(loc, posibrain_inside)//Spawns a deactivated terminal at AI location.
- new_core.circuit.battery = battery
- ai_restore_power()//So the AI initially has power.
- control_disabled = TRUE //Can't control things remotely if you're stuck in a card!
- radio_enabled = FALSE //No talking on the built-in radio for you either!
- forceMove(card)
- card.AI = src
- to_chat(src, "You have been downloaded to a mobile storage device. Remote device connection severed.")
- to_chat(user, "[span_boldnotice("Transfer successful")]: [name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory.")
+ if(interaction != AI_TRANS_TO_CARD)//The only possible interaction. Upload AI mob to a card.
+ return
+ if(!can_be_carded)
+ balloon_alert(user, "transfer failed!")
+ return
+ disconnect_shell() //If the AI is controlling a borg, force the player back to core!
+ if(!mind)
+ balloon_alert(user, "no intelligence detected!") // average tg coder am i right
+ return
+ ShutOffDoomsdayDevice()
+ var/obj/structure/ai_core/new_core = new /obj/structure/ai_core/deactivated(loc, posibrain_inside)//Spawns a deactivated terminal at AI location.
+ new_core.circuit.battery = battery
+ ai_restore_power()//So the AI initially has power.
+ control_disabled = TRUE //Can't control things remotely if you're stuck in a card!
+ radio_enabled = FALSE //No talking on the built-in radio for you either!
+ forceMove(card)
+ card.AI = src
+ to_chat(src, "You have been downloaded to a mobile storage device. Remote device connection severed.")
+ to_chat(user, "[span_boldnotice("Transfer successful")]: [name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory.")
/mob/living/silicon/ai/can_perform_action(atom/movable/target, action_bitflags)
if(control_disabled)
diff --git a/code/modules/mob/living/silicon/ai/multicam.dm b/code/modules/mob/living/silicon/ai/multicam.dm
index e5bcd813b7e..45924e2fe98 100644
--- a/code/modules/mob/living/silicon/ai/multicam.dm
+++ b/code/modules/mob/living/silicon/ai/multicam.dm
@@ -86,7 +86,7 @@
name = ""
icon = 'icons/misc/pic_in_pic.dmi'
icon_state = "room_background"
- flags_1 = NOJAUNT
+ turf_flags = NOJAUNT
/turf/open/ai_visible/Initialize(mapload)
. = ..()
diff --git a/code/modules/mob/living/silicon/damage_procs.dm b/code/modules/mob/living/silicon/damage_procs.dm
index 59db1264a30..8ee146508a4 100644
--- a/code/modules/mob/living/silicon/damage_procs.dm
+++ b/code/modules/mob/living/silicon/damage_procs.dm
@@ -1,5 +1,5 @@
-/mob/living/silicon/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, attacking_item)
+/mob/living/silicon/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = 0, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, attacking_item)
var/hit_percent = (100-blocked)/100
if((!damage || (!forced && hit_percent <= 0)))
return 0
diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm
index 0f3dde4b359..ae56f65b0cd 100644
--- a/code/modules/mob/living/silicon/robot/life.dm
+++ b/code/modules/mob/living/silicon/robot/life.dm
@@ -1,5 +1,5 @@
/mob/living/silicon/robot/Life(seconds_per_tick = SSMOBS_DT, times_fired)
- if (src.notransform)
+ if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
return
..()
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 9732222f0cf..30559e616b5 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -19,6 +19,7 @@
AddElement(/datum/element/ridable, /datum/component/riding/creature/cyborg)
RegisterSignal(src, COMSIG_PROCESS_BORGCHARGER_OCCUPANT, PROC_REF(charge))
RegisterSignal(src, COMSIG_LIGHT_EATER_ACT, PROC_REF(on_light_eater))
+ RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur))
robot_modules_background = new()
robot_modules_background.icon_state = "block"
@@ -470,6 +471,13 @@
smash_headlamp()
return COMPONENT_BLOCK_LIGHT_EATER
+/// special handling for getting shot with a light disruptor/saboteur e.g. the fisher
+/mob/living/silicon/robot/proc/on_saboteur(datum/source, disrupt_duration)
+ SIGNAL_HANDLER
+ if(lamp_enabled)
+ toggle_headlamp(TRUE)
+ to_chat(src, span_warning("Your headlamp was forcibly turned off. Restarting it should fix it, though."))
+ return COMSIG_SABOTEUR_SUCCESS
/**
* Handles headlamp smashing
diff --git a/code/modules/mob/living/silicon/robot/robot_model.dm b/code/modules/mob/living/silicon/robot/robot_model.dm
index 451abb50805..f47fb8648de 100644
--- a/code/modules/mob/living/silicon/robot/robot_model.dm
+++ b/code/modules/mob/living/silicon/robot/robot_model.dm
@@ -237,6 +237,9 @@
return new_model
/obj/item/robot_model/proc/be_transformed_to(obj/item/robot_model/old_model, forced = FALSE)
+ if(HAS_TRAIT(robot, TRAIT_NO_TRANSFORM))
+ robot.balloon_alert(robot, "can't transform right now!")
+ return FALSE
if(islist(borg_skins) && !forced)
var/mob/living/silicon/robot/cyborg = loc
var/list/reskin_icons = list()
@@ -294,7 +297,7 @@
var/mob/living/silicon/robot/cyborg = loc
sleep(0.1 SECONDS)
flick("[cyborg_base_icon]_transform", cyborg)
- cyborg.notransform = TRUE
+ ADD_TRAIT(cyborg, TRAIT_NO_TRANSFORM, REF(src))
if(locked_transform)
cyborg.ai_lockdown = TRUE
cyborg.SetLockdown(TRUE)
@@ -308,7 +311,7 @@
cyborg.ai_lockdown = FALSE
cyborg.setDir(SOUTH)
cyborg.set_anchored(FALSE)
- cyborg.notransform = FALSE
+ REMOVE_TRAIT(cyborg, TRAIT_NO_TRANSFORM, REF(src))
cyborg.updatehealth()
cyborg.update_icons()
cyborg.notify_ai(AI_NOTIFICATION_NEW_MODEL)
@@ -682,7 +685,7 @@
/obj/item/circular_saw,
/obj/item/bonesetter,
/obj/item/extinguisher/mini,
- /obj/item/roller/robo,
+ /obj/item/emergency_bed/silicon,
/obj/item/borg/cyborghug/medical,
/obj/item/stack/medical/gauze,
/obj/item/stack/medical/bone_gel,
@@ -901,7 +904,7 @@
/obj/item/melee/energy/sword/cyborg/saw,
/obj/item/bonesetter,
/obj/item/blood_filter,
- /obj/item/roller/robo,
+ /obj/item/emergency_bed/silicon,
/obj/item/crowbar/cyborg,
/obj/item/extinguisher/mini,
/obj/item/pinpointer/syndicate_cyborg,
diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
index b4b4dd80f7f..71008588465 100644
--- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
@@ -92,7 +92,7 @@
)
/mob/living/simple_animal/bot/cleanbot/autopatrol
- bot_mode_flags = BOT_MODE_ON | BOT_MODE_AUTOPATROL | BOT_MODE_REMOTE_ENABLED | BOT_MODE_CAN_BE_SAPIENT
+ bot_mode_flags = BOT_MODE_ON | BOT_MODE_AUTOPATROL | BOT_MODE_REMOTE_ENABLED | BOT_MODE_CAN_BE_SAPIENT | BOT_MODE_ROUNDSTART_POSSESSION
/mob/living/simple_animal/bot/cleanbot/medbay
name = "Scrubs, MD"
diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm
index d01e36c334b..12f33dec723 100644
--- a/code/modules/mob/living/simple_animal/bot/construction.dm
+++ b/code/modules/mob/living/simple_animal/bot/construction.dm
@@ -273,6 +273,10 @@
switch(build_step)
if(ASSEMBLY_FIRST_STEP)
if(istype(W, /obj/item/healthanalyzer))
+ var/obj/item/healthanalyzer/analyzer = W // SKYRAT EDIT ADDITION BEGIN -- EXTRA ROBOTICS HEALTH ANALYZERS
+ if (!analyzer.can_be_used_in_medibot())
+ user?.balloon_alert(user, "no attachment ports!")
+ return // SKYRAT EDIT ADDITION END
if(!user.temporarilyRemoveItemFromInventory(W))
return
healthanalyzer = W.type
diff --git a/code/modules/mob/living/simple_animal/bot/honkbot.dm b/code/modules/mob/living/simple_animal/bot/honkbot.dm
index 8c46d8bec9c..220c4a5ccce 100644
--- a/code/modules/mob/living/simple_animal/bot/honkbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/honkbot.dm
@@ -9,7 +9,7 @@
radio_key = /obj/item/encryptionkey/headset_service //doesn't have security key
radio_channel = RADIO_CHANNEL_SERVICE //Doesn't even use the radio anyway.
bot_type = HONK_BOT
- bot_mode_flags = BOT_MODE_ON | BOT_MODE_REMOTE_ENABLED | BOT_MODE_CAN_BE_SAPIENT | BOT_MODE_AUTOPATROL
+ bot_mode_flags = BOT_MODE_ON | BOT_MODE_REMOTE_ENABLED | BOT_MODE_CAN_BE_SAPIENT | BOT_MODE_AUTOPATROL | BOT_MODE_ROUNDSTART_POSSESSION
hackables = "sound control systems"
path_image_color = "#FF69B4"
data_hud_type = DATA_HUD_SECURITY_BASIC //show jobs
diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm
index f3b9040e4b1..9c06465b8a5 100644
--- a/code/modules/mob/living/simple_animal/bot/medbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/medbot.dm
@@ -102,6 +102,8 @@
var/tipped_status = MEDBOT_PANIC_NONE
///The name we got when we were tipped
var/tipper_name
+ ///The trim type that will grant additional access to this medibot
+ var/datum/id_trim/additional_access = /datum/id_trim/job/paramedic
///Last announced healing a person in critical condition
COOLDOWN_DECLARE(last_patient_message)
@@ -111,7 +113,7 @@
COOLDOWN_DECLARE(last_tipping_action_voice)
/mob/living/simple_animal/bot/medbot/autopatrol
- bot_mode_flags = BOT_MODE_ON | BOT_MODE_AUTOPATROL | BOT_MODE_REMOTE_ENABLED | BOT_MODE_CAN_BE_SAPIENT
+ bot_mode_flags = BOT_MODE_ON | BOT_MODE_AUTOPATROL | BOT_MODE_REMOTE_ENABLED | BOT_MODE_CAN_BE_SAPIENT | BOT_MODE_ROUNDSTART_POSSESSION
/mob/living/simple_animal/bot/medbot/stationary
medical_mode_flags = MEDBOT_DECLARE_CRIT | MEDBOT_STATIONARY_MODE | MEDBOT_SPEAK_MODE
@@ -144,6 +146,7 @@
damagetype_healer = "all"
heal_threshold = 0
heal_amount = 5
+ additional_access = /datum/id_trim/syndicom/crew
/mob/living/simple_animal/bot/medbot/nukie/Initialize(mapload, new_skin)
. = ..()
@@ -152,6 +155,7 @@
RegisterSignal(SSdcs, COMSIG_GLOB_NUKE_DEVICE_DETONATING, PROC_REF(nuke_detonate))
internal_radio.set_frequency(FREQ_SYNDICATE)
internal_radio.freqlock = RADIO_FREQENCY_LOCKED
+ faction += ROLE_SYNDICATE //one of us
/mob/living/simple_animal/bot/medbot/nukie/proc/nuke_disarm()
SIGNAL_HANDLER
@@ -204,15 +208,20 @@
. = ..()
// Doing this hurts my soul, but simplebot access reworks are for another day.
- var/datum/id_trim/job/para_trim = SSid_access.trim_singletons_by_path[/datum/id_trim/job/paramedic]
- access_card.add_access(para_trim.access + para_trim.wildcard_access)
+ var/datum/id_trim/additional_trim = SSid_access.trim_singletons_by_path[additional_access]
+ access_card.add_access(additional_trim.access + additional_trim.wildcard_access)
prev_access = access_card.access.Copy()
if(!isnull(new_skin))
skin = new_skin
update_appearance()
- if(!CONFIG_GET(flag/no_default_techweb_link) && !linked_techweb)
- linked_techweb = SSresearch.science_tech
+
+ if(HAS_TRAIT(SSstation, STATION_TRAIT_MEDBOT_MANIA) && mapload && is_station_level(z))
+ skin = "advanced"
+ update_appearance(UPDATE_OVERLAYS)
+ damagetype_healer = "all"
+ if(prob(50))
+ name += ", PhD."
AddComponent(/datum/component/tippable, \
tip_time = 3 SECONDS, \
@@ -221,6 +230,12 @@
pre_tipped_callback = CALLBACK(src, PROC_REF(pre_tip_over)), \
post_tipped_callback = CALLBACK(src, PROC_REF(after_tip_over)), \
post_untipped_callback = CALLBACK(src, PROC_REF(after_righted)))
+ return INITIALIZE_HINT_LATELOAD
+
+/mob/living/simple_animal/bot/medbot/LateInitialize()
+ . = ..()
+ if(!CONFIG_GET(flag/no_default_techweb_link) && !linked_techweb)
+ CONNECT_TO_RND_SERVER_ROUNDSTART(linked_techweb, src)
/mob/living/simple_animal/bot/medbot/bot_reset()
..()
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
index b095016827f..a0f078acd92 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
@@ -74,7 +74,7 @@
/// Default [/mob/living/simple_animal/drone/var/internal_storage] item
var/obj/item/default_storage = /obj/item/storage/drone_tools
/// Default [/mob/living/simple_animal/drone/var/head] item
- var/obj/item/default_hatmask
+ var/obj/item/default_headwear
/**
* icon_state of drone from icons/mobs/drone.dmi
*
@@ -181,9 +181,16 @@
if(default_storage)
var/obj/item/I = new default_storage(src)
equip_to_slot_or_del(I, ITEM_SLOT_DEX_STORAGE)
- if(default_hatmask)
- var/obj/item/I = new default_hatmask(src)
- equip_to_slot_or_del(I, ITEM_SLOT_HEAD)
+
+ for(var/holiday_name in GLOB.holidays)
+ var/datum/holiday/holiday_today = GLOB.holidays[holiday_name]
+ var/obj/item/potential_hat = holiday_today.holiday_hat
+ if(!isnull(potential_hat) && isnull(default_headwear)) //If our drone type doesn't start with a hat, we take the holiday one.
+ default_headwear = potential_hat
+
+ if(default_headwear)
+ var/obj/item/new_hat = new default_headwear(src)
+ equip_to_slot_or_del(new_hat, ITEM_SLOT_HEAD)
ADD_TRAIT(access_card, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT)
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
index 38c3585271a..d4353c95c82 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
@@ -27,7 +27,7 @@
"2. Kill.\n"+\
"3. Destroy."
default_storage = /obj/item/uplink
- default_hatmask = /obj/item/clothing/head/helmet/swat
+ default_headwear = /obj/item/clothing/head/helmet/swat
hacked = TRUE
shy = FALSE
flavortext = null
@@ -49,7 +49,7 @@
W.implant(src, force = TRUE)
/mob/living/simple_animal/drone/snowflake
- default_hatmask = /obj/item/clothing/head/chameleon/drone
+ default_headwear = /obj/item/clothing/head/chameleon/drone
/mob/living/simple_animal/drone/snowflake/Initialize(mapload)
. = ..()
@@ -87,7 +87,7 @@
/mob/living/simple_animal/drone/polymorphed
default_storage = null
- default_hatmask = null
+ default_headwear = null
picked = TRUE
flavortext = null
@@ -132,7 +132,7 @@
/mob/living/simple_animal/drone/derelict
name = "derelict drone"
- default_hatmask = /obj/item/clothing/head/costume/ushanka
+ default_headwear = /obj/item/clothing/head/costume/ushanka
laws = \
"1. You may not involve yourself in the matters of another sentient being outside the station that housed your activation, even if such matters conflict with Law Two or Law Three, unless the other being is another Drone.\n"+\
"2. You may not harm any sentient being, regardless of intent or circumstance.\n"+\
diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
index baeb6123d25..af1b4eb1370 100644
--- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
+++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
@@ -11,7 +11,7 @@
emote_see = list("shakes their head.", "stamps a foot.", "glares around.")
speak_chance = 1
turns_per_move = 5
- butcher_results = list(/obj/item/food/meat/slab = 4)
+ butcher_results = list(/obj/item/food/meat/slab/grassfed = 4)
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
diff --git a/code/modules/mob/living/simple_animal/guardian/guardian_creator.dm b/code/modules/mob/living/simple_animal/guardian/guardian_creator.dm
index b57ae45e1b7..ebd5658f07f 100644
--- a/code/modules/mob/living/simple_animal/guardian/guardian_creator.dm
+++ b/code/modules/mob/living/simple_animal/guardian/guardian_creator.dm
@@ -87,9 +87,10 @@ GLOBAL_LIST_INIT(guardian_radial_images, setup_guardian_radial())
if(LAZYLEN(candidates))
var/mob/dead/observer/candidate = pick(candidates)
spawn_guardian(user, candidate, guardian_path)
+ used = TRUE
+ SEND_SIGNAL(src, COMSIG_TRAITOR_ITEM_USED(type))
else
to_chat(user, failure_message)
- used = FALSE
/obj/item/guardiancreator/proc/spawn_guardian(mob/living/user, mob/dead/candidate, guardian_path)
if(QDELETED(user) || user.stat == DEAD)
diff --git a/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm b/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm
deleted file mode 100644
index 5ecdf09d6ec..00000000000
--- a/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm
+++ /dev/null
@@ -1,139 +0,0 @@
-/mob/living/simple_animal/hostile/boss
- name = "\improper A Perfectly Generic Boss Placeholder"
- desc = ""
- robust_searching = 1
- stat_attack = HARD_CRIT
- status_flags = 0
- combat_mode = TRUE
- sentience_type = SENTIENCE_BOSS
- gender = NEUTER
- var/list/boss_abilities = list() //list of /datum/action/boss
- var/datum/boss_active_timed_battle/atb
- var/point_regen_delay = 1
-
-
-/mob/living/simple_animal/hostile/boss/Initialize(mapload)
- . = ..()
-
- atb = new()
- atb.point_regen_delay = point_regen_delay
- atb.boss = src
-
- for(var/ab in boss_abilities)
- boss_abilities -= ab
- var/datum/action/boss/AB = new ab()
- AB.boss = src
- AB.Grant(src)
- boss_abilities += AB
-
- atb.assign_abilities(boss_abilities)
-
-
-/mob/living/simple_animal/hostile/boss/Destroy()
- qdel(atb)
- atb = null
- for(var/ab in boss_abilities)
- var/datum/action/boss/AB = ab
- AB.boss = null
- AB.Remove(src)
- qdel(AB)
- boss_abilities.Cut()
- return ..()
-
-
-//Action datum for bosses
-//Override Trigger() as shown below to do things
-/datum/action/boss
- check_flags = AB_CHECK_CONSCIOUS //Incase the boss is given a player
- var/boss_cost = 100 //Cost of usage for the boss' AI 1-100
- var/usage_probability = 100
- var/mob/living/simple_animal/hostile/boss/boss
- var/boss_type = /mob/living/simple_animal/hostile/boss
- var/needs_target = TRUE //Does the boss need to have a target? (Only matters for the AI)
- var/say_when_triggered = "" //What does the boss Say() when the ability triggers?
-
-/datum/action/boss/Trigger(trigger_flags)
- . = ..()
- if(!.)
- return
- if(!istype(boss, boss_type))
- return
- if(!boss.atb)
- return
- if(boss.atb.points < boss_cost)
- return
- if(!boss.client)
- if(needs_target && !boss.target)
- return
- if(boss)
- if(say_when_triggered)
- boss.say(say_when_triggered, forced = "boss action")
- if(!boss.atb.spend(boss_cost))
- return
-
-//Example:
-/*
-/datum/action/boss/selfgib/Trigger(trigger_flags)
- if(..())
- boss.gib()
-*/
-
-
-//Designed for boss mobs only
-/datum/boss_active_timed_battle
- var/list/abilities //a list of /datum/action/boss owned by a boss mob
- var/point_regen_delay = 5
- var/points = 50 //1-100, start with 50 so we can use some abilities but not insta-buttfug somebody
- var/next_point_time = 0
- var/chance_to_hold_onto_points = 50
- var/highest_cost = 0
- var/mob/living/simple_animal/hostile/boss/boss
-
-
-/datum/boss_active_timed_battle/New()
- ..()
- START_PROCESSING(SSobj, src)
-
-
-/datum/boss_active_timed_battle/proc/assign_abilities(list/L)
- if(!L)
- return 0
- abilities = L
- for(var/ab in abilities)
- var/datum/action/boss/AB = ab
- if(AB.boss_cost > highest_cost)
- highest_cost = AB.boss_cost
-
-
-/datum/boss_active_timed_battle/proc/spend(cost)
- if(cost <= points)
- points = max(0,points-cost)
- return 1
- return 0
-
-
-/datum/boss_active_timed_battle/proc/refund(cost)
- points = min(points+cost, 100)
-
-
-/datum/boss_active_timed_battle/process()
- if(world.time >= next_point_time)
- next_point_time = world.time + point_regen_delay
- points = min(100, ++points) //has to be out of 100
-
- if(abilities)
- chance_to_hold_onto_points = highest_cost*0.5
- if(points != 100 && prob(chance_to_hold_onto_points))
- return //Let's save our points for a better ability (unless we're at max points, in which case we can't save anymore!)
- if(!boss.client)
- abilities = shuffle(abilities)
- for(var/ab in abilities)
- var/datum/action/boss/AB = ab
- if(prob(AB.usage_probability) && AB.Trigger())
- break
-
-
-/datum/boss_active_timed_battle/Destroy()
- abilities = null
- SSobj.processing.Remove(src)
- return ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/heretic_monsters.dm b/code/modules/mob/living/simple_animal/hostile/heretic_monsters.dm
index 4269f847d92..2c0b9ba983a 100644
--- a/code/modules/mob/living/simple_animal/hostile/heretic_monsters.dm
+++ b/code/modules/mob/living/simple_animal/hostile/heretic_monsters.dm
@@ -145,7 +145,7 @@
mob_size = MOB_SIZE_HUGE
sentience_type = SENTIENCE_BOSS
environment_smash = ENVIRONMENT_SMASH_RWALLS
- mob_biotypes = MOB_ORGANIC|MOB_EPIC
+ mob_biotypes = MOB_ORGANIC|MOB_SPECIAL
obj_damage = 200
ranged_cooldown_time = 5
ranged = TRUE
diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm
index aa7ddc11c72..5ef5987942e 100644
--- a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm
+++ b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm
@@ -216,9 +216,8 @@
if(z != target.z)
return
hopping = TRUE
- ADD_TRAIT(src, TRAIT_UNDENSE, LEAPING_TRAIT)
+ add_traits(list(TRAIT_UNDENSE, TRAIT_NO_TRANSFORM), LEAPING_TRAIT)
pass_flags |= PASSMOB
- notransform = TRUE
var/turf/new_turf = locate((target.x + rand(-3,3)),(target.y + rand(-3,3)),target.z)
if(player_hop)
new_turf = get_turf(target)
@@ -229,8 +228,7 @@
throw_at(new_turf, max(3,get_dist(src,new_turf)), 1, src, FALSE, callback = CALLBACK(src, PROC_REF(FinishHop)))
/mob/living/simple_animal/hostile/jungle/leaper/proc/FinishHop()
- REMOVE_TRAIT(src, TRAIT_UNDENSE, LEAPING_TRAIT)
- notransform = FALSE
+ remove_traits(list(TRAIT_UNDENSE, TRAIT_NO_TRANSFORM), LEAPING_TRAIT)
pass_flags &= ~PASSMOB
hopping = FALSE
playsound(src.loc, 'sound/effects/meteorimpact.ogg', 100, TRUE)
@@ -241,9 +239,9 @@
/mob/living/simple_animal/hostile/jungle/leaper/proc/BellyFlop()
var/turf/new_turf = get_turf(target)
hopping = TRUE
- notransform = TRUE
+ ADD_TRAIT(src, TRAIT_NO_TRANSFORM, LEAPING_TRAIT)
new /obj/effect/temp_visual/leaper_crush(new_turf)
- addtimer(CALLBACK(src, PROC_REF(BellyFlopHop), new_turf), 30)
+ addtimer(CALLBACK(src, PROC_REF(BellyFlopHop), new_turf), 3 SECONDS)
/mob/living/simple_animal/hostile/jungle/leaper/proc/BellyFlopHop(turf/T)
ADD_TRAIT(src, TRAIT_UNDENSE, LEAPING_TRAIT)
@@ -251,8 +249,7 @@
/mob/living/simple_animal/hostile/jungle/leaper/proc/Crush()
hopping = FALSE
- REMOVE_TRAIT(src, TRAIT_UNDENSE, LEAPING_TRAIT)
- notransform = FALSE
+ remove_traits(list(TRAIT_UNDENSE, TRAIT_NO_TRANSFORM), LEAPING_TRAIT)
playsound(src, 'sound/effects/meteorimpact.ogg', 200, TRUE)
for(var/mob/living/L in orange(1, src))
L.adjustBruteLoss(35)
diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm b/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm
deleted file mode 100644
index 5cb22b75521..00000000000
--- a/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm
+++ /dev/null
@@ -1,240 +0,0 @@
-#define SEEDLING_STATE_NEUTRAL 0
-#define SEEDLING_STATE_WARMUP 1
-#define SEEDLING_STATE_ACTIVE 2
-#define SEEDLING_STATE_RECOVERY 3
-
-//A plant rooted in the ground that forfeits its melee attack in favor of ranged barrages.
-//It will fire flurries of solar energy, and occasionally charge up a powerful blast that makes it vulnerable to attack.
-/mob/living/simple_animal/hostile/jungle/seedling
- name = "seedling"
- desc = "This oversized, predatory flower conceals what can only be described as an organic energy cannon, and it will not die until its hidden vital organs are sliced out. \
- The concentrated streams of energy it sometimes produces require its full attention, attacking it during this time will prevent it from finishing its attack."
- icon = 'icons/mob/simple/jungle/seedling.dmi'
- icon_state = "seedling"
- icon_living = "seedling"
- icon_dead = "seedling_dead"
- mob_biotypes = MOB_ORGANIC | MOB_PLANT
- maxHealth = 100
- health = 100
- melee_damage_lower = 30
- melee_damage_upper = 30
- SET_BASE_PIXEL(-16, -14)
-
- minimum_distance = 3
- move_to_delay = 20
- vision_range = 9
- aggro_vision_range = 15
- ranged = TRUE
- ranged_cooldown_time = 10
- projectiletype = /obj/projectile/seedling
- projectilesound = 'sound/weapons/pierce.ogg'
- robust_searching = TRUE
- stat_attack = HARD_CRIT
- move_resist = MOVE_FORCE_EXTREMELY_STRONG
- var/combatant_state = SEEDLING_STATE_NEUTRAL
- var/mob/living/beam_debuff_target
- var/solar_beam_identifier = 0
-
-/obj/projectile/seedling
- name = "solar energy"
- icon_state = "seedling"
- damage = 10
- damage_type = BURN
- light_range = 2
- armor_flag = ENERGY
- light_color = LIGHT_COLOR_DIM_YELLOW
- hitsound = 'sound/weapons/sear.ogg'
- hitsound_wall = 'sound/weapons/effects/searwall.ogg'
- nondirectional_sprite = TRUE
-
-/obj/projectile/seedling/Bump(atom/A)//Stops seedlings from destroying other jungle mobs through FF
- if(isliving(A))
- var/mob/living/L = A
- if(FACTION_JUNGLE in L.faction)
- return FALSE
- return ..()
-
-/obj/effect/temp_visual/solarbeam_killsat
- name = "beam of solar energy"
- icon_state = "solar_beam"
- icon = 'icons/effects/beam.dmi'
- plane = LIGHTING_PLANE
- layer = LIGHTING_PRIMARY_LAYER
- duration = 5
- randomdir = FALSE
-
-/datum/status_effect/seedling_beam_indicator
- id = "seedling beam indicator"
- duration = 3 SECONDS
- status_type = STATUS_EFFECT_MULTIPLE
- alert_type = null
- tick_interval = 0.2 SECONDS
- var/atom/movable/screen/seedling/seedling_screen_object
- var/atom/target
-
-
-/datum/status_effect/seedling_beam_indicator/on_creation(mob/living/new_owner, target_plant)
- . = ..()
- if(.)
- target = target_plant
- tick()
-
-/datum/status_effect/seedling_beam_indicator/on_apply()
- if(owner.client)
- seedling_screen_object = new /atom/movable/screen/seedling()
- owner.client.screen += seedling_screen_object
- tick()
- return ..()
-
-/datum/status_effect/seedling_beam_indicator/Destroy()
- if(owner)
- if(owner.client)
- owner.client.screen -= seedling_screen_object
- return ..()
-
-/datum/status_effect/seedling_beam_indicator/tick(seconds_between_ticks)
- var/target_angle = get_angle(owner, target)
- var/matrix/final = matrix()
- final.Turn(target_angle)
- seedling_screen_object.transform = final
-
-/atom/movable/screen/seedling
- icon = 'icons/mob/simple/jungle/arachnid.dmi'
- icon_state = "seedling_beam_indicator"
- screen_loc = "CENTER:-16,CENTER:-16"
-
-/mob/living/simple_animal/hostile/jungle/seedling/Goto()
- if(combatant_state != SEEDLING_STATE_NEUTRAL)
- return
- return ..()
-
-/mob/living/simple_animal/hostile/jungle/seedling/AttackingTarget()
- if(isliving(target))
- if(ranged_cooldown <= world.time && combatant_state == SEEDLING_STATE_NEUTRAL)
- OpenFire(target)
- return
- return ..()
-
-/mob/living/simple_animal/hostile/jungle/seedling/OpenFire()
- WarmupAttack()
-
-/mob/living/simple_animal/hostile/jungle/seedling/proc/WarmupAttack()
- if(combatant_state == SEEDLING_STATE_NEUTRAL)
- combatant_state = SEEDLING_STATE_WARMUP
- SSmove_manager.stop_looping(src)
- update_icons()
- var/target_dist = get_dist(src,target)
- var/living_target_check = isliving(target)
- if(living_target_check)
- if(target_dist > 7)//Offscreen check
- SolarBeamStartup(target)
- return
- if(get_dist(src,target) >= 4 && prob(40))
- SolarBeamStartup(target)
- return
- addtimer(CALLBACK(src, PROC_REF(Volley)), 5)
-
-/mob/living/simple_animal/hostile/jungle/seedling/proc/SolarBeamStartup(mob/living/living_target)//It's more like requiem than final spark
- if(combatant_state == SEEDLING_STATE_WARMUP && target)
- combatant_state = SEEDLING_STATE_ACTIVE
- living_target.apply_status_effect(/datum/status_effect/seedling_beam_indicator, src)
- beam_debuff_target = living_target
- playsound(src,'sound/effects/seedling_chargeup.ogg', 100, FALSE)
- if(get_dist(src,living_target) > 7)
- playsound(living_target,'sound/effects/seedling_chargeup.ogg', 100, FALSE)
- solar_beam_identifier = world.time
- addtimer(CALLBACK(src, PROC_REF(Beamu), living_target, solar_beam_identifier), 35)
-
-/mob/living/simple_animal/hostile/jungle/seedling/proc/Beamu(mob/living/living_target, beam_id = 0)
- if(combatant_state == SEEDLING_STATE_ACTIVE && living_target && beam_id == solar_beam_identifier)
- if(living_target.z == z)
- update_icons()
- var/obj/effect/temp_visual/solarbeam_killsat/S = new (get_turf(src))
- var/matrix/starting = matrix()
- starting.Scale(1,32)
- starting.Translate(0,520)
- S.transform = starting
- var/obj/effect/temp_visual/solarbeam_killsat/K = new (get_turf(living_target))
- var/matrix/final = matrix()
- final.Scale(1,32)
- final.Translate(0,512)
- K.transform = final
- living_target.adjustFireLoss(30)
- living_target.adjust_fire_stacks(0.2)//Just here for the showmanship
- living_target.ignite_mob()
- playsound(living_target,'sound/weapons/sear.ogg', 50, TRUE)
- addtimer(CALLBACK(src, PROC_REF(AttackRecovery)), 5)
- return
- AttackRecovery()
-
-/mob/living/simple_animal/hostile/jungle/seedling/proc/Volley()
- if(combatant_state == SEEDLING_STATE_WARMUP && target)
- combatant_state = SEEDLING_STATE_ACTIVE
- update_icons()
- var/datum/callback/cb = CALLBACK(src, PROC_REF(InaccurateShot))
- for(var/i in 1 to 13)
- addtimer(cb, i)
- addtimer(CALLBACK(src, PROC_REF(AttackRecovery)), 14)
-
-/mob/living/simple_animal/hostile/jungle/seedling/proc/InaccurateShot()
- if(!QDELETED(target) && combatant_state == SEEDLING_STATE_ACTIVE && !stat)
- if(get_dist(src,target) <= 3)//If they're close enough just aim straight at them so we don't miss at point blank ranges
- Shoot(target)
- return
- var/turf/our_turf = get_turf(src)
- var/obj/projectile/seedling/readied_shot = new /obj/projectile/seedling(our_turf)
- readied_shot.preparePixelProjectile(target, src, null, rand(-10, 10))
- readied_shot.fire()
- playsound(src, projectilesound, 100, TRUE)
-
-/mob/living/simple_animal/hostile/jungle/seedling/proc/AttackRecovery()
- if(combatant_state == SEEDLING_STATE_ACTIVE)
- combatant_state = SEEDLING_STATE_RECOVERY
- update_icons()
- ranged_cooldown = world.time + ranged_cooldown_time
- if(target)
- face_atom(target)
- addtimer(CALLBACK(src, PROC_REF(ResetNeutral)), 10)
-
-/mob/living/simple_animal/hostile/jungle/seedling/proc/ResetNeutral()
- combatant_state = SEEDLING_STATE_NEUTRAL
- if(target && !stat)
- update_icons()
- Goto(target, move_to_delay, minimum_distance)
-
-/mob/living/simple_animal/hostile/jungle/seedling/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
- . = ..()
- if(combatant_state == SEEDLING_STATE_ACTIVE && beam_debuff_target)
- beam_debuff_target.remove_status_effect(/datum/status_effect/seedling_beam_indicator)
- beam_debuff_target = null
- solar_beam_identifier = 0
- AttackRecovery()
-
-/mob/living/simple_animal/hostile/jungle/seedling/update_icons()
- . = ..()
- if(!stat)
- switch(combatant_state)
- if(SEEDLING_STATE_NEUTRAL)
- icon_state = "seedling"
- if(SEEDLING_STATE_WARMUP)
- icon_state = "seedling_charging"
- if(SEEDLING_STATE_ACTIVE)
- icon_state = "seedling_fire"
- if(SEEDLING_STATE_RECOVERY)
- icon_state = "seedling"
-
-/mob/living/simple_animal/hostile/jungle/seedling/GiveTarget()
- if(target)
- if(combatant_state == SEEDLING_STATE_WARMUP || combatant_state == SEEDLING_STATE_ACTIVE)//So it doesn't 180 and blast you in the face while it's firing at someone else
- return
- return ..()
-
-/mob/living/simple_animal/hostile/jungle/seedling/LoseTarget()
- if(combatant_state == SEEDLING_STATE_WARMUP || combatant_state == SEEDLING_STATE_ACTIVE)
- return
- return ..()
-
-#undef SEEDLING_STATE_NEUTRAL
-#undef SEEDLING_STATE_WARMUP
-#undef SEEDLING_STATE_ACTIVE
-#undef SEEDLING_STATE_RECOVERY
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/_megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/_megafauna.dm
index 6a040ed7a33..3484c27375d 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/_megafauna.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/_megafauna.dm
@@ -6,7 +6,7 @@
combat_mode = TRUE
sentience_type = SENTIENCE_BOSS
environment_smash = ENVIRONMENT_SMASH_RWALLS
- mob_biotypes = MOB_ORGANIC|MOB_EPIC
+ mob_biotypes = MOB_ORGANIC|MOB_SPECIAL
obj_damage = 400
light_range = 3
faction = list(FACTION_MINING, FACTION_BOSS)
@@ -123,24 +123,47 @@
if(!client && ranged && ranged_cooldown <= world.time)
OpenFire()
- if(L.health <= HEALTH_THRESHOLD_DEAD && HAS_TRAIT(L, TRAIT_NODEATH)) //Nope, it still gibs yall
+ if(L.health <= HEALTH_THRESHOLD_DEAD && HAS_TRAIT(L, TRAIT_NODEATH)) //Nope, it still kills yall
devour(L)
else
devour(L)
/// Devours a target and restores health to the megafauna
/mob/living/simple_animal/hostile/megafauna/proc/devour(mob/living/L)
- if(!L)
+ if(!L || L.has_status_effect(/datum/status_effect/gutted))
return FALSE
- visible_message(
- span_danger("[src] devours [L]!"),
- span_userdanger("You feast on [L], restoring your health!"))
+ celebrate_kill(L)
if(!is_station_level(z) || client) //NPC monsters won't heal while on station
adjustBruteLoss(-L.maxHealth/2)
L.investigate_log("has been devoured by [src].", INVESTIGATE_DEATHS)
- L.gib()
+ var/mob/living/carbon/carbonTarget = L
+ if(istype(carbonTarget))
+ qdel(L.get_organ_slot(ORGAN_SLOT_LUNGS))
+ qdel(L.get_organ_slot(ORGAN_SLOT_HEART))
+ qdel(L.get_organ_slot(ORGAN_SLOT_LIVER))
+ L.adjustBruteLoss(500)
+ L.death() //make sure they die
+ L.apply_status_effect(/datum/status_effect/gutted)
+ LoseTarget()
return TRUE
+/mob/living/simple_animal/hostile/megafauna/proc/celebrate_kill(mob/living/L)
+ visible_message(
+ span_danger("[src] disembowels [L]!"),
+ span_userdanger("You feast on [L]'s organs, restoring your health!"))
+
+
+
+/mob/living/simple_animal/hostile/megafauna/CanAttack(atom/the_target)
+ . = ..()
+ if (!.)
+ return FALSE
+ if(!isliving(the_target))
+ return TRUE
+ var/mob/living/living_target = the_target
+ return !living_target.has_status_effect(/datum/status_effect/gutted)
+
+
/mob/living/simple_animal/hostile/megafauna/ex_act(severity, target)
switch (severity)
if (EXPLODE_DEVASTATE)
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
index 72d4c1da9b9..1bd196651fd 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
@@ -75,6 +75,7 @@ Difficulty: Medium
kinetic_accelerator.Grant(src)
dash_attack.Grant(src)
transform_weapon.Grant(src)
+ AddComponent(/datum/component/boss_music, 'sound/lavaland/bdm_boss.ogg', 167 SECONDS)
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/Destroy()
QDEL_NULL(dash)
@@ -136,15 +137,12 @@ Difficulty: Medium
if(isliving(target))
var/mob/living/living_target = target
if(living_target.stat == DEAD)
- visible_message(span_danger("[src] butchers [living_target]!"),
- span_userdanger("You butcher [living_target], restoring your health!"))
if(!is_station_level(z) || client) //NPC monsters won't heal while on station
if(guidance)
adjustHealth(-living_target.maxHealth)
else
adjustHealth(-(living_target.maxHealth * 0.5))
- living_target.investigate_log("has been gibbed by [src].", INVESTIGATE_DEATHS)
- living_target.gib()
+ devour(living_target)
return TRUE
changeNext_move(CLICK_CD_MELEE)
miner_saw.melee_attack_chain(src, target)
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
index db18216880e..02d9e582b1a 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
@@ -153,7 +153,7 @@ Difficulty: Hard
/mob/living/simple_animal/hostile/megafauna/bubblegum/attackby(obj/item/W, mob/user, params)
. = ..()
if(istype(W, /obj/item/organ/internal/tongue))
- user.client?.give_award(/datum/award/achievement/misc/frenching, user)
+ user.client?.give_award(/datum/award/achievement/jobs/frenching, user)
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/try_bloodattack()
var/list/targets = get_mobs_on_blood()
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
index a9c38d985c1..8a92ca680f7 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
@@ -157,11 +157,6 @@
var/mob/living/carbon/human/human_victim = victim
return human_victim.mind && istype(human_victim.mind.martial_art, /datum/martial_art/the_sleeping_carp)
-/mob/living/simple_animal/hostile/megafauna/colossus/devour(mob/living/victim)
- visible_message(span_colossus("[src] disintegrates [victim]!"))
- victim.investigate_log("has been devoured by [src].", INVESTIGATE_DEATHS)
- victim.dust()
-
/obj/effect/temp_visual/at_shield
name = "anti-toolbox field"
desc = "A shimmering forcefield protecting the colossus."
@@ -593,8 +588,7 @@
. = ..()
if(isliving(arrived) && holder_animal)
var/mob/living/possessor = arrived
- possessor.notransform = TRUE
- ADD_TRAIT(possessor, TRAIT_MUTE, STASIS_MUTE)
+ possessor.add_traits(list(TRAIT_UNDENSE, TRAIT_NO_TRANSFORM), STASIS_MUTE)
possessor.status_flags |= GODMODE
possessor.mind.transfer_to(holder_animal)
var/datum/action/exit_possession/escape = new(holder_animal)
@@ -603,9 +597,8 @@
/obj/structure/closet/stasis/dump_contents(kill = TRUE)
for(var/mob/living/possessor in src)
- REMOVE_TRAIT(possessor, TRAIT_MUTE, STASIS_MUTE)
+ possessor.remove_traits(list(TRAIT_UNDENSE, TRAIT_NO_TRANSFORM), STASIS_MUTE)
possessor.status_flags &= ~GODMODE
- possessor.notransform = FALSE
if(kill || !isanimal_or_basicmob(loc))
possessor.investigate_log("has died from [src].", INVESTIGATE_DEATHS)
possessor.death(FALSE)
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm
index fab7548e4e9..8a307cec2bd 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm
@@ -80,6 +80,7 @@ Difficulty: Extremely Hard
AddElement(/datum/element/knockback, 7, FALSE, TRUE)
AddElement(/datum/element/lifesteal, 50)
ADD_TRAIT(src, TRAIT_NO_FLOATING_ANIM, INNATE_TRAIT)
+ AddComponent(/datum/component/boss_music, 'sound/lavaland/bdm_boss.ogg', 167 SECONDS)
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/Destroy()
QDEL_NULL(frost_orbs)
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 22b7240907b..745a48c948c 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
@@ -430,15 +430,9 @@ Difficulty: Hard
set_stat(CONSCIOUS) // deathgasp won't run if dead, stupid
..(force_grant = stored_nearby)
-/mob/living/simple_animal/hostile/megafauna/hierophant/devour(mob/living/L)
- for(var/obj/item/W in L)
- if(!L.dropItemToGround(W))
- qdel(W)
+/mob/living/simple_animal/hostile/megafauna/hierophant/celebrate_kill(mob/living/L)
visible_message(span_hierophant_warning("\"[pick(kill_phrases)]\""))
- visible_message(span_hierophant_warning("[src] annihilates [L]!"),span_userdanger("You annihilate [L], restoring your health!"))
- adjustHealth(-L.maxHealth*0.5)
- L.investigate_log("has been devoured by [src].", INVESTIGATE_DEATHS)
- L.dust()
+ visible_message(span_hierophant_warning("[src] obliterates [L]!"),span_userdanger("You absorb [L]'s life force, restoring your health!"))
/mob/living/simple_animal/hostile/megafauna/hierophant/CanAttack(atom/the_target)
. = ..()
@@ -472,6 +466,8 @@ Difficulty: Hard
burst_range = 3
INVOKE_ASYNC(src, PROC_REF(burst), get_turf(src), 0.25) //melee attacks on living mobs cause it to release a fast burst if on cooldown
OpenFire()
+ if(L.health <= HEALTH_THRESHOLD_DEAD && HAS_TRAIT(L, TRAIT_NODEATH)) //Nope, it still kills yall
+ devour(L)
else
devour(L)
else
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/brimdemon.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/brimdemon.dm
deleted file mode 100644
index d9bd88cb889..00000000000
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/brimdemon.dm
+++ /dev/null
@@ -1,242 +0,0 @@
-#define BRIMBEAM_RANGE 10
-
-/mob/living/simple_animal/hostile/asteroid/brimdemon
- name = "brimdemon"
- desc = "A misshapen demon with big, red eyes and a hinged mouth. Not much is known about the creatures \
- due to their response to any unexpected stimulus being \"brimbeam\", a deadly blood-laser barrage."
- icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
- icon_state = "brimdemon"
- icon_living = "brimdemon"
- icon_dead = "brimdemon_dead"
- mob_biotypes = MOB_ORGANIC|MOB_BEAST
- speak_emote = list("cackles")
- emote_taunt = list("screeches")
- emote_hear = list("cackles","screeches")
- combat_mode = TRUE
- stat_attack = HARD_CRIT
- ranged_cooldown_time = 5 SECONDS
- vision_range = 9
- retreat_distance = 2
- speed = 3
- move_to_delay = 5
- maxHealth = 250
- health = 250
- obj_damage = 15
- melee_damage_lower = 7.5
- melee_damage_upper = 7.5
- rapid_melee = 2 // every second attack
- attack_verb_continuous = "bites"
- attack_verb_simple = "bite"
- attack_sound = 'sound/weapons/bite.ogg'
- attack_vis_effect = ATTACK_EFFECT_BITE
- butcher_results = list(
- /obj/item/food/meat/slab = 2,
- /obj/effect/decal/cleanable/brimdust = 1,
- /obj/item/organ/internal/monster_core/brimdust_sac = 1,
- )
- loot = list()
- robust_searching = TRUE
- footstep_type = FOOTSTEP_MOB_CLAW
- death_message = "wails as infernal energy escapes from its wounds, leaving it an empty husk."
- death_sound = 'sound/magic/demon_dies.ogg'
- light_color = LIGHT_COLOR_BLOOD_MAGIC
- light_power = 5
- light_range = 1.4
- crusher_loot = /obj/item/crusher_trophy/brimdemon_fang
- /// Are we charging/firing? If yes stops our movement.
- var/firing = FALSE
- /// A list of all the beam parts.
- var/list/beamparts = list()
-
-/mob/living/simple_animal/hostile/asteroid/brimdemon/Destroy()
- QDEL_LIST(beamparts)
- return ..()
-
-/mob/living/simple_animal/hostile/asteroid/brimdemon/Login()
- ranged = TRUE
- return ..()
-
-/mob/living/simple_animal/hostile/asteroid/brimdemon/Logout()
- ranged = FALSE
- return ..()
-
-/mob/living/simple_animal/hostile/asteroid/brimdemon/death()
- firing = FALSE
- cut_overlay("brimdemon_telegraph_dir")
- move_resist = initial(move_resist)
- return ..()
-
-/mob/living/simple_animal/hostile/asteroid/brimdemon/Goto(target, delay, minimum_distance)
- if(firing)
- return FALSE
- return ..()
-
-/mob/living/simple_animal/hostile/asteroid/brimdemon/MoveToTarget(list/possible_targets)
- if(firing)
- return FALSE
- return ..()
-
-/mob/living/simple_animal/hostile/asteroid/brimdemon/AttackingTarget(atom/attacked_target)
- if(firing)
- return FALSE
- return ..()
-
-/mob/living/simple_animal/hostile/asteroid/brimdemon/Move(atom/newloc, dir, step_x , step_y)
- if(firing)
- return FALSE
- return ..()
-
-/mob/living/simple_animal/hostile/asteroid/brimdemon/OpenFire()
- if(firing)
- balloon_alert(src, "already firing!")
- return
- if(!COOLDOWN_FINISHED(src, ranged_cooldown))
- balloon_alert(src, "on cooldown!")
- return
- firing = TRUE
- set_dir_on_move = FALSE
- icon_state = "brimdemon_firing"
- move_resist = MOVE_FORCE_VERY_STRONG
- add_overlay("brimdemon_telegraph_dir")
- visible_message(span_danger("[src] starts charging!"))
- balloon_alert(src, "charging...")
- addtimer(CALLBACK(src, PROC_REF(fire_laser)), 1 SECONDS)
- COOLDOWN_START(src, ranged_cooldown, ranged_cooldown_time)
-
-/mob/living/simple_animal/hostile/asteroid/brimdemon/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change = TRUE)
- . = ..()
- check_fire()
-
-/mob/living/simple_animal/hostile/asteroid/brimdemon/proc/check_fire()
- if(key || QDELETED(target) || get_dist(src, target) > BRIMBEAM_RANGE || !(get_dir(src, target) in GLOB.cardinals))
- return
- face_atom(target)
- OpenFire()
-
-/// Fires a brimbeam, getting a line of turfs between it and the direction to the target and creating a brimbeam effect on every one of them.
-/mob/living/simple_animal/hostile/asteroid/brimdemon/proc/fire_laser()
- if(stat == DEAD)
- return
- visible_message(span_danger("[src] fires a brimbeam!"))
- balloon_alert(src, "brimbeam fired")
- playsound(src, 'sound/creatures/brimdemon.ogg', 150, FALSE, 0, 3)
- cut_overlay("brimdemon_telegraph_dir")
- var/turf/target_turf = get_ranged_target_turf(src, dir, BRIMBEAM_RANGE)
- var/turf/origin_turf = get_turf(src)
- var/list/affected_turfs = get_line(origin_turf, target_turf) - origin_turf
- for(var/turf/affected_turf in affected_turfs)
- var/blocked = FALSE
- if(affected_turf.opacity)
- blocked = TRUE
- for(var/obj/potential_block in affected_turf.contents)
- if(potential_block.opacity)
- blocked = TRUE
- break
- if(blocked)
- break
- var/atom/new_brimbeam = new /obj/effect/brimbeam(affected_turf)
- new_brimbeam.dir = dir
- beamparts += new_brimbeam
- for(var/mob/living/hit_mob in affected_turf.contents)
- hit_mob.adjustFireLoss(25)
- to_chat(hit_mob, span_userdanger("You're hit by [src]'s brimbeam!"))
- if(length(beamparts))
- var/atom/last_brimbeam = beamparts[length(beamparts)]
- last_brimbeam.icon_state = "brimbeam_end"
- var/atom/first_brimbeam = beamparts[1]
- first_brimbeam.icon_state = "brimbeam_start"
- addtimer(CALLBACK(src, PROC_REF(end_laser)), 2 SECONDS)
-
-/// Deletes all the brimbeam parts and sets variables back to their initial ones.
-/mob/living/simple_animal/hostile/asteroid/brimdemon/proc/end_laser()
- if(stat != DEAD)
- icon_state = initial(icon_state)
- move_resist = initial(move_resist)
- set_dir_on_move = initial(set_dir_on_move)
- firing = FALSE
- for(var/obj/effect/brimbeam/beam in beamparts)
- animate(beam, time = 0.5 SECONDS, alpha = 0)
- QDEL_IN(beam, 0.5 SECONDS)
- beamparts -= beam
-
-/obj/effect/brimbeam
- name = "brimbeam"
- icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
- icon_state = "brimbeam_mid"
- layer = ABOVE_MOB_LAYER
- plane = ABOVE_GAME_PLANE
- mouse_opacity = MOUSE_OPACITY_TRANSPARENT
- light_color = LIGHT_COLOR_BLOOD_MAGIC
- light_power = 3
- light_range = 2
-
-/obj/effect/brimbeam/Initialize(mapload)
- . = ..()
- START_PROCESSING(SSfastprocess, src)
-
-/obj/effect/brimbeam/Destroy()
- STOP_PROCESSING(SSfastprocess, src)
- return ..()
-
-/obj/effect/brimbeam/process()
- for(var/mob/living/hit_mob in get_turf(src))
- damage(hit_mob)
-
-/obj/effect/brimbeam/proc/damage(mob/living/hit_mob)
- hit_mob.adjustFireLoss(5)
- to_chat(hit_mob, span_danger("You're damaged by [src]!"))
-
-/obj/item/crusher_trophy/brimdemon_fang
- name = "brimdemon's fang"
- icon_state = "brimdemon_fang"
- desc = "A fang from a brimdemon's corpse."
- denied_type = /obj/item/crusher_trophy/brimdemon_fang
- var/static/list/comic_phrases = list("BOOM", "BANG", "KABLOW", "KAPOW", "OUCH", "BAM", "KAPOW", "WHAM", "POW", "KABOOM")
-
-/obj/item/crusher_trophy/brimdemon_fang/effect_desc()
- return "mark detonation creates visual and audiosensory effects on the target"
-
-/obj/item/crusher_trophy/brimdemon_fang/on_mark_detonation(mob/living/target, mob/living/user)
- target.balloon_alert_to_viewers("[pick(comic_phrases)]!")
- playsound(target, 'sound/lavaland/brimdemon_crush.ogg', 100)
-
-/obj/effect/decal/cleanable/brimdust
- name = "brimdust"
- desc = "Dust from a brimdemon. It is considered valuable for its' botanical abilities."
- icon_state = "brimdust"
- icon = 'icons/obj/mining.dmi'
- layer = FLOOR_CLEAN_LAYER
- mergeable_decal = FALSE
-
-/obj/effect/decal/cleanable/brimdust/Initialize(mapload)
- . = ..()
- reagents.add_reagent(/datum/reagent/brimdust, 15)
-
-/obj/item/ore_sensor
- name = "ore sensor"
- desc = "Using demonic frequencies, this ear-mounted tool detects ores in the nearby terrain."
- icon_state = "oresensor"
- icon = 'icons/obj/mining.dmi'
- slot_flags = ITEM_SLOT_EARS
- var/range = 5
- var/cooldown = 4 SECONDS //between the standard and the advanced ore scanner in strength
- COOLDOWN_DECLARE(ore_sensing_cooldown)
-
-/obj/item/ore_sensor/equipped(mob/user, slot, initial)
- . = ..()
- if(slot & ITEM_SLOT_EARS)
- START_PROCESSING(SSobj, src)
- else
- STOP_PROCESSING(SSobj, src)
-
-/obj/item/ore_sensor/dropped(mob/user, silent)
- . = ..()
- STOP_PROCESSING(SSobj, src)
-
-/obj/item/ore_sensor/process(seconds_per_tick)
- if(!COOLDOWN_FINISHED(src, ore_sensing_cooldown))
- return
- COOLDOWN_START(src, ore_sensing_cooldown, cooldown)
- mineral_scan_pulse(get_turf(src), range)
-
-#undef BRIMBEAM_RANGE
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm
index 9a00d34e34e..2d92ef88a65 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm
@@ -1,11 +1,11 @@
/mob/living/simple_animal/hostile/asteroid/hivelord
name = "hivelord"
- desc = "A truly alien creature, it is a mass of unknown organic material, constantly fluctuating. When attacking, pieces of it split off and attack in tandem with the original."
+ 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_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
@@ -18,11 +18,11 @@
harm_intent_damage = 5
melee_damage_lower = 0
melee_damage_upper = 0
- attack_verb_continuous = "lashes out at"
- attack_verb_simple = "lash out at"
+ attack_verb_continuous = "weakly tackles"
+ attack_verb_simple = "weakly tackles"
speak_emote = list("telepathically cries")
attack_sound = 'sound/weapons/pierce.ogg'
- throw_message = "falls right through the strange body of the"
+ throw_message = "passes between the bodies of the"
ranged_cooldown = 0
ranged_cooldown_time = 20
obj_damage = 0
@@ -40,14 +40,14 @@
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)
- var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/A = new brood_type(src.loc)
-
- A.flags_1 |= (flags_1 & ADMIN_SPAWNED_1)
- A.GiveTarget(target)
- A.friends = friends
- A.faction = faction.Copy()
- ranged_cooldown = world.time + ranged_cooldown_time
+ 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()
@@ -55,17 +55,17 @@
/mob/living/simple_animal/hostile/asteroid/hivelord/death(gibbed)
mouse_opacity = MOUSE_OPACITY_ICON
- ..(gibbed)
+ return ..()
//A fragile but rapidly produced creature
/mob/living/simple_animal/hostile/asteroid/hivelordbrood
name = "hivelord brood"
- desc = "A fragment of the original Hivelord, rallying behind its original. One isn't much of a threat, but..."
+ 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 = "Hivelordbrood"
- icon_living = "Hivelordbrood"
- icon_aggro = "Hivelordbrood"
- icon_dead = "Hivelordbrood"
+ 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"
@@ -93,11 +93,16 @@
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/Initialize(mapload)
. = ..()
- addtimer(CALLBACK(src, PROC_REF(death)), 100)
+ 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"
@@ -160,9 +165,7 @@
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/legioninfested/snow(our_turf)
-
- new /obj/effect/mob_spawn/corpse/human/legioninfested/dwarf(our_turf)
+ new /obj/effect/mob_spawn/corpse/human/snowlegioninfested(our_turf)
else
new /obj/effect/mob_spawn/corpse/human/legioninfested(our_turf)
return ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/ooze.dm b/code/modules/mob/living/simple_animal/hostile/ooze.dm
index 72b464ff136..9491f5aa163 100644
--- a/code/modules/mob/living/simple_animal/hostile/ooze.dm
+++ b/code/modules/mob/living/simple_animal/hostile/ooze.dm
@@ -64,7 +64,7 @@
var/consumption_amount = min(reagents.get_reagent_amount(reagent.type), ooze_metabolism_modifier * REAGENTS_METABOLISM * seconds_per_tick)
if(istype(reagent, /datum/reagent/consumable))
var/datum/reagent/consumable/consumable = reagent
- nutrition_change += consumption_amount * consumable.nutriment_factor
+ nutrition_change += consumption_amount * consumable.get_nutriment_factor()
reagents.remove_reagent(reagent.type, consumption_amount)
adjust_ooze_nutrition(nutrition_change)
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/goose.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/goose.dm
index 29f628d148e..e4b07470c58 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/goose.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/goose.dm
@@ -8,7 +8,7 @@
mob_biotypes = MOB_ORGANIC|MOB_BEAST
speak_chance = 0
turns_per_move = 5
- butcher_results = list(/obj/item/food/meat/slab = 2)
+ butcher_results = list(/obj/item/food/meat/slab/grassfed = 2)
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
diff --git a/code/modules/mob/living/simple_animal/revenant.dm b/code/modules/mob/living/simple_animal/revenant.dm
index 25a283a7364..6e2ec11afea 100644
--- a/code/modules/mob/living/simple_animal/revenant.dm
+++ b/code/modules/mob/living/simple_animal/revenant.dm
@@ -3,6 +3,9 @@
//Can hear deadchat, but are NOT normal ghosts and do NOT have x-ray vision
//Admin-spawn or random event
+/// Source for a trait we get when we're stunned
+#define REVENANT_STUNNED_TRAIT "revenant_got_stunned"
+
/mob/living/simple_animal/revenant
name = "revenant"
desc = "A malevolent spirit."
@@ -129,6 +132,7 @@
/mob/living/simple_animal/revenant/Life(seconds_per_tick = SSMOBS_DT, times_fired)
if(stasis)
return
+ var/delta_time = DELTA_WORLD_TIME(SSmobs)
if(revealed && essence <= 0)
death()
if(unreveal_time && world.time >= unreveal_time)
@@ -139,10 +143,10 @@
to_chat(src, span_revenboldnotice("You are once more concealed."))
if(unstun_time && world.time >= unstun_time)
unstun_time = 0
- notransform = FALSE
+ REMOVE_TRAIT(src, TRAIT_NO_TRANSFORM, REVENANT_STUNNED_TRAIT)
to_chat(src, span_revenboldnotice("You can move again!"))
if(essence_regenerating && !inhibited && essence < essence_regen_cap) //While inhibited, essence will not regenerate
- essence = min(essence + (essence_regen_amount * seconds_per_tick), essence_regen_cap)
+ essence = min(essence + (essence_regen_amount * delta_time), essence_regen_cap)
update_mob_action_buttons() //because we update something required by our spells in life, we need to update our buttons
update_spooky_icon()
update_health_hud()
@@ -239,7 +243,7 @@
return
stasis = TRUE
to_chat(src, span_revendanger("NO! No... it's too late, you can feel your essence [pick("breaking apart", "drifting away")]..."))
- notransform = TRUE
+ ADD_TRAIT(src, TRAIT_NO_TRANSFORM, REVENANT_STUNNED_TRAIT)
revealed = TRUE
invisibility = 0
playsound(src, 'sound/effects/screech.ogg', 100, TRUE)
@@ -282,7 +286,7 @@
return
if(time <= 0)
return
- notransform = TRUE
+ ADD_TRAIT(src, TRAIT_NO_TRANSFORM, REVENANT_STUNNED_TRAIT)
if(!unstun_time)
to_chat(src, span_revendanger("You cannot move!"))
unstun_time = world.time + time
@@ -294,7 +298,7 @@
/mob/living/simple_animal/revenant/proc/update_spooky_icon()
if(revealed)
- if(notransform)
+ if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
if(draining)
icon_state = icon_drain
else
@@ -351,7 +355,7 @@
/mob/living/simple_animal/revenant/proc/death_reset()
revealed = FALSE
unreveal_time = 0
- notransform = 0
+ REMOVE_TRAIT(src, TRAIT_NO_TRANSFORM, REVENANT_STUNNED_TRAIT)
unstun_time = 0
inhibited = FALSE
draining = FALSE
@@ -541,3 +545,4 @@
/datum/objective/revenant_fluff/check_completion()
return TRUE
+#undef REVENANT_STUNNED_TRAIT
diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm
index 27827bbd88b..a103a55b996 100644
--- a/code/modules/mob/living/simple_animal/slime/life.dm
+++ b/code/modules/mob/living/simple_animal/slime/life.dm
@@ -1,5 +1,5 @@
/mob/living/simple_animal/slime/Life(seconds_per_tick = SSMOBS_DT, times_fired)
- if (notransform)
+ if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
return
. = ..()
if(!.)
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 9c94e70c194..a6b3a6245cc 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -592,7 +592,7 @@
if(is_blind()) //blind people see things differently (through touch)
if(!blind_examine_check(examinify))
return
- else if(!(examine_turf.luminosity || examine_turf.dynamic_lumcount) && \
+ else if(examine_turf && !(examine_turf.luminosity || examine_turf.dynamic_lumcount) && \
get_dist(src, examine_turf) > 1 && \
!has_nightvision()) // If you aren't blind, it's in darkness (that you can't see) and farther then next to you
return
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index ddf2bb72b78..12905700318 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -84,14 +84,6 @@
/// Tick time the mob can next move
var/next_move = null
- /**
- * Magic var that stops you moving and interacting with anything
- *
- * Set when you're being turned into something else and also used in a bunch of places
- * it probably shouldn't really be
- */
- var/notransform = null //Carbon
-
/// What is the mobs real name (name is overridden for disguises etc)
var/real_name = null
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 45262602c7d..e9b0f532da5 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -74,8 +74,8 @@
return FALSE
if(!mob?.loc)
return FALSE
- if(mob.notransform)
- return FALSE //This is sota the goto stop mobs from moving var
+ if(HAS_TRAIT(mob, TRAIT_NO_TRANSFORM))
+ return FALSE //This is sorta the goto stop mobs from moving trait
if(mob.control_object)
return Move_object(direct)
if(!isliving(mob))
diff --git a/code/modules/mob/mob_transformation_simple.dm b/code/modules/mob/mob_transformation_simple.dm
index bb72a21089b..9bc6a5b22db 100644
--- a/code/modules/mob/mob_transformation_simple.dm
+++ b/code/modules/mob/mob_transformation_simple.dm
@@ -66,6 +66,7 @@
else
desired_mob.key = key
+ SEND_SIGNAL(src, COMSIG_MOB_CHANGED_TYPE)
if(delete_old_mob)
QDEL_IN(src, 1)
return desired_mob
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index f02624449ba..09ce3b3c65c 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -1,7 +1,11 @@
#define TRANSFORMATION_DURATION 22
+/// Will be removed once the transformation is complete.
+#define TEMPORARY_TRANSFORMATION_TRAIT "temporary_transformation"
+/// Considered "permanent" since we'll be deleting the old mob and the client will be inserted into a new one (without this trait)
+#define PERMANENT_TRANSFORMATION_TRAIT "permanent_transformation"
/mob/living/carbon/proc/monkeyize(instant = FALSE)
- if (notransform || transformation_timer)
+ if (transformation_timer || HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
return
if(ismonkey(src))
@@ -12,7 +16,7 @@
return
//Make mob invisible and spawn animation
- notransform = TRUE
+ ADD_TRAIT(src, TRAIT_NO_TRANSFORM, TEMPORARY_TRANSFORMATION_TRAIT)
Paralyze(TRANSFORMATION_DURATION, ignore_canstun = TRUE)
icon = null
cut_overlays()
@@ -23,8 +27,8 @@
/mob/living/carbon/proc/finish_monkeyize()
transformation_timer = null
- to_chat(src, "You are now a monkey.")
- notransform = FALSE
+ to_chat(src, span_boldnotice("You are now a monkey."))
+ REMOVE_TRAIT(src, TRAIT_NO_TRANSFORM, TEMPORARY_TRANSFORMATION_TRAIT)
icon = initial(icon)
invisibility = 0
set_species(/datum/species/monkey)
@@ -32,14 +36,13 @@
set_name()
SEND_SIGNAL(src, COMSIG_HUMAN_MONKEYIZE)
uncuff()
- regenerate_icons()
return src
////////////////////////// Humanize //////////////////////////////
//Could probably be merged with monkeyize but other transformations got their own procs, too
/mob/living/carbon/proc/humanize(species = /datum/species/human, instant = FALSE)
- if (notransform || transformation_timer)
+ if (transformation_timer || HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
return
if(!ismonkey(src))
@@ -50,7 +53,7 @@
return
//Make mob invisible and spawn animation
- notransform = TRUE
+ ADD_TRAIT(src, TRAIT_NO_TRANSFORM, TEMPORARY_TRANSFORMATION_TRAIT)
Paralyze(TRANSFORMATION_DURATION, ignore_canstun = TRUE)
icon = null
cut_overlays()
@@ -61,13 +64,12 @@
/mob/living/carbon/proc/finish_humanize(species = /datum/species/human)
transformation_timer = null
- to_chat(src, "You are now a human.")
- notransform = FALSE
+ to_chat(src, span_boldnotice("You are now a human."))
+ REMOVE_TRAIT(src, TRAIT_NO_TRANSFORM, TEMPORARY_TRANSFORMATION_TRAIT)
icon = initial(icon)
invisibility = 0
set_species(species)
SEND_SIGNAL(src, COMSIG_MONKEY_HUMANIZE)
- regenerate_icons()
return src
/mob/proc/AIize(client/preference_source, move = TRUE)
@@ -107,9 +109,9 @@
qdel(src)
/mob/living/carbon/AIize(client/preference_source, transfer_after = TRUE)
- if (notransform)
+ if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
return
- notransform = TRUE
+ ADD_TRAIT(src, TRAIT_NO_TRANSFORM, PERMANENT_TRANSFORMATION_TRAIT)
Paralyze(1, ignore_canstun = TRUE)
for(var/obj/item/W in src)
dropItemToGround(W)
@@ -119,7 +121,7 @@
return ..()
/mob/living/carbon/human/AIize(client/preference_source, transfer_after = TRUE)
- if (notransform)
+ if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
return
for(var/t in bodyparts)
qdel(t)
@@ -127,9 +129,9 @@
return ..()
/mob/proc/Robotize(delete_items = 0, transfer_after = TRUE)
- if(notransform)
+ if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
return
- notransform = TRUE
+ ADD_TRAIT(src, TRAIT_NO_TRANSFORM, PERMANENT_TRANSFORMATION_TRAIT)
var/mob/living/silicon/robot/new_borg = new /mob/living/silicon/robot(loc)
new_borg.gender = gender
@@ -162,9 +164,9 @@
qdel(src)
/mob/living/Robotize(delete_items = 0, transfer_after = TRUE)
- if(notransform)
+ if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
return
- notransform = TRUE
+ ADD_TRAIT(src, TRAIT_NO_TRANSFORM, TEMPORARY_TRANSFORMATION_TRAIT)
Paralyze(1, ignore_canstun = TRUE)
for(var/obj/item/W in src)
@@ -176,7 +178,7 @@
icon = null
invisibility = INVISIBILITY_MAXIMUM
- notransform = FALSE
+ REMOVE_TRAIT(src, TRAIT_NO_TRANSFORM, TEMPORARY_TRANSFORMATION_TRAIT)
return ..()
/mob/living/silicon/robot/proc/replace_banned_cyborg()
@@ -191,9 +193,9 @@
//human -> alien
/mob/living/carbon/human/proc/Alienize()
- if (notransform)
+ if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
return
- notransform = TRUE
+ ADD_TRAIT(src, TRAIT_NO_TRANSFORM, PERMANENT_TRANSFORMATION_TRAIT)
add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), TRAIT_GENERIC)
for(var/obj/item/W in src)
dropItemToGround(W)
@@ -216,14 +218,14 @@
new_xeno.set_combat_mode(TRUE)
new_xeno.key = key
- to_chat(new_xeno, "You are now an alien.")
- . = new_xeno
+ to_chat(new_xeno, span_boldnotice("You are now an alien."))
qdel(src)
+ return new_xeno
/mob/living/carbon/human/proc/slimeize(reproduce as num)
- if (notransform)
+ if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
return
- notransform = TRUE
+ ADD_TRAIT(src, TRAIT_NO_TRANSFORM, PERMANENT_TRANSFORMATION_TRAIT)
add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), TRAIT_GENERIC)
for(var/obj/item/W in src)
dropItemToGround(W)
@@ -248,9 +250,9 @@
new_slime.set_combat_mode(TRUE)
new_slime.key = key
- to_chat(new_slime, "You are now a slime. Skreee!")
- . = new_slime
+ to_chat(new_slime, span_boldnotice("You are now a slime. Skreee!"))
qdel(src)
+ return new_slime
/mob/proc/become_overmind(starting_points = OVERMIND_STARTING_POINTS)
var/mob/camera/blob/B = new /mob/camera/blob(get_turf(src), starting_points)
@@ -260,9 +262,9 @@
/mob/living/carbon/human/proc/corgize()
- if (notransform)
+ if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
return
- notransform = TRUE
+ ADD_TRAIT(src, TRAIT_NO_TRANSFORM, PERMANENT_TRANSFORMATION_TRAIT)
Paralyze(1, ignore_canstun = TRUE)
for(var/obj/item/W in src)
dropItemToGround(W)
@@ -276,14 +278,14 @@
new_corgi.set_combat_mode(TRUE)
new_corgi.key = key
- to_chat(new_corgi, "You are now a Corgi. Yap Yap!")
- . = new_corgi
+ to_chat(new_corgi, span_boldnotice("You are now a Corgi. Yap Yap!"))
qdel(src)
+ return new_corgi
/mob/living/carbon/proc/gorillize()
- if(notransform)
+ if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
return
- notransform = TRUE
+ ADD_TRAIT(src, TRAIT_NO_TRANSFORM, PERMANENT_TRANSFORMATION_TRAIT)
Paralyze(1, ignore_canstun = TRUE)
SSblackbox.record_feedback("amount", "gorillas_created", 1)
@@ -302,9 +304,9 @@
mind.transfer_to(new_gorilla)
else
new_gorilla.key = key
- to_chat(new_gorilla, "You are now a gorilla. Ooga ooga!")
- . = new_gorilla
+ to_chat(new_gorilla, span_boldnotice("You are now a gorilla. Ooga ooga!"))
qdel(src)
+ return new_gorilla
/mob/living/carbon/human/Animalize()
@@ -316,9 +318,9 @@
to_chat(usr, span_danger("Sorry but this mob type is currently unavailable."))
return
- if(notransform)
+ if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
return
- notransform = TRUE
+ ADD_TRAIT(src, TRAIT_NO_TRANSFORM, PERMANENT_TRANSFORMATION_TRAIT)
Paralyze(1, ignore_canstun = TRUE)
for(var/obj/item/W in src)
@@ -337,8 +339,8 @@
new_mob.set_combat_mode(TRUE)
to_chat(new_mob, span_boldnotice("You suddenly feel more... animalistic."))
- . = new_mob
qdel(src)
+ return new_mob
/mob/proc/Animalize()
@@ -398,4 +400,6 @@
//Not in here? Must be untested!
return FALSE
+#undef PERMANENT_TRANSFORMATION_TRAIT
+#undef TEMPORARY_TRANSFORMATION_TRAIT
#undef TRANSFORMATION_DURATION
diff --git a/code/modules/mob_spawn/corpses/mining_corpses.dm b/code/modules/mob_spawn/corpses/mining_corpses.dm
index 8f28bbd430d..c0ea4b6af42 100644
--- a/code/modules/mob_spawn/corpses/mining_corpses.dm
+++ b/code/modules/mob_spawn/corpses/mining_corpses.dm
@@ -59,7 +59,7 @@
outfit = /datum/outfit/consumed_shadowperson
. = ..()
-/obj/effect/mob_spawn/corpse/human/legioninfested/snow/Initialize(mapload)
+/obj/effect/mob_spawn/corpse/human/snowlegioninfested/Initialize(mapload)
var/corpse_theme = pick_weight(list(
"Miner" = 64,
"Clown" = 5,
diff --git a/code/modules/mob_spawn/corpses/species_corpses.dm b/code/modules/mob_spawn/corpses/species_corpses.dm
index a9faabf7a05..57cc1d32284 100644
--- a/code/modules/mob_spawn/corpses/species_corpses.dm
+++ b/code/modules/mob_spawn/corpses/species_corpses.dm
@@ -2,6 +2,8 @@
//corpses that only differentiate themselves by representing a species
/obj/effect/mob_spawn/corpse/human/skeleton
+ //these are also fished in chasms so it wouldn't hurt giving them an apter name than "mob spawner"
+ name = "skeleton"
mob_species = /datum/species/skeleton
/obj/effect/mob_spawn/corpse/human/zombie
diff --git a/code/modules/mob_spawn/mob_spawn.dm b/code/modules/mob_spawn/mob_spawn.dm
index 0e5c7f7ce4b..a853d48c0ec 100644
--- a/code/modules/mob_spawn/mob_spawn.dm
+++ b/code/modules/mob_spawn/mob_spawn.dm
@@ -58,6 +58,7 @@
spawned_human.underwear = "Nude"
spawned_human.undershirt = "Nude"
spawned_human.socks = "Nude"
+ spawned_human.bra = "Nude" //SKYRAT EDIT ADDITION
if(hairstyle)
spawned_human.hairstyle = hairstyle
else
@@ -200,7 +201,7 @@
LAZYREMOVE(ckeys_trying_to_spawn, user_ckey)
return
- if(is_banned_from(user.key, role_ban))
+ if(is_banned_from(user.ckey, role_ban))
to_chat(user, span_warning("You are banned from this role!"))
LAZYREMOVE(ckeys_trying_to_spawn, user_ckey)
return
@@ -234,7 +235,7 @@
*/
/obj/effect/mob_spawn/ghost_role/proc/create_from_ghost(mob/dead/user)
ASSERT(istype(user))
- var/user_ckey = user.ckey // We need to do it before everything else, because after the create() the ckey will already have been transfered.
+ var/user_ckey = user.ckey // We need to do it before everything else, because after the create() the ckey will already have been transferred.
user.log_message("became a [prompt_name].", LOG_GAME)
uses -= 1 // Remove a use before trying to spawn to prevent strangeness like the spawner trying to spawn more mobs than it should be able to
diff --git a/code/modules/mod/mod_actions.dm b/code/modules/mod/mod_actions.dm
index d82912055e2..111ea425b6a 100644
--- a/code/modules/mod/mod_actions.dm
+++ b/code/modules/mod/mod_actions.dm
@@ -125,6 +125,8 @@
var/obj/item/mod/module/module
/// A reference to the mob we are pinned to.
var/mob/pinner
+ /// Timer until we remove our cooldown overlay
+ var/cooldown_timer
/datum/action/item_action/mod/pinned_module/New(Target, obj/item/mod/module/linked_module, mob/user)
var/obj/item/mod/control/mod = Target
@@ -141,11 +143,22 @@
check_flags = NONE
name = "Activate [capitalize(linked_module.name)]"
desc = "Quickly activate [linked_module]."
- RegisterSignals(linked_module, list(COMSIG_MODULE_ACTIVATED, COMSIG_MODULE_DEACTIVATED, COMSIG_MODULE_USED), PROC_REF(module_interacted_with))
+ RegisterSignals(linked_module, list(
+ COMSIG_MODULE_ACTIVATED,
+ COMSIG_MODULE_DEACTIVATED,
+ COMSIG_MODULE_USED,
+ ), PROC_REF(module_interacted_with))
+ RegisterSignal(linked_module, COMSIG_MODULE_COOLDOWN_STARTED, PROC_REF(cooldown_started))
RegisterSignal(user, COMSIG_QDELETING, PROC_REF(pinner_deleted))
/datum/action/item_action/mod/pinned_module/Destroy()
- UnregisterSignal(module, list(COMSIG_MODULE_ACTIVATED, COMSIG_MODULE_DEACTIVATED, COMSIG_MODULE_USED))
+ deltimer(cooldown_timer)
+ UnregisterSignal(module, list(
+ COMSIG_MODULE_ACTIVATED,
+ COMSIG_MODULE_DEACTIVATED,
+ COMSIG_MODULE_COOLDOWN_STARTED,
+ COMSIG_MODULE_USED,
+ ))
module.pinned_to -= REF(pinner)
module = null
pinner = null
@@ -178,12 +191,19 @@
else if(module.active)
current_button.add_overlay(image(icon = 'icons/hud/radial.dmi', icon_state = "module_active", layer = FLOAT_LAYER-0.1))
if(!COOLDOWN_FINISHED(module, cooldown_timer))
- var/image/cooldown_image = image(icon = 'icons/hud/radial.dmi', icon_state = "module_cooldown")
- current_button.add_overlay(cooldown_image)
- addtimer(CALLBACK(current_button, TYPE_PROC_REF(/image, cut_overlay), cooldown_image), COOLDOWN_TIMELEFT(module, cooldown_timer))
+ current_button.add_overlay(image(icon = 'icons/hud/radial.dmi', icon_state = "module_cooldown"))
return ..()
/datum/action/item_action/mod/pinned_module/proc/module_interacted_with(datum/source)
SIGNAL_HANDLER
build_all_button_icons(UPDATE_BUTTON_OVERLAY|UPDATE_BUTTON_STATUS)
+
+/datum/action/item_action/mod/pinned_module/proc/cooldown_started(datum/source, cooldown_time)
+ SIGNAL_HANDLER
+
+ deltimer(cooldown_timer)
+ build_all_button_icons(UPDATE_BUTTON_OVERLAY)
+ if (cooldown_time == 0)
+ return
+ cooldown_timer = addtimer(CALLBACK(src, PROC_REF(build_all_button_icons), UPDATE_BUTTON_OVERLAY), cooldown_time + 1, TIMER_STOPPABLE)
diff --git a/code/modules/mod/mod_theme.dm b/code/modules/mod/mod_theme.dm
index 521dd6f0240..9adaaf4f146 100644
--- a/code/modules/mod/mod_theme.dm
+++ b/code/modules/mod/mod_theme.dm
@@ -949,6 +949,7 @@
default_skin = "syndicate"
armor_type = /datum/armor/mod_theme_syndicate
atom_flags = PREVENT_CONTENTS_EXPLOSION_1
+ complexity_max = DEFAULT_MAX_COMPLEXITY + 3
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
siemens_coefficient = 0
slowdown_inactive = 1
@@ -1043,6 +1044,7 @@
resistance_flags = FIRE_PROOF|ACID_PROOF
atom_flags = PREVENT_CONTENTS_EXPLOSION_1
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
+ complexity_max = DEFAULT_MAX_COMPLEXITY + 3
siemens_coefficient = 0
slowdown_inactive = 1
slowdown_active = 0.5
diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm
index 6abf91562d1..f11c6b9b4b9 100644
--- a/code/modules/mod/mod_types.dm
+++ b/code/modules/mod/mod_types.dm
@@ -231,12 +231,14 @@
/obj/item/mod/module/emp_shield,
/obj/item/mod/module/magnetic_harness,
/obj/item/mod/module/jetpack/advanced,
+ /obj/item/mod/module/jump_jet,
/obj/item/mod/module/flashlight,
/obj/item/mod/module/dna_lock,
)
default_pins = list(
/obj/item/mod/module/armor_booster,
/obj/item/mod/module/jetpack/advanced,
+ /obj/item/mod/module/jump_jet,
)
/obj/item/mod/control/pre_equipped/nuclear
@@ -249,13 +251,21 @@
/obj/item/mod/module/emp_shield,
/obj/item/mod/module/magnetic_harness,
/obj/item/mod/module/jetpack/advanced,
+ /obj/item/mod/module/jump_jet,
/obj/item/mod/module/flashlight,
)
default_pins = list(
/obj/item/mod/module/armor_booster,
/obj/item/mod/module/jetpack/advanced,
+ /obj/item/mod/module/jump_jet,
)
+/obj/item/mod/control/pre_equipped/nuclear/plasmaman
+
+/obj/item/mod/control/pre_equipped/nuclear/plasmaman/Initialize(mapload, new_theme, new_skin, new_core)
+ applied_modules += /obj/item/mod/module/plasma_stabilizer
+ return ..()
+
/obj/item/mod/control/pre_equipped/nuclear/unrestricted
req_access = null
@@ -269,11 +279,13 @@
/obj/item/mod/module/emp_shield,
/obj/item/mod/module/magnetic_harness,
/obj/item/mod/module/jetpack/advanced,
+ /obj/item/mod/module/jump_jet,
/obj/item/mod/module/flashlight,
)
default_pins = list(
/obj/item/mod/module/armor_booster,
/obj/item/mod/module/jetpack/advanced,
+ /obj/item/mod/module/jump_jet,
)
/obj/item/mod/control/pre_equipped/elite/flamethrower
@@ -283,12 +295,14 @@
/obj/item/mod/module/magnetic_harness,
/obj/item/mod/module/thermal_regulator,
/obj/item/mod/module/jetpack/advanced,
+ /obj/item/mod/module/jump_jet,
/obj/item/mod/module/flashlight,
/obj/item/mod/module/flamethrower,
)
default_pins = list(
/obj/item/mod/module/armor_booster,
/obj/item/mod/module/jetpack/advanced,
+ /obj/item/mod/module/jump_jet,
/obj/item/mod/module/flamethrower,
)
diff --git a/code/modules/mod/modules/_module.dm b/code/modules/mod/modules/_module.dm
index d5699986ee9..a3067e0c150 100644
--- a/code/modules/mod/modules/_module.dm
+++ b/code/modules/mod/modules/_module.dm
@@ -89,6 +89,13 @@
on_use()
SEND_SIGNAL(mod, COMSIG_MOD_MODULE_SELECTED, src)
+/// Apply a cooldown until this item can be used again
+/obj/item/mod/module/proc/start_cooldown(applied_cooldown)
+ if (isnull(applied_cooldown))
+ applied_cooldown = cooldown_time
+ COOLDOWN_START(src, cooldown_timer, applied_cooldown)
+ SEND_SIGNAL(src, COMSIG_MODULE_COOLDOWN_STARTED, applied_cooldown)
+
/// Called when the module is activated
/obj/item/mod/module/proc/on_activation()
if(!COOLDOWN_FINISHED(src, cooldown_timer))
@@ -129,8 +136,8 @@
update_signal(used_button)
balloon_alert(mod.wearer, "[src] activated, [used_button]-click to use")
active = TRUE
- COOLDOWN_START(src, cooldown_timer, cooldown_time)
mod.wearer.update_clothing(mod.slot_flags)
+ start_cooldown()
SEND_SIGNAL(src, COMSIG_MODULE_ACTIVATED)
return TRUE
@@ -166,7 +173,7 @@
return FALSE
if(SEND_SIGNAL(src, COMSIG_MODULE_TRIGGERED, mod.wearer) & MOD_ABORT_USE)
return FALSE
- COOLDOWN_START(src, cooldown_timer, cooldown_time)
+ start_cooldown()
addtimer(CALLBACK(mod.wearer, TYPE_PROC_REF(/mob, update_clothing), mod.slot_flags), cooldown_time+1) //need to run it a bit after the cooldown starts to avoid conflicts
mod.wearer.update_clothing(mod.slot_flags)
SEND_SIGNAL(src, COMSIG_MODULE_USED)
diff --git a/code/modules/mod/modules/module_kinesis.dm b/code/modules/mod/modules/module_kinesis.dm
index 52e08133857..ff56a2329c6 100644
--- a/code/modules/mod/modules/module_kinesis.dm
+++ b/code/modules/mod/modules/module_kinesis.dm
@@ -187,7 +187,7 @@
grabbed_atom.cut_overlay(kinesis_icon)
QDEL_NULL(kinesis_beam)
if(isliving(grabbed_atom))
- remove_traits(grabbed_atom, list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), REF(src))
+ grabbed_atom.remove_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), REF(src))
REMOVE_TRAIT(grabbed_atom, TRAIT_NO_FLOATING_ANIM, REF(src))
if(!isitem(grabbed_atom))
animate(grabbed_atom, 0.2 SECONDS, pixel_x = grabbed_atom.base_pixel_x, pixel_y = grabbed_atom.base_pixel_y)
diff --git a/code/modules/mod/modules/modules_antag.dm b/code/modules/mod/modules/modules_antag.dm
index ce438fed83f..1cd70ef9f80 100644
--- a/code/modules/mod/modules/modules_antag.dm
+++ b/code/modules/mod/modules/modules_antag.dm
@@ -503,3 +503,19 @@
if(deleting)
return
mod.helmet.flash_protect = initial(mod.helmet.flash_protect)
+
+///Medbeam - Medbeam but built into a modsuit
+/obj/item/mod/module/medbeam
+ name = "MOD Medbeam Module"
+ desc = "A wrist mounted variant of the medbeam gun, allowing the user to heal their allies without the risk of dropping it."
+ icon_state = "chronogun"
+ module_type = MODULE_ACTIVE
+ complexity = 1
+ active_power_cost = DEFAULT_CHARGE_DRAIN
+ device = /obj/item/gun/medbeam/mod
+ incompatible_modules = list(/obj/item/mod/module/medbeam)
+ removable = TRUE
+ cooldown_time = 0.5
+
+/obj/item/gun/medbeam/mod
+ name = "MOD medbeam"
diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm
index 757d952974e..6d47a5b60ba 100644
--- a/code/modules/mod/modules/modules_general.dm
+++ b/code/modules/mod/modules/modules_general.dm
@@ -169,12 +169,53 @@
/obj/item/mod/module/jetpack/advanced
name = "MOD advanced ion jetpack module"
desc = "An improvement on the previous model of electric thrusters. This one achieves higher speeds through \
- mounting of more jets and a red paint applied on it."
+ mounting of more jets and application of red paint."
icon_state = "jetpack_advanced"
overlay_state_inactive = "module_jetpackadv"
overlay_state_active = "module_jetpackadv_on"
full_speed = TRUE
+/// Cooldown to use if we didn't actually launch a jump jet
+#define FAILED_ACTIVATION_COOLDOWN 3 SECONDS
+
+///Jump Jet - Briefly removes the effect of gravity and pushes you up one z-level if possible.
+/obj/item/mod/module/jump_jet
+ name = "MOD ionic jump jet module"
+ desc = "A specialised ionic thruster which provides a short but powerful boost capable of pushing against gravity, \
+ after which time it needs to recharge."
+ icon_state = "jump_jet"
+ module_type = MODULE_USABLE
+ complexity = 3
+ cooldown_time = 30 SECONDS
+ use_power_cost = DEFAULT_CHARGE_DRAIN * 5
+ incompatible_modules = list(/obj/item/mod/module/jump_jet)
+
+/obj/item/mod/module/jump_jet/on_use()
+ . = ..()
+ if (!.)
+ return FALSE
+ if (DOING_INTERACTION(mod.wearer, mod.wearer))
+ balloon_alert(mod.wearer, "busy!")
+ return
+ balloon_alert(mod.wearer, "launching...")
+ mod.wearer.Shake(duration = 1 SECONDS)
+ if (!do_after(mod.wearer, 1 SECONDS, target = mod.wearer))
+ start_cooldown(FAILED_ACTIVATION_COOLDOWN) // Don't go on full cooldown if we failed to launch
+ return FALSE
+ playsound(mod.wearer, 'sound/vehicles/rocketlaunch.ogg', 100, TRUE)
+ mod.wearer.apply_status_effect(/datum/status_effect/jump_jet)
+ var/turf/launch_from = get_turf(mod.wearer)
+ if (mod.wearer.zMove(UP, z_move_flags = ZMOVE_CHECK_PULLS))
+ launch_from.visible_message(span_warning("[mod.wearer] rockets into the air!"))
+ new /obj/effect/temp_visual/jet_plume(launch_from)
+
+ var/obj/item/mod/module/jetpack/linked_jetpack = locate() in mod.modules
+ if (!isnull(linked_jetpack) && !linked_jetpack.active)
+ linked_jetpack.on_activation()
+ return TRUE
+
+#undef FAILED_ACTIVATION_COOLDOWN
+
///Status Readout - Puts a lot of information including health, nutrition, fingerprints, temperature to the suit TGUI.
/obj/item/mod/module/status_readout
name = "MOD status readout module"
@@ -762,7 +803,7 @@
accepted_mats, 50 * SHEET_MATERIAL_AMOUNT, \
MATCONTAINER_EXAMINE|MATCONTAINER_NO_INSERT, \
container_signals = list( \
- COMSIG_MATCONTAINER_SHEETS_RETRIVED = TYPE_PROC_REF(/obj/item/mod/module/recycler, InsertSheets) \
+ COMSIG_MATCONTAINER_SHEETS_RETRIEVED = TYPE_PROC_REF(/obj/item/mod/module/recycler, InsertSheets) \
) \
)
diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm
index 18a17311c3f..21d2b8352fb 100644
--- a/code/modules/modular_computers/computers/item/computer.dm
+++ b/code/modules/modular_computers/computers/item/computer.dm
@@ -65,6 +65,8 @@
///If the computer has a flashlight/LED light built-in.
var/has_light = FALSE
+ /// If the computer's flashlight/LED light has forcibly disabled for a temporary amount of time.
+ COOLDOWN_DECLARE(disabled_time)
/// How far the computer's light can reach, is not editable by players.
var/comp_light_luminosity = 3
/// The built-in light's color, editable by players.
@@ -127,6 +129,7 @@
UpdateDisplay()
if(has_light)
add_item_action(/datum/action/item_action/toggle_computer_light)
+ RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur))
if(inserted_disk)
inserted_disk = new inserted_disk(src)
if(internal_cell)
@@ -200,10 +203,7 @@
return TRUE
if(istype(inserted_pai)) // Remove pAI
- user.put_in_hands(inserted_pai)
- balloon_alert(user, "removed pAI")
- inserted_pai = null
- update_appearance(UPDATE_ICON)
+ remove_pai(user)
return TRUE
// Gets IDs/access levels from card slot. Would be useful when/if PDAs would become modular PCs. //guess what
@@ -414,7 +414,7 @@
var/mob/living/carbon/human/human_wearer = loc
human_wearer.sec_hud_set_ID()
if(inserted_pai == gone)
- inserted_pai = null
+ update_appearance(UPDATE_ICON)
if(inserted_disk == gone)
inserted_disk = null
update_appearance(UPDATE_ICON)
@@ -660,7 +660,7 @@
/obj/item/modular_computer/ui_action_click(mob/user, actiontype)
if(istype(actiontype, /datum/action/item_action/toggle_computer_light))
- toggle_flashlight()
+ toggle_flashlight(user)
return
return ..()
@@ -671,14 +671,32 @@
* Called from ui_act(), does as the name implies.
* It is separated from ui_act() to be overwritten as needed.
*/
-/obj/item/modular_computer/proc/toggle_flashlight()
+/obj/item/modular_computer/proc/toggle_flashlight(mob/user)
if(!has_light)
return FALSE
+ if(!COOLDOWN_FINISHED(src, disabled_time))
+ balloon_alert(user, "disrupted!")
+ return FALSE
set_light_on(!light_on)
update_appearance()
update_item_action_buttons(force = TRUE) //force it because we added an overlay, not changed its icon
return TRUE
+/**
+ * Disables the computer's flashlight/LED light, if it has one, for a given disrupt_duration.
+ *
+ * Called when sent COMSIG_HIT_BY_SABOTEUR.
+ */
+/obj/item/modular_computer/proc/on_saboteur(datum/source, disrupt_duration)
+ SIGNAL_HANDLER
+ if(!has_light)
+ return
+ set_light_on(FALSE)
+ update_appearance()
+ update_item_action_buttons(force = TRUE) //force it because we added an overlay, not changed its icon
+ COOLDOWN_START(src, disabled_time, disrupt_duration)
+ return COMSIG_SABOTEUR_SUCCESS
+
/**
* Sets the computer's light color, if it has a light.
*
@@ -713,12 +731,7 @@
return
// Inserting a pAI
- if(istype(attacking_item, /obj/item/pai_card) && !inserted_pai)
- if(!user.transferItemToLoc(attacking_item, src))
- return
- inserted_pai = attacking_item
- balloon_alert(user, "inserted pai")
- update_appearance(UPDATE_ICON)
+ if(istype(attacking_item, /obj/item/pai_card) && insert_pai(user, attacking_item))
return
if(istype(attacking_item, /obj/item/stock_parts/cell))
@@ -792,7 +805,7 @@
internal_cell?.forceMove(drop_location())
computer_id_slot?.forceMove(drop_location())
inserted_disk?.forceMove(drop_location())
- inserted_pai?.forceMove(drop_location())
+ remove_pai()
new /obj/item/stack/sheet/iron(get_turf(loc), steel_sheet_cost)
user.balloon_alert(user, "disassembled")
relay_qdel()
@@ -840,3 +853,30 @@
///Returns a string of what to send at the end of messenger's messages.
/obj/item/modular_computer/proc/get_messenger_ending()
return "Sent from my PDA"
+
+/obj/item/modular_computer/proc/insert_pai(mob/user, obj/item/pai_card/card)
+ if(inserted_pai)
+ return FALSE
+ if(!user.transferItemToLoc(card, src))
+ return FALSE
+ inserted_pai = card
+ balloon_alert(user, "inserted pai")
+ var/datum/action/innate/pai/messenger/messenger_ability = new(inserted_pai.pai)
+ messenger_ability.Grant(inserted_pai.pai)
+ update_appearance(UPDATE_ICON)
+ return TRUE
+
+/obj/item/modular_computer/proc/remove_pai(mob/user)
+ if(!inserted_pai)
+ return FALSE
+ var/datum/action/innate/pai/messenger/messenger_ability = locate() in inserted_pai.pai.actions
+ messenger_ability.Remove(inserted_pai.pai)
+ qdel(messenger_ability)
+ if(user)
+ user.put_in_hands(inserted_pai)
+ balloon_alert(user, "removed pAI")
+ else
+ inserted_pai.forceMove(drop_location())
+ inserted_pai = null
+ update_appearance(UPDATE_ICON)
+ return TRUE
diff --git a/code/modules/modular_computers/computers/item/computer_ui.dm b/code/modules/modular_computers/computers/item/computer_ui.dm
index 11c12ea0c47..d5dcf98c623 100644
--- a/code/modules/modular_computers/computers/item/computer_ui.dm
+++ b/code/modules/modular_computers/computers/item/computer_ui.dm
@@ -20,15 +20,21 @@
active_ui = new(user, src, "NtosMain")
return active_ui.open()
- if(active_program)
- active_ui.interface = active_program.tgui_id
- active_ui.title = active_program.filedesc
- active_program.ui_interact(user, active_ui)
- else
- active_ui.interface = "NtosMain"
+ for (var/datum/tgui/window as anything in open_uis)
+ if(active_program)
+ window.interface = active_program.tgui_id
+ window.title = active_program.filedesc
+ active_program.ui_interact(user, window)
+ else
+ window.interface = "NtosMain"
+ window.send_assets()
+ update_static_data_for_all_viewers()
- update_static_data(user, active_ui)
- active_ui.send_assets()
+
+/obj/item/modular_computer/ui_state(mob/user)
+ if(inserted_pai && (user == inserted_pai.pai))
+ return GLOB.contained_state
+ return ..()
/obj/item/modular_computer/interact(mob/user)
if(enabled)
@@ -206,10 +212,9 @@
if("PC_Pai_Interact")
switch(params["option"])
if("eject")
- usr.put_in_hands(inserted_pai)
- to_chat(usr, span_notice("You remove [inserted_pai] from the [name]."))
- inserted_pai = null
- update_appearance(UPDATE_ICON)
+ if(!ishuman(usr))
+ return
+ remove_pai(usr)
if("interact")
inserted_pai.attack_self(usr)
return TRUE
diff --git a/code/modules/modular_computers/computers/item/pda.dm b/code/modules/modular_computers/computers/item/pda.dm
index db45a3e286b..a4b08f2d90f 100644
--- a/code/modules/modular_computers/computers/item/pda.dm
+++ b/code/modules/modular_computers/computers/item/pda.dm
@@ -86,7 +86,7 @@
/obj/item/modular_computer/pda/interact(mob/user)
. = ..()
if(HAS_TRAIT(src, TRAIT_PDA_MESSAGE_MENU_RIGGED))
- explode(usr, from_message_menu = TRUE)
+ explode(user, from_message_menu = TRUE)
/obj/item/modular_computer/pda/attack_self(mob/user)
// bypass literacy checks to access syndicate uplink
@@ -379,7 +379,7 @@
.["comp_light_color"] = robo.lamp_color
//Makes the flashlight button affect the borg rather than the tablet
-/obj/item/modular_computer/pda/silicon/toggle_flashlight()
+/obj/item/modular_computer/pda/silicon/toggle_flashlight(mob/user)
if(!silicon_owner || QDELETED(silicon_owner))
return FALSE
if(iscyborg(silicon_owner))
diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm
index 59ef183f6d6..1f36713380d 100644
--- a/code/modules/modular_computers/file_system/program.dm
+++ b/code/modules/modular_computers/file_system/program.dm
@@ -120,7 +120,7 @@
*access can contain a list of access numbers to check against. If access is not empty, it will be used istead of checking any inserted ID.
*/
/datum/computer_file/program/proc/can_run(mob/user, loud = FALSE, access_to_check, transfer = FALSE, list/access)
- if(issilicon(user))
+ if(issilicon(user) && !ispAI(user))
return TRUE
if(isAdminGhostAI(user))
diff --git a/code/modules/modular_computers/file_system/programs/frontier.dm b/code/modules/modular_computers/file_system/programs/frontier.dm
index aa897467a8c..cf6cc4b2bc2 100644
--- a/code/modules/modular_computers/file_system/programs/frontier.dm
+++ b/code/modules/modular_computers/file_system/programs/frontier.dm
@@ -25,7 +25,7 @@
/datum/computer_file/program/scipaper_program/on_start(mob/living/user)
. = ..()
if(!CONFIG_GET(flag/no_default_techweb_link) && !linked_techweb)
- linked_techweb = SSresearch.science_tech
+ CONNECT_TO_RND_SERVER_ROUNDSTART(linked_techweb, src)
/datum/computer_file/program/scipaper_program/application_attackby(obj/item/attacking_item, mob/living/user)
if(!istype(attacking_item, /obj/item/multitool))
diff --git a/code/modules/modular_computers/file_system/programs/messenger/messenger_program.dm b/code/modules/modular_computers/file_system/programs/messenger/messenger_program.dm
index 2b5d3048052..637b2b33f16 100644
--- a/code/modules/modular_computers/file_system/programs/messenger/messenger_program.dm
+++ b/code/modules/modular_computers/file_system/programs/messenger/messenger_program.dm
@@ -91,6 +91,8 @@
for(var/messenger_ref in messengers_sorted)
var/datum/computer_file/program/messenger/messenger = messengers_sorted[messenger_ref]
+ if(!istype(messenger) || !istype(messenger.computer))
+ continue
if(messenger == src || messenger.invisible)
continue
@@ -552,7 +554,7 @@
return send_message_signal(sender, message, targets, fake_photo, FALSE, TRUE, fake_name, fake_job)
/datum/computer_file/program/messenger/proc/send_message_signal(mob/sender, message, list/datum/computer_file/program/messenger/targets, photo_path = null, everyone = FALSE, rigged = FALSE, fake_name = null, fake_job = null)
- if(!sender.can_perform_action(computer))
+ if(!sender.can_perform_action(computer, ALLOW_RESTING))
return FALSE
if(!COOLDOWN_FINISHED(src, last_text))
@@ -654,17 +656,17 @@
if(!isnull(viewing_messages_of) && viewing_messages_of == sender_ref)
viewing_messages_of = REF(chat)
- var/mob/living/receiver_mob = null
- //Check our immediate loc
- if(isliving(computer.loc))
- receiver_mob = computer.loc
- //Maybe they are a silicon!
- else
- receiver_mob = get(computer, /mob/living/silicon)
+ var/list/mob/living/receievers = list()
+ if(computer.inserted_pai)
+ receievers += computer.inserted_pai.pai
+ if(computer.loc && isliving(computer.loc))
+ receievers += computer.loc
- var/should_ring = !alert_silenced || is_rigged
-
- if(should_ring && istype(receiver_mob) && receiver_mob.is_literate() && (receiver_mob.stat == CONSCIOUS || receiver_mob.stat == SOFT_CRIT))
+ for(var/mob/living/messaged_mob as anything in receievers)
+ if(messaged_mob.stat >= UNCONSCIOUS)
+ continue
+ if(!messaged_mob.is_literate())
+ continue
var/reply_href = signal.data["rigged"] ? "explode" : "message"
var/photo_href = signal.data["rigged"] ? "explode" : "open"
var/reply
@@ -679,16 +681,16 @@
var/sender_title = is_fake_user ? STRINGIFY_PDA_TARGET(fake_name, fake_job) : get_messenger_name(sender_messenger)
var/sender_name = is_fake_user ? fake_name : sender_messenger.computer.saved_identification
- if (isAI(receiver_mob))
- sender_title = "[sender_title]"
+ if (isAI(messaged_mob))
+ sender_title = "[sender_title]"
var/inbound_message = "[signal.format_message()]"
inbound_message = emoji_parse(inbound_message)
var/photo_message = signal.data["photo"] ? " (Photo Attached)" : ""
- to_chat(receiver_mob, span_infoplain("[icon2html(computer, receiver_mob)] PDA message from [sender_title], \"[inbound_message]\"[photo_message] [reply]"))
+ to_chat(messaged_mob, span_infoplain("[icon2html(computer, messaged_mob)] PDA message from [sender_title], \"[inbound_message]\"[photo_message] [reply]"))
- if (alert_able && should_ring)
+ if (alert_able && (!alert_silenced || is_rigged))
computer.ring(ringtone)
SStgui.update_uis(computer)
diff --git a/code/modules/modular_computers/file_system/programs/notepad.dm b/code/modules/modular_computers/file_system/programs/notepad.dm
index 2e1eb52add5..01afaa08c19 100644
--- a/code/modules/modular_computers/file_system/programs/notepad.dm
+++ b/code/modules/modular_computers/file_system/programs/notepad.dm
@@ -10,7 +10,14 @@
usage_flags = PROGRAM_TABLET
var/written_note = "Congratulations on your station upgrading to the new NtOS and Thinktronic based collaboration effort, \
- bringing you the best in electronics and software since 2467!"
+ bringing you the best in electronics and software since 2467!\n\
+ To help with navigation, we have provided the following definitions:\n\
+ Fore - Toward front of ship\n\
+ Aft - Toward back of ship\n\
+ Port - Left side of ship\n\
+ Starboard - Right side of ship\n\
+ Quarter - Either sides of Aft\n\
+ Bow - Either sides of Fore"
/datum/computer_file/program/notepad/ui_act(action, list/params, datum/tgui/ui)
switch(action)
diff --git a/code/modules/modular_computers/file_system/programs/statusdisplay.dm b/code/modules/modular_computers/file_system/programs/statusdisplay.dm
index 9259e6fd468..9350254f646 100644
--- a/code/modules/modular_computers/file_system/programs/statusdisplay.dm
+++ b/code/modules/modular_computers/file_system/programs/statusdisplay.dm
@@ -58,7 +58,28 @@
if(picture in GLOB.status_display_state_pictures)
post_status(picture)
else
- post_status("alert", picture)
+ if(picture == "currentalert") // You cannot set Code Blue display during Code Red and similiar
+ switch(SSsecurity_level.get_current_level_as_number())
+ if(SEC_LEVEL_DELTA)
+ post_status("alert", "deltaalert")
+ if(SEC_LEVEL_RED)
+ post_status("alert", "redalert")
+ if(SEC_LEVEL_BLUE)
+ post_status("alert", "bluealert")
+ if(SEC_LEVEL_GREEN)
+ post_status("alert", "greenalert")
+ // SKYRAT EDIT ADD START - Alert Levels
+ if(SEC_LEVEL_VIOLET)
+ post_status("alert", "violetalert")
+ if(SEC_LEVEL_ORANGE)
+ post_status("alert", "orangealert")
+ if(SEC_LEVEL_AMBER)
+ post_status("alert", "amberalert")
+ if(SEC_LEVEL_GAMMA)
+ post_status("alert", "gammaalert")
+ // SKYRAT EDIT ADD END - Alert Levels
+ else
+ post_status("alert", picture)
log_game("[key_name(usr)] has changed the station status display message to \"[picture]\" [loc_name(usr)]")
diff --git a/code/modules/modular_computers/file_system/programs/techweb.dm b/code/modules/modular_computers/file_system/programs/techweb.dm
index 52129d39997..9c097b2fb9b 100644
--- a/code/modules/modular_computers/file_system/programs/techweb.dm
+++ b/code/modules/modular_computers/file_system/programs/techweb.dm
@@ -24,7 +24,7 @@
/datum/computer_file/program/science/on_start(mob/living/user)
. = ..()
if(!CONFIG_GET(flag/no_default_techweb_link) && !stored_research)
- stored_research = SSresearch.science_tech
+ CONNECT_TO_RND_SERVER_ROUNDSTART(stored_research, src)
/datum/computer_file/program/science/application_attackby(obj/item/attacking_item, mob/living/user)
if(!istype(attacking_item, /obj/item/multitool))
@@ -194,7 +194,7 @@
var/list/price = tech_node.get_price(stored_research)
if(stored_research.can_afford(price))
user.investigate_log("researched [id]([json_encode(price)]) on techweb id [stored_research.id] via [computer].", INVESTIGATE_RESEARCH)
- if(stored_research == SSresearch.science_tech)
+ if(istype(stored_research, /datum/techweb/science))
SSblackbox.record_feedback("associative", "science_techweb_unlock", 1, list("id" = "[id]", "name" = tech_node.display_name, "price" = "[json_encode(price)]", "time" = SQLtime()))
if(stored_research.research_node_id(id))
computer.say("Successfully researched [tech_node.display_name].")
diff --git a/code/modules/modular_computers/laptop_vendor.dm b/code/modules/modular_computers/laptop_vendor.dm
deleted file mode 100644
index 28a6e12843f..00000000000
--- a/code/modules/modular_computers/laptop_vendor.dm
+++ /dev/null
@@ -1,152 +0,0 @@
-// A vendor machine for modular computer portable devices - Laptops and Tablets
-
-/obj/machinery/lapvend
- name = "computer vendor"
- desc = "A vending machine with microfabricator capable of dispensing various NT-branded computers."
- icon = 'icons/obj/machines/vending.dmi'
- icon_state = "robotics"
- layer = 2.9
- density = TRUE
-
- // The actual laptop/tablet
- var/obj/item/modular_computer/laptop/fabricated_laptop
- var/obj/item/modular_computer/pda/fabricated_tablet
-
- // Utility vars
- var/state = 0 // 0: Select device type, 1: Select loadout, 2: Payment, 3: Thankyou screen
- var/devtype = 0 // 0: None(unselected), 1: Laptop, 2: Tablet
- var/total_price = 0 // Price of currently vended device.
- var/credits = 0
-
-// Removes all traces of old order and allows you to begin configuration from scratch.
-/obj/machinery/lapvend/proc/reset_order()
- state = 0
- devtype = 0
- if(fabricated_laptop)
- qdel(fabricated_laptop)
- fabricated_laptop = null
- if(fabricated_tablet)
- qdel(fabricated_tablet)
- fabricated_tablet = null
-
-// Recalculates the price and optionally even fabricates the device.
-/obj/machinery/lapvend/proc/fabricate_and_recalc_price(fabricate = FALSE)
- total_price = 0
- if(devtype == 1) // Laptop, generally cheaper to make it accessible for most station roles
- if(fabricate)
- fabricated_laptop = new /obj/item/modular_computer/laptop/buildable(src)
- total_price = 99
-
- return total_price
- else if(devtype == 2) // Tablet, more expensive, not everyone could probably afford this.
- if(fabricate)
- fabricated_tablet = new(src)
- total_price = 199
- return FALSE
-
-/obj/machinery/lapvend/ui_act(action, params)
- . = ..()
- if(.)
- return
-
- switch(action)
- if("pick_device")
- if(state) // We've already picked a device type
- return FALSE
- devtype = text2num(params["pick"])
- state = 1
- fabricate_and_recalc_price(FALSE)
- return TRUE
- if("clean_order")
- reset_order()
- return TRUE
- if("purchase")
- try_purchase()
- return TRUE
- if((state != 1) && devtype) // Following IFs should only be usable when in the Select Loadout mode
- return FALSE
- switch(action)
- if("confirm_order")
- state = 2 // Wait for ID swipe for payment processing
- fabricate_and_recalc_price(FALSE)
- return TRUE
- return FALSE
-
-/obj/machinery/lapvend/ui_interact(mob/user, datum/tgui/ui)
- if(machine_stat & (BROKEN | NOPOWER | MAINT))
- if(ui)
- ui.close()
- return FALSE
-
- ui = SStgui.try_update_ui(user, src, ui)
- if (!ui)
- ui = new(user, src, "ComputerFabricator")
- ui.open()
-
-/obj/machinery/lapvend/attackby(obj/item/I, mob/user)
- if(istype(I, /obj/item/stack/spacecash))
- var/obj/item/stack/spacecash/c = I
- if(!user.temporarilyRemoveItemFromInventory(c))
- return
- credits += c.value
- visible_message(span_info("[span_name("[user]")] inserts [c.value] cr into [src]."))
- qdel(c)
- return
- else if(istype(I, /obj/item/holochip))
- var/obj/item/holochip/HC = I
- credits += HC.credits
- visible_message(span_info("[user] inserts a [HC.credits] cr holocredit chip into [src]."))
- qdel(HC)
- return
- else if(isidcard(I))
- if(state != 2)
- return
- var/obj/item/card/id/ID = I
- var/datum/bank_account/account = ID.registered_account
- var/target_credits = total_price - credits
- if(!account.adjust_money(-target_credits, "Vending: Laptop Vendor"))
- say("Insufficient credits on card to purchase!")
- return
- credits += target_credits
- say("[target_credits] cr have been withdrawn from your account.")
- return
- return ..()
-
-// Simplified payment processing, returns 1 on success.
-/obj/machinery/lapvend/proc/process_payment()
- if(total_price > credits)
- say("Insufficient credits.")
- return FALSE
- else
- return TRUE
-
-/obj/machinery/lapvend/ui_data(mob/user)
-
- var/list/data = list()
- data["state"] = state
- if(state == 1)
- data["devtype"] = devtype
- if(state == 1 || state == 2)
- data["totalprice"] = total_price
- data["credits"] = credits
-
- return data
-
-
-/obj/machinery/lapvend/proc/try_purchase()
- // Awaiting payment state
- if(state == 2)
- if(process_payment())
- fabricate_and_recalc_price(1)
- if((devtype == 1) && fabricated_laptop)
- fabricated_laptop.forceMove(src.loc)
- fabricated_laptop = null
- else if((devtype == 2) && fabricated_tablet)
- fabricated_tablet.forceMove(src.loc)
- fabricated_tablet = null
- credits -= total_price
- say("Enjoy your new product!")
- state = 3
- addtimer(CALLBACK(src, PROC_REF(reset_order)), 100)
- return TRUE
- return FALSE
diff --git a/code/modules/pai/actions.dm b/code/modules/pai/actions.dm
index 0d22d828382..e067cca01e9 100644
--- a/code/modules/pai/actions.dm
+++ b/code/modules/pai/actions.dm
@@ -61,3 +61,18 @@
/datum/action/innate/pai/light/Trigger(trigger_flags)
..()
pai_owner.toggle_integrated_light()
+
+/datum/action/innate/pai/messenger
+ name = "Interact with PDA"
+ button_icon_state = "pda"
+ background_icon_state = "bg_tech"
+ overlay_icon_state = "bg_tech_border"
+
+/datum/action/innate/pai/messenger/Trigger(trigger_flags)
+ . = ..()
+ var/obj/item/pai_card/pai_holder = owner.loc
+ if(!istype(pai_holder.loc, /obj/item/modular_computer))
+ owner.balloon_alert(owner, "not in a pda!")
+ return
+ var/obj/item/modular_computer/computer_host = pai_holder.loc
+ computer_host.interact(owner)
diff --git a/code/modules/pai/camera.dm b/code/modules/pai/camera.dm
index 30b1918651e..a091b208638 100644
--- a/code/modules/pai/camera.dm
+++ b/code/modules/pai/camera.dm
@@ -1,10 +1,8 @@
/mob/living/silicon/pai/ClickOn(atom/target, params)
- ..()
- if(!camera?.in_camera_mode)
- return FALSE
- //pAI picture taking
- camera.toggle_camera_mode(sound = FALSE)
- camera.captureimage(target, usr, camera.picture_size_x - 1, camera.picture_size_y - 1)
+ . = ..()
+ if(aicamera && aicamera.in_camera_mode)
+ aicamera.toggle_camera_mode(sound = FALSE)
+ aicamera.captureimage(target, usr)
return TRUE
/obj/item/camera/siliconcam/pai_camera
@@ -46,13 +44,14 @@
* @returns {boolean} - TRUE if the camera worked.
*/
/mob/living/silicon/pai/proc/use_camera(mob/user, mode)
- if(!camera || isnull(mode))
+ if(!aicamera || isnull(mode))
return FALSE
switch(mode)
if(PAI_PHOTO_MODE_CAMERA)
- camera.toggle_camera_mode(user)
+ aicamera.toggle_camera_mode(user)
if(PAI_PHOTO_MODE_PRINTER)
- camera.pai_print(user)
+ var/obj/item/camera/siliconcam/pai_camera/paicam = aicamera
+ paicam.pai_print(user)
if(PAI_PHOTO_MODE_ZOOM)
- camera.adjust_zoom(user)
+ aicamera.adjust_zoom(user)
return TRUE
diff --git a/code/modules/pai/hud.dm b/code/modules/pai/hud.dm
index 057a199cdad..530780758d2 100644
--- a/code/modules/pai/hud.dm
+++ b/code/modules/pai/hud.dm
@@ -150,7 +150,7 @@
if(!..())
return
var/mob/living/silicon/pai/pAI = usr
- pAI.camera.toggle_camera_mode(usr)
+ pAI.aicamera.toggle_camera_mode(usr)
/atom/movable/screen/pai/image_view
name = "View Images"
@@ -161,7 +161,7 @@
if(!..())
return
var/mob/living/silicon/pai/pAI = usr
- pAI.camera.viewpictures(usr)
+ pAI.aicamera.viewpictures(usr)
/atom/movable/screen/pai/radio
name = "radio"
@@ -177,7 +177,6 @@
/datum/hud/pai/New(mob/living/silicon/pai/owner)
..()
var/atom/movable/screen/using
- var/mob/living/silicon/pai/mypai = mymob
// Software menu
using = new /atom/movable/screen/pai/software(null, src)
@@ -238,9 +237,8 @@
using = new /atom/movable/screen/pai/modpc(null, src)
using.screen_loc = ui_pai_mod_int
static_inventory += using
- mypai.pda_button = using
var/atom/movable/screen/pai/modpc/tablet_button = using
- tablet_button.pAI = mypai
+ tablet_button.pAI = mymob
// Internal GPS
using = new /atom/movable/screen/pai/internal_gps(null, src)
diff --git a/code/modules/pai/pai.dm b/code/modules/pai/pai.dm
index 4dfaaca5437..8c3039d8c62 100644
--- a/code/modules/pai/pai.dm
+++ b/code/modules/pai/pai.dm
@@ -79,10 +79,6 @@
var/obj/item/instrument/piano_synth/instrument
/// Newscaster
var/obj/machinery/newscaster/pai/newscaster
- /// PDA
- var/atom/movable/screen/ai/modpc/pda_button
- /// Photography module
- var/obj/item/camera/siliconcam/pai_camera/camera
/// Remote signaler
var/obj/item/assembly/signaler/internal/signaler
@@ -155,7 +151,6 @@
/mob/living/silicon/pai/Destroy()
QDEL_NULL(atmos_analyzer)
- QDEL_NULL(camera)
QDEL_NULL(hacking_cable)
QDEL_NULL(host_scan)
QDEL_NULL(instrument)
@@ -187,8 +182,8 @@
/mob/living/silicon/pai/Exited(atom/movable/gone, direction)
if(gone == atmos_analyzer)
atmos_analyzer = null
- else if(gone == camera)
- camera = null
+ else if(gone == aicamera)
+ aicamera = null
else if(gone == host_scan)
host_scan = null
else if(gone == internal_gps)
diff --git a/code/modules/pai/software.dm b/code/modules/pai/software.dm
index 85f952c43eb..103056a5535 100644
--- a/code/modules/pai/software.dm
+++ b/code/modules/pai/software.dm
@@ -125,7 +125,7 @@
if("Newscaster")
newscaster = new(src)
if("Photography Module")
- camera = new(src)
+ aicamera = new /obj/item/camera/siliconcam/pai_camera(src)
if("Remote Signaler")
signaler = new(src)
return TRUE
diff --git a/code/modules/paperwork/paper_cutter.dm b/code/modules/paperwork/paper_cutter.dm
index 0dddb90c1db..9586ec6e861 100644
--- a/code/modules/paperwork/paper_cutter.dm
+++ b/code/modules/paperwork/paper_cutter.dm
@@ -171,8 +171,9 @@
to_chat(user, span_userdanger("You neatly cut [stored_paper][clumsy ? "... and your finger in the process!" : "."]"))
if(clumsy)
var/obj/item/bodypart/finger = user.get_active_hand()
- var/datum/wound/slash/moderate/papercut = new
- papercut.apply_wound(finger, wound_source = "paper cut")
+ if (iscarbon(user))
+ var/mob/living/carbon/carbon_user = user
+ carbon_user.cause_wound_of_type_and_severity(WOUND_SLASH, finger, WOUND_SEVERITY_MODERATE, wound_source = "paper cut")
stored_paper = null
qdel(stored_paper)
new /obj/item/paper/paperslip(get_turf(src))
diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm
index 3caa5d5b77a..05606ac3a2e 100644
--- a/code/modules/paperwork/pen.dm
+++ b/code/modules/paperwork/pen.dm
@@ -237,7 +237,7 @@
return
if(!M.reagents)
return
- reagents.trans_to(M, reagents.total_volume, transfered_by = user, methods = INJECT)
+ reagents.trans_to(M, reagents.total_volume, transferred_by = user, methods = INJECT)
/obj/item/pen/sleepy/Initialize(mapload)
@@ -363,6 +363,9 @@
icon_state = "pendriver"
toolspeed = 1.2 // gotta have some downside
+/obj/item/pen/screwdriver/get_all_tool_behaviours()
+ return list(TOOL_SCREWDRIVER)
+
/obj/item/pen/screwdriver/Initialize(mapload)
. = ..()
AddComponent( \
diff --git a/code/modules/paperwork/ticketmachine.dm b/code/modules/paperwork/ticketmachine.dm
index 8d62bf784cb..a5902a9df5a 100644
--- a/code/modules/paperwork/ticketmachine.dm
+++ b/code/modules/paperwork/ticketmachine.dm
@@ -31,6 +31,7 @@
/obj/machinery/ticket_machine/Initialize(mapload)
. = ..()
update_appearance()
+ find_and_hang_on_wall()
/obj/machinery/ticket_machine/Destroy()
for(var/obj/item/ticket_machine_ticket/ticket in tickets)
@@ -55,7 +56,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/ticket_machine, 32)
return
var/obj/item/multitool/M = I
M.set_buffer(src)
- to_chat(user, span_notice("You store linkage information in [I]'s buffer."))
+ balloon_alert(user, "saved to multitool buffer")
return TRUE
/obj/machinery/ticket_machine/emag_act(mob/user, obj/item/card/emag/emag_card) //Emag the ticket machine to dispense burning tickets, as well as randomize its number to destroy the HoP's mind.
diff --git a/code/modules/photography/camera/camera.dm b/code/modules/photography/camera/camera.dm
index 33c22c66aef..1c0e360ed75 100644
--- a/code/modules/photography/camera/camera.dm
+++ b/code/modules/photography/camera/camera.dm
@@ -187,7 +187,7 @@
var/list/turfs = list()
var/list/mobs = list()
var/blueprints = FALSE
- var/clone_area = SSmapping.RequestBlockReservation(size_x * 2 + 1, size_y * 2 + 1)
+ var/clone_area = SSmapping.request_turf_block_reservation(size_x * 2 + 1, size_y * 2 + 1, 1)
var/width = size_x * 2 + 1
var/height = size_y * 2 + 1
diff --git a/code/modules/photography/camera/camera_image_capturing.dm b/code/modules/photography/camera/camera_image_capturing.dm
index 6b48e29da52..d928164ff01 100644
--- a/code/modules/photography/camera/camera_image_capturing.dm
+++ b/code/modules/photography/camera/camera_image_capturing.dm
@@ -16,13 +16,14 @@
var/wipe_atoms = FALSE
if(istype(clone_area) && total_x == clone_area.width && total_y == clone_area.height && size_x >= 0 && size_y > 0)
- var/cloned_center_x = round(clone_area.bottom_left_coords[1] + ((total_x - 1) / 2))
- var/cloned_center_y = round(clone_area.bottom_left_coords[2] + ((total_y - 1) / 2))
+ var/turf/bottom_left = clone_area.bottom_left_turfs[1]
+ var/cloned_center_x = round(bottom_left.x + ((total_x - 1) / 2))
+ var/cloned_center_y = round(bottom_left.y + ((total_y - 1) / 2))
for(var/t in turfs)
var/turf/T = t
var/offset_x = T.x - center.x
var/offset_y = T.y - center.y
- var/turf/newT = locate(cloned_center_x + offset_x, cloned_center_y + offset_y, clone_area.bottom_left_coords[3])
+ var/turf/newT = locate(cloned_center_x + offset_x, cloned_center_y + offset_y, bottom_left.z)
if(!(newT in clone_area.reserved_turfs)) //sanity check so we don't overwrite other areas somehow
continue
atoms += new /obj/effect/appearance_clone(newT, T)
@@ -34,7 +35,7 @@
atoms += new /obj/effect/appearance_clone(newT, A)
skip_normal = TRUE
wipe_atoms = TRUE
- center = locate(cloned_center_x, cloned_center_y, clone_area.bottom_left_coords[3])
+ center = locate(cloned_center_x, cloned_center_y, bottom_left.z)
if(!skip_normal)
for(var/i in turfs)
diff --git a/code/modules/plumbing/plumbers/bottler.dm b/code/modules/plumbing/plumbers/bottler.dm
index e28126d6220..7ce4c2f5576 100644
--- a/code/modules/plumbing/plumbers/bottler.dm
+++ b/code/modules/plumbing/plumbers/bottler.dm
@@ -85,15 +85,15 @@
var/obj/item/reagent_containers/B = AM
///see if it would overflow else inject
if((B.reagents.total_volume + wanted_amount) <= B.reagents.maximum_volume)
- reagents.trans_to(B, wanted_amount, transfered_by = src)
+ reagents.trans_to(B, wanted_amount, transferred_by = src)
B.forceMove(goodspot)
return
///glass was full so we move it away
AM.forceMove(badspot)
if(istype(AM, /obj/item/slime_extract)) ///slime extracts need inject
AM.forceMove(goodspot)
- reagents.trans_to(AM, wanted_amount, transfered_by = src, methods = INJECT)
+ reagents.trans_to(AM, wanted_amount, transferred_by = src, methods = INJECT)
return
if(istype(AM, /obj/item/slimecross/industrial)) ///no need to move slimecross industrial things
- reagents.trans_to(AM, wanted_amount, transfered_by = src, methods = INJECT)
+ reagents.trans_to(AM, wanted_amount, transferred_by = src, methods = INJECT)
return
diff --git a/code/modules/plumbing/plumbers/grinder_chemical.dm b/code/modules/plumbing/plumbers/grinder_chemical.dm
index 54a8b48f2d2..e70977bc1f4 100644
--- a/code/modules/plumbing/plumbers/grinder_chemical.dm
+++ b/code/modules/plumbing/plumbers/grinder_chemical.dm
@@ -1,6 +1,6 @@
/obj/machinery/plumbing/grinder_chemical
name = "chemical grinder"
- desc = "chemical grinder."
+ desc = "Chemical grinder. Can either grind or juice stuff you put in."
icon_state = "grinder_chemical"
layer = ABOVE_ALL_MOB_LAYER
plane = ABOVE_GAME_PLANE
@@ -8,7 +8,6 @@
reagent_flags = TRANSPARENT | DRAINABLE
buffer = 400
active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2
- var/eat_dir = SOUTH
/obj/machinery/plumbing/grinder_chemical/Initialize(mapload, bolt, layer)
. = ..()
@@ -18,21 +17,35 @@
)
AddElement(/datum/element/connect_loc, loc_connections)
-/obj/machinery/plumbing/grinder_chemical/setDir(newdir)
- . = ..()
- eat_dir = newdir
+/obj/machinery/plumbing/grinder_chemical/attackby(obj/item/weapon, mob/user, params)
+ if(istype(weapon, /obj/item/storage/bag))
+ to_chat(user, span_notice("You dump items from [weapon] into the grinder."))
+ for(var/obj/item/obj_item in weapon.contents)
+ grind(obj_item)
+ else
+ to_chat(user, span_notice("You attempt to grind [weapon]."))
+ grind(weapon)
+
+ return TRUE
/obj/machinery/plumbing/grinder_chemical/CanAllowThrough(atom/movable/mover, border_dir)
. = ..()
if(!anchored)
return
- if(border_dir == eat_dir)
- return TRUE
+ if(!istype(mover, /obj/item))
+ return FALSE
+ return TRUE
/obj/machinery/plumbing/grinder_chemical/proc/on_entered(datum/source, atom/movable/AM)
SIGNAL_HANDLER
+
grind(AM)
+/**
+ * Grinds/Juices the atom
+ * Arguments
+ * * [AM][atom] - the atom to grind or juice
+ */
/obj/machinery/plumbing/grinder_chemical/proc/grind(atom/AM)
if(machine_stat & NOPOWER)
return
@@ -40,19 +53,14 @@
return
if(!isitem(AM))
return
- var/obj/item/I = AM
- if(I.juice_results || I.grind_results)
- use_power(active_power_usage)
- if(I.juice_results)
- I.on_juice()
- reagents.add_reagent_list(I.juice_results)
- if(I.reagents)
- I.reagents.trans_to(src, I.reagents.total_volume, transfered_by = src)
- qdel(I)
- return
- I.on_grind()
- reagents.add_reagent_list(I.grind_results)
- if(I.reagents)
- I.reagents.trans_to(src, I.reagents.total_volume, transfered_by = src)
- qdel(I)
+ var/obj/item/I = AM
+ var/result
+ if(I.grind_results || I.juice_typepath)
+ use_power(active_power_usage)
+ if(I.grind_results)
+ result = I.grind(reagents, usr)
+ else if (I.juice_typepath)
+ result = I.juice(reagents, usr)
+ if(result)
+ qdel(I)
diff --git a/code/modules/plumbing/plumbers/teleporter.dm b/code/modules/plumbing/plumbers/teleporter.dm
index 7b3a62c9939..a8e6e7ae3ac 100644
--- a/code/modules/plumbing/plumbers/teleporter.dm
+++ b/code/modules/plumbing/plumbers/teleporter.dm
@@ -73,7 +73,7 @@
var/obj/item/multitool/M = I
M.set_buffer(src)
- to_chat(user, span_notice("You store linkage information in [I]'s buffer."))
+ balloon_alert(user, "saved to multitool buffer")
return TRUE
/obj/machinery/plumbing/receiver/process(seconds_per_tick)
diff --git a/code/modules/power/apc/apc_attack.dm b/code/modules/power/apc/apc_attack.dm
index 85dc47f90dc..3ff3d640c62 100644
--- a/code/modules/power/apc/apc_attack.dm
+++ b/code/modules/power/apc/apc_attack.dm
@@ -243,7 +243,7 @@
balloon_alert(ethereal, "can't transfer power!")
return
if(istype(stomach))
- balloon_alert(ethereal, "transfered power")
+ balloon_alert(ethereal, "transferred power")
stomach.adjust_charge(-APC_POWER_GAIN)
cell.give(APC_POWER_GAIN)
else
diff --git a/code/modules/power/apc/apc_main.dm b/code/modules/power/apc/apc_main.dm
index b9f60aea016..fb9fd389c17 100644
--- a/code/modules/power/apc/apc_main.dm
+++ b/code/modules/power/apc/apc_main.dm
@@ -212,6 +212,7 @@
AddElement(/datum/element/contextual_screentip_bare_hands, rmb_text = "Toggle interface lock")
AddElement(/datum/element/contextual_screentip_mob_typechecks, hovering_mob_typechecks)
+ find_and_hang_on_wall()
/obj/machinery/power/apc/Destroy()
if(malfai && operating)
diff --git a/code/modules/power/floodlight.dm b/code/modules/power/floodlight.dm
index 3ab8ece250f..f36c9b13038 100644
--- a/code/modules/power/floodlight.dm
+++ b/code/modules/power/floodlight.dm
@@ -144,6 +144,7 @@
/obj/machinery/power/floodlight/Initialize(mapload)
. = ..()
RegisterSignal(src, COMSIG_OBJ_PAINTED, TYPE_PROC_REF(/obj/machinery/power/floodlight, on_color_change)) //update light color when color changes
+ RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur))
register_context()
/obj/machinery/power/floodlight/proc/on_color_change(obj/machinery/power/flood_light, mob/user, obj/item/toy/crayon/spraycan/spraycan, is_dark_color)
@@ -289,6 +290,11 @@
/obj/machinery/power/floodlight/attack_ai(mob/user)
return attack_hand(user)
+/obj/machinery/power/floodlight/proc/on_saboteur(datum/source, disrupt_duration)
+ SIGNAL_HANDLER
+ atom_break(ENERGY) // technically,
+ return COMSIG_SABOTEUR_SUCCESS
+
/obj/machinery/power/floodlight/atom_break(damage_flag)
. = ..()
if(!.)
@@ -297,7 +303,8 @@
var/obj/structure/floodlight_frame/floodlight_frame = new(loc)
floodlight_frame.state = FLOODLIGHT_NEEDS_LIGHTS
- new /obj/item/light/tube(loc)
+ var/obj/item/light/tube/our_light = new(loc)
+ our_light.shatter()
qdel(src)
diff --git a/code/modules/power/lighting/light.dm b/code/modules/power/lighting/light.dm
index 2486a6500c1..ed4b2159cab 100644
--- a/code/modules/power/lighting/light.dm
+++ b/code/modules/power/lighting/light.dm
@@ -114,7 +114,9 @@
// Light projects out backwards from the dir of the light
set_light(l_dir = REVERSE_DIR(dir))
RegisterSignal(src, COMSIG_LIGHT_EATER_ACT, PROC_REF(on_light_eater))
+ RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur))
AddElement(/datum/element/atmos_sensitive, mapload)
+ find_and_hang_on_wall(custom_drop_callback = CALLBACK(src, PROC_REF(knock_down)))
return INITIALIZE_HINT_LATELOAD
/obj/machinery/light/LateInitialize()
@@ -706,6 +708,11 @@
tube?.burn()
return
+/obj/machinery/light/proc/on_saboteur(datum/source, disrupt_duration)
+ SIGNAL_HANDLER
+ break_light_tube()
+ return COMSIG_SABOTEUR_SUCCESS
+
/obj/machinery/light/proc/grey_tide(datum/source, list/grey_tide_areas)
SIGNAL_HANDLER
@@ -714,6 +721,20 @@
continue
INVOKE_ASYNC(src, PROC_REF(flicker))
+/**
+ * All the effects that occur when a light falls off a wall that it was hung onto.
+ */
+/obj/machinery/light/proc/knock_down()
+ new /obj/item/wallframe/light_fixture(drop_location())
+ new /obj/item/stack/cable_coil(drop_location(), 1, "red")
+ if(status != LIGHT_BROKEN)
+ break_light_tube(FALSE)
+ if(status != LIGHT_EMPTY)
+ drop_light_tube()
+ if(cell)
+ cell.forceMove(drop_location())
+ qdel(src)
+
/obj/machinery/light/floor
name = "floor light"
desc = "A lightbulb you can walk on without breaking it, amazing."
diff --git a/code/modules/power/lighting/light_construct.dm b/code/modules/power/lighting/light_construct.dm
index 5a8f406b86c..05d9533c79e 100644
--- a/code/modules/power/lighting/light_construct.dm
+++ b/code/modules/power/lighting/light_construct.dm
@@ -33,6 +33,7 @@
. = ..()
if(building)
setDir(ndir)
+ find_and_hang_on_wall()
/obj/structure/light_construct/Destroy()
QDEL_NULL(cell)
diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm
index d3e4fe9e808..0a797a2d7d6 100644
--- a/code/modules/power/singularity/singularity.dm
+++ b/code/modules/power/singularity/singularity.dm
@@ -14,6 +14,7 @@
/// the prepended string to the icon state (singularity_s1, dark_matter_s1, etc)
var/singularity_icon_variant = "singularity"
+
/// The singularity component itself.
/// A weak ref in case an admin removes the component to preserve the functionality.
var/datum/weakref/singularity_component
@@ -55,6 +56,8 @@
/obj/singularity/Initialize(mapload, starting_energy = 50)
. = ..()
+ energy = starting_energy
+
START_PROCESSING(SSsinguloprocess, src)
SSpoints_of_interest.make_point_of_interest(src)
@@ -212,7 +215,7 @@
if(STAGE_TWO)
if(check_cardinals_range(1, TRUE))
current_size = STAGE_TWO
- icon = 'icons/obj/machines/engine/singularity.dmi'
+ icon = 'icons/effects/96x96.dmi'
icon_state = "[singularity_icon_variant]_s3"
pixel_x = -32
pixel_y = -32
@@ -224,7 +227,7 @@
if(STAGE_THREE)
if(check_cardinals_range(2, TRUE))
current_size = STAGE_THREE
- icon = 'icons/obj/machines/engine/singularity.dmi'
+ icon = 'icons/effects/160x160.dmi'
icon_state = "[singularity_icon_variant]_s5"
pixel_x = -64
pixel_y = -64
@@ -236,7 +239,7 @@
if(STAGE_FOUR)
if(check_cardinals_range(3, TRUE))
current_size = STAGE_FOUR
- icon = 'icons/obj/machines/engine/singularity.dmi'
+ icon = 'icons/effects/224x224.dmi'
icon_state = "[singularity_icon_variant]_s7"
pixel_x = -96
pixel_y = -96
@@ -247,7 +250,7 @@
dissipate_strength = 10
if(STAGE_FIVE)//this one also lacks a check for gens because it eats everything
current_size = STAGE_FIVE
- icon = 'icons/obj/machines/engine/singularity.dmi'
+ icon = 'icons/effects/288x288.dmi'
icon_state = "[singularity_icon_variant]_s9"
pixel_x = -128
pixel_y = -128
diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm
index 71f2346646c..654ea805440 100644
--- a/code/modules/power/supermatter/supermatter.dm
+++ b/code/modules/power/supermatter/supermatter.dm
@@ -39,6 +39,8 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
var/absorption_ratio = 0.15
/// The gasmix we just recently absorbed. Tile's air multiplied by absorption_ratio
var/datum/gas_mixture/absorbed_gasmix
+ /// The current gas behaviors for this particular crystal
+ var/list/current_gas_behavior
///Refered to as EER on the monitor. This value effects gas output, damage, and power generation.
var/internal_energy = 0
@@ -109,7 +111,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
///The cutoff for a bolt jumping, grows with heat, lowers with higher mol count,
var/zap_cutoff = 1500
///How much the bullets damage should be multiplied by when it is added to the internal variables
- var/bullet_energy = 2
+ var/bullet_energy = SUPERMATTER_DEFAULT_BULLET_ENERGY
///How much hallucination should we produce per unit of power?
var/hallucination_power = 0.1
@@ -172,8 +174,14 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
/// Lazy list of the crazy engineers who managed to turn a cascading engine around.
var/list/datum/weakref/saviors = null
+ /// If a sliver of the supermatter has been removed. Almost certainly by a traitor. Lowers the delamination countdown time.
+ var/supermatter_sliver_removed = FALSE
+ /// Cooldown for sending emergency alerts to the common radio channel
+ COOLDOWN_DECLARE(common_radio_cooldown)
+
/obj/machinery/power/supermatter_crystal/Initialize(mapload)
. = ..()
+ current_gas_behavior = init_sm_gas()
gas_percentage = list()
absorbed_gasmix = new()
uid = gl_uid++
@@ -262,22 +270,25 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
// Some extra effects like [/datum/sm_gas/carbon_dioxide/extra_effects]
// needs more than one gas and rely on a fully parsed gas_percentage.
for (var/gas_path in absorbed_gasmix.gases)
- var/datum/sm_gas/sm_gas = GLOB.sm_gas_behavior[gas_path]
+ var/datum/sm_gas/sm_gas = current_gas_behavior[gas_path]
sm_gas?.extra_effects(src)
// PART 3: POWER PROCESSING
internal_energy_factors = calculate_internal_energy()
zap_factors = calculate_zap_multiplier()
- if(internal_energy && (last_power_zap + 4 SECONDS - (internal_energy * 0.001)) < world.time)
+ 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)
var/zap_color = color_matrix_rotate_hue(hue_angle_shift)
+ //Scale the strength of the zap with the world's time elapsed between zaps in seconds.
+ //Capped at 16 seconds to prevent a crazy burst of energy if atmos was halted for a long time.
+ var/delta_time = min((world.time - last_power_zap) * 0.1, 16)
supermatter_zap(
zapstart = src,
range = 3,
- zap_str = 5 * internal_energy * zap_multiplier,
+ zap_str = 1.25 * internal_energy * zap_multiplier * delta_time,
zap_flags = ZAP_SUPERMATTER_FLAGS,
- zap_cutoff = 300,
+ zap_cutoff = 300 * delta_time,
power_level = internal_energy,
color = zap_color,
)
@@ -322,7 +333,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
var/mob/living/savior = savior_ref.resolve()
if(!istype(savior)) // didn't live to tell the tale, sadly.
continue
- savior.client?.give_award(/datum/award/achievement/misc/theoretical_limits, savior)
+ savior.client?.give_award(/datum/award/achievement/jobs/theoretical_limits, savior)
LAZYNULL(saviors)
if(prob(15))
@@ -502,10 +513,23 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
radio.talk_into(
src,
count_down_messages[1],
- emergency_channel
+ emergency_channel,
+ list(SPAN_COMMAND)
)
- for(var/i in SUPERMATTER_COUNTDOWN_TIME to 0 step -10)
+ var/delamination_countdown_time = SUPERMATTER_COUNTDOWN_TIME
+ // If a sliver was removed from the supermatter, the countdown time is significantly decreased
+ if (supermatter_sliver_removed == TRUE)
+ delamination_countdown_time = SUPERMATTER_SLIVER_REMOVED_COUNTDOWN_TIME
+ radio.talk_into(
+ src,
+ "WARNING: Projected time until full crystal delamination significantly lower than expected. \
+ Please inspect crystal for structural abnormalities or sabotage!",
+ emergency_channel,
+ list(SPAN_COMMAND)
+ )
+
+ for(var/i in delamination_countdown_time to 0 step -10)
if(last_delamination_strategy != delamination_strategy)
count_down_messages = delamination_strategy.count_down_messages()
last_delamination_strategy = delamination_strategy
@@ -524,7 +548,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
else
message = "[i*0.1]..."
- radio.talk_into(src, message, emergency_channel)
+ radio.talk_into(src, message, emergency_channel, list(SPAN_COMMAND))
if(healed)
final_countdown = FALSE
@@ -580,7 +604,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
if(mole_count < MINIMUM_MOLE_COUNT) //save processing power from small amounts like these
continue
gas_percentage[gas_path] = mole_count / total_moles
- var/datum/sm_gas/sm_gas = GLOB.sm_gas_behavior[gas_path]
+ 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]
@@ -916,7 +940,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
multi = 8
if(zap_flags & ZAP_SUPERMATTER_FLAGS)
var/remaining_power = target.zap_act(zap_str * multi, zap_flags)
- zap_str = remaining_power * 0.5 //Coils should take a lot out of the power of the zap
+ zap_str = remaining_power / multi //Coils should take a lot out of the power of the zap
else
zap_str /= 3
@@ -951,6 +975,14 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
child_targets_hit = targets_hit.Copy() //Pass by ref begone
supermatter_zap(target, new_range, zap_str, zap_flags, child_targets_hit, zap_cutoff, power_level, zap_icon, color)
+// For /datum/sm_delam to check if it should be sending an alert on common radio channel
+/obj/machinery/power/supermatter_crystal/proc/should_alert_common()
+ if(!COOLDOWN_FINISHED(src, common_radio_cooldown))
+ return FALSE
+
+ COOLDOWN_START(src, common_radio_cooldown, SUPERMATTER_COMMON_RADIO_DELAY)
+ return TRUE
+
#undef BIKE
#undef COIL
#undef ROD
diff --git a/code/modules/power/supermatter/supermatter_delamination/_sm_delam.dm b/code/modules/power/supermatter/supermatter_delamination/_sm_delam.dm
index 5091b768bed..8edcc6710bf 100644
--- a/code/modules/power/supermatter/supermatter_delamination/_sm_delam.dm
+++ b/code/modules/power/supermatter/supermatter_delamination/_sm_delam.dm
@@ -47,17 +47,25 @@ GLOBAL_LIST_INIT(sm_delam_list, list(
return FALSE
sm.lastwarning = REALTIMEOFDAY
+ if(sm.damage_archived - sm.damage > SUPERMATTER_FAST_HEALING_RATE && sm.damage_archived >= sm.emergency_point) // Fast healing, engineers probably have it all sorted
+ if(sm.should_alert_common()) // We alert common once per cooldown period, otherwise alert engineering
+ sm.radio.talk_into(sm,"Crystalline hyperstructure returning to safe operating parameters. Integrity: [round(sm.get_integrity_percent(), 0.01)]%", sm.emergency_channel)
+ else
+ sm.radio.talk_into(sm,"Crystalline hyperstructure returning to safe operating parameters. Integrity: [round(sm.get_integrity_percent(), 0.01)]%", sm.warning_channel)
+ playsound(sm, 'sound/machines/terminal_alert.ogg', 75)
+ return FALSE
+
switch(sm.get_status())
if(SUPERMATTER_DELAMINATING)
// SKYRAT EDIT ADDITION
alert_sound_to_playing('modular_skyrat/master_files/sound/effects/reactor/meltdown.ogg', override_volume = TRUE)
- alert_sound_to_playing('modular_skyrat/modules/alerts/sound/alerts/alert1.ogg', override_volume = TRUE)
+ alert_sound_to_playing('sound/effects/alert.ogg', override_volume = TRUE)
// SKYRAT EDIT END
playsound(sm, 'sound/misc/bloblarm.ogg', 100, FALSE, 40, 30, falloff_distance = 10)
if(SUPERMATTER_EMERGENCY)
// SKYRAT EDIT ADDITION
alert_sound_to_playing('modular_skyrat/master_files/sound/effects/reactor/core_overheating.ogg', override_volume = TRUE)
- alert_sound_to_playing('modular_skyrat/modules/alerts/sound/alerts/alert1.ogg', override_volume = TRUE)
+ alert_sound_to_playing('sound/misc/notice1.ogg', override_volume = TRUE)
// SKYRAT EDIT END
playsound(sm, 'sound/machines/engine_alert1.ogg', 100, FALSE, 30, 30, falloff_distance = 10)
if(SUPERMATTER_DANGER)
@@ -65,13 +73,12 @@ GLOBAL_LIST_INIT(sm_delam_list, list(
if(SUPERMATTER_WARNING)
playsound(sm, 'sound/machines/terminal_alert.ogg', 75)
- if(sm.damage < sm.damage_archived) // Healing
- sm.radio.talk_into(sm,"Crystalline hyperstructure returning to safe operating parameters. Integrity: [round(sm.get_integrity_percent(), 0.01)]%", sm.damage_archived >= sm.emergency_point ? sm.emergency_channel : sm.warning_channel)
- return FALSE
-
- if(sm.damage >= sm.emergency_point) // Taking damage, in emergency
- sm.radio.talk_into(sm, "CRYSTAL DELAMINATION IMMINENT Integrity: [round(sm.get_integrity_percent(), 0.01)]%", sm.emergency_channel)
+ if(sm.damage >= sm.emergency_point) // In emergency
+ sm.radio.talk_into(sm, "CRYSTAL DELAMINATION IMMINENT! Integrity: [round(sm.get_integrity_percent(), 0.01)]%", sm.emergency_channel)
sm.lastwarning = REALTIMEOFDAY - (SUPERMATTER_WARNING_DELAY / 2) // Cut the time to next announcement in half.
+ else if(sm.damage_archived > sm.damage) // Healing, in warning
+ sm.radio.talk_into(sm,"Crystalline hyperstructure returning to safe operating parameters. Integrity: [round(sm.get_integrity_percent(), 0.01)]%", sm.warning_channel)
+ return FALSE
else // Taking damage, in warning
sm.radio.talk_into(sm, "Danger! Crystal hyperstructure integrity faltering! Integrity: [round(sm.get_integrity_percent(), 0.01)]%", sm.warning_channel)
diff --git a/code/modules/power/supermatter/supermatter_delamination/cascade_delam.dm b/code/modules/power/supermatter/supermatter_delamination/cascade_delam.dm
index 106bc727bbd..5d8cfecaa40 100644
--- a/code/modules/power/supermatter/supermatter_delamination/cascade_delam.dm
+++ b/code/modules/power/supermatter/supermatter_delamination/cascade_delam.dm
@@ -90,7 +90,7 @@
return FALSE
priority_announce("Attention: Long range anomaly scans indicate abnormal quantities of harmonic flux originating from \
a subject within [station_name()], a resonance collapse may occur.",
- "Nanotrasen Star Observation Association")
+ "Nanotrasen Star Observation Association", 'sound/misc/airraid.ogg')
return TRUE
/// Signal calls cant sleep, we gotta do this.
diff --git a/code/modules/power/supermatter/supermatter_delamination/delamination_effects.dm b/code/modules/power/supermatter/supermatter_delamination/delamination_effects.dm
index 49415d65dec..21b91725d36 100644
--- a/code/modules/power/supermatter/supermatter_delamination/delamination_effects.dm
+++ b/code/modules/power/supermatter/supermatter_delamination/delamination_effects.dm
@@ -132,7 +132,7 @@
// say goodbye to that shuttle of yours
if(SSshuttle.emergency.mode != SHUTTLE_ESCAPE)
priority_announce("Fatal error occurred in emergency shuttle uplink during transit. Unable to reestablish connection.",
- "Emergency Shuttle Uplink Alert", 'sound/misc/announce_dig.ogg')
+ "Emergency Shuttle Uplink Alert", ANNOUNCER_SHUTTLE) // SKYRAT EDIT CHANGE - Announcer Sounds
else
// except if you are on it already, then you are safe c:
minor_announce("ERROR: Corruption detected in navigation protocols. Connection with Transponder #XCC-P5831-ES13 lost. \
diff --git a/code/modules/power/supermatter/supermatter_hit_procs.dm b/code/modules/power/supermatter/supermatter_hit_procs.dm
index 5c68669e6e2..452b37e0541 100644
--- a/code/modules/power/supermatter/supermatter_hit_procs.dm
+++ b/code/modules/power/supermatter/supermatter_hit_procs.dm
@@ -67,6 +67,7 @@
if (scalpel.usesLeft)
to_chat(user, span_danger("You extract a sliver from \the [src]. \The [src] begins to react violently!"))
new /obj/item/nuke_core/supermatter_sliver(src.drop_location())
+ supermatter_sliver_removed = TRUE
external_power_trickle += 800
log_activation(who = user, how = scalpel)
scalpel.usesLeft--
diff --git a/code/modules/power/turbine/turbine.dm b/code/modules/power/turbine/turbine.dm
index fedfd42014e..bb4afcede94 100644
--- a/code/modules/power/turbine/turbine.dm
+++ b/code/modules/power/turbine/turbine.dm
@@ -69,14 +69,14 @@
* Handles all the calculations needed for the gases, work done, temperature increase/decrease
*/
/obj/machinery/power/turbine/proc/transfer_gases(datum/gas_mixture/input_mix, datum/gas_mixture/output_mix, work_amount_to_remove, intake_size = 1)
- //pump gases. if no gases were transfered then no work was done
+ //pump gases. if no gases were transferred then no work was done
var/output_pressure = PRESSURE_MAX(output_mix.return_pressure())
- var/datum/gas_mixture/transfered_gases = input_mix.pump_gas_to(output_mix, input_mix.return_pressure() * intake_size)
- if(!transfered_gases)
+ var/datum/gas_mixture/transferred_gases = input_mix.pump_gas_to(output_mix, input_mix.return_pressure() * intake_size)
+ if(!transferred_gases)
return 0
//compute work done
- var/work_done = QUANTIZE(transfered_gases.total_moles()) * R_IDEAL_GAS_EQUATION * transfered_gases.temperature * log((transfered_gases.volume * PRESSURE_MAX(transfered_gases.return_pressure())) / (output_mix.volume * output_pressure)) * TURBINE_WORK_CONVERSION_MULTIPLIER
+ var/work_done = QUANTIZE(transferred_gases.total_moles()) * R_IDEAL_GAS_EQUATION * transferred_gases.temperature * log((transferred_gases.volume * PRESSURE_MAX(transferred_gases.return_pressure())) / (output_mix.volume * output_pressure)) * TURBINE_WORK_CONVERSION_MULTIPLIER
if(work_amount_to_remove)
work_done = work_done - work_amount_to_remove
diff --git a/code/modules/procedural_mapping/mapGenerators/repair.dm b/code/modules/procedural_mapping/mapGenerators/repair.dm
index c9df8496389..505dc36f02c 100644
--- a/code/modules/procedural_mapping/mapGenerators/repair.dm
+++ b/code/modules/procedural_mapping/mapGenerators/repair.dm
@@ -28,7 +28,18 @@
var/z_offset = SSmapping.station_start
var/list/bounds
for (var/path in SSmapping.config.GetFullMapPaths())
- var/datum/parsed_map/parsed = load_map(file(path), 1, 1, z_offset, measureOnly = FALSE, no_changeturf = FALSE, cropMap=TRUE, x_lower = mother1.x_low, y_lower = mother1.y_low, x_upper = mother1.x_high, y_upper = mother1.y_high)
+ var/datum/parsed_map/parsed = load_map(
+ file(path),
+ 1,
+ 1,
+ z_offset,
+ no_changeturf = FALSE,
+ crop_map = TRUE,
+ x_lower = mother1.x_low,
+ y_lower = mother1.y_low,
+ x_upper = mother1.x_high,
+ y_upper = mother1.y_high,
+ )
bounds = parsed?.bounds
z_offset += bounds[MAP_MAXZ] - bounds[MAP_MINZ] + 1
diff --git a/code/modules/projectiles/ammunition/_ammunition.dm b/code/modules/projectiles/ammunition/_ammunition.dm
index 9641adc29b5..e492afb776b 100644
--- a/code/modules/projectiles/ammunition/_ammunition.dm
+++ b/code/modules/projectiles/ammunition/_ammunition.dm
@@ -30,8 +30,6 @@
var/click_cooldown_override = 0
///the visual effect appearing when the ammo is fired.
var/firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect
- ///Does this leave a casing behind?
- var/is_cased_ammo = TRUE
///pacifism check for boolet, set to FALSE if bullet is non-lethal
var/harmful = TRUE
@@ -148,8 +146,6 @@
return ..()
/obj/item/ammo_casing/proc/bounce_away(still_warm = FALSE, bounce_delay = 3)
- if(!is_cased_ammo)
- return
update_appearance()
SpinAnimation(10, 1)
var/turf/T = get_turf(src)
diff --git a/code/modules/projectiles/ammunition/_firing.dm b/code/modules/projectiles/ammunition/_firing.dm
index b890222a86c..dee2c087c68 100644
--- a/code/modules/projectiles/ammunition/_firing.dm
+++ b/code/modules/projectiles/ammunition/_firing.dm
@@ -64,7 +64,7 @@
loaded_projectile.ignore_source_check = TRUE
if(reagents && loaded_projectile.reagents)
- reagents.trans_to(loaded_projectile, reagents.total_volume, transfered_by = user) //For chemical darts/bullets
+ reagents.trans_to(loaded_projectile, reagents.total_volume, transferred_by = user) //For chemical darts/bullets
qdel(reagents)
/obj/item/ammo_casing/proc/throw_proj(atom/target, turf/targloc, mob/living/user, params, spread, atom/fired_from)
diff --git a/code/modules/projectiles/ammunition/ballistic/shotgun.dm b/code/modules/projectiles/ammunition/ballistic/shotgun.dm
index e1f233d51f8..53ff1f8a350 100644
--- a/code/modules/projectiles/ammunition/ballistic/shotgun.dm
+++ b/code/modules/projectiles/ammunition/ballistic/shotgun.dm
@@ -106,12 +106,12 @@
/obj/item/ammo_casing/shotgun/improvised
name = "improvised shell"
- desc = "An extremely weak shotgun shell with multiple small pellets made out of metal shards."
+ desc = "A homemade shotgun casing filled with crushed glass, used to commmit vandalism and property damage."
icon_state = "improvshell"
projectile_type = /obj/projectile/bullet/pellet/shotgun_improvised
- custom_materials = list(/datum/material/iron=SMALL_MATERIAL_AMOUNT*2.5)
- pellets = 10
- variance = 25
+ custom_materials = list(/datum/material/iron=SMALL_MATERIAL_AMOUNT*2, /datum/material/glass=SMALL_MATERIAL_AMOUNT*1)
+ pellets = 6
+ variance = 30
/obj/item/ammo_casing/shotgun/ion
name = "ion shell"
diff --git a/code/modules/projectiles/ammunition/energy/_energy.dm b/code/modules/projectiles/ammunition/energy/_energy.dm
index 788c0f7810d..808cbdfbfe7 100644
--- a/code/modules/projectiles/ammunition/energy/_energy.dm
+++ b/code/modules/projectiles/ammunition/energy/_energy.dm
@@ -8,8 +8,4 @@
var/select_name = CALIBER_ENERGY
fire_sound = 'sound/weapons/laser.ogg'
firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/energy
- is_cased_ammo = FALSE
-
- //SKYRAT EDIT ADD - CELL LOADED GUNS
- var/select_color = FALSE //This is the color that shows up when selecting an ammo type. Disabled by default
- //SKYRAT EDIT ADD END
+ var/select_color = FALSE //SKYRAT EDIT ADDITION - This is the color that shows up when selecting an ammo type. Disabled by default
diff --git a/code/modules/projectiles/ammunition/energy/special.dm b/code/modules/projectiles/ammunition/energy/special.dm
index bedfab7b235..24fba4b9ba4 100644
--- a/code/modules/projectiles/ammunition/energy/special.dm
+++ b/code/modules/projectiles/ammunition/energy/special.dm
@@ -74,3 +74,9 @@
select_name = "marksman nanoshot"
e_cost = 0
fire_sound = 'sound/weapons/gun/revolver/shot_alt.ogg'
+
+/obj/item/ammo_casing/energy/fisher
+ projectile_type = /obj/projectile/energy/fisher
+ select_name = "light-buster"
+ e_cost = 250
+ fire_sound = 'sound/weapons/gun/general/heavy_shot_suppressed.ogg' // fwip fwip fwip fwip
diff --git a/code/modules/projectiles/ammunition/special/magic.dm b/code/modules/projectiles/ammunition/special/magic.dm
index c6737fd3cab..9135e3ec5b9 100644
--- a/code/modules/projectiles/ammunition/special/magic.dm
+++ b/code/modules/projectiles/ammunition/special/magic.dm
@@ -4,7 +4,6 @@
slot_flags = null
projectile_type = /obj/projectile/magic
firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/magic
- is_cased_ammo = FALSE
/obj/item/ammo_casing/magic/change
projectile_type = /obj/projectile/magic/change
diff --git a/code/modules/projectiles/ammunition/special/syringe.dm b/code/modules/projectiles/ammunition/special/syringe.dm
index 59f5f3b3177..c06069c4d10 100644
--- a/code/modules/projectiles/ammunition/special/syringe.dm
+++ b/code/modules/projectiles/ammunition/special/syringe.dm
@@ -15,7 +15,7 @@
var/obj/item/reagent_containers/syringe/S = SG.syringes[1]
- S.reagents.trans_to(loaded_projectile, S.reagents.total_volume, transfered_by = user)
+ S.reagents.trans_to(loaded_projectile, S.reagents.total_volume, transferred_by = user)
loaded_projectile.name = S.name
var/obj/projectile/bullet/dart/D = loaded_projectile
D.inject_flags = S.inject_flags
@@ -25,7 +25,7 @@
var/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/syringe_gun = loc
var/obj/item/reagent_containers/syringe/loaded_syringe = syringe_gun.syringes[1]
var/obj/projectile/bullet/dart/shot_dart = loaded_projectile
- syringe_gun.reagents.trans_to(shot_dart, min(loaded_syringe.volume, syringe_gun.reagents.total_volume), transfered_by = user)
+ syringe_gun.reagents.trans_to(shot_dart, min(loaded_syringe.volume, syringe_gun.reagents.total_volume), transferred_by = user)
shot_dart.name = loaded_syringe.name
shot_dart.inject_flags = loaded_syringe.inject_flags
LAZYREMOVE(syringe_gun.syringes, loaded_syringe)
@@ -45,7 +45,7 @@
var/obj/item/gun/chem/CG = loc
if(CG.syringes_left <= 0)
return
- CG.reagents.trans_to(loaded_projectile, 15, transfered_by = user)
+ CG.reagents.trans_to(loaded_projectile, 15, transferred_by = user)
loaded_projectile.name = "piercing chemical dart"
CG.syringes_left--
return ..()
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 96900458922..e76af741a18 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -26,6 +26,7 @@
var/vary_fire_sound = TRUE
var/fire_sound_volume = 50
var/dry_fire_sound = 'sound/weapons/gun/general/dry_fire.ogg'
+ var/dry_fire_sound_volume = 30
var/suppressed = null //whether or not a message is displayed when fired
var/can_suppress = FALSE
var/suppressed_sound = 'sound/weapons/gun/general/heavy_shot_suppressed.ogg'
@@ -44,7 +45,7 @@
var/weapon_weight = WEAPON_LIGHT
var/dual_wield_spread = 24 //additional spread when dual wielding
///Can we hold up our target with this? Default to yes
- var/can_hold_up = TRUE
+ var/can_hold_up = FALSE // SKYRAT EDIT - DISABLED ORIGINAL: TRUE
/// Just 'slightly' snowflakey way to modify projectile damage for projectiles fired from this gun.
var/projectile_damage_multiplier = 1
@@ -169,7 +170,7 @@
/obj/item/gun/proc/shoot_with_empty_chamber(mob/living/user as mob|obj)
balloon_alert_to_viewers("*click*")
- playsound(src, dry_fire_sound, 30, TRUE)
+ playsound(src, dry_fire_sound, dry_fire_sound_volume, TRUE)
/obj/item/gun/proc/fire_sounds()
if(suppressed)
diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm
index 61dcb1748e4..576ba6395be 100644
--- a/code/modules/projectiles/guns/ballistic.dm
+++ b/code/modules/projectiles/guns/ballistic.dm
@@ -441,9 +441,6 @@
if (sawn_off)
bonus_spread += SAWN_OFF_ACC_PENALTY
- if(magazine && !chambered.is_cased_ammo)
- magazine.stored_ammo -= chambered
-
return ..()
/obj/item/gun/ballistic/shoot_live_shot(mob/living/user, pointblank = 0, atom/pbtarget = null, message = 1)
diff --git a/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm b/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm
index d9443719a7e..5d33b3fce51 100644
--- a/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm
+++ b/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm
@@ -11,7 +11,6 @@
throwforce = 1
firing_effect_type = null
caliber = CALIBER_ARROW
- is_cased_ammo = FALSE
///Whether the bullet type spawns another casing of the same type or not.
var/reusable = TRUE
diff --git a/code/modules/projectiles/guns/ballistic/launchers.dm b/code/modules/projectiles/guns/ballistic/launchers.dm
index 82282d2efe6..0b676ae3dfa 100644
--- a/code/modules/projectiles/guns/ballistic/launchers.dm
+++ b/code/modules/projectiles/guns/ballistic/launchers.dm
@@ -88,13 +88,13 @@
user.visible_message(span_warning("[user] aims [src] at the ground! It looks like [user.p_theyre()] performing a sick rocket jump!"), \
span_userdanger("You aim [src] at the ground to perform a bisnasty rocket jump..."))
if(can_shoot())
- user.notransform = TRUE
+ ADD_TRAIT(user, TRAIT_NO_TRANSFORM, REF(src))
playsound(src, 'sound/vehicles/rocketlaunch.ogg', 80, TRUE, 5)
animate(user, pixel_z = 300, time = 30, easing = LINEAR_EASING)
sleep(7 SECONDS)
animate(user, pixel_z = 0, time = 5, easing = LINEAR_EASING)
sleep(0.5 SECONDS)
- user.notransform = FALSE
+ REMOVE_TRAIT(user, TRAIT_NO_TRANSFORM, REF(src))
process_fire(user, user, TRUE)
if(!QDELETED(user)) //if they weren't gibbed by the explosion, take care of them for good.
user.gib()
diff --git a/code/modules/projectiles/guns/energy/beam_rifle.dm b/code/modules/projectiles/guns/energy/beam_rifle.dm
index 68479abbf47..8869da14a59 100644
--- a/code/modules/projectiles/guns/energy/beam_rifle.dm
+++ b/code/modules/projectiles/guns/energy/beam_rifle.dm
@@ -30,7 +30,6 @@
ammo_type = list(/obj/item/ammo_casing/energy/beam_rifle/hitscan)
actions_types = list(/datum/action/item_action/zoom_lock_action)
cell_type = /obj/item/stock_parts/cell/beam_rifle
- canMouseDown = TRUE
var/aiming = FALSE
var/aiming_time = 12
var/aiming_time_fire_threshold = 5
@@ -72,8 +71,6 @@
var/current_zoom_x = 0
var/current_zoom_y = 0
- var/mob/listeningTo
-
/obj/item/gun/energy/beam_rifle/apply_fantasy_bonuses(bonus)
. = ..()
delay = modify_fantasy_variable("delay", delay, -bonus * 2)
@@ -179,7 +176,6 @@
STOP_PROCESSING(SSfastprocess, src)
set_user(null)
QDEL_LIST(current_tracers)
- listeningTo = null
return ..()
/obj/item/gun/energy/beam_rifle/emp_act(severity)
@@ -232,30 +228,28 @@
if(!istype(current_user) || !isturf(current_user.loc) || !(src in current_user.held_items) || current_user.incapacitated()) //Doesn't work if you're not holding it!
if(automatic_cleanup)
stop_aiming()
- set_user(null)
return FALSE
return TRUE
-/obj/item/gun/energy/beam_rifle/proc/process_aim()
- if(istype(current_user) && current_user.client && current_user.client.mouseParams)
- var/angle = mouse_angle_from_client(current_user.client)
- current_user.setDir(angle2dir_cardinal(angle))
- var/difference = abs(closer_angle_difference(lastangle, angle))
- delay_penalty(difference * aiming_time_increase_angle_multiplier)
- lastangle = angle
+/obj/item/gun/energy/beam_rifle/proc/process_aim(params)
+ var/angle = mouse_angle_from_client(current_user?.client, params)
+ current_user.setDir(angle2dir_cardinal(angle))
+ var/difference = abs(closer_angle_difference(lastangle, angle))
+ delay_penalty(difference * aiming_time_increase_angle_multiplier)
+ lastangle = angle
/obj/item/gun/energy/beam_rifle/proc/on_mob_move()
SIGNAL_HANDLER
check_user()
if(aiming)
delay_penalty(aiming_time_increase_user_movement)
- process_aim()
+ process_aim(current_user?.client?.mouseParams)
INVOKE_ASYNC(src, PROC_REF(aiming_beam), TRUE)
-/obj/item/gun/energy/beam_rifle/proc/start_aiming()
+/obj/item/gun/energy/beam_rifle/proc/start_aiming(params)
aiming_time_left = aiming_time
aiming = TRUE
- process_aim()
+ process_aim(params)
aiming_beam(TRUE)
zooming_angle = lastangle
start_zooming()
@@ -271,47 +265,65 @@
if(user == current_user)
return
stop_aiming(current_user)
- if(listeningTo)
- UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
- listeningTo = null
if(istype(current_user))
+ unregister_client_signals(current_user)
+ UnregisterSignal(current_user, list(COMSIG_MOVABLE_MOVED, COMSIG_MOB_LOGIN, COMSIG_MOB_LOGOUT))
current_user = null
- if(istype(user))
- current_user = user
- RegisterSignal(user, COMSIG_MOVABLE_MOVED, PROC_REF(on_mob_move))
- listeningTo = user
+ if(!istype(user))
+ return
+ current_user = user
+ RegisterSignal(user, COMSIG_MOVABLE_MOVED, PROC_REF(on_mob_move))
+ RegisterSignal(user, COMSIG_MOB_LOGIN, PROC_REF(register_client_signals))
+ RegisterSignal(user, COMSIG_MOB_LOGOUT, PROC_REF(unregister_client_signals))
+ if(user.client)
+ register_client_signals(user)
-/obj/item/gun/energy/beam_rifle/onMouseDrag(src_object, over_object, src_location, over_location, params, mob)
+/obj/item/gun/energy/beam_rifle/proc/register_client_signals(mob/source)
+ SIGNAL_HANDLER
+ RegisterSignal(source.client, COMSIG_CLIENT_MOUSEDOWN, PROC_REF(on_mouse_down))
+
+/obj/item/gun/energy/beam_rifle/proc/unregister_client_signals(mob/source)
+ SIGNAL_HANDLER
+ stop_aiming()
+ if(QDELETED(source.client))
+ return
+ UnregisterSignal(source.client, list(COMSIG_CLIENT_MOUSEDOWN, COMSIG_CLIENT_MOUSEUP, COMSIG_CLIENT_MOUSEDRAG))
+
+///change the aiming beam angle to that of the mouse cursor.
+/obj/item/gun/energy/beam_rifle/proc/on_mouse_drag(client/source, src_object, over_object, src_location, over_location, src_control, over_control, params)
+ SIGNAL_HANDLER
if(aiming)
- process_aim()
- aiming_beam()
+ process_aim(params)
+ INVOKE_ASYNC(src, PROC_REF(aiming_beam))
if(zoom_lock == ZOOM_LOCK_AUTOZOOM_FREEMOVE)
zooming_angle = lastangle
set_autozoom_pixel_offsets_immediate(zooming_angle)
- return ..()
-/obj/item/gun/energy/beam_rifle/onMouseDown(object, location, params, mob/mob)
- if(istype(mob))
- set_user(mob)
- if(istype(object, /atom/movable/screen) && !istype(object, /atom/movable/screen/click_catcher))
+///Start aiming and charging the beam
+/obj/item/gun/energy/beam_rifle/proc/on_mouse_down(client/source, atom/movable/object, location, control, params)
+ SIGNAL_HANDLER
+ if(source.mob.get_active_held_item() != src)
return
- if((object in mob.contents) || (object == mob))
+ if(!object.IsAutoclickable() || (object in source.mob.contents) || (object == source.mob))
return
- start_aiming()
- return ..()
+ INVOKE_ASYNC(src, PROC_REF(start_aiming), params)
+ RegisterSignal(source, COMSIG_CLIENT_MOUSEDRAG, PROC_REF(on_mouse_drag))
+ RegisterSignal(source, COMSIG_CLIENT_MOUSEUP, PROC_REF(on_mouse_up))
-/obj/item/gun/energy/beam_rifle/onMouseUp(object, location, params, mob/M)
- if(istype(object, /atom/movable/screen) && !istype(object, /atom/movable/screen/click_catcher))
+///Stop aiming and fire the beam if charged enough
+/obj/item/gun/energy/beam_rifle/proc/on_mouse_up(client/source, atom/movable/object, location, control, params)
+ SIGNAL_HANDLER
+ if(!object.IsAutoclickable())
return
- process_aim()
+ process_aim(params)
+ UnregisterSignal(source, list(COMSIG_CLIENT_MOUSEDRAG, COMSIG_CLIENT_MOUSEUP))
if(aiming_time_left <= aiming_time_fire_threshold && check_user())
sync_ammo()
- var/atom/target = M.client.mouse_object_ref?.resolve()
+ var/atom/target = source.mouse_object_ref?.resolve()
if(target)
- afterattack(target, M, FALSE, M.client.mouseParams, passthrough = TRUE)
+ INVOKE_ASYNC(src, PROC_REF(afterattack), target, source.mob, FALSE, source.mouseParams, passthrough = TRUE)
stop_aiming()
QDEL_LIST(current_tracers)
- return ..()
/obj/item/gun/energy/beam_rifle/afterattack(atom/target, mob/living/user, flag, params, passthrough = FALSE)
. |= AFTERATTACK_PROCESSED_ITEM
diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
index 3286675dfd0..71342c77956 100644
--- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
+++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
@@ -263,10 +263,10 @@
/obj/item/borg/upgrade/modkit/proc/install(obj/item/gun/energy/recharge/kinetic_accelerator/KA, mob/user, transfer_to_loc = TRUE)
. = TRUE
if(minebot_upgrade)
- if(minebot_exclusive && !istype(KA.loc, /mob/living/simple_animal/hostile/mining_drone))
+ if(minebot_exclusive && !istype(KA.loc, /mob/living/basic/mining_drone))
to_chat(user, span_notice("The modkit you're trying to install is only rated for minebot use."))
return FALSE
- else if(istype(KA.loc, /mob/living/simple_animal/hostile/mining_drone))
+ else if(istype(KA.loc, /mob/living/basic/mining_drone))
to_chat(user, span_notice("The modkit you're trying to install is not rated for minebot use."))
return FALSE
if(denied_type)
diff --git a/code/modules/projectiles/guns/energy/recharge.dm b/code/modules/projectiles/guns/energy/recharge.dm
index 6644accd8a5..eed27478755 100644
--- a/code/modules/projectiles/guns/energy/recharge.dm
+++ b/code/modules/projectiles/guns/energy/recharge.dm
@@ -135,3 +135,36 @@
custom_materials = list(/datum/material/iron=SHEET_MATERIAL_AMOUNT*2)
suppressed = null
ammo_type = list(/obj/item/ammo_casing/energy/bolt/large)
+
+/// A silly gun that does literally zero damage, but disrupts electrical sources of light, like flashlights.
+/obj/item/gun/energy/recharge/fisher
+ name = "\improper SC/FISHER disruptor"
+ desc = "A self-recharging, permanently suppressed, and very haphazardly modified accelerator handgun that does literally nothing to anything except light fixtures and cameras. \
+ Can fire twice before requiring a recharge, with bolts passing through machinery, but demands precision."
+ icon_state = "fisher"
+ base_icon_state = "fisher"
+ dry_fire_sound_volume = 10
+ w_class = WEIGHT_CLASS_SMALL
+ holds_charge = TRUE
+ suppressed = TRUE
+ recharge_time = 1.2 SECONDS
+ ammo_type = list(/obj/item/ammo_casing/energy/fisher)
+
+/obj/item/gun/energy/recharge/fisher/examine_more(mob/user)
+ . = ..()
+ . += span_notice("The SC/FISHER is an illegally-modified kinetic accelerator cut down and refit into a disassembled miniature energy gun chassis, with its pressure chamber \
+ attenuated to launch kinetic bolts that disrupt flashlights and cameras, if only temporarily. This effect also works on cyborg headlamps, and works longer in melee.
\
+ While some would argue that this is a really terrible design choice, others argue that it is very funny to be able to shoot at light sources. Caveat emptor.")
+
+/obj/item/gun/energy/recharge/fisher/afterattack(atom/target, mob/living/user, flag, params)
+ // you should just shoot them, but in case you can't/wont
+ . = ..()
+ if(user.Adjacent(target))
+ var/obj/projectile/energy/fisher/melee/simulated_hit = new
+ simulated_hit.on_hit(target)
+
+/obj/item/gun/energy/recharge/fisher/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
+ // ...you reeeeeally just shoot them, but in case you can't/won't
+ . = ..()
+ var/obj/projectile/energy/fisher/melee/simulated_hit = new
+ simulated_hit.on_hit(hit_atom)
diff --git a/code/modules/projectiles/guns/magic/staff.dm b/code/modules/projectiles/guns/magic/staff.dm
index b0c98406b1d..6b28fd32ff8 100644
--- a/code/modules/projectiles/guns/magic/staff.dm
+++ b/code/modules/projectiles/guns/magic/staff.dm
@@ -128,9 +128,10 @@
recharge_rate = 2
no_den_usage = 1
school = SCHOOL_FORBIDDEN //this staff is evil. okay? it just is. look at this projectile type list. this is wrong.
- /// Static list of all projectiles we can fire from our staff.
+
+ /// List of all projectiles we can fire from our staff.
/// Doesn't contain all subtypes of magic projectiles, unlike what it looks like
- var/static/list/allowed_projectile_types = list(
+ var/list/allowed_projectile_types = list(
/obj/projectile/magic/animate,
/obj/projectile/magic/antimagic,
/obj/projectile/magic/arcane_barrage,
@@ -170,6 +171,47 @@
process_fire(user, user, FALSE)
return FALSE
+/**
+ * Staff of chaos given to the wizard upon completing a cheesy grand ritual. Is completely evil and if something
+ * breaks, it's completely intended. Fuck off.
+ * Also can be used by everyone, because why not.
+ */
+/obj/item/gun/magic/staff/chaos/true_wabbajack
+ name = "\proper Wabbajack"
+ desc = "If there is some deity out there, they've definitely skipped their psych appointment before creating this."
+ icon_state = "the_wabbajack"
+ inhand_icon_state = "the_wabbajack"
+ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF //fuck you
+ max_charges = 999999 //fuck you
+ recharge_rate = 1
+ allow_intruder_use = TRUE
+
+/obj/item/gun/magic/staff/chaos/true_wabbajack/Initialize(mapload)
+ . = ..()
+ allowed_projectile_types |= subtypesof(/obj/projectile/bullet/cannonball)
+ allowed_projectile_types |= subtypesof(/obj/projectile/bullet/rocket)
+ allowed_projectile_types |= subtypesof(/obj/projectile/energy/tesla)
+ allowed_projectile_types |= subtypesof(/obj/projectile/magic)
+ allowed_projectile_types |= subtypesof(/obj/projectile/temp)
+ allowed_projectile_types |= list(
+ /obj/projectile/beam/mindflayer,
+ /obj/projectile/bullet/gyro,
+ /obj/projectile/bullet/honker,
+ /obj/projectile/bullet/mime,
+ /obj/projectile/curse_hand,
+ /obj/projectile/energy/declone,
+ /obj/projectile/energy/electrode,
+ /obj/projectile/energy/net,
+ /obj/projectile/energy/nuclear_particle,
+ /obj/projectile/gravityattract,
+ /obj/projectile/gravitychaos,
+ /obj/projectile/gravityrepulse,
+ /obj/projectile/ion,
+ /obj/projectile/meteor,
+ /obj/projectile/neurotoxin,
+ /obj/projectile/plasma,
+ ) //if you ever try to expand this list, avoid adding bullets/energy projectiles, this ain't supposed to be a gun... unless it's funny
+
/obj/item/gun/magic/staff/door
name = "staff of door creation"
desc = "An artefact that spits bolts of transformative magic that can create doors in walls."
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index 60bec6ac3b0..2f5fa84c441 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -231,12 +231,12 @@
SEND_SIGNAL(src, COMSIG_PROJECTILE_RANGE_OUT)
qdel(src)
-//to get the correct limb (if any) for the projectile hit message
-/mob/living/proc/check_limb_hit(hit_zone)
+/// Returns the string form of the def_zone we have hit.
+/mob/living/proc/check_hit_limb_zone_name(hit_zone)
if(has_limbs)
return hit_zone
-/mob/living/carbon/check_limb_hit(hit_zone)
+/mob/living/carbon/check_hit_limb_zone_name(hit_zone)
if(get_bodypart(hit_zone))
return hit_zone
else //when a limb is missing the damage is actually passed to the chest
@@ -250,21 +250,20 @@
* blocked - percentage of hit blocked
* pierce_hit - are we piercing through or regular hitting
*/
-/* SKYRAT EDIT REMOVAL - MOVED TO MASTER_FILES PROJECTILE.DM
/obj/projectile/proc/on_hit(atom/target, blocked = FALSE, pierce_hit)
// i know that this is probably more with wands and gun mods in mind, but it's a bit silly that the projectile on_hit signal doesn't ping the projectile itself.
// maybe we care what the projectile thinks! See about combining these via args some time when it's not 5AM
- var/obj/item/bodypart/hit_limb
+ var/hit_limb_zone
if(isliving(target))
var/mob/living/L = target
- hit_limb = L.check_limb_hit(def_zone)
+ hit_limb_zone = L.check_hit_limb_zone_name(def_zone)
if(fired_from)
- SEND_SIGNAL(fired_from, COMSIG_PROJECTILE_ON_HIT, firer, target, Angle, hit_limb)
- SEND_SIGNAL(src, COMSIG_PROJECTILE_SELF_ON_HIT, firer, target, Angle, hit_limb)
+ SEND_SIGNAL(fired_from, COMSIG_PROJECTILE_ON_HIT, firer, target, Angle, hit_limb_zone)
+ SEND_SIGNAL(src, COMSIG_PROJECTILE_SELF_ON_HIT, firer, target, Angle, hit_limb_zone)
if(QDELETED(src)) // in case one of the above signals deleted the projectile for whatever reason
return
- var/turf/target_loca = get_turf(target)
+ var/turf/target_turf = get_turf(target)
var/hitx
var/hity
@@ -275,66 +274,89 @@
hitx = target.pixel_x + rand(-8, 8)
hity = target.pixel_y + rand(-8, 8)
- if(damage > 0 && (damage_type == BRUTE || damage_type == BURN) && iswallturf(target_loca) && prob(75))
- var/turf/closed/wall/W = target_loca
- if(impact_effect_type && !hitscan)
- new impact_effect_type(target_loca, hitx, hity)
+ // SKYRAT EDIT ADDITION BEGIN - IMPACT SOUNDS
+ var/impact_sound
+ if(hitsound)
+ impact_sound = hitsound
+ else
+ impact_sound = target.impact_sound
+ get_sfx()
+ playsound(src, get_sfx_skyrat(impact_sound), vol_by_damage(), TRUE, -1)
+ // SKYRAT EDIT ADDITION END
- W.add_dent(WALL_DENT_SHOT, hitx, hity)
+ if(damage > 0 && (damage_type == BRUTE || damage_type == BURN) && iswallturf(target_turf) && prob(75))
+ var/turf/closed/wall/target_wall = target_turf
+ if(impact_effect_type && !hitscan)
+ new impact_effect_type(target_wall, hitx, hity)
+
+ target_wall.add_dent(WALL_DENT_SHOT, hitx, hity)
return BULLET_ACT_HIT
if(!isliving(target))
if(impact_effect_type && !hitscan)
- new impact_effect_type(target_loca, hitx, hity)
+ new impact_effect_type(target_turf, hitx, hity)
+ /* SKYRAT EDIT REMOVAL - IMPACT SOUNDS
if(isturf(target) && hitsound_wall)
var/volume = clamp(vol_by_damage() + 20, 0, 100)
if(suppressed)
volume = 5
playsound(loc, hitsound_wall, volume, TRUE, -1)
+ SKYRAT EDIT REMOVAL END */
return BULLET_ACT_HIT
- var/mob/living/L = target
+ var/mob/living/living_target = target
if(blocked != 100) // not completely blocked
- if(damage && L.blood_volume && damage_type == BRUTE)
- var/splatter_dir = dir
- if(starting)
- splatter_dir = get_dir(starting, target_loca)
- if(isalien(L))
- new /obj/effect/temp_visual/dir_setting/bloodsplatter/xenosplatter(target_loca, splatter_dir)
- else
- new /obj/effect/temp_visual/dir_setting/bloodsplatter(target_loca, splatter_dir)
- if(prob(33))
- L.add_splatter_floor(target_loca)
+ var/obj/item/bodypart/hit_bodypart = living_target.get_bodypart(hit_limb_zone)
+ if (damage)
+ if (living_target.blood_volume && damage_type == BRUTE && (isnull(hit_bodypart) || hit_bodypart.can_bleed()))
+ var/splatter_dir = dir
+ if(starting)
+ splatter_dir = get_dir(starting, target_turf)
+ if(isalien(living_target))
+ new /obj/effect/temp_visual/dir_setting/bloodsplatter/xenosplatter(target_turf, splatter_dir)
+ else
+ new /obj/effect/temp_visual/dir_setting/bloodsplatter(target_turf, splatter_dir)
+ if(prob(33))
+ living_target.add_splatter_floor(target_turf)
+ else if (!isnull(hit_bodypart) && (hit_bodypart.biological_state & (BIO_METAL|BIO_WIRED)))
+ var/random_damage_mult = RANDOM_DECIMAL(0.85, 1.15) // SOMETIMES you can get more or less sparks
+ var/damage_dealt = ((damage / (1 - (blocked / 100))) * random_damage_mult)
+
+ var/spark_amount = round((damage_dealt / PROJECTILE_DAMAGE_PER_ROBOTIC_SPARK))
+ if (spark_amount > 0)
+ do_sparks(spark_amount, FALSE, living_target)
+
else if(impact_effect_type && !hitscan)
- new impact_effect_type(target_loca, hitx, hity)
+ new impact_effect_type(target_turf, hitx, hity)
var/organ_hit_text = ""
- var/limb_hit = hit_limb
- if(limb_hit)
- organ_hit_text = " in \the [parse_zone(limb_hit)]"
+ if(hit_limb_zone)
+ organ_hit_text = " in \the [parse_zone(hit_limb_zone)]"
if(suppressed == SUPPRESSED_VERY)
- playsound(loc, hitsound, 5, TRUE, -1)
+ //playsound(loc, hitsound, 5, TRUE, -1) SKYRAT EDIT REMOVAL - IMPACT SOUNDS
else if(suppressed)
- playsound(loc, hitsound, 5, TRUE, -1)
- to_chat(L, span_userdanger("You're shot by \a [src][organ_hit_text]!"))
+ //playsound(loc, hitsound, 5, TRUE, -1) SKYRAT EDIT REMOVAL - IMPACT SOUNDS
+ to_chat(living_target, span_userdanger("You're shot by \a [src][organ_hit_text]!"))
else
+ /* SKYRAT EDIT REMOVAL - IMPACT SOUNDS
if(hitsound)
var/volume = vol_by_damage()
playsound(src, hitsound, volume, TRUE, -1)
- L.visible_message(span_danger("[L] is hit by \a [src][organ_hit_text]!"), \
+ SKYRAT EDIT REMOVAL END */
+ living_target.visible_message(span_danger("[living_target] is hit by \a [src][organ_hit_text]!"), \
span_userdanger("You're hit by \a [src][organ_hit_text]!"), null, COMBAT_MESSAGE_RANGE)
- if(L.is_blind())
- to_chat(L, span_userdanger("You feel something hit you[organ_hit_text]!"))
- L.on_hit(src)
+ if(living_target.is_blind())
+ to_chat(living_target, span_userdanger("You feel something hit you[organ_hit_text]!"))
+ living_target.on_hit(src)
var/reagent_note
if(reagents?.reagent_list)
reagent_note = "REAGENTS: [pretty_string_from_reagent_list(reagents.reagent_list)]"
if(ismob(firer))
- log_combat(firer, L, "shot", src, reagent_note)
+ log_combat(firer, living_target, "shot", src, reagent_note)
return BULLET_ACT_HIT
if(isvehicle(firer))
@@ -344,12 +366,12 @@
if(!LAZYLEN(logging_mobs))
logging_mobs = firing_vehicle.return_drivers()
for(var/mob/logged_mob as anything in logging_mobs)
- log_combat(logged_mob, L, "shot", src, "from inside [firing_vehicle][logging_mobs.len > 1 ? " with multiple occupants" : null][reagent_note ? " and contained [reagent_note]" : null]")
+ log_combat(logged_mob, living_target, "shot", src, "from inside [firing_vehicle][logging_mobs.len > 1 ? " with multiple occupants" : null][reagent_note ? " and contained [reagent_note]" : null]")
return BULLET_ACT_HIT
- L.log_message("has been shot by [firer] with [src][reagent_note ? " containing [reagent_note]" : null]", LOG_VICTIM, color="orange")
+ living_target.log_message("has been shot by [firer] with [src][reagent_note ? " containing [reagent_note]" : null]", LOG_ATTACK, color="orange")
return BULLET_ACT_HIT
-*/
+
/obj/projectile/proc/vol_by_damage()
if(src.damage)
return clamp((src.damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then CLAMP the value between 30 and 100
diff --git a/code/modules/projectiles/projectile/bullets/shotgun.dm b/code/modules/projectiles/projectile/bullets/shotgun.dm
index 446654a3489..639939e150f 100644
--- a/code/modules/projectiles/projectile/bullets/shotgun.dm
+++ b/code/modules/projectiles/projectile/bullets/shotgun.dm
@@ -118,14 +118,13 @@
embedding = null
/obj/projectile/bullet/pellet/shotgun_improvised
- tile_dropoff = 0.35 //Come on it does 6 damage don't be like that.
- damage = 6
- wound_bonus = 0
- bare_wound_bonus = 7.5
+ damage = 5
+ wound_bonus = -5
+ demolition_mod = 3 //Very good at acts of vandalism
/obj/projectile/bullet/pellet/shotgun_improvised/Initialize(mapload)
. = ..()
- range = rand(1, 8)
+ range = rand(3, 8)
/obj/projectile/bullet/pellet/shotgun_improvised/on_range()
do_sparks(1, TRUE, src)
diff --git a/code/modules/projectiles/projectile/special/curse.dm b/code/modules/projectiles/projectile/special/curse.dm
index 3eaf6e8c7e3..624af8867eb 100644
--- a/code/modules/projectiles/projectile/special/curse.dm
+++ b/code/modules/projectiles/projectile/special/curse.dm
@@ -1,7 +1,5 @@
/obj/effect/ebeam/curse_arm
name = "curse arm"
- layer = LARGE_MOB_LAYER
- plane = GAME_PLANE_UPPER_FOV_HIDDEN
/obj/projectile/curse_hand
name = "curse hand"
diff --git a/code/modules/projectiles/projectile/special/lightbreaker.dm b/code/modules/projectiles/projectile/special/lightbreaker.dm
new file mode 100644
index 00000000000..fd7d3d89e7a
--- /dev/null
+++ b/code/modules/projectiles/projectile/special/lightbreaker.dm
@@ -0,0 +1,35 @@
+/obj/projectile/energy/fisher
+ name = "attenuated kinetic force"
+ alpha = 0
+ damage = 0
+ damage_type = BRUTE
+ armor_flag = BOMB
+ range = 14
+ projectile_phasing = PASSTABLE | PASSMOB | PASSMACHINE | PASSSTRUCTURE
+ hitscan = TRUE
+ var/disrupt_duration = 10 SECONDS
+
+/obj/projectile/energy/fisher/on_hit(atom/target, blocked, pierce_hit)
+ . = ..()
+ var/lights_flickered = 0
+ if(SEND_SIGNAL(target, COMSIG_HIT_BY_SABOTEUR, disrupt_duration) & COMSIG_SABOTEUR_SUCCESS)
+ lights_flickered++
+ if(!isliving(target))
+ return
+ var/list/things_to_disrupt = list()
+ if(ishuman(target))
+ var/mob/living/carbon/human/human_target = target
+ things_to_disrupt = human_target.get_all_gear()
+ else
+ var/mob/living/living_target = target // i guess this covers borgs too?
+ things_to_disrupt = living_target.get_equipped_items(include_pockets = TRUE, include_accessories = TRUE)
+ for(var/obj/item/thingy as anything in things_to_disrupt)
+ if(SEND_SIGNAL(thingy, COMSIG_HIT_BY_SABOTEUR, disrupt_duration) & COMSIG_SABOTEUR_SUCCESS)
+ lights_flickered++
+ if(lights_flickered)
+ to_chat(target, span_warning("Your light [lights_flickered > 1 ? "sources flick" : "source flicks"] off."))
+
+/obj/projectile/energy/fisher/melee
+ range = 1
+ suppressed = SUPPRESSED_VERY
+ disrupt_duration = 20 SECONDS
diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm
index f9b5a2b18de..902ccf35e6a 100644
--- a/code/modules/reagents/chemistry/holder.dm
+++ b/code/modules/reagents/chemistry/holder.dm
@@ -82,10 +82,10 @@
if(reagent_to_react_count[reagent_id] < reagent_to_react_count[preferred_id])
preferred_id = reagent_id
continue
-
- if(!reaction_lookup[preferred_id])
- reaction_lookup[preferred_id] = list()
- reaction_lookup[preferred_id] += reaction
+ if (preferred_id != null)
+ if(!reaction_lookup[preferred_id])
+ reaction_lookup[preferred_id] = list()
+ reaction_lookup[preferred_id] += reaction
for(var/datum/chemical_reaction/reaction as anything in reactions)
var/list/product_ids = list()
@@ -421,6 +421,28 @@
SEND_SIGNAL(src, COMSIG_REAGENTS_DEL_REAGENT, reagent)
return TRUE
+/// Turn one reagent into another, preserving volume, temp, purity, ph
+/datum/reagents/proc/convert_reagent(source_reagent_typepath, target_reagent_typepath, multiplier = 1, include_source_subtypes = FALSE)
+ var/reagent_amount
+ var/reagent_purity
+ var/reagent_ph
+ if(include_source_subtypes)
+ reagent_ph = ph
+ var/weighted_purity
+ for(var/datum/reagent/reagent as anything in reagent_list)
+ if(reagent.type in typecacheof(source_reagent_typepath))
+ weighted_purity += reagent.volume * reagent.purity
+ reagent_amount += reagent.volume
+ remove_reagent(reagent.type, reagent.volume)
+ reagent_purity = weighted_purity / reagent_amount
+ else
+ var/datum/reagent/source_reagent = get_reagent(source_reagent_typepath)
+ reagent_amount = source_reagent.volume
+ reagent_purity = source_reagent.purity
+ reagent_ph = source_reagent.ph
+ remove_reagent(source_reagent_typepath, reagent_amount)
+ add_reagent(target_reagent_typepath, reagent_amount * multiplier, reagtemp = chem_temp, added_purity = reagent_purity, added_ph = reagent_ph)
+
//Converts the creation_purity to purity
/datum/reagents/proc/uncache_creation_purity(id)
var/datum/reagent/R = has_reagent(id)
@@ -497,14 +519,14 @@
* * multiplier - multiplies amount of each reagent by this number
* * preserve_data - if preserve_data=0, the reagents data will be lost. Usefull if you use data for some strange stuff and don't want it to be transferred.
* * no_react - passed through to [/datum/reagents/proc/add_reagent]
- * * mob/transfered_by - used for logging
+ * * mob/transferred_by - used for logging
* * remove_blacklisted - skips transferring of reagents without REAGENT_CAN_BE_SYNTHESIZED in chemical_flags
* * methods - passed through to [/datum/reagents/proc/expose_single] and [/datum/reagent/proc/on_transfer]
* * show_message - passed through to [/datum/reagents/proc/expose_single]
* * round_robin - if round_robin=TRUE, so transfer 5 from 15 water, 15 sugar and 15 plasma becomes 10, 15, 15 instead of 13.3333, 13.3333 13.3333. Good if you hate floating point errors
* * ignore_stomach - when using methods INGEST will not use the stomach as the target
*/
-/datum/reagents/proc/trans_to(obj/target, amount = 1, multiplier = 1, preserve_data = TRUE, no_react = FALSE, mob/transfered_by, remove_blacklisted = FALSE, methods = NONE, show_message = TRUE, round_robin = FALSE, ignore_stomach = FALSE)
+/datum/reagents/proc/trans_to(obj/target, amount = 1, multiplier = 1, preserve_data = TRUE, no_react = FALSE, mob/transferred_by, remove_blacklisted = FALSE, methods = NONE, show_message = TRUE, round_robin = FALSE, ignore_stomach = FALSE)
var/list/cached_reagents = reagent_list
if(!target || !total_volume)
return
@@ -551,7 +573,7 @@
trans_data = copy_data(reagent)
if(reagent.intercept_reagents_transfer(R, cached_amount))//Use input amount instead.
continue
- if(!R.add_reagent(reagent.type, transfer_amount * multiplier, trans_data, chem_temp, reagent.purity, reagent.ph, no_react = TRUE, ignore_splitting = reagent.chemical_flags & REAGENT_DONOTSPLIT)) //we only handle reaction after every reagent has been transfered.
+ if(!R.add_reagent(reagent.type, transfer_amount * multiplier, trans_data, chem_temp, reagent.purity, reagent.ph, no_react = TRUE, ignore_splitting = reagent.chemical_flags & REAGENT_DONOTSPLIT)) //we only handle reaction after every reagent has been transferred.
continue
if(methods)
r_to_send += reagent
@@ -585,7 +607,7 @@
transfer_amount = reagent.volume
if(reagent.intercept_reagents_transfer(R, cached_amount))//Use input amount instead.
continue
- if(!R.add_reagent(reagent.type, transfer_amount * multiplier, trans_data, chem_temp, reagent.purity, reagent.ph, no_react = TRUE, ignore_splitting = reagent.chemical_flags & REAGENT_DONOTSPLIT)) //we only handle reaction after every reagent has been transfered.
+ if(!R.add_reagent(reagent.type, transfer_amount * multiplier, trans_data, chem_temp, reagent.purity, reagent.ph, no_react = TRUE, ignore_splitting = reagent.chemical_flags & REAGENT_DONOTSPLIT)) //we only handle reaction after every reagent has been transferred.
continue
to_transfer = max(to_transfer - transfer_amount , 0)
if(methods)
@@ -598,9 +620,9 @@
var/list/reagent_qualities = list(REAGENT_TRANSFER_AMOUNT = transfer_amount, REAGENT_PURITY = reagent.purity)
transfer_log[reagent.type] = reagent_qualities
- if(transfered_by && target_atom)
- target_atom.add_hiddenprint(transfered_by) //log prints so admins can figure out who touched it last.
- log_combat(transfered_by, target_atom, "transferred reagents ([get_external_reagent_log_string(transfer_log)]) from [my_atom] to")
+ if(transferred_by && target_atom)
+ target_atom.add_hiddenprint(transferred_by) //log prints so admins can figure out who touched it last.
+ log_combat(transferred_by, target_atom, "transferred reagents ([get_external_reagent_log_string(transfer_log)]) from [my_atom] to")
update_total()
R.update_total()
@@ -937,7 +959,7 @@
return FALSE //Yup, no reactions here. No siree.
if(is_reacting)//Prevent wasteful calculations
- if(!(datum_flags & DF_ISPROCESSING))//If we're reacting - but not processing (i.e. we've transfered)
+ if(!(datum_flags & DF_ISPROCESSING))//If we're reacting - but not processing (i.e. we've transferred)
START_PROCESSING(SSreagents, src)
if(!(has_changed_state()))
return FALSE
@@ -1141,7 +1163,7 @@
* Force stops the current holder/reagents datum from reacting
*
* Calls end_reaction() for each equlilbrium datum in reaction_list and finish_reacting()
-* Usually only called when a datum is transfered into a NO_REACT container
+* Usually only called when a datum is transferred into a NO_REACT container
*/
/datum/reagents/proc/force_stop_reacting()
var/list/mix_message = list()
@@ -1176,7 +1198,7 @@
* Transfers the reaction_list to a new reagents datum
*
* Arguments:
-* * target - the datum/reagents that this src is being transfered into
+* * target - the datum/reagents that this src is being transferred into
*/
/datum/reagents/proc/transfer_reactions(datum/reagents/target)
if(QDELETED(target))
@@ -1369,17 +1391,16 @@
/// Is this holder full or not
/datum/reagents/proc/holder_full()
- if(total_volume >= maximum_volume)
- return TRUE
- return FALSE
+ return total_volume >= maximum_volume
/// Get the amount of this reagent
-/datum/reagents/proc/get_reagent_amount(reagent)
+/datum/reagents/proc/get_reagent_amount(reagent, include_subtypes = FALSE)
var/list/cached_reagents = reagent_list
+ var/total_amount = 0
for(var/datum/reagent/cached_reagent as anything in cached_reagents)
- if(cached_reagent.type == reagent)
- return round(cached_reagent.volume, CHEMICAL_QUANTISATION_LEVEL)
- return 0
+ if((!include_subtypes && cached_reagent.type == reagent) || (include_subtypes && ispath(cached_reagent.type, reagent)))
+ total_amount += round(cached_reagent.volume, CHEMICAL_QUANTISATION_LEVEL)
+ return total_amount
/datum/reagents/proc/get_multiple_reagent_amounts(list/reagents)
var/list/cached_reagents = reagent_list
@@ -1397,6 +1418,36 @@
return round(cached_reagent.purity, 0.01)
return 0
+/// Directly set the purity of all contained reagents to a new value
+/datum/reagents/proc/set_all_reagents_purity(new_purity = 0)
+ var/list/cached_reagents = reagent_list
+ for(var/datum/reagent/cached_reagent as anything in cached_reagents)
+ cached_reagent.purity = max(0, new_purity)
+
+/// Get the average purity of all reagents (or all subtypes of provided typepath)
+/datum/reagents/proc/get_average_purity(parent_type = null)
+ var/total_amount
+ var/weighted_purity
+ var/list/cached_reagents = reagent_list
+ for(var/datum/reagent/reagent as anything in cached_reagents)
+ if(!isnull(parent_type) && !istype(reagent, parent_type))
+ continue
+ total_amount += reagent.volume
+ weighted_purity += reagent.volume * reagent.purity
+ return weighted_purity / total_amount
+
+/// Get the average nutriment_factor of all consumable reagents
+/datum/reagents/proc/get_average_nutriment_factor()
+ var/consumable_volume
+ var/weighted_nutriment_factor
+ var/list/cached_reagents = reagent_list
+ for(var/datum/reagent/reagent as anything in cached_reagents)
+ if(istype(reagent, /datum/reagent/consumable))
+ var/datum/reagent/consumable/consumable_reagent = reagent
+ consumable_volume += consumable_reagent.volume
+ weighted_nutriment_factor += consumable_reagent.volume * consumable_reagent.nutriment_factor
+ return weighted_nutriment_factor / consumable_volume
+
/// Get a comma separated string of every reagent name in this holder. UNUSED
/datum/reagents/proc/get_reagent_names()
var/list/names = list()
diff --git a/code/modules/reagents/chemistry/items.dm b/code/modules/reagents/chemistry/items.dm
index b2e29e3c5d6..37d089aab42 100644
--- a/code/modules/reagents/chemistry/items.dm
+++ b/code/modules/reagents/chemistry/items.dm
@@ -180,7 +180,7 @@
to_chat(user, span_warning("[src] is full."))
return
- var/trans = container.reagents.trans_to(src, container.amount_per_transfer_from_this, transfered_by = user)
+ var/trans = container.reagents.trans_to(src, container.amount_per_transfer_from_this, transferred_by = user)
to_chat(user, span_notice("You fill [src] with [trans] unit\s of the contents of [container]."))
if(I.heat < 1000)
return
diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
index 516951e0e04..a3ed883551f 100644
--- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
@@ -111,6 +111,8 @@
/datum/reagent/medicine/morphine
)
//SKYRAT EDIT ADDITION END
+ /// Starting purity of the created reagents
+ var/base_reagent_purity = 1
var/list/recording_recipe
@@ -319,7 +321,7 @@
if(!cell?.use(to_dispense / powerefficiency))
say("Not enough energy to complete operation!")
return
- holder.add_reagent(reagent, to_dispense, reagtemp = dispensed_temperature)
+ holder.add_reagent(reagent, to_dispense, reagtemp = dispensed_temperature, added_purity = base_reagent_purity)
work_animation()
else
@@ -359,7 +361,7 @@
if(!cell?.use(to_dispense / powerefficiency))
say("Not enough energy to complete operation!")
return
- holder.add_reagent(reagent, to_dispense, reagtemp = dispensed_temperature)
+ holder.add_reagent(reagent, to_dispense, reagtemp = dispensed_temperature, added_purity = base_reagent_purity)
work_animation()
else
recording_recipe[key] += dispense_amount
@@ -457,7 +459,7 @@
if(beaker?.reagents)
R += beaker.reagents
for(var/i in 1 to total)
- Q.add_reagent(pick(dispensable_reagents), 10, reagtemp = dispensed_temperature)
+ Q.add_reagent(pick(dispensable_reagents), 10, reagtemp = dispensed_temperature, added_purity = base_reagent_purity)
R += Q
chem_splash(get_turf(src), null, 3, R)
if(beaker?.reagents)
@@ -607,6 +609,7 @@
/datum/reagent/toxin/mindbreaker,
/datum/reagent/toxin/staminatoxin
)
+ base_reagent_purity = 0.5
/obj/machinery/chem_dispenser/drinks/Initialize(mapload)
. = ..()
diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm
index 2c4cff9c376..0a49fd1beb1 100644
--- a/code/modules/reagents/chemistry/machinery/chem_master.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_master.dm
@@ -29,8 +29,8 @@ GLOBAL_LIST_INIT(chem_master_containers, list(
/obj/item/reagent_containers/condiment/coldsauce,
/obj/item/reagent_containers/condiment/mayonnaise,
/obj/item/reagent_containers/condiment/ketchup,
- /obj/item/reagent_containers/condiment/quality_oil,
- /obj/item/reagent_containers/condiment/cooking_oil,
+ /obj/item/reagent_containers/condiment/olive_oil,
+ /obj/item/reagent_containers/condiment/vegetable_oil,
/obj/item/reagent_containers/condiment/peanut_butter,
/obj/item/reagent_containers/condiment/cherryjelly,
/obj/item/reagent_containers/condiment/honey,
@@ -422,7 +422,7 @@ GLOBAL_LIST_INIT(chem_master_containers, list(
adjust_item_drop_location(item)
item.name = item_name
item.reagents.clear_reagents()
- reagents.trans_to(item, volume_in_each, transfered_by = src)
+ reagents.trans_to(item, volume_in_each, transferred_by = src)
printing_progress++
item_count--
update_appearance(UPDATE_ICON)
diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
index 15929e190cc..26ebfa1d18d 100644
--- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
+++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
@@ -99,11 +99,9 @@
. = ..()
if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN)
return
- if(!can_interact(user) || !user.can_perform_action(src, ALLOW_SILICON_REACH|FORBID_TELEKINESIS_REACH))
+ if(operating || !user.can_perform_action(src, ALLOW_SILICON_REACH | FORBID_TELEKINESIS_REACH))
return
- if(operating)
- return
- replace_beaker(user)
+ eject(user)
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
/obj/machinery/reagentgrinder/attack_robot_secondary(mob/user, list/modifiers)
@@ -146,24 +144,28 @@
default_unfasten_wrench(user, tool)
return TOOL_ACT_TOOLTYPE_SUCCESS
-/obj/machinery/reagentgrinder/attackby(obj/item/I, mob/living/user, params)
- //You can only screw open empty grinder
- if(!beaker && !length(holdingitems) && default_deconstruction_screwdriver(user, icon_state, icon_state, I))
- return
+/obj/machinery/reagentgrinder/screwdriver_act(mob/living/user, obj/item/tool)
+ . = TOOL_ACT_TOOLTYPE_SUCCESS
+ if(!beaker && !length(holdingitems))
+ return default_deconstruction_screwdriver(user, icon_state, icon_state, tool)
- if(default_deconstruction_crowbar(I))
- return
+/obj/machinery/reagentgrinder/crowbar_act(mob/living/user, obj/item/tool)
+ return default_deconstruction_crowbar(tool)
+/obj/machinery/reagentgrinder/attackby(obj/item/weapon, mob/living/user, params)
if(panel_open) //Can't insert objects when its screwed open
return TRUE
- if (is_reagent_container(I) && !(I.item_flags & ABSTRACT) && I.is_open_container())
- var/obj/item/reagent_containers/B = I
+ if(!weapon.grind_requirements(src)) //Error messages should be in the objects' definitions
+ return
+
+ if (is_reagent_container(weapon) && !(weapon.item_flags & ABSTRACT) && weapon.is_open_container())
+ var/obj/item/reagent_containers/container = weapon
. = TRUE //no afterattack
- if(!user.transferItemToLoc(B, src))
+ if(!user.transferItemToLoc(container, src))
return
- replace_beaker(user, B)
- to_chat(user, span_notice("You add [B] to [src]."))
+ replace_beaker(user, container)
+ to_chat(user, span_notice("You add [container] to [src]."))
update_appearance()
return TRUE //no afterattack
@@ -172,39 +174,36 @@
return TRUE
//Fill machine with a bag!
- if(istype(I, /obj/item/storage/bag))
- if(!I.contents.len)
- to_chat(user, span_notice("[I] is empty!"))
+ if(istype(weapon, /obj/item/storage/bag))
+ if(!weapon.contents.len)
+ to_chat(user, span_notice("[weapon] is empty!"))
return TRUE
var/list/inserted = list()
- if(I.atom_storage.remove_type(/obj/item/food/grown, src, limit - length(holdingitems), TRUE, FALSE, user, inserted))
+ if(weapon.atom_storage.remove_type(/obj/item/food/grown, src, limit - length(holdingitems), TRUE, FALSE, user, inserted))
for(var/i in inserted)
holdingitems[i] = TRUE
inserted = list()
- if(I.atom_storage.remove_type(/obj/item/food/honeycomb, src, limit - length(holdingitems), TRUE, FALSE, user, inserted))
+ if(weapon.atom_storage.remove_type(/obj/item/food/honeycomb, src, limit - length(holdingitems), TRUE, FALSE, user, inserted))
for(var/i in inserted)
holdingitems[i] = TRUE
- if(!I.contents.len)
- to_chat(user, span_notice("You empty [I] into [src]."))
+ if(!weapon.contents.len)
+ to_chat(user, span_notice("You empty [weapon] into [src]."))
else
to_chat(user, span_notice("You fill [src] to the brim."))
return TRUE
- if(!I.grind_results && !I.juice_results)
+ if(!weapon.grind_results && !weapon.juice_typepath)
if(user.combat_mode)
return ..()
else
- to_chat(user, span_warning("You cannot grind [I] into reagents!"))
+ to_chat(user, span_warning("You cannot grind/juice [weapon] into reagents!"))
return TRUE
- if(!I.grind_requirements(src)) //Error messages should be in the objects' definitions
- return
-
- if(user.transferItemToLoc(I, src))
- to_chat(user, span_notice("You add [I] to [src]."))
- holdingitems[I] = TRUE
+ if(user.transferItemToLoc(weapon, src))
+ to_chat(user, span_notice("You add [weapon] to [src]."))
+ holdingitems[weapon] = TRUE
return FALSE
/obj/machinery/reagentgrinder/ui_interact(mob/user) // The microwave Menu //I am reasonably certain that this is not a microwave
@@ -261,9 +260,9 @@
if(beaker)
replace_beaker(user)
-/obj/machinery/reagentgrinder/proc/remove_object(obj/item/O)
- holdingitems -= O
- qdel(O)
+/obj/machinery/reagentgrinder/proc/remove_object(obj/item/weapon)
+ holdingitems -= weapon
+ qdel(weapon)
/obj/machinery/reagentgrinder/proc/start_shaking()
var/static/list/transforms
@@ -304,45 +303,44 @@
/obj/machinery/reagentgrinder/proc/stop_operating()
operating = FALSE
-/obj/machinery/reagentgrinder/proc/juice()
+/obj/machinery/reagentgrinder/proc/juice(mob/user)
power_change()
- if(!beaker || machine_stat & (NOPOWER|BROKEN) || beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
+ if(!beaker || machine_stat & (NOPOWER|BROKEN) || beaker.reagents.holder_full())
return
operate_for(50, juicing = TRUE)
for(var/obj/item/i in holdingitems)
- if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
+ if(beaker.reagents.holder_full())
break
var/obj/item/I = i
- if(I.juice_results)
- juice_item(I)
+ if(I.juice_typepath)
+ juice_item(I, user)
-/obj/machinery/reagentgrinder/proc/juice_item(obj/item/I) //Juicing results can be found in respective object definitions
- if(I.on_juice(src) == -1)
+/obj/machinery/reagentgrinder/proc/juice_item(obj/item/I, mob/user) //Juicing results can be found in respective object definitions
+ if(!I.juice(beaker.reagents, user))
to_chat(usr, span_danger("[src] shorts out as it tries to juice up [I], and transfers it back to storage."))
return
- beaker.reagents.add_reagent_list(I.juice_results)
remove_object(I)
/obj/machinery/reagentgrinder/proc/grind(mob/user)
power_change()
- if(!beaker || machine_stat & (NOPOWER|BROKEN) || beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
+ if(!beaker || machine_stat & (NOPOWER|BROKEN) || beaker.reagents.holder_full())
return
operate_for(60)
warn_of_dust() // don't breathe this.
for(var/i in holdingitems)
- if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
+ if(beaker.reagents.holder_full())
break
var/obj/item/I = i
if(I.grind_results)
grind_item(i, user)
/obj/machinery/reagentgrinder/proc/grind_item(obj/item/I, mob/user) //Grind results can be found in respective object definitions
- if(I.on_grind(src) == -1) //Call on_grind() to change amount as needed, and stop grinding the item if it returns -1
- to_chat(usr, span_danger("[src] shorts out as it tries to grind up [I], and transfers it back to storage."))
+ if(!I.grind(beaker.reagents, user))
+ if(isstack(I))
+ to_chat(usr, span_notice("[src] attempts to grind as many pieces of [I] as possible."))
+ else
+ to_chat(usr, span_danger("[src] shorts out as it tries to grind up [I], and transfers it back to storage."))
return
- beaker.reagents.add_reagent_list(I.grind_results)
- if(I.reagents)
- I.reagents.trans_to(beaker, I.reagents.total_volume, transfered_by = user)
remove_object(I)
/obj/machinery/reagentgrinder/proc/mix(mob/user)
@@ -351,22 +349,21 @@
if(!beaker || machine_stat & (NOPOWER|BROKEN))
return
operate_for(50, juicing = TRUE)
- addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/reagentgrinder, mix_complete)), 50)
+ addtimer(CALLBACK(src, PROC_REF(mix_complete)), 50 / speed)
/obj/machinery/reagentgrinder/proc/mix_complete()
- if(beaker?.reagents.total_volume)
- //Recipe to make Butter
- var/butter_amt = FLOOR(beaker.reagents.get_reagent_amount(/datum/reagent/consumable/milk) / MILK_TO_BUTTER_COEFF, 1)
- beaker.reagents.remove_reagent(/datum/reagent/consumable/milk, MILK_TO_BUTTER_COEFF * butter_amt)
- for(var/i in 1 to butter_amt)
- new /obj/item/food/butter(drop_location())
- //Recipe to make Mayonnaise
- if (beaker.reagents.has_reagent(/datum/reagent/consumable/eggyolk))
- var/amount = beaker.reagents.get_reagent_amount(/datum/reagent/consumable/eggyolk)
- beaker.reagents.remove_reagent(/datum/reagent/consumable/eggyolk, amount)
- beaker.reagents.add_reagent(/datum/reagent/consumable/mayonnaise, amount)
- //Recipe to make whipped cream
- if (beaker.reagents.has_reagent(/datum/reagent/consumable/cream))
- var/amount = beaker.reagents.get_reagent_amount(/datum/reagent/consumable/cream)
- beaker.reagents.remove_reagent(/datum/reagent/consumable/cream, amount)
- beaker.reagents.add_reagent(/datum/reagent/consumable/whipped_cream, amount)
+ if(beaker?.reagents.total_volume <= 0)
+ return
+ //Recipe to make Butter
+ var/butter_amt = FLOOR(beaker.reagents.get_reagent_amount(/datum/reagent/consumable/milk) / MILK_TO_BUTTER_COEFF, 1)
+ var/purity = beaker.reagents.get_reagent_purity(/datum/reagent/consumable/milk)
+ beaker.reagents.remove_reagent(/datum/reagent/consumable/milk, MILK_TO_BUTTER_COEFF * butter_amt)
+ for(var/i in 1 to butter_amt)
+ var/obj/item/food/butter/tasty_butter = new(drop_location())
+ tasty_butter.reagents.set_all_reagents_purity(purity)
+ //Recipe to make Mayonnaise
+ if (beaker.reagents.has_reagent(/datum/reagent/consumable/eggyolk))
+ beaker.reagents.convert_reagent(/datum/reagent/consumable/eggyolk, /datum/reagent/consumable/mayonnaise)
+ //Recipe to make whipped cream
+ if (beaker.reagents.has_reagent(/datum/reagent/consumable/cream))
+ beaker.reagents.convert_reagent(/datum/reagent/consumable/cream, /datum/reagent/consumable/whipped_cream)
diff --git a/code/modules/reagents/chemistry/machinery/smoke_machine.dm b/code/modules/reagents/chemistry/machinery/smoke_machine.dm
index 0271c17d18b..3a8754bfe4f 100644
--- a/code/modules/reagents/chemistry/machinery/smoke_machine.dm
+++ b/code/modules/reagents/chemistry/machinery/smoke_machine.dm
@@ -103,7 +103,7 @@
add_fingerprint(user)
if(is_reagent_container(I) && I.is_open_container())
var/obj/item/reagent_containers/RC = I
- var/units = RC.reagents.trans_to(src, RC.amount_per_transfer_from_this, transfered_by = user)
+ var/units = RC.reagents.trans_to(src, RC.amount_per_transfer_from_this, transferred_by = user)
if(units)
to_chat(user, span_notice("You transfer [units] units of the solution to [src]."))
return
diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm
index 44cf8b995da..8de1d98cc2e 100644
--- a/code/modules/reagents/chemistry/reagents.dm
+++ b/code/modules/reagents/chemistry/reagents.dm
@@ -162,14 +162,18 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
return
holder.remove_reagent(type, metabolization_rate * M.metabolism_efficiency * seconds_per_tick) //By default it slowly disappears.
+/// Called in burns.dm *if* the reagent has the REAGENT_AFFECTS_WOUNDS process flag
+/datum/reagent/proc/on_burn_wound_processing(datum/wound/burn/flesh/burn_wound)
+ return
+
/*
-Used to run functions before a reagent is transfered. Returning TRUE will block the transfer attempt.
+Used to run functions before a reagent is transferred. Returning TRUE will block the transfer attempt.
Primarily used in reagents/reaction_agents
*/
/datum/reagent/proc/intercept_reagents_transfer(datum/reagents/target)
return FALSE
-///Called after a reagent is transfered
+///Called after a reagent is transferred
/datum/reagent/proc/on_transfer(atom/A, methods=TOUCH, trans_volume)
return
diff --git a/code/modules/reagents/chemistry/reagents/atmos_gas_reagents.dm b/code/modules/reagents/chemistry/reagents/atmos_gas_reagents.dm
index 2299cab5493..817e5ed98bf 100644
--- a/code/modules/reagents/chemistry/reagents/atmos_gas_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/atmos_gas_reagents.dm
@@ -52,7 +52,8 @@
breather.adjustFireLoss(-2 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
breather.adjustToxLoss(-5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
breather.adjustBruteLoss(-2 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- return ..()
+ . = ..()
+ return TRUE
/datum/reagent/hypernoblium
name = "Hyper-Noblium"
@@ -90,7 +91,8 @@
/datum/reagent/nitrium_high_metabolization/on_mob_life(mob/living/carbon/breather, seconds_per_tick, times_fired)
breather.adjustStaminaLoss(-2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
breather.adjustToxLoss(0.1 * current_cycle * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) // 1 toxin damage per cycle at cycle 10
- return ..()
+ . = ..()
+ return TRUE
/datum/reagent/nitrium_low_metabolization
name = "Nitrium"
@@ -123,13 +125,15 @@
if(!HAS_TRAIT(breather, TRAIT_KNOCKEDOUT))
return ..()
+ . = ..()
for(var/obj/item/organ/organ_being_healed as anything in breather.organs)
if(!organ_being_healed.damage)
continue
organ_being_healed.apply_organ_damage(-0.5 * REM * seconds_per_tick, required_organ_flag = ORGAN_ORGANIC)
+ . = TRUE
- return ..()
+ return .
/datum/reagent/zauker
name = "Zauker"
@@ -147,4 +151,5 @@
breather.adjustOxyLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
breather.adjustFireLoss(2 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
breather.adjustToxLoss(2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- return ..()
+ ..()
+ return TRUE
diff --git a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm
index 8a6717ca52f..693404431fa 100644
--- a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm
@@ -46,12 +46,11 @@
if(good_kind_of_healing && !reaping && SPT_PROB(0.00005, seconds_per_tick)) //janken with the grim reaper!
notify_ghosts("[affected_mob] has entered a game of rock-paper-scissors with death!", source = affected_mob, action = NOTIFY_ORBIT, header = "Who Will Win?")
reaping = TRUE
- var/list/RockPaperScissors = list("rock" = "paper", "paper" = "scissors", "scissors" = "rock") //choice = loses to
if(affected_mob.apply_status_effect(/datum/status_effect/necropolis_curse, CURSE_BLINDING))
helbent = TRUE
to_chat(affected_mob, span_hierophant("Malevolent spirits appear before you, bartering your life in a 'friendly' game of rock, paper, scissors. Which do you choose?"))
var/timeisticking = world.time
- var/RPSchoice = tgui_alert(affected_mob, "Janken Time! You have 60 Seconds to Choose!", "Rock Paper Scissors", RockPaperScissors, 60)
+ var/RPSchoice = tgui_alert(affected_mob, "Janken Time! You have 60 Seconds to Choose!", "Rock Paper Scissors", list("rock" , "paper" , "scissors"), 60)
if(QDELETED(affected_mob) || (timeisticking+(1.1 MINUTES) < world.time))
reaping = FALSE
return //good job, you ruined it
@@ -59,21 +58,21 @@
to_chat(affected_mob, span_hierophant("You decide to not press your luck, but the spirits remain... hopefully they'll go away soon."))
reaping = FALSE
return
- var/grim = pick(RockPaperScissors)
- if(grim == RPSchoice) //You Tied!
- to_chat(affected_mob, span_hierophant("You tie, and the malevolent spirits disappear... for now."))
- reaping = FALSE
- else if(RockPaperScissors[RPSchoice] == grim) //You lost!
- to_chat(affected_mob, span_hierophant("You lose, and the malevolent spirits smirk eerily as they surround your body."))
- affected_mob.investigate_log("has lost rock paper scissors with the grim reaper and been dusted.", INVESTIGATE_DEATHS)
- affected_mob.dust()
- return
- else //VICTORY ROYALE
- to_chat(affected_mob, span_hierophant("You win, and the malevolent spirits fade away as well as your wounds."))
- affected_mob.client.give_award(/datum/award/achievement/misc/helbitaljanken, affected_mob)
- affected_mob.revive(HEAL_ALL)
- holder.del_reagent(type)
- return
+ switch(rand(1,3))
+ if(1) //You Tied!
+ to_chat(affected_mob, span_hierophant("You tie, and the malevolent spirits disappear... for now."))
+ reaping = FALSE
+ if(2) //You lost!
+ to_chat(affected_mob, span_hierophant("You lose, and the malevolent spirits smirk eerily as they surround your body."))
+ affected_mob.investigate_log("has lost rock paper scissors with the grim reaper and been dusted.", INVESTIGATE_DEATHS)
+ affected_mob.dust()
+ return
+ if(3) //VICTORY ROYALE
+ to_chat(affected_mob, span_hierophant("You win, and the malevolent spirits fade away as well as your wounds."))
+ affected_mob.client.give_award(/datum/award/achievement/jobs/helbitaljanken, affected_mob)
+ affected_mob.revive(HEAL_ALL)
+ holder.del_reagent(type)
+ return
..()
return
@@ -117,7 +116,7 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/c2/probital/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustBruteLoss(-2.25 * REM * normalise_creation_purity() * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
+ affected_mob.adjustBruteLoss(-2.25 * REM * normalise_creation_purity() * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
var/ooo_youaregettingsleepy = 3.5
switch(round(affected_mob.getStaminaLoss()))
if(10 to 40)
@@ -126,17 +125,17 @@
ooo_youaregettingsleepy = 2.5
if(61 to 200) //you really can only go to 120
ooo_youaregettingsleepy = 2
- affected_mob.adjustStaminaLoss(ooo_youaregettingsleepy * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
+ affected_mob.adjustStaminaLoss(ooo_youaregettingsleepy * REM * seconds_per_tick)
..()
. = TRUE
/datum/reagent/medicine/c2/probital/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustStaminaLoss(3 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
+ affected_mob.adjustStaminaLoss(3 * REM * seconds_per_tick, updating_stamina = FALSE)
if(affected_mob.getStaminaLoss() >= 80)
affected_mob.adjust_drowsiness(2 SECONDS * REM * seconds_per_tick)
if(affected_mob.getStaminaLoss() >= 100)
to_chat(affected_mob,span_warning("You feel more tired than you usually do, perhaps if you rest your eyes for a bit..."))
- affected_mob.adjustStaminaLoss(-100, TRUE, required_biotype = affected_biotype)
+ affected_mob.adjustStaminaLoss(-100, updating_stamina = TRUE) // Don't add the biotype parameter here as it results in infinite sleep and chat spam.
affected_mob.Sleeping(10 SECONDS)
..()
. = TRUE
@@ -554,6 +553,7 @@
H.set_heartattack(TRUE)
volume = 0
. = ..()
+ return TRUE
/datum/reagent/medicine/c2/penthrite/on_mob_end_metabolize(mob/living/user)
user.clear_alert("penthrite")
diff --git a/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm
index aacef0822e1..f67b813be0c 100644
--- a/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm
@@ -8,6 +8,7 @@
nutriment_factor = 0
taste_description = "alcohol"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
+ creation_purity = 1 // impure base reagents are a big no-no
ph = 7.33
burning_temperature = 2193//ethanol burns at 1970C (at it's peak)
burning_volume = 0.1
@@ -41,7 +42,7 @@
/datum/reagent/consumable/ethanol/New(list/data)
if(LAZYLEN(data))
- if(data["quality"])
+ if(!isnull(data["quality"]))
quality = data["quality"]
name = "Natural " + name
if(data["boozepwr"])
@@ -99,7 +100,7 @@
name = "Beer"
description = "An alcoholic beverage brewed since ancient times on Old Earth. Still popular today."
color = "#664300" // rgb: 102, 67, 0
- nutriment_factor = 1 * REAGENTS_METABOLISM
+ nutriment_factor = 1
boozepwr = 25
taste_description = "mild carbonated malt"
ph = 4
@@ -193,7 +194,7 @@
name = "Thirteen Loko"
description = "A potent mixture of caffeine and alcohol."
color = "#102000" // rgb: 16, 32, 0
- nutriment_factor = 1 * REAGENTS_METABOLISM
+ nutriment_factor = 1
boozepwr = 80
quality = DRINK_GOOD
overdose_threshold = 60
@@ -264,7 +265,7 @@
name = "Bilk"
description = "This appears to be beer mixed with milk. Disgusting."
color = "#895C4C" // rgb: 137, 92, 76
- nutriment_factor = 2 * REAGENTS_METABOLISM
+ nutriment_factor = 2
boozepwr = 15
taste_description = "desperation and lactate"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -1063,7 +1064,7 @@
name = "Mead"
description = "A Viking drink, though a cheap one."
color = "#e0c058" // rgb: 224,192,88
- nutriment_factor = 1 * REAGENTS_METABOLISM
+ nutriment_factor = 1
boozepwr = 30
quality = DRINK_NICE
taste_description = "sweet, sweet alcohol"
@@ -1195,7 +1196,7 @@
/datum/reagent/consumable/ethanol/driestmartini
name = "Driest Martini"
description = "Only for the experienced. You think you see sand floating in the glass."
- nutriment_factor = 1 * REAGENTS_METABOLISM
+ nutriment_factor = 1
color = "#2E6671" // rgb: 46, 102, 113
boozepwr = 65
quality = DRINK_GOOD
@@ -1205,7 +1206,7 @@
/datum/reagent/consumable/ethanol/bananahonk
name = "Banana Honk"
description = "A drink from Clown Heaven."
- nutriment_factor = 1 * REAGENTS_METABOLISM
+ nutriment_factor = 1
color = "#FFFF91" // rgb: 255, 255, 140
boozepwr = 60
quality = DRINK_GOOD
@@ -1222,7 +1223,7 @@
/datum/reagent/consumable/ethanol/silencer
name = "Silencer"
description = "A drink from Mime Heaven."
- nutriment_factor = 2 * REAGENTS_METABOLISM
+ nutriment_factor = 2
color = "#a8a8a8" // rgb: 168,168,168
boozepwr = 59 //Proof that clowns are better than mimes right here
quality = DRINK_GOOD
@@ -1257,7 +1258,7 @@
name = "Hard Cider"
description = "Apple juice, for adults."
color = "#CD6839"
- nutriment_factor = 1 * REAGENTS_METABOLISM
+ nutriment_factor = 1
boozepwr = 25
taste_description = "the season that falls between summer and winter"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -1449,7 +1450,7 @@
name = "Eggnog"
description = "For enjoying the most wonderful time of the year."
color = "#fcfdc6" // rgb: 252, 253, 198
- nutriment_factor = 2 * REAGENTS_METABOLISM
+ nutriment_factor = 2
boozepwr = 1
quality = DRINK_VERYGOOD
taste_description = "custard and alcohol"
@@ -1606,7 +1607,7 @@
color = "#FF0000"
boozepwr = 40
taste_description = "stale bread with a staler aftertaste"
- nutriment_factor = 2 * REAGENTS_METABOLISM
+ nutriment_factor = 2
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/squirt_cider/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
@@ -1630,7 +1631,7 @@
boozepwr = 10
quality = DRINK_GOOD
taste_description = "your arteries clogging with sugar"
- nutriment_factor = 2 * REAGENTS_METABOLISM
+ nutriment_factor = 2
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/sugar_rush/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
@@ -1857,7 +1858,7 @@
/datum/reagent/consumable/ethanol/blank_paper
name = "Blank Paper"
description = "A bubbling glass of blank paper. Just looking at it makes you feel fresh."
- nutriment_factor = 1 * REAGENTS_METABOLISM
+ nutriment_factor = 1
color = "#DCDCDC" // rgb: 220, 220, 220
boozepwr = 20
quality = DRINK_GOOD
@@ -2143,7 +2144,7 @@
if(SPT_PROB(5, seconds_per_tick))
stored_teleports += rand(2, 6)
if(prob(70))
- drinker.vomit(vomit_type = VOMIT_PURPLE)
+ drinker.vomit(vomit_flags = VOMIT_CATEGORY_DEFAULT, vomit_type = /obj/effect/decal/cleanable/vomit/purple)
return ..()
/datum/reagent/consumable/ethanol/planet_cracker
@@ -2313,7 +2314,7 @@
color = "#FF5B69"
quality = DRINK_NICE
taste_description = "regret"
- nutriment_factor = 3 * REAGENTS_METABOLISM
+ nutriment_factor = 3
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/protein_blend/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
@@ -2511,7 +2512,7 @@
name = "Plum wine"
description = "Plums turned into wine."
color = "#8a0421"
- nutriment_factor = 1 * REAGENTS_METABOLISM
+ nutriment_factor = 1
boozepwr = 20
taste_description = "a poet's love and undoing"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
diff --git a/code/modules/reagents/chemistry/reagents/drinks/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drinks/drink_reagents.dm
index 4fe48c629ef..36444d6229b 100644
--- a/code/modules/reagents/chemistry/reagents/drinks/drink_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drinks/drink_reagents.dm
@@ -165,7 +165,7 @@
/datum/reagent/consumable/potato_juice
name = "Potato Juice"
description = "Juice of the potato. Bleh."
- nutriment_factor = 2 * REAGENTS_METABOLISM
+ nutriment_factor = 2
color = "#302000" // rgb: 48, 32, 0
taste_description = "irish sadness"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -173,7 +173,7 @@
/datum/reagent/consumable/pickle
name = "Pickle Juice"
description = "More accurately, this is the brine the pickle was floating in"
- nutriment_factor = 2 * REAGENTS_METABOLISM
+ nutriment_factor = 2
color = "#302000" // rgb: 48, 32, 0
taste_description = "vinegar brine"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -296,10 +296,39 @@
affected_mob.AdjustSleeping(-20 * REM * seconds_per_tick)
if(affected_mob.getToxLoss() && SPT_PROB(10, seconds_per_tick))
affected_mob.adjustToxLoss(-1, FALSE, required_biotype = affected_biotype)
+ var/to_chatted = FALSE
+ for(var/datum/wound/iter_wound as anything in affected_mob.all_wounds)
+ if(SPT_PROB(10, seconds_per_tick))
+ var/helped = iter_wound.tea_life_process()
+ if(!to_chatted && helped)
+ to_chat(affected_mob, span_notice("A calm, relaxed feeling suffuses you. Your wounds feel a little healthier."))
+ to_chatted = TRUE
affected_mob.adjust_bodytemperature(20 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, affected_mob.get_body_temp_normal())
..()
. = TRUE
+// Different handling, different name.
+// Returns FALSE by default so broken bones and 'loss' wounds don't give a false message
+/datum/wound/proc/tea_life_process()
+ return FALSE
+
+// Slowly increase (gauzed) clot rate
+/datum/wound/pierce/bleed/tea_life_process()
+ gauzed_clot_rate += 0.1
+ return TRUE
+
+// Slowly increase clot rate
+/datum/wound/slash/flesh/tea_life_process()
+ clot_rate += 0.2
+ return TRUE
+
+// There's a designated burn process, but I felt this would be better for consistency with the rest of the reagent's procs
+/datum/wound/burn/flesh/tea_life_process()
+ // Sanitizes and heals, but with a limit
+ flesh_healing = (flesh_healing > 0.1) ? flesh_healing : flesh_healing + 0.02
+ infestation_rate = max(infestation_rate - 0.005, 0)
+ return TRUE
+
/datum/reagent/consumable/lemonade
name = "Lemonade"
description = "Sweet, tangy lemonade. Good for the soul."
@@ -314,7 +343,7 @@
description = "Encourages the patient to go golfing."
color = "#FFB766"
quality = DRINK_NICE
- nutriment_factor = 10 * REAGENTS_METABOLISM
+ nutriment_factor = 10
taste_description = "bitter tea"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -434,7 +463,7 @@
description = "A delightfully bubbly root beer, filled with so much sugar that it can actually speed up the user's trigger finger."
color = "#181008" // rgb: 24, 16, 8
quality = DRINK_VERYGOOD
- nutriment_factor = 10 * REAGENTS_METABOLISM
+ nutriment_factor = 10
metabolization_rate = 2 * REAGENTS_METABOLISM
taste_description = "a monstrous sugar rush"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -745,7 +774,7 @@
description = "A cherry flavored milkshake."
color = "#FFB6C1"
quality = DRINK_VERYGOOD
- nutriment_factor = 8 * REAGENTS_METABOLISM
+ nutriment_factor = 8
taste_description = "creamy tart cherry"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
glass_price = DRINK_PRICE_MEDIUM
@@ -755,7 +784,7 @@
description = "An exotic milkshake."
color = "#00F1FF"
quality = DRINK_VERYGOOD
- nutriment_factor = 8 * REAGENTS_METABOLISM
+ nutriment_factor = 8
taste_description = "creamy blue cherry"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -764,7 +793,7 @@
description = "A vanilla flavored milkshake. The basics are still good."
color = "#E9D2B2"
quality = DRINK_VERYGOOD
- nutriment_factor = 8 * REAGENTS_METABOLISM
+ nutriment_factor = 8
taste_description = "sweet creamy vanilla"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
glass_price = DRINK_PRICE_MEDIUM
@@ -774,7 +803,7 @@
description = "A caramel flavored milkshake. Your teeth hurt looking at it."
color = "#E17C00"
quality = DRINK_GOOD
- nutriment_factor = 10 * REAGENTS_METABOLISM
+ nutriment_factor = 10
taste_description = "sweet rich creamy caramel"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
glass_price = DRINK_PRICE_MEDIUM
@@ -784,7 +813,7 @@
description = "A frosty chocolate milkshake."
color = "#541B00"
quality = DRINK_VERYGOOD
- nutriment_factor = 8 * REAGENTS_METABOLISM
+ nutriment_factor = 8
taste_description = "sweet creamy chocolate"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
glass_price = DRINK_PRICE_MEDIUM
@@ -794,7 +823,7 @@
description = "A strawberry milkshake."
color = "#ff7b7b"
quality = DRINK_VERYGOOD
- nutriment_factor = 8 * REAGENTS_METABOLISM
+ nutriment_factor = 8
taste_description = "sweet strawberries and milk"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
glass_price = DRINK_PRICE_MEDIUM
@@ -804,7 +833,7 @@
description = "A banana milkshake. Stuff that clowns drink at their honkday parties."
color = "#f2d554"
quality = DRINK_VERYGOOD
- nutriment_factor = 8 * REAGENTS_METABOLISM
+ nutriment_factor = 8
taste_description = "thick banana"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
glass_price = DRINK_PRICE_MEDIUM
@@ -814,7 +843,7 @@
description = "A mix of pumpkin juice and coffee."
color = "#F4A460"
quality = DRINK_VERYGOOD
- nutriment_factor = 3 * REAGENTS_METABOLISM
+ nutriment_factor = 3
taste_description = "creamy pumpkin"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -823,7 +852,7 @@
description = "Ice cream on top of a Dr. Gibb glass."
color = "#B22222"
quality = DRINK_NICE
- nutriment_factor = 3 * REAGENTS_METABOLISM
+ nutriment_factor = 3
taste_description = "creamy cherry"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -871,7 +900,7 @@
/datum/reagent/consumable/hot_coco
name = "Hot Coco"
description = "Made with love! And coco beans."
- nutriment_factor = 4 * REAGENTS_METABOLISM
+ nutriment_factor = 4
color = "#403010" // rgb: 64, 48, 16
taste_description = "creamy chocolate"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -888,7 +917,7 @@
/datum/reagent/consumable/italian_coco
name = "Italian Hot Chocolate"
description = "Made with love! You can just imagine a happy Nonna from the smell."
- nutriment_factor = 8 * REAGENTS_METABOLISM
+ nutriment_factor = 8
color = "#57372A"
quality = DRINK_VERYGOOD
taste_description = "thick creamy chocolate"
diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm
index 060351a8c88..23d6010f1a9 100644
--- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm
@@ -122,6 +122,7 @@
affected_human.set_hairstyle("Bald", update = FALSE)
affected_mob.set_species(/datum/species/human/krokodil_addict)
affected_mob.adjustBruteLoss(50 * REM, FALSE, required_bodytype = affected_bodytype) // holy shit your skin just FELL THE FUCK OFF
+ . = TRUE
..()
/datum/reagent/drug/krokodil/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
@@ -324,17 +325,17 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
addiction_types = list(/datum/addiction/stimulants = 6) //2.6 per 2 seconds
-/datum/reagent/drug/pumpup/on_mob_metabolize(mob/living/carbon/L)
- ..()
- ADD_TRAIT(L, TRAIT_BATON_RESISTANCE, type)
- var/obj/item/organ/internal/liver/liver = L.get_organ_slot(ORGAN_SLOT_LIVER)
- if(HAS_TRAIT(liver, TRAIT_MAINTENANCE_METABOLISM))
- L.add_mood_event("maintenance_fun", /datum/mood_event/maintenance_high)
+/datum/reagent/drug/pumpup/on_mob_metabolize(mob/living/carbon/affected_mob)
+ . = ..()
+ ADD_TRAIT(affected_mob, TRAIT_BATON_RESISTANCE, type)
+ var/obj/item/organ/internal/liver/liver = affected_mob.get_organ_slot(ORGAN_SLOT_LIVER)
+ if(liver && HAS_TRAIT(liver, TRAIT_MAINTENANCE_METABOLISM))
+ affected_mob.add_mood_event("maintenance_fun", /datum/mood_event/maintenance_high)
metabolization_rate *= 0.8
-/datum/reagent/drug/pumpup/on_mob_end_metabolize(mob/living/L)
- REMOVE_TRAIT(L, TRAIT_BATON_RESISTANCE, type)
- ..()
+/datum/reagent/drug/pumpup/on_mob_end_metabolize(mob/living/affected_mob)
+ REMOVE_TRAIT(affected_mob, TRAIT_BATON_RESISTANCE, type)
+ return ..()
/datum/reagent/drug/pumpup/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
affected_mob.set_jitter_if_lower(10 SECONDS * REM * seconds_per_tick)
@@ -344,8 +345,9 @@
if(SPT_PROB(7.5, seconds_per_tick))
affected_mob.losebreath++
affected_mob.adjustToxLoss(2, FALSE, required_biotype = affected_biotype)
+ . = TRUE
..()
- . = TRUE
+
/datum/reagent/drug/pumpup/overdose_start(mob/living/affected_mob)
to_chat(affected_mob, span_userdanger("You can't stop shaking, your heart beats faster and faster..."))
@@ -367,7 +369,7 @@
name = "Maintenance Drugs"
chemical_flags = NONE
-/datum/reagent/drug/pumpup/on_mob_metabolize(mob/living/carbon/L)
+/datum/reagent/drug/maint/on_mob_metabolize(mob/living/carbon/L)
var/obj/item/organ/internal/liver/liver = L.get_organ_slot(ORGAN_SLOT_LIVER)
if(HAS_TRAIT(liver, TRAIT_MAINTENANCE_METABOLISM))
L.add_mood_event("maintenance_fun", /datum/mood_event/maintenance_high)
@@ -418,6 +420,7 @@
/datum/reagent/drug/maint/sludge/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
affected_mob.adjustToxLoss(0.5 * REM * seconds_per_tick, required_biotype = affected_biotype)
+ return TRUE
/datum/reagent/drug/maint/sludge/on_mob_end_metabolize(mob/living/affected_mob)
. = ..()
@@ -432,7 +435,7 @@
carbie.adjustToxLoss(1 * REM * seconds_per_tick, required_biotype = affected_biotype)
if(SPT_PROB(5, seconds_per_tick))
carbie.adjustToxLoss(5, required_biotype = affected_biotype)
- carbie.vomit()
+ carbie.vomit(VOMIT_CATEGORY_DEFAULT)
/datum/reagent/drug/maint/tar
name = "Maintenance Tar"
@@ -445,13 +448,13 @@
/datum/reagent/drug/maint/tar/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
-
affected_mob.AdjustStun(-10 * REM * seconds_per_tick)
affected_mob.AdjustKnockdown(-10 * REM * seconds_per_tick)
affected_mob.AdjustUnconscious(-10 * REM * seconds_per_tick)
affected_mob.AdjustParalyzed(-10 * REM * seconds_per_tick)
affected_mob.AdjustImmobilized(-10 * REM * seconds_per_tick)
affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 1.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ return TRUE
/datum/reagent/drug/maint/tar/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
. = ..()
@@ -603,6 +606,7 @@
if(SPT_PROB(BLASTOFF_DANCE_MOVE_CHANCE_PER_UNIT * volume, seconds_per_tick))
dancer.emote("flip")
+ return TRUE
/datum/reagent/drug/blastoff/overdose_process(mob/living/dancer, seconds_per_tick, times_fired)
. = ..()
@@ -670,6 +674,7 @@
/datum/reagent/drug/saturnx/on_mob_life(mob/living/carbon/invisible_man, seconds_per_tick, times_fired)
. = ..()
invisible_man.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.3 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ return TRUE
/datum/reagent/drug/saturnx/on_mob_metabolize(mob/living/invisible_man)
. = ..()
@@ -785,7 +790,7 @@
//I wish i could give it some kind of bonus when smoked, but we don't have an INHALE method.
/datum/reagent/drug/kronkaine/on_mob_life(mob/living/carbon/kronkaine_fiend, seconds_per_tick, times_fired)
- . = ..()
+ . = ..() || TRUE
kronkaine_fiend.add_mood_event("tweaking", /datum/mood_event/stimulant_medium, name)
kronkaine_fiend.adjustOrganLoss(ORGAN_SLOT_HEART, 0.4 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
kronkaine_fiend.set_jitter_if_lower(20 SECONDS * REM * seconds_per_tick)
diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm
index 0cc3d7beea8..1e0559d6034 100644
--- a/code/modules/reagents/chemistry/reagents/food_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm
@@ -13,8 +13,9 @@
taste_mult = 4
inverse_chem_val = 0.1
inverse_chem = null
+ creation_purity = 0.5 // 50% pure by default. Below - synthetic food. Above - natural food.
/// How much nutrition this reagent supplies
- var/nutriment_factor = 1 * REAGENTS_METABOLISM
+ var/nutriment_factor = 1
/// affects mood, typically higher for mixed drinks with more complex recipes'
var/quality = 0
@@ -23,7 +24,7 @@
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(!HAS_TRAIT(H, TRAIT_NOHUNGER))
- H.adjust_nutrition(nutriment_factor * REM * seconds_per_tick)
+ H.adjust_nutrition(get_nutriment_factor() * REM * seconds_per_tick)
if(length(reagent_removal_skip_list))
return
holder.remove_reagent(type, metabolization_rate * seconds_per_tick)
@@ -55,11 +56,14 @@
exposed_mob.add_mood_event("quality_drink", /datum/mood_event/race_drink)
// SKYRAT ADDITION END
+/datum/reagent/consumable/proc/get_nutriment_factor()
+ return nutriment_factor * REAGENTS_METABOLISM * (purity * 2)
+
/datum/reagent/consumable/nutriment
name = "Nutriment"
description = "All the vitamins, minerals, and carbohydrates the body needs in pure form."
reagent_state = SOLID
- nutriment_factor = 15 * REAGENTS_METABOLISM
+ nutriment_factor = 15
color = "#664330" // rgb: 102, 67, 48
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_DEAD_PROCESS
@@ -134,9 +138,90 @@
name = "Protein"
description = "A natural polyamide made up of amino acids. An essential constituent of mosts known forms of life."
brute_heal = 0.8 //Rewards the player for eating a balanced diet.
- nutriment_factor = 9 * REAGENTS_METABOLISM //45% as calorie dense as corn oil.
+ nutriment_factor = 9 //45% as calorie dense as oil.
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
+/datum/reagent/consumable/nutriment/fat
+ name = "Fat"
+ description = "Triglycerides found in vegetable oils and fatty animal tissue."
+ color = "#f0eed7"
+ taste_description = "lard"
+ brute_heal = 0
+ burn_heal = 1
+ nutriment_factor = 18 // Twice as nutritious compared to protein and carbohydrates
+ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
+ var/fry_temperature = 450 //Around ~350 F (117 C) which deep fryers operate around in the real world
+
+/datum/reagent/consumable/nutriment/fat/expose_obj(obj/exposed_obj, reac_volume)
+ . = ..()
+ if(!holder || (holder.chem_temp <= fry_temperature))
+ return
+ if(!isitem(exposed_obj) || HAS_TRAIT(exposed_obj, TRAIT_FOOD_FRIED))
+ return
+ if(is_type_in_typecache(exposed_obj, GLOB.oilfry_blacklisted_items) || (exposed_obj.resistance_flags & INDESTRUCTIBLE))
+ exposed_obj.visible_message(span_notice("The hot oil has no effect on [exposed_obj]!"))
+ return
+ if(exposed_obj.atom_storage)
+ exposed_obj.visible_message(span_notice("The hot oil splatters about as [exposed_obj] touches it. It seems too full to cook properly!"))
+ return
+
+ exposed_obj.visible_message(span_warning("[exposed_obj] rapidly fries as it's splashed with hot oil! Somehow."))
+ exposed_obj.AddElement(/datum/element/fried_item, volume)
+ exposed_obj.reagents.add_reagent(src.type, reac_volume)
+
+/datum/reagent/consumable/nutriment/fat/expose_mob(mob/living/exposed_mob, methods = TOUCH, reac_volume, show_message = TRUE, touch_protection = 0)
+ . = ..()
+ if(!(methods & (VAPOR|TOUCH)) || isnull(holder) || (holder.chem_temp < fry_temperature)) //Directly coats the mob, and doesn't go into their bloodstream
+ return
+
+ var/burn_damage = ((holder.chem_temp / fry_temperature) * 0.33) //Damage taken per unit
+ if(methods & TOUCH)
+ burn_damage *= max(1 - touch_protection, 0)
+ var/FryLoss = round(min(38, burn_damage * reac_volume))
+ if(!HAS_TRAIT(exposed_mob, TRAIT_OIL_FRIED))
+ exposed_mob.visible_message(span_warning("The boiling oil sizzles as it covers [exposed_mob]!"), \
+ span_userdanger("You're covered in boiling oil!"))
+ if(FryLoss)
+ exposed_mob.emote("scream")
+ playsound(exposed_mob, 'sound/machines/fryer/deep_fryer_emerge.ogg', 25, TRUE)
+ ADD_TRAIT(exposed_mob, TRAIT_OIL_FRIED, "cooking_oil_react")
+ addtimer(CALLBACK(exposed_mob, TYPE_PROC_REF(/mob/living, unfry_mob)), 3)
+ if(FryLoss)
+ exposed_mob.adjustFireLoss(FryLoss)
+
+/datum/reagent/consumable/nutriment/fat/expose_turf(turf/open/exposed_turf, reac_volume)
+ . = ..()
+ if(!istype(exposed_turf))
+ return
+ exposed_turf.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = reac_volume*2 SECONDS)
+ var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in exposed_turf)
+ if(hotspot)
+ var/datum/gas_mixture/lowertemp = exposed_turf.remove_air(exposed_turf.air.total_moles())
+ lowertemp.temperature = max( min(lowertemp.temperature-2000,lowertemp.temperature / 2) ,0)
+ lowertemp.react(src)
+ exposed_turf.assume_air(lowertemp)
+ qdel(hotspot)
+
+/datum/reagent/consumable/nutriment/fat/oil
+ name = "Vegetable Oil"
+ description = "A variety of cooking oil derived from plant fats. Used in food preparation and frying."
+ color = "#EADD6B" //RGB: 234, 221, 107 (based off of canola oil)
+ taste_mult = 0.8
+ taste_description = "oil"
+ nutriment_factor = 7 //Not very healthy on its own
+ metabolization_rate = 10 * REAGENTS_METABOLISM
+ penetrates_skin = NONE
+ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
+ default_container = /obj/item/reagent_containers/condiment/vegetable_oil
+
+/datum/reagent/consumable/nutriment/fat/oil/olive
+ name = "Olive Oil"
+ description = "A high quality oil, suitable for dishes where the oil is a key flavour."
+ taste_description = "olive oil"
+ color = "#DBCF5C"
+ nutriment_factor = 10
+ default_container = /obj/item/reagent_containers/condiment/olive_oil
+
/datum/reagent/consumable/nutriment/organ_tissue
name = "Organ Tissue"
description = "Natural tissues that make up the bulk of organs, providing many vitamins and minerals."
@@ -146,7 +231,7 @@
/datum/reagent/consumable/nutriment/cloth_fibers
name = "Cloth Fibers"
description = "It's not actually a form of nutriment but it does keep Mothpeople going for a short while..."
- nutriment_factor = 30 * REAGENTS_METABOLISM
+ nutriment_factor = 30
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
brute_heal = 0
burn_heal = 0
@@ -175,79 +260,21 @@
current_cycle++
if (HAS_TRAIT(eater, TRAIT_ROCK_EATER) && !HAS_TRAIT(eater, TRAIT_NOHUNGER) && ishuman(eater))
var/mob/living/carbon/human/golem_eater = eater
- golem_eater.adjust_nutrition(nutriment_factor * REM * delta_time)
+ golem_eater.adjust_nutrition(get_nutriment_factor() * REM * delta_time)
if(length(reagent_removal_skip_list))
return
holder.remove_reagent(type, metabolization_rate * delta_time)
-/datum/reagent/consumable/cooking_oil
- name = "Cooking Oil"
- description = "A variety of cooking oil derived from fat or plants. Used in food preparation and frying."
- color = "#EADD6B" //RGB: 234, 221, 107 (based off of canola oil)
- taste_mult = 0.8
- taste_description = "oil"
- nutriment_factor = 7 * REAGENTS_METABOLISM //Not very healthy on its own
- metabolization_rate = 10 * REAGENTS_METABOLISM
- penetrates_skin = NONE
- var/fry_temperature = 450 //Around ~350 F (117 C) which deep fryers operate around in the real world
- chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
- default_container = /obj/item/reagent_containers/condiment/cooking_oil
-
-/datum/reagent/consumable/cooking_oil/expose_obj(obj/exposed_obj, reac_volume)
- . = ..()
- if(!holder || (holder.chem_temp <= fry_temperature))
- return
- if(!isitem(exposed_obj) || HAS_TRAIT(exposed_obj, TRAIT_FOOD_FRIED))
- return
- if(is_type_in_typecache(exposed_obj, GLOB.oilfry_blacklisted_items) || (exposed_obj.resistance_flags & INDESTRUCTIBLE))
- exposed_obj.visible_message(span_notice("The hot oil has no effect on [exposed_obj]!"))
- return
- if(exposed_obj.atom_storage)
- exposed_obj.visible_message(span_notice("The hot oil splatters about as [exposed_obj] touches it. It seems too full to cook properly!"))
- return
-
- exposed_obj.visible_message(span_warning("[exposed_obj] rapidly fries as it's splashed with hot oil! Somehow."))
- exposed_obj.AddElement(/datum/element/fried_item, volume)
- exposed_obj.reagents.add_reagent(/datum/reagent/consumable/cooking_oil, reac_volume)
-
-/datum/reagent/consumable/cooking_oil/expose_mob(mob/living/exposed_mob, methods = TOUCH, reac_volume, show_message = TRUE, touch_protection = 0)
- . = ..()
- if(!(methods & (VAPOR|TOUCH)) || isnull(holder) || (holder.chem_temp < fry_temperature)) //Directly coats the mob, and doesn't go into their bloodstream
- return
-
- var/oil_damage = ((holder.chem_temp / fry_temperature) * 0.33) //Damage taken per unit
- if(methods & TOUCH)
- oil_damage *= max(1 - touch_protection, 0)
- var/FryLoss = round(min(38, oil_damage * reac_volume))
- if(!HAS_TRAIT(exposed_mob, TRAIT_OIL_FRIED))
- exposed_mob.visible_message(span_warning("The boiling oil sizzles as it covers [exposed_mob]!"), \
- span_userdanger("You're covered in boiling oil!"))
- if(FryLoss)
- exposed_mob.emote("scream")
- playsound(exposed_mob, 'sound/machines/fryer/deep_fryer_emerge.ogg', 25, TRUE)
- ADD_TRAIT(exposed_mob, TRAIT_OIL_FRIED, "cooking_oil_react")
- addtimer(CALLBACK(exposed_mob, TYPE_PROC_REF(/mob/living, unfry_mob)), 3)
- if(FryLoss)
- exposed_mob.adjustFireLoss(FryLoss)
-
-/datum/reagent/consumable/cooking_oil/expose_turf(turf/open/exposed_turf, reac_volume)
- . = ..()
- if(!istype(exposed_turf) || isgroundlessturf(exposed_turf) || (reac_volume < 5))
- return
-
- exposed_turf.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = reac_volume * 1.5 SECONDS)
- exposed_turf.name = "Deep-fried [initial(exposed_turf.name)]"
- exposed_turf.add_atom_colour(color, TEMPORARY_COLOUR_PRIORITY)
-
/datum/reagent/consumable/sugar
name = "Sugar"
description = "The organic compound commonly known as table sugar and sometimes called saccharose. This white, odorless, crystalline powder has a pleasing, sweet taste."
reagent_state = SOLID
color = "#FFFFFF" // rgb: 255, 255, 255
taste_mult = 1.5 // stop sugar drowning out other flavours
- nutriment_factor = 10 * REAGENTS_METABOLISM
+ nutriment_factor = 2
metabolization_rate = 2 * REAGENTS_METABOLISM
- overdose_threshold = 200 // Hyperglycaemic shock
+ creation_purity = 1 // impure base reagents are a big no-no
+ overdose_threshold = 100 // Hyperglycaemic shock
taste_description = "sweetness"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
default_container = /obj/item/reagent_containers/condiment/sugar
@@ -270,7 +297,7 @@
/datum/reagent/consumable/virus_food
name = "Virus Food"
description = "A mixture of water and milk. Virus cells can use this mixture to reproduce."
- nutriment_factor = 2 * REAGENTS_METABOLISM
+ nutriment_factor = 2
color = "#899613" // rgb: 137, 150, 19
taste_description = "watery milk"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -282,7 +309,7 @@
/datum/reagent/consumable/soysauce
name = "Soysauce"
description = "A salty sauce made from the soy plant."
- nutriment_factor = 2 * REAGENTS_METABOLISM
+ nutriment_factor = 2
color = "#792300" // rgb: 121, 35, 0
taste_description = "umami"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -291,7 +318,7 @@
/datum/reagent/consumable/ketchup
name = "Ketchup"
description = "Ketchup, catsup, whatever. It's tomato paste."
- nutriment_factor = 5 * REAGENTS_METABOLISM
+ nutriment_factor = 5
color = "#731008" // rgb: 115, 16, 8
taste_description = "ketchup"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -422,7 +449,7 @@
if(prob(10))
victim.set_dizzy_if_lower(2 SECONDS)
if(prob(5))
- victim.vomit()
+ victim.vomit(VOMIT_CATEGORY_DEFAULT)
/datum/reagent/consumable/condensedcapsaicin/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired)
if(!holder.has_reagent(/datum/reagent/consumable/milk))
@@ -446,6 +473,40 @@
return
exposed_turf.spawn_unique_cleanable(/obj/effect/decal/cleanable/food/salt)
+/datum/reagent/consumable/salt/expose_mob(mob/living/exposed_mob, methods, reac_volume)
+ . = ..()
+ var/mob/living/carbon/carbies = exposed_mob
+ if(!(methods & (PATCH|TOUCH|VAPOR)))
+ return
+ for(var/datum/wound/iter_wound as anything in carbies.all_wounds)
+ iter_wound.on_salt(reac_volume, carbies)
+
+// Salt can help with wounds by soaking up fluid, but undiluted salt will also cause irritation from the loose crystals, and it might soak up the body's water as well!
+// A saltwater mixture would be best, but we're making improvised chems here, not real ones.
+/datum/wound/proc/on_salt(reac_volume, mob/living/carbon/carbies)
+ return
+
+/datum/wound/pierce/bleed/on_salt(reac_volume, mob/living/carbon/carbies)
+ adjust_blood_flow(-0.06 * reac_volume, initial_flow * 0.6) // 20u of a salt shacker * 0.1 = -1.6~ blood flow, but is always clamped to, at best, third blood loss from that wound.
+ // Crystal irritation worsening recovery.
+ gauzed_clot_rate *= 0.65
+ to_chat(carbies, span_notice("The salt bits seep in and stick to [lowertext(src)], painfully irritating the skin but soaking up most of the blood."))
+
+/datum/wound/slash/flesh/on_salt(reac_volume, mob/living/carbon/carbies)
+ adjust_blood_flow(-0.1 * reac_volume, initial_flow * 0.5) // 20u of a salt shacker * 0.1 = -2~ blood flow, but is always clamped to, at best, halve blood loss from that wound.
+ // Crystal irritation worsening recovery.
+ clot_rate *= 0.75
+ to_chat(carbies, span_notice("The salt bits seep in and stick to [lowertext(src)], painfully irritating the skin but soaking up most of the blood."))
+
+/datum/wound/burn/flesh/on_salt(reac_volume)
+ // Slightly sanitizes and disinfects, but also increases infestation rate (some bacteria are aided by salt), and decreases flesh healing (can damage the skin from moisture absorption)
+ sanitization += VALUE_PER(0.4, 30) * reac_volume
+ infestation -= max(VALUE_PER(0.3, 30) * reac_volume, 0)
+ infestation_rate += VALUE_PER(0.12, 30) * reac_volume
+ flesh_healing -= max(VALUE_PER(5, 30) * reac_volume, 0)
+ to_chat(victim, span_notice("The salt bits seep in and stick to [lowertext(src)], painfully irritating the skin! After a few moments, it feels marginally better."))
+
+
/datum/reagent/consumable/blackpepper
name = "Black Pepper"
description = "A powder ground from peppercorns. *AAAACHOOO*"
@@ -459,7 +520,7 @@
name = "Coco Powder"
description = "A fatty, bitter paste made from coco beans."
reagent_state = SOLID
- nutriment_factor = 5 * REAGENTS_METABOLISM
+ nutriment_factor = 5
color = "#302000" // rgb: 48, 32, 0
taste_description = "bitterness"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -528,28 +589,6 @@
. = TRUE
..()
-/datum/reagent/consumable/cornoil
- name = "Corn Oil"
- description = "An oil derived from various types of corn."
- nutriment_factor = 20 * REAGENTS_METABOLISM
- color = "#302000" // rgb: 48, 32, 0
- taste_description = "slime"
- chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
- default_container = /obj/item/reagent_containers/condiment/cooking_oil
-
-/datum/reagent/consumable/cornoil/expose_turf(turf/open/exposed_turf, reac_volume)
- . = ..()
- if(!istype(exposed_turf))
- return
- exposed_turf.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = reac_volume*2 SECONDS)
- var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in exposed_turf)
- if(hotspot)
- var/datum/gas_mixture/lowertemp = exposed_turf.remove_air(exposed_turf.air.total_moles())
- lowertemp.temperature = max( min(lowertemp.temperature-2000,lowertemp.temperature / 2) ,0)
- lowertemp.react(src)
- exposed_turf.assume_air(lowertemp)
- qdel(hotspot)
-
/datum/reagent/consumable/enzyme
name = "Universal Enzyme"
description = "A universal enzyme used in the preparation of certain chemicals and foods."
@@ -570,7 +609,7 @@
/datum/reagent/consumable/hot_ramen
name = "Hot Ramen"
description = "The noodles are boiled, the flavors are artificial, just like being back in school."
- nutriment_factor = 5 * REAGENTS_METABOLISM
+ nutriment_factor = 5
color = "#302000" // rgb: 48, 32, 0
taste_description = "wet and cheap noodles"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -579,7 +618,7 @@
/datum/reagent/consumable/nutraslop
name = "Nutraslop"
description = "Mixture of leftover prison foods served on previous days."
- nutriment_factor = 5 * REAGENTS_METABOLISM
+ nutriment_factor = 5
color = "#3E4A00" // rgb: 62, 74, 0
taste_description = "your imprisonment"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -591,7 +630,7 @@
/datum/reagent/consumable/hell_ramen
name = "Hell Ramen"
description = "The noodles are boiled, the flavors are artificial, just like being back in school."
- nutriment_factor = 5 * REAGENTS_METABOLISM
+ nutriment_factor = 5
color = "#302000" // rgb: 48, 32, 0
taste_description = "wet and cheap noodles on fire"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -606,9 +645,38 @@
reagent_state = SOLID
color = "#FFFFFF" // rgb: 0, 0, 0
taste_description = "chalky wheat"
- chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
+ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_AFFECTS_WOUNDS
default_container = /obj/item/reagent_containers/condiment/flour
+/datum/reagent/consumable/flour/expose_mob(mob/living/exposed_mob, methods, reac_volume)
+ . = ..()
+ var/mob/living/carbon/carbies = exposed_mob
+ if(!(methods & (PATCH|TOUCH|VAPOR)))
+ return
+ for(var/datum/wound/iter_wound as anything in carbies.all_wounds)
+ iter_wound.on_flour(reac_volume, carbies)
+
+/datum/wound/proc/on_flour(reac_volume, mob/living/carbon/carbies)
+ return
+
+/datum/wound/pierce/bleed/on_flour(reac_volume, mob/living/carbon/carbies)
+ adjust_blood_flow(-0.015 * reac_volume) // 30u of a flour sack * 0.015 = -0.45~ blood flow, prettay good
+ to_chat(carbies, span_notice("The flour seeps into [lowertext(src)], painfully drying it up and absorbing some of the blood."))
+ // When some nerd adds infection for wounds, make this increase the infection
+
+/datum/wound/slash/flesh/on_flour(reac_volume, mob/living/carbon/carbies)
+ adjust_blood_flow(-0.04 * reac_volume) // 30u of a flour sack * 0.04 = -1.25~ blood flow, pretty good!
+ to_chat(carbies, span_notice("The flour seeps into [lowertext(src)], painfully drying some of it up and absorbing a little blood."))
+ // When some nerd adds infection for wounds, make this increase the infection
+
+// Don't pour flour onto burn wounds, it increases infection risk! Very unwise. Backed up by REAL info from REAL professionals.
+// https://www.reuters.com/article/uk-factcheck-flour-burn-idUSKCN26F2N3
+/datum/wound/burn/flesh/on_flour(reac_volume)
+ to_chat(victim, span_notice("The flour seeps into [lowertext(src)], spiking you with intense pain! That probably wasn't a good idea..."))
+ sanitization -= min(0, 1)
+ infestation += 0.2
+ return
+
/datum/reagent/consumable/flour/expose_turf(turf/exposed_turf, reac_volume)
. = ..()
if(isspaceturf(exposed_turf))
@@ -621,7 +689,7 @@
/datum/reagent/consumable/cherryjelly
name = "Cherry Jelly"
description = "Totally the best. Only to be spread on foods with excellent lateral symmetry."
- nutriment_factor = 10 * REAGENTS_METABOLISM
+ nutriment_factor = 10
color = "#801E28" // rgb: 128, 30, 40
taste_description = "cherry"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -637,17 +705,25 @@
name = "Rice"
description = "tiny nutritious grains"
reagent_state = SOLID
- nutriment_factor = 3 * REAGENTS_METABOLISM
+ nutriment_factor = 3
color = "#FFFFFF" // rgb: 0, 0, 0
taste_description = "rice"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
default_container = /obj/item/reagent_containers/condiment/rice
+/datum/reagent/consumable/rice_flour
+ name = "Rice Flour"
+ description = "Flour mixed with Rice"
+ reagent_state = SOLID
+ color = "#FFFFFF" // rgb: 0, 0, 0
+ taste_description = "chalky wheat with rice"
+ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
+
/datum/reagent/consumable/vanilla
name = "Vanilla Powder"
description = "A fatty, bitter paste made from vanilla pods."
reagent_state = SOLID
- nutriment_factor = 5 * REAGENTS_METABOLISM
+ nutriment_factor = 5
color = "#FFFACD"
taste_description = "vanilla"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -655,7 +731,7 @@
/datum/reagent/consumable/eggyolk
name = "Egg Yolk"
description = "It's full of protein."
- nutriment_factor = 4 * REAGENTS_METABOLISM
+ nutriment_factor = 8
color = "#FFB500"
taste_description = "egg"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -663,7 +739,7 @@
/datum/reagent/consumable/eggwhite
name = "Egg White"
description = "It's full of even more protein."
- nutriment_factor = 1.5 * REAGENTS_METABOLISM
+ nutriment_factor = 4
color = "#fffdf7"
taste_description = "bland egg"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -673,6 +749,37 @@
description = "A slippery solution."
color = "#DBCE95"
taste_description = "slime"
+ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_AFFECTS_WOUNDS
+
+// Starch has similar absorbing properties to flour (Stronger here because it's rarer)
+/datum/reagent/consumable/corn_starch/expose_mob(mob/living/exposed_mob, methods, reac_volume)
+ . = ..()
+ var/mob/living/carbon/carbies = exposed_mob
+ if(!(methods & (PATCH|TOUCH|VAPOR)))
+ return
+ for(var/datum/wound/iter_wound as anything in carbies.all_wounds)
+ iter_wound.on_starch(reac_volume, carbies)
+
+/datum/wound/proc/on_starch(reac_volume, mob/living/carbon/carbies)
+ return
+
+/datum/wound/pierce/bleed/on_starch(reac_volume, mob/living/carbon/carbies)
+ adjust_blood_flow(-0.03 * reac_volume)
+ to_chat(carbies, span_notice("The slimey starch seeps into [lowertext(src)], painfully drying some of it up and absorbing a little blood."))
+ // When some nerd adds infection for wounds, make this increase the infection
+ return
+
+/datum/wound/slash/flesh/on_starch(reac_volume, mob/living/carbon/carbies)
+ adjust_blood_flow(-0.06 * reac_volume)
+ to_chat(carbies, span_notice("The slimey starch seeps into [lowertext(src)], painfully drying it up and absorbing some of the blood."))
+ // When some nerd adds infection for wounds, make this increase the infection
+ return
+
+/datum/wound/burn/flesh/on_starch(reac_volume, mob/living/carbon/carbies)
+ to_chat(carbies, span_notice("The slimey starch seeps into [lowertext(src)], spiking you with intense pain! That probably wasn't a good idea..."))
+ sanitization -= min(0, 0.5)
+ infestation += 0.1
+ return
/datum/reagent/consumable/corn_syrup
name = "Corn Syrup"
@@ -690,7 +797,7 @@
name = "Honey"
description = "Sweet sweet honey that decays into sugar. Has antibacterial and natural healing properties."
color = "#d3a308"
- nutriment_factor = 15 * REAGENTS_METABOLISM
+ nutriment_factor = 15
metabolization_rate = 1 * REAGENTS_METABOLISM
taste_description = "sweetness"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -712,6 +819,7 @@
M.adjustFireLoss(-1, FALSE, required_bodytype = affected_bodytype)
M.adjustOxyLoss(-1, FALSE, required_biotype = affected_biotype)
M.adjustToxLoss(-1, FALSE, required_biotype = affected_biotype)
+ . = TRUE
..()
/datum/reagent/consumable/honey/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
@@ -749,13 +857,13 @@
name = "Stabilized Nutriment"
description = "A bioengineered protien-nutrient structure designed to decompose in high saturation. In layman's terms, it won't get you fat."
reagent_state = SOLID
- nutriment_factor = 15 * REAGENTS_METABOLISM
+ nutriment_factor = 15
color = "#664330" // rgb: 102, 67, 48
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/nutriment/stabilized/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired)
if(M.nutrition > NUTRITION_LEVEL_FULL - 25)
- M.adjust_nutrition(-3 * REM * nutriment_factor * seconds_per_tick)
+ M.adjust_nutrition(-3 * REM * get_nutriment_factor() * seconds_per_tick)
..()
////Lavaland Flora Reagents////
@@ -812,7 +920,7 @@
name = "Vitrium Froth"
description = "A bubbly paste that heals wounds of the skin."
color = "#d3a308"
- nutriment_factor = 3 * REAGENTS_METABOLISM
+ nutriment_factor = 3
taste_description = "fruity mushroom"
ph = 10.4
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -827,7 +935,7 @@
/datum/reagent/consumable/liquidelectricity
name = "Liquid Electricity"
description = "The blood of Ethereals, and the stuff that keeps them going. Great for them, horrid for anyone else."
- nutriment_factor = 5 * REAGENTS_METABOLISM
+ nutriment_factor = 5
color = "#97ee63"
taste_description = "pure electricity"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -874,7 +982,7 @@
/datum/reagent/consumable/secretsauce
name = "Secret Sauce"
description = "What could it be?"
- nutriment_factor = 2 * REAGENTS_METABOLISM
+ nutriment_factor = 2
color = "#792300"
taste_description = "indescribable"
quality = FOOD_AMAZING
@@ -886,7 +994,7 @@
color = "#BBD4D9"
taste_description = "mint frosting"
description = "These restorative peptides not only speed up wound healing, but are nutritious as well!"
- nutriment_factor = 10 * REAGENTS_METABOLISM // 33% less than nutriment to reduce weight gain
+ nutriment_factor = 10 // 33% less than nutriment to reduce weight gain
brute_heal = 3
burn_heal = 1
inverse_chem = /datum/reagent/peptides_failed//should be impossible, but it's so it appears in the chemical lookup gui
@@ -896,7 +1004,7 @@
/datum/reagent/consumable/caramel
name = "Caramel"
description = "Who would have guessed that heated sugar could be so delicious?"
- nutriment_factor = 10 * REAGENTS_METABOLISM
+ nutriment_factor = 10
color = "#D98736"
taste_mult = 2
taste_description = "caramel"
@@ -907,7 +1015,7 @@
name = "Char"
description = "Essence of the grill. Has strange properties when overdosed."
reagent_state = LIQUID
- nutriment_factor = 5 * REAGENTS_METABOLISM
+ nutriment_factor = 5
color = "#C8C8C8"
taste_mult = 6
taste_description = "smoke"
@@ -923,7 +1031,7 @@
/datum/reagent/consumable/bbqsauce
name = "BBQ Sauce"
description = "Sweet, smoky, savory, and gets everywhere. Perfect for grilling."
- nutriment_factor = 5 * REAGENTS_METABOLISM
+ nutriment_factor = 5
color = "#78280A" // rgb: 120 40, 10
taste_mult = 2.5 //sugar's 1.5, capsacin's 1.5, so a good middle ground.
taste_description = "smokey sweetness"
@@ -935,7 +1043,7 @@
description = "A great dessert for chocolate lovers."
color = "#800000"
quality = DRINK_VERYGOOD
- nutriment_factor = 4 * REAGENTS_METABOLISM
+ nutriment_factor = 4
taste_description = "sweet chocolate"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
glass_price = DRINK_PRICE_EASY
@@ -952,7 +1060,7 @@
description = "A great dessert for vanilla lovers."
color = "#FAFAD2"
quality = DRINK_VERYGOOD
- nutriment_factor = 4 * REAGENTS_METABOLISM
+ nutriment_factor = 4
taste_description = "sweet vanilla"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -967,7 +1075,7 @@
name = "Laughin' Syrup"
description = "The product of juicing Laughin' Peas. Fizzy, and seems to change flavour based on what it's used with!"
color = "#803280"
- nutriment_factor = 5 * REAGENTS_METABOLISM
+ nutriment_factor = 5
taste_mult = 2
taste_description = "fizzy sweetness"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -1005,7 +1113,7 @@
name = "Korta Nectar"
description = "A sweet, sugary syrup made from crushed sweet korta nuts."
color = "#d3a308"
- nutriment_factor = 5 * REAGENTS_METABOLISM
+ nutriment_factor = 5
metabolization_rate = 1 * REAGENTS_METABOLISM
taste_description = "peppery sweetness"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -1014,7 +1122,7 @@
name = "Whipped Cream"
description = "A white fluffy cream made from whipping cream at intense speed."
color = "#efeff0"
- nutriment_factor = 4 * REAGENTS_METABOLISM
+ nutriment_factor = 4
taste_description = "fluffy sweet cream"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -1024,7 +1132,7 @@
taste_description = "peanuts"
reagent_state = SOLID
color = "#D9A066"
- nutriment_factor = 15 * REAGENTS_METABOLISM
+ nutriment_factor = 15
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
default_container = /obj/item/reagent_containers/condiment/peanut_butter
@@ -1042,15 +1150,6 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
default_container = /obj/item/reagent_containers/condiment/vinegar
-//A better oil, representing choices like olive oil, argan oil, avocado oil, etc.
-/datum/reagent/consumable/quality_oil
- name = "Quality Oil"
- description = "A high quality oil, suitable for dishes where the oil is a key flavour."
- taste_description = "olive oil"
- color = "#DBCF5C"
- chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
- default_container = /obj/item/reagent_containers/condiment/quality_oil
-
/datum/reagent/consumable/cornmeal
name = "Cornmeal"
description = "Ground cornmeal, for making corn related things."
@@ -1064,7 +1163,7 @@
description = "Creamy natural yoghurt, with applications in both food and drinks."
taste_description = "yoghurt"
color = "#efeff0"
- nutriment_factor = 2 * REAGENTS_METABOLISM
+ nutriment_factor = 2
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
default_container = /obj/item/reagent_containers/condiment/yoghurt
@@ -1087,7 +1186,7 @@
description = "Powdered milk for cheap coffee. How delightful."
taste_description = "milk"
color = "#efeff0"
- nutriment_factor = 1.5 * REAGENTS_METABOLISM
+ nutriment_factor = 1.5
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
default_container = /obj/item/reagent_containers/condiment/creamer
diff --git a/code/modules/reagents/chemistry/reagents/impure_reagents.dm b/code/modules/reagents/chemistry/reagents/impure_reagents.dm
index d14df37ce96..f7eaba3c211 100644
--- a/code/modules/reagents/chemistry/reagents/impure_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/impure_reagents.dm
@@ -15,12 +15,12 @@
var/liver_damage = 0.5
/datum/reagent/impurity/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
var/obj/item/organ/internal/liver/liver = affected_mob.get_organ_slot(ORGAN_SLOT_LIVER)
- if(!liver)//Though, lets be safe
- affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)//Incase of no liver!
- return ..()
+ if(isnull(liver)) //Though, lets be safe
+ return affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) //Incase of no liver!
affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, liver_damage * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
- return ..()
+ return TRUE
//Basically just so people don't forget to adjust metabolization_rate
/datum/reagent/inverse
@@ -35,8 +35,8 @@
/datum/reagent/inverse/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustToxLoss(tox_damage * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- return ..()
+ . = ..()
+ return affected_mob.adjustToxLoss(tox_damage * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
//Failed chems - generally use inverse if you want to use a impure subtype for it
//technically not a impure chem, but it's here because it can only be made with a failed impure reaction
diff --git a/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm
index 8e09b318d1c..db98ed9d622 100644
--- a/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm
@@ -47,6 +47,7 @@
if("oxy")
owner.adjustOxyLoss(-0.5, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
..()
+ return TRUE
// C2 medications
// Helbital
@@ -198,7 +199,8 @@ Basically, we fill the time between now and 2s from now with hands based off the
/datum/reagent/peptides_failed/on_mob_life(mob/living/carbon/owner, seconds_per_tick, times_fired)
owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.25 * seconds_per_tick, 170)
owner.adjust_nutrition(-5 * REAGENTS_METABOLISM * seconds_per_tick)
- . = ..()
+ ..()
+ return TRUE
//Lenturi
//impure
@@ -233,6 +235,7 @@ Basically, we fill the time between now and 2s from now with hands based off the
//Just the removed itching mechanism - omage to it's origins.
/datum/reagent/inverse/ichiyuri/on_mob_life(mob/living/carbon/owner, seconds_per_tick, times_fired)
if(prob(resetting_probability) && !(HAS_TRAIT(owner, TRAIT_RESTRAINED) || owner.incapacitated()))
+ . = TRUE
if(spammer < world.time)
to_chat(owner,span_warning("You can't help but itch yourself."))
spammer = world.time + (10 SECONDS)
@@ -242,7 +245,7 @@ Basically, we fill the time between now and 2s from now with hands based off the
resetting_probability = 0
resetting_probability += (5*(current_cycle/10) * seconds_per_tick) // 10 iterations = >51% to itch
..()
- return TRUE
+ return .
//Aiuri
//impure
@@ -441,7 +444,7 @@ Basically, we fill the time between now and 2s from now with hands based off the
if (time_until_next_poison <= 0)
time_until_next_poison = poison_interval
owner.adjustToxLoss(creation_purity * 1, required_biotype = affected_biotype)
-
+ . = TRUE
..()
//Kind of a healing effect, Presumably you're using syrinver to purge so this helps that
@@ -561,7 +564,8 @@ Basically, we fill the time between now and 2s from now with hands based off the
if(!heart || heart.organ_flags & ORGAN_FAILING)
remove_buffs(affected_mob)
..()
-
+ return TRUE
+
/datum/reagent/inverse/penthrite/on_mob_delete(mob/living/carbon/affected_mob)
remove_buffs(affected_mob)
var/obj/item/organ/internal/heart/heart = affected_mob.get_organ_slot(ORGAN_SLOT_HEART)
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index 86978985ff8..30fae4db9c7 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -70,7 +70,8 @@
affected_mob.adjustToxLoss(-5 * REM * seconds_per_tick, FALSE, TRUE, affected_biotype)
// Heal everything! That we want to. But really don't heal reagents. Otherwise we'll lose ... us.
affected_mob.fully_heal(full_heal_flags & ~HEAL_ALL_REAGENTS)
- return ..()
+ ..()
+ return TRUE
/datum/reagent/medicine/adminordrazine/quantum_heal
name = "Quantum Medicine"
@@ -136,6 +137,7 @@
if(prob(30))
SEND_SOUND(affected_mob, sound('sound/weapons/flash_ring.ogg'))
..()
+ return TRUE
/datum/reagent/medicine/cryoxadone
name = "Cryoxadone"
@@ -346,7 +348,7 @@
color = "#6D6374"
metabolization_rate = 0.4 * REAGENTS_METABOLISM
ph = 2.6
- chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
+ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_AFFECTS_WOUNDS
/datum/reagent/medicine/mine_salve/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
affected_mob.adjustBruteLoss(-0.25 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
@@ -380,6 +382,10 @@
. = ..()
metabolizer.remove_status_effect(/datum/status_effect/grouped/screwy_hud/fake_healthy, type)
+/datum/reagent/medicine/mine_salve/on_burn_wound_processing(datum/wound/burn/flesh/burn_wound)
+ burn_wound.sanitization += 0.3
+ burn_wound.flesh_healing += 0.5
+
/datum/reagent/medicine/omnizine
name = "Omnizine"
description = "Slowly heals all damage types. Overdose will cause damage in all types instead."
@@ -496,6 +502,7 @@
affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, required_biotype = affected_biotype)
..()
+ return TRUE
/datum/reagent/medicine/pen_acid
name = "Pentetic Acid"
@@ -590,7 +597,7 @@
..()
/datum/reagent/medicine/ephedrine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- if(SPT_PROB(10 * (1-creation_purity), seconds_per_tick) && iscarbon(affected_mob))
+ if(SPT_PROB(10 * (1.5-creation_purity), seconds_per_tick) && iscarbon(affected_mob))
var/obj/item/I = affected_mob.get_active_held_item()
if(I && affected_mob.dropItemToGround(I))
to_chat(affected_mob, span_notice("Your hands spaz out and you drop what you were holding!"))
@@ -726,20 +733,22 @@
affected_mob.adjust_temp_blindness(-4 SECONDS * REM * seconds_per_tick * normalized_purity)
affected_mob.adjust_eye_blur(-4 SECONDS * REM * seconds_per_tick * normalized_purity)
var/obj/item/organ/internal/eyes/eyes = affected_mob.get_organ_slot(ORGAN_SLOT_EYES)
- if(eyes)
- // Healing eye damage will cure nearsightedness and blindness from ... eye damage
- eyes.apply_organ_damage(-2 * REM * seconds_per_tick * normalise_creation_purity(), required_organ_flag = affected_organ_flags)
- // If our eyes are seriously damaged, we have a probability of causing eye blur while healing depending on purity
- if(eyes.damaged && IS_ORGANIC_ORGAN(eyes) && SPT_PROB(16 - min(normalized_purity * 6, 12), seconds_per_tick))
- // While healing, gives some eye blur
- if(affected_mob.is_blind_from(EYE_DAMAGE))
- to_chat(affected_mob, span_warning("Your vision slowly returns..."))
- affected_mob.adjust_eye_blur(20 SECONDS)
- else if(affected_mob.is_nearsighted_from(EYE_DAMAGE))
- to_chat(affected_mob, span_warning("The blackness in your peripheral vision begins to fade."))
- affected_mob.adjust_eye_blur(5 SECONDS)
+ if(isnull(eyes))
+ return ..()
- return ..()
+ // Healing eye damage will cure nearsightedness and blindness from ... eye damage
+ eyes.apply_organ_damage(-2 * REM * seconds_per_tick * normalise_creation_purity(), required_organ_flag = affected_organ_flags)
+ // If our eyes are seriously damaged, we have a probability of causing eye blur while healing depending on purity
+ if(eyes.damaged && IS_ORGANIC_ORGAN(eyes) && SPT_PROB(16 - min(normalized_purity * 6, 12), seconds_per_tick))
+ // While healing, gives some eye blur
+ if(affected_mob.is_blind_from(EYE_DAMAGE))
+ to_chat(affected_mob, span_warning("Your vision slowly returns..."))
+ affected_mob.adjust_eye_blur(20 SECONDS)
+ else if(affected_mob.is_nearsighted_from(EYE_DAMAGE))
+ to_chat(affected_mob, span_warning("The blackness in your peripheral vision begins to fade."))
+ affected_mob.adjust_eye_blur(5 SECONDS)
+
+ return ..() || TRUE
/datum/reagent/medicine/oculine/on_mob_delete(mob/living/affected_mob)
var/obj/item/organ/internal/eyes/eyes = affected_mob.get_organ_slot(ORGAN_SLOT_EYES)
@@ -779,6 +788,7 @@
return ..()
ears.adjustEarDamage(-4 * REM * seconds_per_tick * normalise_creation_purity(), -4 * REM * seconds_per_tick * normalise_creation_purity())
..()
+ return TRUE
/datum/reagent/medicine/inacusiate/on_mob_delete(mob/living/affected_mob)
. = ..()
@@ -844,14 +854,13 @@
..()
/datum/reagent/medicine/epinephrine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- . = TRUE
if(holder.has_reagent(/datum/reagent/toxin/lexorin))
holder.remove_reagent(/datum/reagent/toxin/lexorin, 2 * REM * seconds_per_tick)
holder.remove_reagent(/datum/reagent/medicine/epinephrine, 1 * REM * seconds_per_tick)
if(SPT_PROB(10, seconds_per_tick))
holder.add_reagent(/datum/reagent/toxin/histamine, 4)
..()
- return
+ return FALSE
if(affected_mob.health <= affected_mob.crit_threshold)
affected_mob.adjustToxLoss(-0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
affected_mob.adjustBruteLoss(-0.5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
@@ -868,6 +877,7 @@
if(SPT_PROB(10, seconds_per_tick))
affected_mob.AdjustAllImmobility(-20)
..()
+ return TRUE
/datum/reagent/medicine/epinephrine/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
if(SPT_PROB(18, REM * seconds_per_tick))
@@ -983,7 +993,8 @@
var/damage_at_random = rand(0, 250)/100 //0 to 2.5
affected_mob.adjustBruteLoss(damage_at_random * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
affected_mob.adjustFireLoss(damage_at_random * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- return ..()
+ ..()
+ return TRUE
/datum/reagent/medicine/mannitol
name = "Mannitol"
@@ -1000,6 +1011,7 @@
/datum/reagent/medicine/mannitol/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -2 * REM * seconds_per_tick * normalise_creation_purity(), required_organ_flag = affected_organ_flags)
..()
+ return TRUE
//Having mannitol in you will pause the brain damage from brain tumor (so it heals an even 2 brain damage instead of 1.8)
/datum/reagent/medicine/mannitol/on_mob_metabolize(mob/living/carbon/affected_mob)
@@ -1110,6 +1122,14 @@
..()
. = TRUE
+/datum/reagent/medicine/antihol/expose_mob(mob/living/carbon/exposed_carbon, methods=TOUCH, reac_volume)
+ . = ..()
+ if(!(methods & (TOUCH|VAPOR|PATCH)))
+ return
+
+ for(var/datum/surgery/surgery as anything in exposed_carbon.surgeries)
+ surgery.speed_modifier = max(surgery.speed_modifier - 0.1, -0.9)
+
/datum/reagent/medicine/stimulants
name = "Stimulants"
description = "Increases resistance to batons and movement speed in addition to restoring minor damage and weakness. Overdose causes weakness and toxin damage."
@@ -1228,7 +1248,7 @@
/datum/reagent/medicine/syndicate_nanites/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) //wtb flavortext messages that hint that you're vomitting up robots
if(SPT_PROB(13, seconds_per_tick))
affected_mob.reagents.remove_reagent(type, metabolization_rate*15) // ~5 units at a rate of 0.4 but i wanted a nice number in code
- affected_mob.vomit(20) // nanite safety protocols make your body expel them to prevent harmies
+ affected_mob.vomit(vomit_flags = VOMIT_CATEGORY_DEFAULT, vomit_type = /obj/effect/decal/cleanable/vomit/nanites, lost_nutrition = 20) // nanite safety protocols make your body expel them to prevent harmies
..()
. = TRUE
@@ -1539,7 +1559,7 @@
/datum/reagent/medicine/metafactor/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
if(SPT_PROB(13, seconds_per_tick))
- affected_mob.vomit()
+ affected_mob.vomit(VOMIT_CATEGORY_DEFAULT)
..()
/datum/reagent/medicine/silibinin
@@ -1731,4 +1751,5 @@
M.adjust_drowsiness(2 SECONDS * REM * seconds_per_tick)
if(SPT_PROB(15, seconds_per_tick) && !M.getStaminaLoss())
M.adjustStaminaLoss(10)
+ . = TRUE
M.adjust_disgust(-10 * REM * seconds_per_tick)
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index 42edf6bee30..121d80f7676 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -131,7 +131,7 @@
color = "#CC4633"
description = "You don't even want to think about what's in here."
taste_description = "gross iron"
- nutriment_factor = 2 * REAGENTS_METABOLISM
+ nutriment_factor = 2
material = /datum/material/meat
ph = 7.45
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
@@ -306,6 +306,53 @@
//You don't belong in this world, monster!
mytray.reagents.remove_reagent(type, volume)
+/datum/reagent/water/salt
+ name = "Saltwater"
+ description = "Water, but salty. Smells like... the station infirmary?"
+ color = "#aaaaaa9d" // rgb: 170, 170, 170, 77 (alpha)
+ taste_description = "the sea"
+ cooling_temperature = 3
+ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_CLEANS
+ default_container = /obj/item/reagent_containers/cup/glass/waterbottle
+
+/datum/glass_style/shot_glass/water/salt
+ required_drink_type = /datum/reagent/water/salt
+ icon_state = "shotglassclear"
+
+/datum/glass_style/drinking_glass/water/salt
+ required_drink_type = /datum/reagent/water/salt
+ name = "glass of saltwater"
+ desc = "If you have a sore throat, gargle some saltwater and watch the pain go away. Can be used as a very improvised topical medicine against wounds."
+ icon_state = "glass_clear"
+
+/datum/reagent/water/salt/expose_mob(mob/living/exposed_mob, methods, reac_volume)
+ . = ..()
+ var/mob/living/carbon/carbies = exposed_mob
+ if(!(methods & (PATCH|TOUCH|VAPOR)))
+ return
+ for(var/datum/wound/iter_wound as anything in carbies.all_wounds)
+ iter_wound.on_saltwater(reac_volume, carbies)
+
+// Mixed salt with water! All the help of salt with none of the irritation. Plus increased volume.
+/datum/wound/proc/on_saltwater(reac_volume, mob/living/carbon/carbies)
+ return
+
+/datum/wound/pierce/bleed/on_saltwater(reac_volume, mob/living/carbon/carbies)
+ adjust_blood_flow(-0.06 * reac_volume, initial_flow * 0.6)
+ to_chat(carbies, span_notice("The salt water splashes over [lowertext(src)], soaking up the blood."))
+
+/datum/wound/slash/flesh/on_saltwater(reac_volume, mob/living/carbon/carbies)
+ adjust_blood_flow(-0.1 * reac_volume, initial_flow * 0.5)
+ to_chat(carbies, span_notice("The salt water splashes over [lowertext(src)], soaking up the blood."))
+
+/datum/wound/burn/flesh/on_saltwater(reac_volume)
+ // Similar but better stats from normal salt.
+ sanitization += VALUE_PER(0.6, 30) * reac_volume
+ infestation -= max(VALUE_PER(0.5, 30) * reac_volume, 0)
+ infestation_rate += VALUE_PER(0.07, 30) * reac_volume
+ to_chat(victim, span_notice("The salt water splashes over [lowertext(src)], soaking up the... miscellaneous fluids. It feels somewhat better afterwards."))
+ return
+
/datum/reagent/water/holywater
name = "Holy Water"
description = "Water blessed by some deity."
@@ -436,6 +483,7 @@
name = "Unholy Water"
description = "Something that shouldn't exist on this plane of existence."
taste_description = "suffering"
+ self_consuming = TRUE //unholy intervention won't be limited by the lack of a liver
metabolization_rate = 2.5 * REAGENTS_METABOLISM //0.5u/second
penetrates_skin = TOUCH|VAPOR
ph = 6.5
@@ -459,6 +507,7 @@
affected_mob.adjustOxyLoss(1 * REM * seconds_per_tick, 0)
affected_mob.adjustBruteLoss(1 * REM * seconds_per_tick, 0)
..()
+ return TRUE
/datum/reagent/hellwater //if someone has this in their system they've really pissed off an eldrich god
name = "Hell Water"
@@ -474,6 +523,7 @@
affected_mob.adjustFireLoss(0.5*seconds_per_tick, 0) //Hence the other damages... ain't I a bastard?
affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2.5*seconds_per_tick, 150)
holder.remove_reagent(type, 0.5*seconds_per_tick)
+ return TRUE
/datum/reagent/medicine/omnizine/godblood
name = "Godblood"
@@ -940,6 +990,7 @@
affected_mob.emote(pick("twitch","drool","moan"))
affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5*seconds_per_tick)
..()
+ return TRUE
/datum/reagent/sulfur
name = "Sulfur"
@@ -1065,7 +1116,7 @@
color = "#D0EFEE" // space cleaner but lighter
taste_description = "bitterness"
ph = 10.5
- chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
+ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_AFFECTS_WOUNDS
/datum/reagent/space_cleaner/sterilizine/expose_mob(mob/living/carbon/exposed_carbon, methods=TOUCH, reac_volume)
. = ..()
@@ -1075,6 +1126,9 @@
for(var/datum/surgery/surgery as anything in exposed_carbon.surgeries)
surgery.speed_modifier = max(0.2, surgery.speed_modifier)
+/datum/reagent/space_cleaner/sterilizine/on_burn_wound_processing(datum/wound/burn/flesh/burn_wound)
+ burn_wound.sanitization += 0.9
+
/datum/reagent/iron
name = "Iron"
description = "Pure iron is a metal."
@@ -1124,6 +1178,7 @@
/datum/reagent/uranium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
affected_mob.adjustToxLoss(tox_damage * seconds_per_tick * REM)
..()
+ return TRUE
/datum/reagent/uranium/expose_turf(turf/exposed_turf, reac_volume)
. = ..()
@@ -1238,14 +1293,14 @@
/datum/reagent/space_cleaner
name = "Space Cleaner"
- description = "A compound used to clean things. Now with 50% more sodium hypochlorite!"
+ description = "A compound used to clean things. Now with 50% more sodium hypochlorite! Can be used to clean wounds, but it's not really meant for that."
color = "#A5F0EE" // rgb: 165, 240, 238
taste_description = "sourness"
reagent_weight = 0.6 //so it sprays further
- penetrates_skin = NONE
+ penetrates_skin = VAPOR
var/clean_types = CLEAN_WASH
ph = 5.5
- chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_CLEANS
+ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_CLEANS|REAGENT_AFFECTS_WOUNDS
/datum/reagent/space_cleaner/expose_obj(obj/exposed_obj, reac_volume)
. = ..()
@@ -1271,6 +1326,13 @@
if(methods & (TOUCH|VAPOR))
exposed_mob.wash(clean_types)
+/datum/reagent/space_cleaner/on_burn_wound_processing(datum/wound/burn/flesh/burn_wound)
+ burn_wound.sanitization += 0.3
+ if(prob(5))
+ to_chat(burn_wound.victim, span_notice("Your [burn_wound] stings and burns from the [src] covering it! It does look pretty clean though."))
+ burn_wound.victim.adjustToxLoss(0.5)
+ burn_wound.limb.receive_damage(burn = 0.5, wound_bonus = CANT_WOUND)
+
/datum/reagent/space_cleaner/ez_clean
name = "EZ Clean"
description = "A powerful, acidic cleaner sold by Waffle Co. Affects organic matter while leaving other objects unaffected."
@@ -1285,6 +1347,7 @@
affected_mob.adjustFireLoss(1.665*seconds_per_tick)
affected_mob.adjustToxLoss(1.665*seconds_per_tick)
..()
+ return TRUE
/datum/reagent/space_cleaner/ez_clean/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
. = ..()
@@ -1326,8 +1389,10 @@
/datum/reagent/impedrezene/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
affected_mob.adjust_jitter(-5 SECONDS * seconds_per_tick)
+ . = FALSE
if(SPT_PROB(55, seconds_per_tick))
affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2)
+ . = TRUE
if(SPT_PROB(30, seconds_per_tick))
affected_mob.adjust_drowsiness(6 SECONDS)
if(SPT_PROB(5, seconds_per_tick))
@@ -2492,8 +2557,10 @@
/datum/reagent/peaceborg/tire/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
var/healthcomp = (100 - affected_mob.health) //DOES NOT ACCOUNT FOR ADMINBUS THINGS THAT MAKE YOU HAVE MORE THAN 200/210 HEALTH, OR SOMETHING OTHER THAN A HUMAN PROCESSING THIS.
+ . = FALSE
if(affected_mob.getStaminaLoss() < (45 - healthcomp)) //At 50 health you would have 200 - 150 health meaning 50 compensation. 60 - 50 = 10, so would only do 10-19 stamina.)
affected_mob.adjustStaminaLoss(10 * REM * seconds_per_tick)
+ . = TRUE
if(SPT_PROB(16, seconds_per_tick))
to_chat(affected_mob, "You should sit down and take a rest...")
..()
@@ -2553,7 +2620,10 @@
if(yuck_cycles % YUCK_PUKE_CYCLES == 0)
if(yuck_cycles >= YUCK_PUKE_CYCLES * YUCK_PUKES_TO_STUN)
holder.remove_reagent(type, 5)
- affected_mob.vomit(rand(14, 26), stun = yuck_cycles >= YUCK_PUKE_CYCLES * YUCK_PUKES_TO_STUN)
+ var/passable_flags = (MOB_VOMIT_MESSAGE | MOB_VOMIT_HARM)
+ if(yuck_cycles >= (YUCK_PUKE_CYCLES * YUCK_PUKES_TO_STUN))
+ passable_flags |= MOB_VOMIT_STUN
+ affected_mob.vomit(vomit_flags = passable_flags, lost_nutrition = rand(14, 26))
if(holder)
return ..()
#undef YUCK_PUKE_CYCLES
@@ -2718,6 +2788,7 @@
It re-energizes and heals those who can see beyond this fragile reality, \
but is incredibly harmful to the closed-minded. It metabolizes very quickly."
taste_description = "Ag'hsj'saje'sh"
+ self_consuming = TRUE //eldritch intervention won't be limited by the lack of a liver
color = "#1f8016"
metabolization_rate = 2.5 * REAGENTS_METABOLISM //0.5u/second
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
@@ -2799,7 +2870,8 @@
victim.emote("scream")
if(SPT_PROB(2, seconds_per_tick)) // Stuns, but purges ants.
victim.vomit(rand(5,10), FALSE, TRUE, 1, TRUE, FALSE, purge_ratio = 1)
- return ..()
+ ..()
+ return TRUE
/datum/reagent/ants/on_mob_end_metabolize(mob/living/living_anthill)
ant_damage = 0
@@ -2849,8 +2921,9 @@
metabolization_rate = 0.4 * REAGENTS_METABOLISM
/datum/reagent/lead/on_mob_life(mob/living/carbon/victim)
- . = ..()
victim.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5)
+ ..()
+ return TRUE
//The main feedstock for kronkaine production, also a shitty stamina healer.
/datum/reagent/kronkus_extract
@@ -2862,9 +2935,10 @@
addiction_types = list(/datum/addiction/stimulants = 5)
/datum/reagent/kronkus_extract/on_mob_life(mob/living/carbon/kronkus_enjoyer)
- . = ..()
+ ..()
kronkus_enjoyer.adjustOrganLoss(ORGAN_SLOT_HEART, 0.1)
kronkus_enjoyer.adjustStaminaLoss(-2, FALSE)
+ return TRUE
/datum/reagent/brimdust
name = "Brimdust"
@@ -2876,7 +2950,7 @@
/datum/reagent/brimdust/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
- affected_mob.adjustFireLoss((ispodperson(affected_mob) ? -1 : 1) * seconds_per_tick)
+ return affected_mob.adjustFireLoss((ispodperson(affected_mob) ? -1 : 1) * seconds_per_tick)
/datum/reagent/brimdust/on_hydroponics_apply(obj/machinery/hydroponics/mytray, mob/user)
mytray.adjust_weedlevel(-1)
@@ -2958,3 +3032,4 @@
if(SPT_PROB(10, seconds_per_tick))
affected_mob.emote(pick("twitch","choke","shiver","gag"))
..()
+ return TRUE
diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
index 0d52ca4e825..6f99273ad4e 100644
--- a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
@@ -203,6 +203,7 @@
/datum/reagent/napalm/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
affected_mob.adjust_fire_stacks(1 * REM * seconds_per_tick)
..()
+ return TRUE
/datum/reagent/napalm/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
. = ..()
diff --git a/code/modules/reagents/chemistry/reagents/reaction_agents_reagents.dm b/code/modules/reagents/chemistry/reagents/reaction_agents_reagents.dm
index a86bcfc97b0..c1da8b7424f 100644
--- a/code/modules/reagents/chemistry/reagents/reaction_agents_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/reaction_agents_reagents.dm
@@ -35,7 +35,7 @@
if(target.ph <= ph)
target.my_atom.audible_message(span_warning("The beaker froths as the buffer is added, to no effect."))
playsound(target.my_atom, 'sound/chemistry/bufferadd.ogg', 50, TRUE)
- holder.remove_reagent(type, amount)//Remove from holder because it's not transfered
+ holder.remove_reagent(type, amount)//Remove from holder because it's not transferred
return
var/ph_change = -((amount/target.total_volume)*strength)
target.adjust_all_reagents_ph(ph_change, ph, 14)
@@ -61,7 +61,7 @@
if(target.ph >= ph)
target.my_atom.audible_message(span_warning("The beaker froths as the buffer is added, to no effect."))
playsound(target.my_atom, 'sound/chemistry/bufferadd.ogg', 50, TRUE)
- holder.remove_reagent(type, amount)//Remove from holder because it's not transfered
+ holder.remove_reagent(type, amount)//Remove from holder because it's not transferred
return
var/ph_change = (amount/target.total_volume)*strength
target.adjust_all_reagents_ph(ph_change, 0, ph)
diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
index a9735cd7e75..d655698646c 100644
--- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
@@ -64,8 +64,8 @@
exposed_mob.domutcheck()
/datum/reagent/toxin/mutagen/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustToxLoss(0.5 * seconds_per_tick * REM, required_biotype = affected_biotype)
- return ..()
+ . = affected_mob.adjustToxLoss(0.5 * seconds_per_tick * REM, required_biotype = affected_biotype)
+ return ..() || .
/datum/reagent/toxin/mutagen/on_hydroponics_apply(obj/machinery/hydroponics/mytray, mob/user)
mytray.mutation_roll(user)
@@ -513,7 +513,8 @@
if(51 to INFINITY)
affected_mob.Sleeping(40 * REM * seconds_per_tick)
affected_mob.adjustToxLoss(1 * (current_cycle - 50) * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- return ..()
+ . = TRUE
+ return ..() || .
/datum/reagent/toxin/coffeepowder
name = "Coffee Grounds"
@@ -559,7 +560,7 @@
/datum/reagent/toxin/mutetoxin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
// Gain approximately 12 seconds * creation purity seconds of silence every metabolism tick.
affected_mob.set_silence_if_lower(6 SECONDS * REM * normalise_creation_purity() * seconds_per_tick)
- ..()
+ return ..()
/datum/reagent/toxin/staminatoxin
name = "Tirizene"
@@ -590,8 +591,8 @@
affected_mob.AddComponent(/datum/component/irradiated)
else
affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, required_biotype = affected_biotype)
-
- ..()
+ . = TRUE
+ return ..() || .
/datum/reagent/toxin/histamine
name = "Histamine"
@@ -904,9 +905,10 @@
/datum/reagent/toxin/lipolicide/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
if(affected_mob.nutrition <= NUTRITION_LEVEL_STARVING)
affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
+ . = TRUE
affected_mob.adjust_nutrition(-3 * REM * normalise_creation_purity() * seconds_per_tick) // making the chef more valuable, one meme trap at a time
affected_mob.overeatduration = 0
- return ..()
+ return ..() || .
/datum/reagent/toxin/coniine
name = "Coniine"
@@ -936,7 +938,12 @@
/datum/reagent/toxin/spewium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
.=..()
if(current_cycle >= 11 && SPT_PROB(min(30, current_cycle), seconds_per_tick))
- affected_mob.vomit(10, prob(10), prob(50), rand(0,4), TRUE)
+ var/constructed_flags = (MOB_VOMIT_MESSAGE | MOB_VOMIT_HARM)
+ if(prob(10))
+ constructed_flags |= MOB_VOMIT_BLOOD
+ if(prob(50))
+ constructed_flags |= MOB_VOMIT_STUN
+ affected_mob.vomit(vomit_flags = constructed_flags, distance = rand(0,4))
for(var/datum/reagent/toxin/R in affected_mob.reagents.reagent_list)
if(R != src)
affected_mob.reagents.remove_reagent(R.type,1)
@@ -945,7 +952,7 @@
. = ..()
if(current_cycle >= 33 && SPT_PROB(7.5, seconds_per_tick))
affected_mob.spew_organ()
- affected_mob.vomit(0, TRUE, TRUE, 4)
+ affected_mob.vomit(VOMIT_CATEGORY_BLOOD, lost_nutrition = 0, distance = 4)
to_chat(affected_mob, span_userdanger("You feel something lumpy come up as you vomit."))
/datum/reagent/toxin/curare
@@ -1193,7 +1200,7 @@
affected_mob.manual_emote(pick("oofs silently.", "looks like [affected_mob.p_their()] bones hurt.", "grimaces, as though [affected_mob.p_their()] bones hurt."))
if(3)
to_chat(affected_mob, span_warning("Your bones hurt!"))
- return ..()
+ return ..() || TRUE
/datum/reagent/toxin/bonehurtingjuice/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
if(SPT_PROB(2, seconds_per_tick) && iscarbon(affected_mob)) //big oof
@@ -1247,11 +1254,11 @@
/datum/reagent/toxin/leadacetate/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
affected_mob.adjustOrganLoss(ORGAN_SLOT_EARS, 1 * REM * seconds_per_tick)
affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1 * REM * seconds_per_tick)
+ . = TRUE
if(SPT_PROB(0.5, seconds_per_tick))
to_chat(affected_mob, span_notice("Ah, what was that? You thought you heard something..."))
affected_mob.adjust_confusion(5 SECONDS)
- return ..()
-
+ return ..() || .
/datum/reagent/toxin/hunterspider
name = "Spider Toxin"
description = "A toxic chemical produced by spiders to weaken prey."
diff --git a/code/modules/reagents/chemistry/recipes/drugs.dm b/code/modules/reagents/chemistry/recipes/drugs.dm
index b692d22b516..8822aa78705 100644
--- a/code/modules/reagents/chemistry/recipes/drugs.dm
+++ b/code/modules/reagents/chemistry/recipes/drugs.dm
@@ -63,6 +63,7 @@
if(ismob(holder.my_atom))
var/mob/M = holder.my_atom
inside_msg = " inside [ADMIN_LOOKUPFLW(M)]"
+ return
var/lastkey = holder.my_atom.fingerprintslast
var/touch_msg = "N/A"
if(lastkey)
diff --git a/code/modules/reagents/chemistry/recipes/medicine.dm b/code/modules/reagents/chemistry/recipes/medicine.dm
index cd755532fb3..e3f1fd1acef 100644
--- a/code/modules/reagents/chemistry/recipes/medicine.dm
+++ b/code/modules/reagents/chemistry/recipes/medicine.dm
@@ -95,7 +95,7 @@
/datum/chemical_reaction/medicine/salglu_solution
results = list(/datum/reagent/medicine/salglu_solution = 3)
- required_reagents = list(/datum/reagent/consumable/salt = 1, /datum/reagent/water = 1, /datum/reagent/consumable/sugar = 1)
+ required_reagents = list(/datum/reagent/water/salt = 2, /datum/reagent/consumable/sugar = 1)
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_HEALING | REACTION_TAG_ORGAN
/datum/chemical_reaction/medicine/mine_salve
@@ -143,8 +143,8 @@
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_HEALING | REACTION_TAG_OTHER
/datum/chemical_reaction/medicine/pen_acid
- results = list(/datum/reagent/medicine/pen_acid = 6)
- required_reagents = list(/datum/reagent/fuel = 1, /datum/reagent/chlorine = 1, /datum/reagent/ammonia = 1, /datum/reagent/toxin/formaldehyde = 1, /datum/reagent/sodium = 1, /datum/reagent/toxin/cyanide = 1)
+ results = list(/datum/reagent/medicine/pen_acid = 5)
+ required_reagents = list(/datum/reagent/fuel = 1, /datum/reagent/ammonia = 1, /datum/reagent/toxin/formaldehyde = 1, /datum/reagent/consumable/salt = 1, /datum/reagent/toxin/cyanide = 1)
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_HEALING | REACTION_TAG_OTHER
/datum/chemical_reaction/medicine/sal_acid
diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm
index 9248c22dbe9..b632bc7b6c8 100644
--- a/code/modules/reagents/chemistry/recipes/others.dm
+++ b/code/modules/reagents/chemistry/recipes/others.dm
@@ -16,7 +16,7 @@
/datum/chemical_reaction/spraytan2
results = list(/datum/reagent/spraytan = 2)
- required_reagents = list(/datum/reagent/consumable/orangejuice = 1, /datum/reagent/consumable/cornoil = 1)
+ required_reagents = list(/datum/reagent/consumable/orangejuice = 1, /datum/reagent/consumable/nutriment/fat/oil = 1)
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_UNIQUE | REACTION_TAG_OTHER
/datum/chemical_reaction/impedrezene
@@ -31,12 +31,12 @@
/datum/chemical_reaction/glycerol
results = list(/datum/reagent/glycerol = 1)
- required_reagents = list(/datum/reagent/consumable/cornoil = 3, /datum/reagent/toxin/acid = 1)
+ required_reagents = list(/datum/reagent/consumable/nutriment/fat/oil = 3, /datum/reagent/toxin/acid = 1)
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_UNIQUE | REACTION_TAG_EXPLOSIVE
/datum/chemical_reaction/sodiumchloride
- results = list(/datum/reagent/consumable/salt = 3)
- required_reagents = list(/datum/reagent/water = 1, /datum/reagent/sodium = 1, /datum/reagent/chlorine = 1)
+ results = list(/datum/reagent/consumable/salt = 2)
+ required_reagents = list(/datum/reagent/sodium = 1, /datum/reagent/chlorine = 1) // That's what I said! Sodium Chloride!
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_FOOD
/datum/chemical_reaction/stable_plasma
@@ -586,15 +586,19 @@
if(ismonkey(M))
M.gib()
else
- M.vomit(blood = TRUE, stun = TRUE) //not having a redo of itching powder (hopefully)
+ M.vomit(VOMIT_CATEGORY_BLOOD)
new /mob/living/carbon/human/species/monkey(location, TRUE)
//water electrolysis
/datum/chemical_reaction/electrolysis
- results = list(/datum/reagent/oxygen = 1.5, /datum/reagent/hydrogen = 3)
- required_reagents = list(/datum/reagent/consumable/liquidelectricity/enriched = 1, /datum/reagent/water = 5)
+ results = list(/datum/reagent/oxygen = 2.5, /datum/reagent/hydrogen = 5)
+ required_reagents = list(/datum/reagent/consumable/liquidelectricity = 1, /datum/reagent/water = 5)
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL
+/datum/chemical_reaction/electrolysis2
+ results = list(/datum/reagent/oxygen = 2.5, /datum/reagent/hydrogen = 5)
+ required_reagents = list(/datum/reagent/consumable/liquidelectricity/enriched = 1, /datum/reagent/water = 5)
+ reaction_tags = REACTION_TAG_EASY | REACTION_TAG_CHEMICAL
//butterflium
/datum/chemical_reaction/butterflium
required_reagents = list(/datum/reagent/colorful_reagent = 1, /datum/reagent/medicine/omnizine = 1, /datum/reagent/medicine/strange_reagent = 1, /datum/reagent/consumable/nutriment = 1)
@@ -770,6 +774,11 @@
required_catalysts = list(/datum/reagent/water/holywater = 1)
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_UNIQUE | REACTION_TAG_PLANT | REACTION_TAG_OTHER
+/datum/chemical_reaction/saltwater
+ results = list(/datum/reagent/water/salt = 2)
+ required_reagents = list(/datum/reagent/water = 1, /datum/reagent/consumable/salt = 1)
+ reaction_tags = REACTION_TAG_EASY | REACTION_TAG_DRINK | REACTION_TAG_ORGAN
+
/datum/chemical_reaction/exotic_stabilizer
results = list(/datum/reagent/exotic_stabilizer = 2)
required_reagents = list(/datum/reagent/plasma_oxide = 1,/datum/reagent/stabilizing_agent = 1)
diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm
index b39eee137c1..6b5ddfc14e3 100644
--- a/code/modules/reagents/chemistry/recipes/slime_extracts.dm
+++ b/code/modules/reagents/chemistry/recipes/slime_extracts.dm
@@ -383,8 +383,8 @@
explosion(holder.my_atom, devastation_range = 1, heavy_impact_range = 3, light_impact_range = 6, explosion_cause = src)
-/datum/chemical_reaction/slime/slimecornoil
- results = list(/datum/reagent/consumable/cornoil = 10)
+/datum/chemical_reaction/slime/slimeoil
+ results = list(/datum/reagent/consumable/nutriment/fat/oil = 10)
required_reagents = list(/datum/reagent/blood = 1)
required_container = /obj/item/slime_extract/oil
diff --git a/code/modules/reagents/chemistry/recipes/special.dm b/code/modules/reagents/chemistry/recipes/special.dm
index 990ace10830..592a281ed73 100644
--- a/code/modules/reagents/chemistry/recipes/special.dm
+++ b/code/modules/reagents/chemistry/recipes/special.dm
@@ -217,6 +217,9 @@ GLOBAL_LIST_INIT(medicine_reagents, build_medicine_reagents())
return FALSE
required_reagents = req_reag
+ if (required_reagents.len == 0)
+ return FALSE
+
var/req_catalysts = unwrap_reagent_list(recipe_data["required_catalysts"])
if(!req_catalysts)
return FALSE
diff --git a/code/modules/reagents/chemistry/recipes/toxins.dm b/code/modules/reagents/chemistry/recipes/toxins.dm
index b4e80e01cd0..0fcae783d89 100644
--- a/code/modules/reagents/chemistry/recipes/toxins.dm
+++ b/code/modules/reagents/chemistry/recipes/toxins.dm
@@ -307,8 +307,8 @@
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_DAMAGING | REACTION_TAG_OTHER
/datum/chemical_reaction/heparin
- results = list(/datum/reagent/toxin/heparin = 4)
- required_reagents = list(/datum/reagent/toxin/formaldehyde = 1, /datum/reagent/sodium = 1, /datum/reagent/chlorine = 1, /datum/reagent/lithium = 1)
+ results = list(/datum/reagent/toxin/heparin = 3)
+ required_reagents = list(/datum/reagent/toxin/formaldehyde = 1, /datum/reagent/consumable/salt = 1, /datum/reagent/lithium = 1)
mix_message = "The mixture thins and loses all color."
is_cold_recipe = FALSE
required_temp = 100
diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm
index acefe102256..49ef6980142 100644
--- a/code/modules/reagents/reagent_containers.dm
+++ b/code/modules/reagents/reagent_containers.dm
@@ -195,9 +195,9 @@
*/
/obj/item/reagent_containers/on_accidental_consumption(mob/living/carbon/M, mob/living/carbon/user, obj/item/source_item, discover_after = TRUE)
M.losebreath += 2
- reagents?.trans_to(M, min(15, reagents.total_volume / rand(5,10)), transfered_by = user, methods = INGEST)
+ reagents?.trans_to(M, min(15, reagents.total_volume / rand(5,10)), transferred_by = user, methods = INGEST)
if(source_item?.reagents)
- reagents.trans_to(source_item, min(source_item.reagents.total_volume / 2, reagents.total_volume / 5), transfered_by = user, methods = TOUCH)
+ reagents.trans_to(source_item, min(source_item.reagents.total_volume / 2, reagents.total_volume / 5), transferred_by = user, methods = TOUCH)
return ..()
diff --git a/code/modules/reagents/reagent_containers/condiment.dm b/code/modules/reagents/reagent_containers/condiment.dm
index 18a89f76a73..3a956d7968e 100644
--- a/code/modules/reagents/reagent_containers/condiment.dm
+++ b/code/modules/reagents/reagent_containers/condiment.dm
@@ -64,7 +64,7 @@
log_combat(user, M, "fed", reagents.get_reagent_log_string())
SEND_SIGNAL(M, COMSIG_GLASS_DRANK, src, user) // SKYRAT EDIT ADDITION - Hemophages can't casually drink what's not going to regenerate their blood
- reagents.trans_to(M, 10, transfered_by = user, methods = INGEST)
+ reagents.trans_to(M, 10, transferred_by = user, methods = INGEST)
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), TRUE)
return TRUE
@@ -83,7 +83,7 @@
to_chat(user, span_warning("[src] is full!"))
return
- var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this, transfered_by = user)
+ var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this, transferred_by = user)
to_chat(user, span_notice("You fill [src] with [trans] units of the contents of [target]."))
//Something like a glass or a food item. Player probably wants to transfer TO it.
@@ -94,7 +94,7 @@
if(target.reagents.total_volume >= target.reagents.maximum_volume)
to_chat(user, span_warning("you can't add anymore to [target]!"))
return
- var/trans = src.reagents.trans_to(target, amount_per_transfer_from_this, transfered_by = user)
+ var/trans = src.reagents.trans_to(target, amount_per_transfer_from_this, transferred_by = user)
to_chat(user, span_notice("You transfer [trans] units of the condiment to [target]."))
/obj/item/reagent_containers/condiment/enzyme
@@ -275,18 +275,18 @@
list_reagents = list(/datum/reagent/consumable/vinegar = 50)
fill_icon_thresholds = null
-/obj/item/reagent_containers/condiment/cooking_oil
+/obj/item/reagent_containers/condiment/vegetable_oil
name = "cooking oil"
desc = "For all your deep-frying needs."
icon_state = "cooking_oil"
- list_reagents = list(/datum/reagent/consumable/cooking_oil = 50)
+ list_reagents = list(/datum/reagent/consumable/nutriment/fat/oil = 50)
fill_icon_thresholds = null
-/obj/item/reagent_containers/condiment/quality_oil
+/obj/item/reagent_containers/condiment/olive_oil
name = "quality oil"
desc = "For the fancy chef inside everyone."
icon_state = "oliveoil"
- list_reagents = list(/datum/reagent/consumable/quality_oil = 50)
+ list_reagents = list(/datum/reagent/consumable/nutriment/fat/oil/olive = 50)
fill_icon_thresholds = null
/obj/item/reagent_containers/condiment/yoghurt
@@ -420,7 +420,7 @@
/datum/reagent/consumable/frostoil = list("condi_frostoil", "Coldsauce", "Leaves the tongue numb in its passage"),
/datum/reagent/consumable/salt = list("condi_salt", "Salt Shaker", "Salt. From space oceans, presumably"),
/datum/reagent/consumable/blackpepper = list("condi_pepper", "Pepper Mill", "Often used to flavor food or make people sneeze"),
- /datum/reagent/consumable/cornoil = list("condi_cornoil", "Corn Oil", "A delicious oil used in cooking. Made from corn"),
+ /datum/reagent/consumable/nutriment/fat/oil = list("condi_cornoil", "Vegetable Oil", "A delicious oil used in cooking."),
/datum/reagent/consumable/sugar = list("condi_sugar", "Sugar", "Tasty spacey sugar!"),
/datum/reagent/consumable/astrotame = list("condi_astrotame", "Astrotame", "The sweetness of a thousand sugars but none of the calories."),
/datum/reagent/consumable/bbqsauce = list("condi_bbq", "BBQ sauce", "Hand wipes not included."),
@@ -458,7 +458,7 @@
return
else
to_chat(user, span_notice("You tear open [src] above [target] and the condiments drip onto it."))
- src.reagents.trans_to(target, amount_per_transfer_from_this, transfered_by = user)
+ src.reagents.trans_to(target, amount_per_transfer_from_this, transferred_by = user)
qdel(src)
return
return . | ..()
diff --git a/code/modules/reagents/reagent_containers/cups/_cup.dm b/code/modules/reagents/reagent_containers/cups/_cup.dm
index c65bfe88090..b5930955a31 100644
--- a/code/modules/reagents/reagent_containers/cups/_cup.dm
+++ b/code/modules/reagents/reagent_containers/cups/_cup.dm
@@ -86,7 +86,7 @@
SEND_SIGNAL(src, COMSIG_GLASS_DRANK, target_mob, user)
SEND_SIGNAL(target_mob, COMSIG_GLASS_DRANK, src, user) // SKYRAT EDIT ADDITION - Hemophages can't casually drink what's not going to regenerate their blood
var/fraction = min(gulp_size/reagents.total_volume, 1)
- reagents.trans_to(target_mob, gulp_size, transfered_by = user, methods = INGEST)
+ reagents.trans_to(target_mob, gulp_size, transferred_by = user, methods = INGEST)
checkLiked(fraction, target_mob)
playsound(target_mob.loc,'sound/items/drink.ogg', rand(10,50), TRUE)
if(!iscarbon(target_mob))
@@ -124,7 +124,7 @@
to_chat(user, span_warning("[target] is full."))
return
- var/trans = reagents.trans_to(target, amount_per_transfer_from_this, transfered_by = user)
+ var/trans = reagents.trans_to(target, amount_per_transfer_from_this, transferred_by = user)
to_chat(user, span_notice("You transfer [trans] unit\s of the solution to [target]."))
else if(target.is_drainable()) //A dispenser. Transfer FROM it TO us.
@@ -136,7 +136,7 @@
to_chat(user, span_warning("[src] is full."))
return
- var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this, transfered_by = user)
+ var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this, transferred_by = user)
to_chat(user, span_notice("You fill [src] with [trans] unit\s of the contents of [target]."))
target.update_appearance()
@@ -157,7 +157,7 @@
to_chat(user, span_warning("[src] is full."))
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
- var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this, transfered_by = user)
+ var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this, transferred_by = user)
to_chat(user, span_notice("You fill [src] with [trans] unit\s of the contents of [target]."))
target.update_appearance()
@@ -193,7 +193,7 @@
to_chat(user, span_notice("[src] is full."))
else
to_chat(user, span_notice("You break [attacking_egg] in [src]."))
- attacking_egg.reagents.trans_to(src, attacking_egg.reagents.total_volume, transfered_by = user)
+ attacking_egg.reagents.trans_to(src, attacking_egg.reagents.total_volume, transferred_by = user)
qdel(attacking_egg)
return
@@ -414,7 +414,7 @@
if(reagents.total_volume < 1)
user.balloon_alert(user, "empty!")
else
- reagents.trans_to(O, 5, transfered_by = user)
+ reagents.trans_to(O, 5, transferred_by = user)
user.balloon_alert(user, "doused [O]")
playsound(loc, 'sound/effects/slosh.ogg', 25, TRUE)
return
@@ -430,13 +430,13 @@
user.balloon_alert(user, "mop is full!")
return
mop.reagents.remove_any(mop.reagents.total_volume * SQUEEZING_DISPERSAL_RATIO)
- mop.reagents.trans_to(src, mop.reagents.total_volume, transfered_by = user)
+ mop.reagents.trans_to(src, mop.reagents.total_volume, transferred_by = user)
user.balloon_alert(user, "mop squeezed")
else
if(reagents.total_volume < 1)
user.balloon_alert(user, "container empty!")
else
- reagents.trans_to(mop, 5, transfered_by = user)
+ reagents.trans_to(mop, 5, transferred_by = user)
user.balloon_alert(user, "mop wet")
playsound(loc, 'sound/effects/slosh.ogg', 25, TRUE)
@@ -515,36 +515,10 @@
if(do_after(user, 25, target = src))
user.adjustStaminaLoss(40)
switch(picked_option)
- if("Juice") //prioritize juicing
- if(grinded.juice_results)
- grinded.on_juice()
- reagents.add_reagent_list(grinded.juice_results)
- to_chat(user, span_notice("You juice [grinded] into a fine liquid."))
- QDEL_NULL(grinded)
- return
- else
- grinded.on_grind()
- reagents.add_reagent_list(grinded.grind_results)
- if(grinded.reagents) //If grinded item has reagents within, transfer them to the mortar
- grinded.reagents.trans_to(src, grinded.reagents.total_volume, transfered_by = user)
- to_chat(user, span_notice("You try to juice [grinded] but there is no liquids in it. Instead you get nice powder."))
- QDEL_NULL(grinded)
- return
+ if("Juice")
+ return juice_item(grinded, user)
if("Grind")
- if(grinded.grind_results)
- grinded.on_grind()
- reagents.add_reagent_list(grinded.grind_results)
- if(grinded.reagents) //If grinded item has reagents within, transfer them to the mortar
- grinded.reagents.trans_to(src, grinded.reagents.total_volume, transfered_by = user)
- to_chat(user, span_notice("You break [grinded] into powder."))
- QDEL_NULL(grinded)
- return
- else
- grinded.on_juice()
- reagents.add_reagent_list(grinded.juice_results)
- to_chat(user, span_notice("You try to grind [grinded] but it almost instantly turns into a fine liquid."))
- QDEL_NULL(grinded)
- return
+ return grind_item(grinded, user)
else
to_chat(user, span_notice("You try to grind the mortar itself instead of [grinded]. You failed."))
return
@@ -555,12 +529,31 @@
if(grinded)
to_chat(user, span_warning("There is something inside already!"))
return
- if(I.juice_results || I.grind_results)
+ if(I.juice_typepath || I.grind_results)
I.forceMove(src)
grinded = I
return
to_chat(user, span_warning("You can't grind this!"))
+/obj/item/reagent_containers/cup/mortar/proc/grind_item(obj/item/item, mob/living/carbon/human/user)
+ if(!item.grind(reagents, user))
+ if(isstack(item))
+ to_chat(usr, span_notice("[src] attempts to grind as many pieces of [item] as possible."))
+ else
+ to_chat(user, span_danger("You fail to grind [item]."))
+ return
+ to_chat(user, span_notice("You grind [item] into a nice powder."))
+ grinded = null
+ QDEL_NULL(item)
+
+/obj/item/reagent_containers/cup/mortar/proc/juice_item(obj/item/item, mob/living/carbon/human/user)
+ if(!item.juice(reagents, user))
+ to_chat(user, span_notice("You fail to juice [item]."))
+ return
+ to_chat(user, span_notice("You juice [item] into a fine liquid."))
+ grinded = null
+ QDEL_NULL(item)
+
//Coffeepots: for reference, a standard cup is 30u, to allow 20u for sugar/sweetener/milk/creamer
/obj/item/reagent_containers/cup/coffeepot
name = "coffeepot"
diff --git a/code/modules/reagents/reagent_containers/cups/bottle.dm b/code/modules/reagents/reagent_containers/cups/bottle.dm
index a2dae93c22e..1e4466da8c3 100644
--- a/code/modules/reagents/reagent_containers/cups/bottle.dm
+++ b/code/modules/reagents/reagent_containers/cups/bottle.dm
@@ -501,7 +501,7 @@
balloon_alert(user, "container full!")
return TRUE
- var/transfer_amount = reagents.trans_to(attacking_item, amount_per_transfer_from_this, transfered_by = user)
+ var/transfer_amount = reagents.trans_to(attacking_item, amount_per_transfer_from_this, transferred_by = user)
balloon_alert(user, "transferred [transfer_amount] unit\s")
flick("syrup_anim",src)
diff --git a/code/modules/reagents/reagent_containers/cups/soda.dm b/code/modules/reagents/reagent_containers/cups/soda.dm
index 0be90bc7a70..4908942b2c0 100644
--- a/code/modules/reagents/reagent_containers/cups/soda.dm
+++ b/code/modules/reagents/reagent_containers/cups/soda.dm
@@ -36,7 +36,7 @@
sleep(1 SECONDS)
H.visible_message(span_suicide("[H] takes a big sip from [src]! It looks like [H.p_theyre()] trying to commit suicide!"))
playsound(H,'sound/items/drink.ogg', 80, TRUE)
- reagents.trans_to(H, src.reagents.total_volume, transfered_by = H) //a big sip
+ reagents.trans_to(H, src.reagents.total_volume, transferred_by = H) //a big sip
sleep(0.5 SECONDS)
H.say(pick(
"Now, Outbomb Cuban Pete, THAT was a game.",
diff --git a/code/modules/reagents/reagent_containers/dropper.dm b/code/modules/reagents/reagent_containers/dropper.dm
index fbfa62f896b..cf01c2cd4c2 100644
--- a/code/modules/reagents/reagent_containers/dropper.dm
+++ b/code/modules/reagents/reagent_containers/dropper.dm
@@ -41,7 +41,7 @@
if(!safe_thing.reagents)
safe_thing.create_reagents(100)
- trans = reagents.trans_to(safe_thing, amount_per_transfer_from_this, transfered_by = user, methods = TOUCH)
+ trans = reagents.trans_to(safe_thing, amount_per_transfer_from_this, transferred_by = user, methods = TOUCH)
target.visible_message(span_danger("[user] tries to squirt something into [target]'s eyes, but fails!"), \
span_userdanger("[user] tries to squirt something into your eyes, but fails!"))
@@ -65,7 +65,7 @@
log_combat(user, M, "squirted", R)
- trans = src.reagents.trans_to(target, amount_per_transfer_from_this, transfered_by = user)
+ trans = src.reagents.trans_to(target, amount_per_transfer_from_this, transferred_by = user)
to_chat(user, span_notice("You transfer [trans] unit\s of the solution."))
update_appearance()
target.update_appearance()
@@ -80,7 +80,7 @@
to_chat(user, span_warning("[target] is empty!"))
return
- var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this, transfered_by = user)
+ var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this, transferred_by = user)
to_chat(user, span_notice("You fill [src] with [trans] unit\s of the solution."))
diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm
index b08ffac4647..63648375045 100644
--- a/code/modules/reagents/reagent_containers/hypospray.dm
+++ b/code/modules/reagents/reagent_containers/hypospray.dm
@@ -15,6 +15,8 @@
slot_flags = ITEM_SLOT_BELT
var/ignore_flags = NONE
var/infinite = FALSE
+ /// If TRUE, won't play a noise when injecting.
+ var/stealthy = FALSE
/obj/item/reagent_containers/hypospray/attack_paw(mob/user, list/modifiers)
return attack_hand(user, modifiers)
@@ -40,13 +42,15 @@
if(reagents.total_volume && (ignore_flags || affected_mob.try_inject(user, injection_flags = INJECT_TRY_SHOW_ERROR_MESSAGE))) // Ignore flag should be checked first or there will be an error message.
to_chat(affected_mob, span_warning("You feel a tiny prick!"))
to_chat(user, span_notice("You inject [affected_mob] with [src]."))
+ if(!stealthy)
+ playsound(affected_mob, 'sound/items/hypospray.ogg', 50, TRUE)
var/fraction = min(amount_per_transfer_from_this/reagents.total_volume, 1)
if(affected_mob.reagents)
var/trans = 0
if(!infinite)
- trans = reagents.trans_to(affected_mob, amount_per_transfer_from_this, transfered_by = user, methods = INJECT)
+ trans = reagents.trans_to(affected_mob, amount_per_transfer_from_this, transferred_by = user, methods = INJECT)
else
reagents.expose(affected_mob, INJECT, fraction)
trans = reagents.copy_to(affected_mob, amount_per_transfer_from_this)
diff --git a/code/modules/reagents/reagent_containers/medigel.dm b/code/modules/reagents/reagent_containers/medigel.dm
index df6c311878d..e6836c7a4c2 100644
--- a/code/modules/reagents/reagent_containers/medigel.dm
+++ b/code/modules/reagents/reagent_containers/medigel.dm
@@ -67,7 +67,7 @@
else
log_combat(user, M, "applied", src, reagents.get_reagent_log_string())
playsound(src, 'sound/effects/spray.ogg', 30, TRUE, -6)
- reagents.trans_to(M, amount_per_transfer_from_this, transfered_by = user, methods = apply_type)
+ reagents.trans_to(M, amount_per_transfer_from_this, transferred_by = user, methods = apply_type)
return
/obj/item/reagent_containers/medigel/libital
diff --git a/code/modules/reagents/reagent_containers/misc.dm b/code/modules/reagents/reagent_containers/misc.dm
index cae8582392b..b7a5fbb71f5 100644
--- a/code/modules/reagents/reagent_containers/misc.dm
+++ b/code/modules/reagents/reagent_containers/misc.dm
@@ -146,7 +146,7 @@
var/reagentlist = pretty_string_from_reagent_list(reagents.reagent_list)
var/log_object = "containing [reagentlist]"
if(user.combat_mode && !carbon_target.is_mouth_covered())
- reagents.trans_to(carbon_target, reagents.total_volume, transfered_by = user, methods = INGEST)
+ reagents.trans_to(carbon_target, reagents.total_volume, transferred_by = user, methods = INGEST)
carbon_target.visible_message(span_danger("[user] smothers \the [carbon_target] with \the [src]!"), span_userdanger("[user] smothers you with \the [src]!"), span_hear("You hear some struggling and muffled cries of surprise."))
log_combat(user, carbon_target, "smothered", src, log_object)
else
diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm
index c8a079f254e..7c7f97f0cc7 100644
--- a/code/modules/reagents/reagent_containers/pill.dm
+++ b/code/modules/reagents/reagent_containers/pill.dm
@@ -53,7 +53,7 @@
if(apply_type == INGEST)
SEND_SIGNAL(src, COMSIG_PILL_CONSUMED, eater = M, feeder = user)
if(reagents.total_volume)
- reagents.trans_to(M, reagents.total_volume, transfered_by = user, methods = apply_type)
+ reagents.trans_to(M, reagents.total_volume, transferred_by = user, methods = apply_type)
qdel(src)
return TRUE
@@ -74,7 +74,7 @@
return
user.visible_message(span_warning("[user] slips something into [target]!"), span_notice("You dissolve [src] in [target]."), null, 2)
- reagents.trans_to(target, reagents.total_volume, transfered_by = user)
+ reagents.trans_to(target, reagents.total_volume, transferred_by = user)
qdel(src)
/*
@@ -82,7 +82,7 @@
*/
/obj/item/reagent_containers/pill/on_accidental_consumption(mob/living/carbon/victim, mob/living/carbon/user, obj/item/source_item, discover_after = FALSE)
to_chat(victim, span_warning("You swallow something small. [source_item ? "Was that in [source_item]?" : ""]"))
- reagents?.trans_to(victim, reagents.total_volume, transfered_by = user, methods = INGEST)
+ reagents?.trans_to(victim, reagents.total_volume, transferred_by = user, methods = INGEST)
qdel(src)
return discover_after
diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm
index 02a26e00bae..28c26c5d356 100644
--- a/code/modules/reagents/reagent_containers/spray.dm
+++ b/code/modules/reagents/reagent_containers/spray.dm
@@ -42,7 +42,7 @@
to_chat(user, span_warning("[src] is full."))
return
- var/trans = target.reagents.trans_to(src, 50, transfered_by = user) //transfer 50u , using the spray's transfer amount would take too long to refill
+ var/trans = target.reagents.trans_to(src, 50, transferred_by = user) //transfer 50u , using the spray's transfer amount would take too long to refill
to_chat(user, span_notice("You fill \the [src] with [trans] units of the contents of \the [target]."))
return
@@ -442,6 +442,7 @@
/obj/item/reagent_containers/spray/hercuri
name = "medical spray (hercuri)"
- desc = "A medical spray bottle.This one contains hercuri, a medicine used to negate the effects of dangerous high-temperature environments. Careful not to freeze the patient!"
- icon_state = "sprayer_large"
+ desc = "A medical spray bottle. This one contains hercuri, a medicine used to negate the effects of dangerous high-temperature environments. Careful not to freeze the patient!"
+ icon = 'icons/obj/medical/chemical.dmi'
+ icon_state = "sprayer_med_yellow"
list_reagents = list(/datum/reagent/medicine/c2/hercuri = 100)
diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm
index b8b77d15561..beed3d17ba6 100644
--- a/code/modules/reagents/reagent_containers/syringes.dm
+++ b/code/modules/reagents/reagent_containers/syringes.dm
@@ -82,7 +82,7 @@
living_target.log_message("injected themselves ([contained]) with [name]", LOG_ATTACK, color="orange")
else
log_combat(user, living_target, "injected", src, addition="which had [contained]")
- reagents.trans_to(target, amount_per_transfer_from_this, transfered_by = user, methods = INJECT)
+ reagents.trans_to(target, amount_per_transfer_from_this, transferred_by = user, methods = INJECT)
to_chat(user, span_notice("You inject [amount_per_transfer_from_this] units of the solution. The syringe now contains [reagents.total_volume] units."))
target.update_appearance()
@@ -117,7 +117,7 @@
to_chat(user, span_warning("You cannot directly remove reagents from [target]!"))
return SECONDARY_ATTACK_CONTINUE_CHAIN
- var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this, transfered_by = user) // transfer from, transfer to - who cares?
+ var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this, transferred_by = user) // transfer from, transfer to - who cares?
to_chat(user, span_notice("You fill [src] with [trans] units of the solution. It now contains [reagents.total_volume] units."))
target.update_appearance()
@@ -134,7 +134,7 @@
to_chat(victim, span_boldwarning("[src] injects you!"))
victim.apply_damage(5, BRUTE, BODY_ZONE_HEAD)
- reagents?.trans_to(victim, round(reagents.total_volume*(2/3)), transfered_by = user, methods = INJECT)
+ reagents?.trans_to(victim, round(reagents.total_volume*(2/3)), transferred_by = user, methods = INJECT)
return discover_after
diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm
index 60f79d3615b..ef48a50af21 100644
--- a/code/modules/reagents/reagent_dispenser.dm
+++ b/code/modules/reagents/reagent_dispenser.dm
@@ -1,3 +1,5 @@
+#define REAGENT_SPILL_DIVISOR 200
+
/obj/structure/reagent_dispensers
name = "Dispenser"
desc = "..."
@@ -206,6 +208,15 @@
return TRUE
return FALSE
+/obj/structure/reagent_dispensers/proc/knock_down()
+ var/datum/effect_system/fluid_spread/smoke/chem/smoke = new ()
+ var/range = reagents.total_volume / REAGENT_SPILL_DIVISOR
+ smoke.attach(drop_location())
+ smoke.set_up(round(range), holder = drop_location(), location = drop_location(), carry = reagents, silent = FALSE)
+ smoke.start(log = TRUE)
+ reagents.clear_reagents()
+ qdel(src)
+
/obj/structure/reagent_dispensers/wrench_act(mob/living/user, obj/item/tool)
. = ..()
if(!openable)
@@ -297,7 +308,7 @@
if(W.reagents.has_reagent(/datum/reagent/fuel, W.max_fuel))
to_chat(user, span_warning("Your [W.name] is already full!"))
return
- reagents.trans_to(W, W.max_fuel, transfered_by = user)
+ reagents.trans_to(W, W.max_fuel, transferred_by = user)
user.visible_message(span_notice("[user] refills [user.p_their()] [W.name]."), span_notice("You refill [W]."))
playsound(src, 'sound/effects/refill.ogg', 50, TRUE)
W.update_appearance()
@@ -341,6 +352,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/reagent_dispensers/wall/peppertank, 3
. = ..()
if(prob(1))
desc = "IT'S PEPPER TIME, BITCH!"
+ find_and_hang_on_wall()
/obj/structure/reagent_dispensers/water_cooler//SKYRAT EDIT - ICON OVERRIDEN BY AESTHETICS - SEE MODULE
name = "liquid cooler"
@@ -392,12 +404,16 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/reagent_dispensers/wall/peppertank, 3
MAPPING_DIRECTIONAL_HELPERS(/obj/structure/reagent_dispensers/wall/virusfood, 30)
+/obj/structure/reagent_dispensers/wall/virusfood/Initialize(mapload)
+ . = ..()
+ find_and_hang_on_wall()
+
/obj/structure/reagent_dispensers/cooking_oil
name = "vat of cooking oil"
desc = "A huge metal vat with a tap on the front. Filled with cooking oil for use in frying food."
icon_state = "vat"
anchored = TRUE
- reagent_id = /datum/reagent/consumable/cooking_oil
+ reagent_id = /datum/reagent/consumable/nutriment/fat/oil
openable = TRUE
/obj/structure/reagent_dispensers/servingdish
@@ -454,3 +470,5 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/reagent_dispensers/wall/virusfood, 30
desc = "A stationary, plumbed, fuel tank."
reagent_id = /datum/reagent/fuel
accepts_rig = TRUE
+
+#undef REAGENT_SPILL_DIVISOR
diff --git a/code/modules/recycling/conveyor.dm b/code/modules/recycling/conveyor.dm
index 84173388518..cb1a0800c51 100644
--- a/code/modules/recycling/conveyor.dm
+++ b/code/modules/recycling/conveyor.dm
@@ -42,6 +42,7 @@ GLOBAL_LIST_EMPTY(conveyors_by_id)
AddElement(/datum/element/footstep_override, priority = STEP_SOUND_CONVEYOR_PRIORITY)
var/static/list/give_turf_traits = list(TRAIT_TURF_IGNORE_SLOWDOWN)
AddElement(/datum/element/give_turf_traits, give_turf_traits)
+ register_context()
/obj/machinery/conveyor/examine(mob/user)
. = ..()
@@ -50,6 +51,20 @@ GLOBAL_LIST_EMPTY(conveyors_by_id)
. += "\nLeft-click with a wrench to rotate."
. += "Left-click with a screwdriver to invert its direction."
. += "Right-click with a screwdriver to flip its belt around."
+ . += "Using another conveyor belt assembly on this will place a new conveyor belt in the direction this one is pointing."
+
+/obj/machinery/conveyor/add_context(atom/source, list/context, obj/item/held_item, mob/user)
+ . = ..()
+ if(istype(held_item, /obj/item/stack/conveyor))
+ context[SCREENTIP_CONTEXT_LMB] = "Extend current conveyor belt"
+ return CONTEXTUAL_SCREENTIP_SET
+ if(held_item?.tool_behaviour == TOOL_WRENCH)
+ context[SCREENTIP_CONTEXT_LMB] = "Rotate conveyor belt"
+ return CONTEXTUAL_SCREENTIP_SET
+ if(held_item?.tool_behaviour == TOOL_SCREWDRIVER)
+ context[SCREENTIP_CONTEXT_LMB] = "Invert conveyor belt"
+ context[SCREENTIP_CONTEXT_RMB] = "Flip conveyor belt"
+ return CONTEXTUAL_SCREENTIP_SET
/obj/machinery/conveyor/centcom_auto
id = "round_end_belt"
@@ -282,6 +297,19 @@ GLOBAL_LIST_EMPTY(conveyors_by_id)
update_move_direction()
to_chat(user, span_notice("You set [src]'s direction [inverted ? "backwards" : "back to default"]."))
+ else if(istype(attacking_item, /obj/item/stack/conveyor))
+ // We should place a new conveyor belt machine on the output turf the conveyor is pointing to.
+ var/turf/target_turf = get_step(get_turf(src), forwards)
+ if(!target_turf)
+ return ..()
+ for(var/obj/machinery/conveyor/belt in target_turf)
+ to_chat(user, span_warning("You cannot place a conveyor belt on top of another conveyor belt."))
+ return ..()
+
+ var/obj/item/stack/conveyor/belt_item = attacking_item
+ belt_item.use(1)
+ new /obj/machinery/conveyor(target_turf, forwards, id)
+
else if(!user.combat_mode)
user.transferItemToLoc(attacking_item, drop_location())
else
@@ -534,6 +562,14 @@ GLOBAL_LIST_EMPTY(conveyors_by_id)
/obj/item/stack/conveyor/update_weight()
return FALSE
+/obj/item/stack/conveyor/examine(mob/user)
+ . = ..()
+ . += span_notice("Use a conveyor switch assembly on this before placing to connect to a lever.")
+
+/obj/item/stack/conveyor/use(used, transfer, check)
+ . = ..()
+ playsound(src, 'sound/weapons/genhit.ogg', 30, TRUE)
+
/obj/item/stack/conveyor/thirty
amount = 30
diff --git a/code/modules/recycling/disposal/multiz.dm b/code/modules/recycling/disposal/multiz.dm
index a4b914d66b8..06f4e52a31c 100644
--- a/code/modules/recycling/disposal/multiz.dm
+++ b/code/modules/recycling/disposal/multiz.dm
@@ -21,11 +21,11 @@
return ..()
//Are we a trunk that goes up? Or down?
- var/turf/target = null
+ var/turf/target = get_turf(src)
if(multiz_dir == MULTIZ_PIPE_UP)
- target = GET_TURF_ABOVE(get_turf(src))
+ target = GET_TURF_ABOVE(target)
if(multiz_dir == MULTIZ_PIPE_DOWN)
- target = GET_TURF_BELOW(get_turf(src))
+ target = GET_TURF_BELOW(target)
if(!target) //Nothing located.
return
diff --git a/code/modules/religion/festival/instrument_rites.dm b/code/modules/religion/festival/instrument_rites.dm
index 83b064a6398..a1c94c92425 100644
--- a/code/modules/religion/festival/instrument_rites.dm
+++ b/code/modules/religion/festival/instrument_rites.dm
@@ -90,7 +90,7 @@
/datum/religion_rites/song_tuner/pain/finish_effect(mob/living/carbon/human/listener, atom/song_source)
var/obj/item/bodypart/sliced_limb = pick(listener.bodyparts)
- sliced_limb.force_wound_upwards(/datum/wound/slash/moderate/many_cuts)
+ sliced_limb.force_wound_upwards(/datum/wound/slash/flesh/moderate/many_cuts)
/datum/religion_rites/song_tuner/lullaby
name = "Spiritual Lullaby"
diff --git a/code/modules/religion/religion_sects.dm b/code/modules/religion/religion_sects.dm
index 0a2486595b2..a322303b00d 100644
--- a/code/modules/religion/religion_sects.dm
+++ b/code/modules/religion/religion_sects.dm
@@ -58,6 +58,13 @@
to_chat(chap, "\"[quote]\"")
to_chat(chap, "[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)
+ SHOULD_CALL_PARENT(TRUE)
+ to_chat(chap, span_boldnotice("You have lost the approval of \the [name]."))
+ if(chap.mind.holy_role == HOLY_ROLE_HIGHPRIEST)
+ 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)
. = TRUE
@@ -292,6 +299,11 @@
return
new_convert.gain_trauma(/datum/brain_trauma/special/burdened, TRAUMA_RESILIENCE_MAGIC)
+/datum/religion_sect/burden/on_deconversion(mob/living/carbon/human/new_convert)
+ if (ishuman(new_convert))
+ new_convert.cure_trauma_type(/datum/brain_trauma/special/burdened, TRAUMA_RESILIENCE_MAGIC)
+ return ..()
+
/datum/religion_sect/burden/tool_examine(mob/living/carbon/human/burdened) //display burden level
if(!ishuman(burdened))
return FALSE
@@ -333,6 +345,11 @@
return FALSE
new_convert.gain_trauma(/datum/brain_trauma/special/honorbound, TRAUMA_RESILIENCE_MAGIC)
+/datum/religion_sect/honorbound/on_deconversion(mob/living/carbon/human/new_convert)
+ if (ishuman(new_convert))
+ new_convert.cure_trauma_type(/datum/brain_trauma/special/honorbound, TRAUMA_RESILIENCE_MAGIC)
+ return ..()
+
#define MINIMUM_YUCK_REQUIRED 5
/datum/religion_sect/maintenance
diff --git a/code/modules/religion/religion_structures.dm b/code/modules/religion/religion_structures.dm
index e9dcfffff48..ae61004b46e 100644
--- a/code/modules/religion/religion_structures.dm
+++ b/code/modules/religion/religion_structures.dm
@@ -61,7 +61,10 @@
. += list(span_notice("Chaplains: [chaplains]."))
/obj/structure/altar_of_gods/proc/reflect_sect_in_icons()
- if(GLOB.religious_sect)
+ if(isnull(GLOB.religious_sect))
+ icon = initial(icon)
+ icon_state = initial(icon_state)
+ else
sect_to_altar = GLOB.religious_sect
if(sect_to_altar.altar_icon)
icon = sect_to_altar.altar_icon
diff --git a/code/modules/religion/rites.dm b/code/modules/religion/rites.dm
index c7e38145349..d907191c33d 100644
--- a/code/modules/religion/rites.dm
+++ b/code/modules/religion/rites.dm
@@ -221,7 +221,7 @@
user.add_mood_event("maint_adaptation", /datum/mood_event/maintenance_adaptation)
if(iscarbon(user))
var/mob/living/carbon/vomitorium = user
- vomitorium.vomit()
+ vomitorium.vomit(VOMIT_CATEGORY_DEFAULT)
var/datum/dna/dna = vomitorium.has_dna()
dna?.add_mutation(/datum/mutation/human/stimmed) //some fluff mutations
dna?.add_mutation(/datum/mutation/human/strong)
diff --git a/code/modules/religion/sparring/sparring_datum.dm b/code/modules/religion/sparring/sparring_datum.dm
index f292293f90c..bfaa94d65a8 100644
--- a/code/modules/religion/sparring/sparring_datum.dm
+++ b/code/modules/religion/sparring/sparring_datum.dm
@@ -216,7 +216,7 @@
var/mob/living/carbon/human/branded = interfering
to_chat(interfering, span_warning("[GLOB.deity] brands your flesh for interfering with [chaplain]'s sparring match!!"))
var/obj/item/bodypart/branded_limb = pick(branded.bodyparts)
- branded_limb.force_wound_upwards(/datum/wound/burn/severe/brand, wound_source = "divine intervention")
+ branded_limb.force_wound_upwards(/datum/wound/burn/flesh/severe/brand, wound_source = "divine intervention")
branded.emote("scream")
flubs--
diff --git a/code/modules/research/designs/biogenerator_designs.dm b/code/modules/research/designs/biogenerator_designs.dm
index 9d3b442773e..f07ef21a8e7 100644
--- a/code/modules/research/designs/biogenerator_designs.dm
+++ b/code/modules/research/designs/biogenerator_designs.dm
@@ -3,7 +3,7 @@
///////////////////////////////////
/datum/design/milk
- name = "Milk"
+ name = "Synthetic Milk"
id = "milk"
build_type = BIOGENERATOR
materials = list(/datum/material/biomass = 0.4)
@@ -11,7 +11,7 @@
category = list(RND_CATEGORY_INITIAL, RND_CATEGORY_BIO_FOOD)
/datum/design/soymilk
- name = "Soy Milk"
+ name = "Synthetic Soy Milk"
id = "soymilk"
build_type = BIOGENERATOR
materials = list(/datum/material/biomass = 0.4)
@@ -19,7 +19,7 @@
category = list(RND_CATEGORY_INITIAL, RND_CATEGORY_BIO_FOOD)
/datum/design/ethanol
- name = "Ethanol"
+ name = "Synthetic Ethanol"
id = "ethanol"
build_type = BIOGENERATOR
materials = list(/datum/material/biomass = 0.6)
@@ -27,7 +27,7 @@
category = list(RND_CATEGORY_INITIAL, RND_CATEGORY_BIO_FOOD)
/datum/design/cream
- name = "Cream"
+ name = "Synthetic Cream"
id = "cream"
build_type = BIOGENERATOR
materials = list(/datum/material/biomass = 0.6)
@@ -35,7 +35,7 @@
category = list(RND_CATEGORY_INITIAL, RND_CATEGORY_BIO_FOOD)
/datum/design/black_pepper
- name = "Black Pepper"
+ name = "Synthetic Black Pepper"
id = "black_pepper"
build_type = BIOGENERATOR
materials = list(/datum/material/biomass = 0.6)
@@ -43,7 +43,7 @@
category = list(RND_CATEGORY_INITIAL, RND_CATEGORY_BIO_FOOD)
/datum/design/enzyme
- name = "Universal Enzyme"
+ name = "Synthetic Enzyme"
id = "enzyme"
build_type = BIOGENERATOR
materials = list(/datum/material/biomass = 0.6)
@@ -51,7 +51,7 @@
category = list(RND_CATEGORY_INITIAL, RND_CATEGORY_BIO_FOOD)
/datum/design/flour
- name = "Flour"
+ name = "Synthetic Flour"
id = "flour_sack"
build_type = BIOGENERATOR
materials = list(/datum/material/biomass = 0.6)
@@ -59,7 +59,7 @@
category = list(RND_CATEGORY_INITIAL, RND_CATEGORY_BIO_FOOD)
/datum/design/sugar
- name = "Sugar"
+ name = "Synthetic Sugar"
id = "sugar"
build_type = BIOGENERATOR
materials = list(/datum/material/biomass = 0.6)
@@ -70,7 +70,7 @@
name = "Monkey Cube"
id = "mcube"
build_type = BIOGENERATOR
- materials = list(/datum/material/biomass =SMALL_MATERIAL_AMOUNT*0.5)
+ materials = list(/datum/material/biomass = 50)
build_path = /obj/item/food/monkeycube
category = list(RND_CATEGORY_INITIAL, RND_CATEGORY_BIO_FOOD)
diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm
index 6597c12fbec..1c44e8bc4fb 100644
--- a/code/modules/research/designs/machine_designs.dm
+++ b/code/modules/research/designs/machine_designs.dm
@@ -51,6 +51,16 @@
)
departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING
+/datum/design/board/mass_driver
+ name = "Mass Driver Board"
+ desc = "The circuit board for a mass driver."
+ id = "mass_driver"
+ build_path = /obj/item/circuitboard/machine/mass_driver
+ category = list(
+ RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ENGINEERING
+ )
+ departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING
+
/datum/design/board/turbine_compressor
name = "Turbine Compressor Board"
desc = "The circuit board for a turbine compressor."
diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm
index 7d7c81fdfd4..c7f55fd02d5 100644
--- a/code/modules/research/designs/mechfabricator_designs.dm
+++ b/code/modules/research/designs/mechfabricator_designs.dm
@@ -1189,6 +1189,17 @@
RND_CATEGORY_MECHFAB_CYBORG_MODULES + RND_SUBCATEGORY_MECHFAB_CYBORG_MODULES_SERVICE
)
+/datum/design/borg_upgrade_drink_apparatus
+ name = "Drink Apparatus"
+ id = "borg_upgrade_drink_apparatus"
+ build_type = MECHFAB
+ build_path = /obj/item/borg/upgrade/drink_app
+ materials = list(/datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT, /datum/material/glass = SHEET_MATERIAL_AMOUNT)
+ construction_time = 4 SECONDS
+ category = list(
+ RND_CATEGORY_MECHFAB_CYBORG_MODULES + RND_SUBCATEGORY_MECHFAB_CYBORG_MODULES_SERVICE
+ )
+
/datum/design/borg_upgrade_service_apparatus
name = "Service Apparatus"
id = "borg_upgrade_service_apparatus"
diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm
index 8bf7723e4bb..2bb779e318b 100644
--- a/code/modules/research/designs/medical_designs.dm
+++ b/code/modules/research/designs/medical_designs.dm
@@ -335,6 +335,30 @@
)
departmental_flags = DEPARTMENT_BITFLAG_MEDICAL
+/datum/design/medical_bed
+ name = "Medical Bed"
+ desc = "A bed made of sterile materials ideal for use in the medical field. Patient assistance or joyriding, it'll do it all!"
+ id = "medicalbed"
+ build_type = PROTOLATHE | AWAY_LATHE
+ materials = list(/datum/material/titanium = SHEET_MATERIAL_AMOUNT * 2.7, /datum/material/plastic = SHEET_MATERIAL_AMOUNT * 1.7)
+ build_path = /obj/structure/bed/medical
+ category = list(
+ RND_CATEGORY_EQUIPMENT + RND_SUBCATEGORY_EQUIPMENT_MEDICAL
+ )
+ departmental_flags = DEPARTMENT_BITFLAG_MEDICAL
+
+/datum/design/emergency_bed
+ name = "Medical Bed (Emergency)"
+ desc = "A portable, foldable version of the medical bed. Perfect for paramedics or whenever you have mass casualties!"
+ id = "medicalbed_emergency"
+ build_type = PROTOLATHE | AWAY_LATHE
+ materials = list(/datum/material/titanium = SHEET_MATERIAL_AMOUNT * 2.7, /datum/material/plastic = SHEET_MATERIAL_AMOUNT * 1.7, /datum/material/diamond = SMALL_MATERIAL_AMOUNT * 5, /datum/material/bluespace = SMALL_MATERIAL_AMOUNT * 5)
+ build_path = /obj/item/emergency_bed
+ category = list(
+ RND_CATEGORY_EQUIPMENT + RND_SUBCATEGORY_EQUIPMENT_MEDICAL
+ )
+ departmental_flags = DEPARTMENT_BITFLAG_MEDICAL
+
/////////////////////////////////////////
//////////Cybernetic Implants////////////
/////////////////////////////////////////
@@ -1089,3 +1113,10 @@
id = "surgery_wing_reconstruction"
surgery = /datum/surgery/advanced/wing_reconstruction
research_icon_state = "surgery_chest"
+
+/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."
+ id = "surgery_oldstation_dissection"
+ surgery = /datum/surgery/advanced/experimental_dissection
+ research_icon_state = "surgery_chest"
diff --git a/code/modules/research/designs/tool_designs.dm b/code/modules/research/designs/tool_designs.dm
index ed617fb9ac1..ee1e09b1143 100644
--- a/code/modules/research/designs/tool_designs.dm
+++ b/code/modules/research/designs/tool_designs.dm
@@ -39,7 +39,6 @@
departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING
autolathe_exportable = FALSE
-/* SKYRAT EDIT - MOVED TO modular_skyrat/modules/electric_welder/code/electric_welder.dm
/datum/design/exwelder
name = "Experimental Welding Tool"
desc = "An experimental welder capable of self-fuel generation."
@@ -51,7 +50,6 @@
RND_CATEGORY_TOOLS + RND_SUBCATEGORY_TOOLS_ENGINEERING_ADVANCED
)
departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING
-*/
/datum/design/rangedanalyzer
name = "Experimental Long-range Gas Analyzer"
diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm
index 46952ab0362..6a090693ffd 100644
--- a/code/modules/research/experimentor.dm
+++ b/code/modules/research/experimentor.dm
@@ -168,11 +168,12 @@
for(var/node_id in listin)
var/datum/techweb_node/N = SSresearch.techweb_node_by_id(node_id)
var/str = "[N.display_name]: [listin[N]] points."
- if(SSresearch.science_tech.researched_nodes[N.id])
+ var/datum/techweb/science_web = locate(/datum/techweb/science) in SSresearch.techwebs
+ if(science_web.researched_nodes[N.id])
res += str
- else if(SSresearch.science_tech.boosted_nodes[N.id])
+ else if(science_web.boosted_nodes[N.id])
boosted += str
- if(SSresearch.science_tech.visible_nodes[N.id]) //JOY OF DISCOVERY!
+ if(science_web.visible_nodes[N.id]) //JOY OF DISCOVERY!
output += str
output += boosted + res
dat += output
diff --git a/code/modules/research/machinery/_production.dm b/code/modules/research/machinery/_production.dm
index f7781d7c8c0..882861b651d 100644
--- a/code/modules/research/machinery/_production.dm
+++ b/code/modules/research/machinery/_production.dm
@@ -46,22 +46,22 @@
)
create_reagents(0, OPENCONTAINER)
- if(stored_research)
- update_designs()
RefreshParts()
update_icon(UPDATE_OVERLAYS)
/obj/machinery/rnd/production/connect_techweb(datum/techweb/new_techweb)
if(stored_research)
UnregisterSignal(stored_research, list(COMSIG_TECHWEB_ADD_DESIGN, COMSIG_TECHWEB_REMOVE_DESIGN))
+ return ..()
+/obj/machinery/rnd/production/on_connected_techweb()
. = ..()
-
RegisterSignals(
stored_research,
list(COMSIG_TECHWEB_ADD_DESIGN, COMSIG_TECHWEB_REMOVE_DESIGN),
PROC_REF(on_techweb_update)
)
+ update_designs()
/obj/machinery/rnd/production/Destroy()
materials = null
diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm
index 10fdb6fe211..fdfcf9bf72d 100644
--- a/code/modules/research/rdconsole.dm
+++ b/code/modules/research/rdconsole.dm
@@ -45,10 +45,10 @@ Nothing else in the console has ID requirements.
return reagent.name
return ID
-/obj/machinery/computer/rdconsole/Initialize(mapload)
+/obj/machinery/computer/rdconsole/LateInitialize()
. = ..()
if(!CONFIG_GET(flag/no_default_techweb_link) && !stored_research)
- stored_research = SSresearch.science_tech
+ CONNECT_TO_RND_SERVER_ROUNDSTART(stored_research, src)
if(stored_research)
stored_research.consoles_accessing += src
@@ -107,7 +107,7 @@ Nothing else in the console has ID requirements.
var/list/price = TN.get_price(stored_research)
if(stored_research.can_afford(price))
user.investigate_log("researched [id]([json_encode(price)]) on techweb id [stored_research.id].", INVESTIGATE_RESEARCH)
- if(stored_research == SSresearch.science_tech)
+ if(istype(stored_research, /datum/techweb/science))
SSblackbox.record_feedback("associative", "science_techweb_unlock", 1, list("id" = "[id]", "name" = TN.display_name, "price" = "[json_encode(price)]", "time" = SQLtime()))
if(stored_research.research_node_id(id))
say("Successfully researched [TN.display_name].")
diff --git a/code/modules/research/rdmachines.dm b/code/modules/research/rdmachines.dm
index bb19fb34817..3047c3e1a9a 100644
--- a/code/modules/research/rdmachines.dm
+++ b/code/modules/research/rdmachines.dm
@@ -20,10 +20,15 @@
/obj/machinery/rnd/Initialize(mapload)
. = ..()
- if(!CONFIG_GET(flag/no_default_techweb_link) && !stored_research)
- connect_techweb(SSresearch.science_tech)
set_wires(new /datum/wires/rnd(src))
+/obj/machinery/rnd/LateInitialize()
+ . = ..()
+ if(!CONFIG_GET(flag/no_default_techweb_link) && !stored_research)
+ CONNECT_TO_RND_SERVER_ROUNDSTART(stored_research, src)
+ if(stored_research)
+ on_connected_techweb()
+
/obj/machinery/rnd/Destroy()
if(stored_research)
log_research("[src] disconnected from techweb [stored_research] (destroyed).")
@@ -31,10 +36,17 @@
QDEL_NULL(wires)
return ..()
+///Called when attempting to connect the machine to a techweb, forgetting the old.
/obj/machinery/rnd/proc/connect_techweb(datum/techweb/new_techweb)
if(stored_research)
log_research("[src] disconnected from techweb [stored_research] when connected to [new_techweb].")
stored_research = new_techweb
+ if(!isnull(stored_research))
+ on_connected_techweb()
+
+///Called post-connection to a new techweb.
+/obj/machinery/rnd/proc/on_connected_techweb()
+ SHOULD_CALL_PARENT(FALSE)
/obj/machinery/rnd/proc/shock(mob/user, prb)
if(machine_stat & (BROKEN|NOPOWER)) // unpowered, no shock
diff --git a/code/modules/research/research_disk.dm b/code/modules/research/research_disk.dm
index 8205fc230c4..43fcd208fcb 100644
--- a/code/modules/research/research_disk.dm
+++ b/code/modules/research/research_disk.dm
@@ -19,5 +19,5 @@
custom_materials = null
/obj/item/disk/tech_disk/debug/Initialize(mapload)
- stored_research = SSresearch.admin_tech
+ stored_research = locate(/datum/techweb/admin) in SSresearch.techwebs
return ..()
diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm
index 7665082f698..45a0a520fa0 100644
--- a/code/modules/research/server.dm
+++ b/code/modules/research/server.dm
@@ -27,8 +27,14 @@
/obj/machinery/rnd/server/Initialize(mapload)
. = ..()
- if(CONFIG_GET(flag/no_default_techweb_link) && !stored_research)
- stored_research = new /datum/techweb
+ //servers handle techwebs differently as we are expected to be there to connect
+ //every other machinery on-station.
+ if(!stored_research)
+ if(CONFIG_GET(flag/no_default_techweb_link))
+ stored_research = new /datum/techweb
+ else
+ var/datum/techweb/science_web = locate(/datum/techweb/science) in SSresearch.techwebs
+ connect_techweb(science_web)
stored_research.techweb_servers |= src
name += " [num2hex(rand(1,65535), -1)]" //gives us a random four-digit hex number as part of the name. Y'know, for fluff.
@@ -103,7 +109,7 @@
if(!stored_research)
return
tool.set_buffer(stored_research)
- to_chat(user, span_notice("Stored [src]'s techweb information in [tool]."))
+ balloon_alert(user, "saved to multitool buffer")
return TRUE
/// Master R&D server. As long as this still exists and still holds the HDD for the theft objective, research points generate at normal speed. Destroy it or an antag steals the HDD? Half research speed.
diff --git a/code/modules/research/server_control.dm b/code/modules/research/server_control.dm
index da6cb322be8..94a429dc6d7 100644
--- a/code/modules/research/server_control.dm
+++ b/code/modules/research/server_control.dm
@@ -9,10 +9,10 @@
///Connected techweb node the server is connected to.
var/datum/techweb/stored_research
-/obj/machinery/computer/rdservercontrol/Initialize(mapload, obj/item/circuitboard/C)
+/obj/machinery/computer/rdservercontrol/LateInitialize()
. = ..()
if(!CONFIG_GET(flag/no_default_techweb_link) && !stored_research)
- stored_research = SSresearch.science_tech
+ CONNECT_TO_RND_SERVER_ROUNDSTART(stored_research, src)
/obj/machinery/computer/rdservercontrol/multitool_act(mob/living/user, obj/item/multitool/tool)
if(!QDELETED(tool.buffer) && istype(tool.buffer, /datum/techweb))
diff --git a/code/modules/research/stock_parts.dm b/code/modules/research/stock_parts.dm
index 3dffdceb87a..ee9a88b629d 100644
--- a/code/modules/research/stock_parts.dm
+++ b/code/modules/research/stock_parts.dm
@@ -100,23 +100,21 @@ If you create T5+ please take a pass at mech_fabricator.dm. The parts being good
*/
/obj/item/storage/part_replacer/bluespace/proc/on_part_entered(datum/source, obj/item/inserted_component)
SIGNAL_HANDLER
+
+ if(istype(inserted_component, /obj/item/stock_parts/cell))
+ var/obj/item/stock_parts/cell/inserted_cell = inserted_component
+ if(inserted_cell.rigged || inserted_cell.corrupted)
+ message_admins("[ADMIN_LOOKUPFLW(usr)] has inserted rigged/corrupted [inserted_cell] into [src].")
+ usr.log_message("has inserted rigged/corrupted [inserted_cell] into [src].", LOG_GAME)
+ usr.log_message("inserted rigged/corrupted [inserted_cell] into [src]", LOG_ATTACK)
+ return
+
if(inserted_component.reagents)
if(length(inserted_component.reagents.reagent_list))
inserted_component.reagents.clear_reagents()
to_chat(usr, span_notice("[src] churns as [inserted_component] has its reagents emptied into bluespace."))
RegisterSignal(inserted_component.reagents, COMSIG_REAGENTS_PRE_ADD_REAGENT, PROC_REF(on_insered_component_reagent_pre_add))
-
- if(!istype(inserted_component, /obj/item/stock_parts/cell))
- return
-
- var/obj/item/stock_parts/cell/inserted_cell = inserted_component
-
- if(inserted_cell.rigged || inserted_cell.corrupted)
- message_admins("[ADMIN_LOOKUPFLW(usr)] has inserted rigged/corrupted [inserted_cell] into [src].")
- usr.log_message("has inserted rigged/corrupted [inserted_cell] into [src].", LOG_GAME)
- usr.log_message("inserted rigged/corrupted [inserted_cell] into [src]", LOG_ATTACK)
-
/**
* Signal handler for when the reagents datum of an inserted part has reagents added to it.
*
diff --git a/code/modules/research/techweb/_techweb.dm b/code/modules/research/techweb/_techweb.dm
index 1ffae0a48dd..521504da351 100644
--- a/code/modules/research/techweb/_techweb.dm
+++ b/code/modules/research/techweb/_techweb.dm
@@ -216,7 +216,8 @@
else
researched_designs[design.id] = TRUE
- hidden_nodes -= design.id
+ for(var/list/datum/techweb_node/unlocked_nodes as anything in design.unlocked_by)
+ hidden_nodes -= unlocked_nodes
return TRUE
diff --git a/code/modules/research/techweb/_techweb_node.dm b/code/modules/research/techweb/_techweb_node.dm
index 6ab7d68beba..2f01252548a 100644
--- a/code/modules/research/techweb/_techweb_node.dm
+++ b/code/modules/research/techweb/_techweb_node.dm
@@ -88,11 +88,12 @@
if(actual_costs[booster])
var/delta = max(0, actual_costs[booster] - 250)
actual_costs[booster] -= min(boostlist[booster], delta)
-
+
return actual_costs
/datum/techweb_node/proc/price_display(datum/techweb/TN)
return techweb_point_display_generic(get_price(TN))
-/datum/techweb_node/proc/on_research() //new proc, not currently in file
- return
+///Proc called when the Station (Science techweb specific) researches a node.
+/datum/techweb_node/proc/on_station_research()
+ SHOULD_CALL_PARENT(FALSE)
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index 2b61bb2e092..570b8af271c 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -279,6 +279,7 @@
"dropper",
"hemostat",
"large_beaker",
+ "medicalbed",
"mmi_m",
"operating",
"petri_dish",
@@ -502,6 +503,16 @@
)
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000)
+/datum/techweb_node/oldstation_surgery
+ id = "oldstation_surgery"
+ display_name = "Experimental Dissection"
+ description = "Grants access to experimental dissections, which allows generation of research points."
+ design_ids = list(
+ "surgery_oldstation_dissection",
+ )
+ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 500)
+ hidden = TRUE
+ show_on_wiki = FALSE
/datum/techweb_node/adv_surgery
id = "adv_surgery"
@@ -589,6 +600,7 @@
"emergency_oxygen_engi",
"emergency_oxygen",
"emitter",
+ "mass_driver",
"firealarm_electronics",
"firelock_board",
"generic_tank",
@@ -735,6 +747,7 @@
design_ids = list(
"bluespace_matter_bin",
"bluespacebodybag",
+ "medicalbed_emergency",
"femto_servo",
"quantum_keycard",
"swapper",
@@ -971,6 +984,7 @@
"borg_upgrade_condiment_synthesizer",
"borg_upgrade_silicon_knife",
"borg_upgrade_service_apparatus",
+ "borg_upgrade_drink_apparatus",
"borg_upgrade_service_cookbook",
)
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2000)
@@ -1218,6 +1232,8 @@
design_ids = list(
"comm_monitor",
"comm_server",
+ "gigabeacon",
+ "message_monitor",
"ntnet_relay",
"s_amplifier",
"s_analyzer",
@@ -1234,7 +1250,6 @@
"s_server",
"s_transmitter",
"s_treatment",
- "gigabeacon",
)
/datum/techweb_node/integrated_hud
@@ -2129,8 +2144,8 @@
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
hidden = TRUE
-/datum/techweb_node/alientech/on_research() //Unlocks the Zeta shuttle for purchase
- SSshuttle.shuttle_purchase_requirements_met[SHUTTLE_UNLOCK_ALIENTECH] = TRUE
+/datum/techweb_node/alientech/on_station_research()
+ SSshuttle.shuttle_purchase_requirements_met[SHUTTLE_UNLOCK_ALIENTECH] = TRUE
/datum/techweb_node/alien_bio
id = "alien_bio"
diff --git a/code/modules/research/techweb/techweb_types.dm b/code/modules/research/techweb/techweb_types.dm
index fef8e51b09d..c01b1226a4c 100644
--- a/code/modules/research/techweb/techweb_types.dm
+++ b/code/modules/research/techweb/techweb_types.dm
@@ -6,19 +6,26 @@
organization = "Nanotrasen"
should_generate_points = TRUE
-
-//When something is researched, triggers the proc for this techweb only
/datum/techweb/science/research_node(datum/techweb_node/node, force = FALSE, auto_adjust_cost = TRUE, get_that_dosh = TRUE)
. = ..()
if(.)
- node.on_research()
+ node.on_station_research()
+
+/datum/techweb/oldstation
+ id = "CHARLIE"
+ organization = "Nanotrasen"
+ should_generate_points = TRUE
+
+/datum/techweb/oldstation/New()
+ . = ..()
+ research_node_id("oldstation_surgery", TRUE, TRUE, FALSE)
/**
* Admin techweb that has everything unlocked by default
*/
/datum/techweb/admin
id = "ADMIN"
- organization = "CentCom"
+ organization = "Central Command"
/datum/techweb/admin/New()
. = ..()
diff --git a/code/modules/research/xenobiology/crossbreeding/__corecross.dm b/code/modules/research/xenobiology/crossbreeding/__corecross.dm
index 7d24c7103dc..b83a0a5b7f4 100644
--- a/code/modules/research/xenobiology/crossbreeding/__corecross.dm
+++ b/code/modules/research/xenobiology/crossbreeding/__corecross.dm
@@ -152,7 +152,7 @@ To add a crossbreed:
to_chat(user, span_warning("This can only be used on yourself."))
return
if(reagents.total_volume && (ignore_flags || M.try_inject(user, injection_flags = INJECT_TRY_SHOW_ERROR_MESSAGE)))
- reagents.trans_to(M, reagents.total_volume, transfered_by = user)
+ reagents.trans_to(M, reagents.total_volume, transferred_by = user)
if(user != M)
to_chat(M, span_warning("[user] presses [src] against you!"))
to_chat(user, span_notice("You press [src] against [M], injecting [M.p_them()]."))
diff --git a/code/modules/research/xenobiology/crossbreeding/_misc.dm b/code/modules/research/xenobiology/crossbreeding/_misc.dm
index 8fc4d50a98c..8eb166bf820 100644
--- a/code/modules/research/xenobiology/crossbreeding/_misc.dm
+++ b/code/modules/research/xenobiology/crossbreeding/_misc.dm
@@ -209,9 +209,13 @@ Slimecrossing Items
else
to_chat(user, span_warning("The device is empty..."))
-/obj/item/capturedevice/proc/store(mob/living/M)
- M.forceMove(src)
+/obj/item/capturedevice/proc/store(mob/living/pokemon)
+ pokemon.forceMove(src)
+ pokemon.add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), ABSTRACT_ITEM_TRAIT)
+ pokemon.cancel_camera()
/obj/item/capturedevice/proc/release()
- for(var/atom/movable/M in contents)
- M.forceMove(get_turf(loc))
+ for(var/mob/living/pokemon in contents)
+ pokemon.forceMove(get_turf(loc))
+ pokemon.remove_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), ABSTRACT_ITEM_TRAIT)
+ pokemon.cancel_camera()
diff --git a/code/modules/research/xenobiology/crossbreeding/_weapons.dm b/code/modules/research/xenobiology/crossbreeding/_weapons.dm
index a7287055794..61f4e7a72e0 100644
--- a/code/modules/research/xenobiology/crossbreeding/_weapons.dm
+++ b/code/modules/research/xenobiology/crossbreeding/_weapons.dm
@@ -96,6 +96,7 @@ Slimecrossing Weapons
item_flags = ABSTRACT | DROPDEL
w_class = WEIGHT_CLASS_HUGE
slot_flags = NONE
+ antimagic_flags = NONE
force = 5
max_charges = 1 //Recharging costs blood.
recharge_rate = 1
diff --git a/code/modules/research/xenobiology/crossbreeding/charged.dm b/code/modules/research/xenobiology/crossbreeding/charged.dm
index cb7070c83a4..8941057453b 100644
--- a/code/modules/research/xenobiology/crossbreeding/charged.dm
+++ b/code/modules/research/xenobiology/crossbreeding/charged.dm
@@ -235,21 +235,23 @@ Charged extracts:
effect_desc = "Randomizes the user's species."
/obj/item/slimecross/charged/black/do_effect(mob/user)
- var/mob/living/carbon/human/H = user
- if(!istype(H))
- to_chat(user, span_warning("You have to be able to have a species to get your species changed."))
+ var/mob/living/carbon/human/experiment_subject = user
+ if(!istype(experiment_subject))
+ balloon_alert(experiment_subject, "incompatible biology!")
return
var/list/allowed_species = list()
for(var/stype in subtypesof(/datum/species))
- var/datum/species/X = stype
- if(initial(X.changesource_flags) & SLIME_EXTRACT)
+ var/datum/species/try_species = stype
+ if(initial(try_species.changesource_flags) & SLIME_EXTRACT)
allowed_species += stype
var/datum/species/changed = pick(allowed_species)
- if(changed)
- H.set_species(changed, icon_update = 1)
- to_chat(H, span_danger("You feel very different!"))
- ..()
+ if(isnull(changed))
+ visible_message(span_notice("[src] fizzes uselessly."))
+ return
+ experiment_subject.set_species(changed, icon_update = TRUE)
+ to_chat(experiment_subject, span_danger("You feel very different!"))
+ return ..()
/obj/item/slimecross/charged/lightpink
colour = SLIME_TYPE_LIGHT_PINK
diff --git a/code/modules/research/xenobiology/crossbreeding/consuming.dm b/code/modules/research/xenobiology/crossbreeding/consuming.dm
index 43bfd2dbe8a..007bacf8bb7 100644
--- a/code/modules/research/xenobiology/crossbreeding/consuming.dm
+++ b/code/modules/research/xenobiology/crossbreeding/consuming.dm
@@ -355,7 +355,7 @@ Consuming extracts:
/obj/item/slime_cookie/green/do_effect(mob/living/M, mob/user)
if(ishuman(M))
var/mob/living/carbon/human/H = M
- H.vomit(25)
+ H.vomit(VOMIT_CATEGORY_DEFAULT, lost_nutrition = 25)
M.reagents.remove_all()
/obj/item/slimecross/consuming/pink
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 1210e5527eb..abb764d0689 100644
--- a/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm
+++ b/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm
@@ -10,11 +10,10 @@
supplementary_reagents = list(
/datum/reagent/growthserum = 2,
/datum/reagent/consumable/liquidgibs = 2,
- /datum/reagent/consumable/cornoil = 2,
/datum/reagent/consumable/nutriment = 1,
/datum/reagent/consumable/nutriment/vitamin = 1,
/datum/reagent/consumable/sugar = 1,
- /datum/reagent/consumable/cooking_oil = 1,
+ /datum/reagent/consumable/nutriment/fat/oil = 2,
/datum/reagent/consumable/rice = 1,
/datum/reagent/consumable/eggyolk = 1)
@@ -176,9 +175,8 @@
/datum/reagent/consumable/nutriment)
supplementary_reagents = list(
- /datum/reagent/consumable/cornoil = 4, //Carp are oily fish
+ /datum/reagent/consumable/nutriment/fat/oil = 4, //Carp are oily fish
/datum/reagent/toxin/carpotoxin = 3,
- /datum/reagent/consumable/cooking_oil = 2,
/datum/reagent/consumable/nutriment/vitamin = 2)
suppressive_reagents = list(
@@ -197,10 +195,9 @@
/datum/reagent/consumable/nutriment)
supplementary_reagents = list(
- /datum/reagent/consumable/cornoil = 4,
+ /datum/reagent/consumable/nutriment/fat/oil = 4,
/datum/reagent/growthserum = 3,
/datum/reagent/toxin/carpotoxin = 2,
- /datum/reagent/consumable/cooking_oil = 2,
/datum/reagent/consumable/nutriment/vitamin = 2)
suppressive_reagents = list(
@@ -484,7 +481,7 @@
/datum/micro_organism/cell_line/clown/fuck_up_growing(obj/machinery/plumbing/growing_vat/vat)
vat.visible_message(span_warning("The biological sample in [vat] seems to have created something horrific!"))
- var/mob/selected_mob = pick(list(/mob/living/simple_animal/hostile/retaliate/clown/mutant/slow, /mob/living/simple_animal/hostile/retaliate/clown/fleshclown))
+ var/mob/selected_mob = pick(list(/mob/living/basic/clown/mutant/slow, /mob/living/basic/clown/fleshclown))
new selected_mob(get_turf(vat))
if(SEND_SIGNAL(vat.biological_sample, COMSIG_SAMPLE_GROWTH_COMPLETED) & SPARE_SAMPLE)
@@ -512,7 +509,7 @@
/datum/reagent/consumable/nothing = -2,
/datum/reagent/fuel/oil = -1)
- resulting_atoms = list(/mob/living/simple_animal/hostile/retaliate/clown/banana = 1)
+ resulting_atoms = list(/mob/living/basic/clown/banana = 1)
/datum/micro_organism/cell_line/clown/glutton
desc = "hyperadipogenic clown stem cells"
@@ -526,8 +523,7 @@
/datum/reagent/consumable/vanillapudding = 8,
/datum/reagent/growthserum = 6,
/datum/reagent/consumable/nutriment/peptides = 4,
- /datum/reagent/consumable/cornoil = 3,
- /datum/reagent/consumable/cooking_oil = 1,
+ /datum/reagent/consumable/nutriment/fat/oil = 3,
/datum/reagent/consumable/space_cola = 1)
suppressive_reagents = list(
@@ -539,7 +535,7 @@
/datum/reagent/consumable/nothing = -2,
/datum/reagent/toxin/bad_food = -1)
- resulting_atoms = list(/mob/living/simple_animal/hostile/retaliate/clown/mutant/glutton = 1)
+ resulting_atoms = list(/mob/living/basic/clown/mutant/glutton = 1)
/datum/micro_organism/cell_line/clown/longclown
desc = "long clown bits"
@@ -562,7 +558,7 @@
/datum/reagent/consumable/nothing = -2,
/datum/reagent/sulfur = -1)
- resulting_atoms = list(/mob/living/simple_animal/hostile/retaliate/clown/longface = 1)
+ resulting_atoms = list(/mob/living/basic/clown/longface = 1)
/datum/micro_organism/cell_line/frog
desc = "anura amphibian cells"
diff --git a/code/modules/security_levels/security_level_datums.dm b/code/modules/security_levels/security_level_datums.dm
index ea78000ab09..175b79d1c87 100644
--- a/code/modules/security_levels/security_level_datums.dm
+++ b/code/modules/security_levels/security_level_datums.dm
@@ -45,7 +45,7 @@
sound = 'sound/misc/notice2.ogg' // Friendly beep
number_level = SEC_LEVEL_GREEN
lowering_to_configuration_key = /datum/config_entry/string/alert_green
- shuttle_call_time_mod = 2
+ shuttle_call_time_mod = ALERT_COEFF_GREEN
/**
* BLUE
@@ -58,7 +58,7 @@
number_level = SEC_LEVEL_BLUE
lowering_to_configuration_key = /datum/config_entry/string/alert_blue_downto
elevating_to_configuration_key = /datum/config_entry/string/alert_blue_upto
- shuttle_call_time_mod = 1
+ shuttle_call_time_mod = ALERT_COEFF_BLUE
/**
* RED
@@ -67,11 +67,11 @@
*/
/datum/security_level/red
name = "red"
- sound = 'sound/misc/notice1.ogg' // The same angry alarm
+ sound = 'sound/misc/notice3.ogg' // More angry alarm
number_level = SEC_LEVEL_RED
lowering_to_configuration_key = /datum/config_entry/string/alert_red_downto
elevating_to_configuration_key = /datum/config_entry/string/alert_red_upto
- shuttle_call_time_mod = 0.5
+ shuttle_call_time_mod = ALERT_COEFF_RED
/**
* DELTA
@@ -80,7 +80,7 @@
*/
/datum/security_level/delta
name = "delta"
- sound = 'sound/misc/notice1.ogg' // The same angry alarm, again
+ sound = 'sound/misc/airraid.ogg' // Air alarm to signify importance
number_level = SEC_LEVEL_DELTA
elevating_to_configuration_key = /datum/config_entry/string/alert_delta
- shuttle_call_time_mod = 0.25
+ shuttle_call_time_mod = ALERT_COEFF_DELTA
diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm
index 8569e8fd350..ab2be975307 100644
--- a/code/modules/shuttle/emergency.dm
+++ b/code/modules/shuttle/emergency.dm
@@ -339,15 +339,9 @@
/obj/docking_port/mobile/emergency/request(obj/docking_port/stationary/S, area/signal_origin, reason, red_alert, set_coefficient=null, silent=FALSE) //SKYRAT EDIT CHANGE - AUTOTRANSFER
if(!isnum(set_coefficient))
- var/security_num = SSsecurity_level.get_current_level_as_number()
- switch(security_num)
- if(SEC_LEVEL_GREEN)
- set_coefficient = 2
- if(SEC_LEVEL_BLUE)
- set_coefficient = 1
- else
- set_coefficient = 0.5
- var/call_time = SSshuttle.emergency_call_time * set_coefficient * engine_coeff
+ set_coefficient = SSsecurity_level.current_security_level.shuttle_call_time_mod
+ alert_coeff = set_coefficient
+ var/call_time = SSshuttle.emergency_call_time * alert_coeff * engine_coeff
switch(mode)
// The shuttle can not normally be called while "recalling", so
// if this proc is called, it's via admin fiat
@@ -576,7 +570,7 @@
destination_dock = "emergency_syndicate"
minor_announce("Corruption detected in \
shuttle navigation protocols. Please contact your \
- supervisor.", "SYSTEM ERROR:", alert=TRUE)
+ supervisor.", "SYSTEM ERROR:", sound_override = 'sound/misc/announce_syndi.ogg')
dock_id(destination_dock)
unbolt_all_doors() //SKYRAT EDIT ADDITION
diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm
index e2966e6bc9e..4ae1c241d06 100644
--- a/code/modules/shuttle/shuttle.dm
+++ b/code/modules/shuttle/shuttle.dm
@@ -382,8 +382,17 @@
/// This should be a unit test, but too much of our other code breaks during shuttle movement, so not yet, not yet.
/proc/test_whiteship_sizes()
var/obj/docking_port/stationary/port_type = /obj/docking_port/stationary/picked/whiteship
- var/datum/turf_reservation/docking_yard = SSmapping.RequestBlockReservation(initial(port_type.width), initial(port_type.height))
- var/turf/spawnpoint = locate(docking_yard.bottom_left_coords[1] + initial(port_type.dwidth), docking_yard.bottom_left_coords[2] + initial(port_type.dheight), docking_yard.bottom_left_coords[3])
+ var/datum/turf_reservation/docking_yard = SSmapping.request_turf_block_reservation(
+ initial(port_type.width),
+ initial(port_type.height),
+ 1,
+ )
+ var/turf/bottom_left = docking_yard.bottom_left_turfs[1]
+ var/turf/spawnpoint = locate(
+ bottom_left.x + initial(port_type.dwidth),
+ bottom_left.y + initial(port_type.dheight),
+ bottom_left.z,
+ )
var/obj/docking_port/stationary/picked/whiteship/port = new(spawnpoint)
var/list/ids = port.shuttlekeys
@@ -439,7 +448,8 @@
var/current_engine_power = 0
///How much engine power (thrust) the shuttle starts with at mapload.
var/initial_engine_power = 0
-
+ ///Speed multiplier based on station alert level
+ var/alert_coeff = ALERT_COEFF_BLUE
///used as a timer (if you want time left to complete move, use timeLeft proc)
var/timer
var/last_timer_length
@@ -798,7 +808,7 @@
if(sunset_mobs.mind && !istype(get_area(sunset_mobs), /area/shuttle/escape/brig))
sunset_mobs.mind.force_escaped = TRUE
// Ghostize them and put them in nullspace stasis (for stat & possession checks)
- sunset_mobs.notransform = TRUE
+ ADD_TRAIT(sunset_mobs, TRAIT_NO_TRANSFORM, REF(src))
sunset_mobs.ghostize(FALSE)
sunset_mobs.moveToNullspace()
@@ -943,6 +953,20 @@
last_timer_length *= multiple
setTimer(time_remaining)
+/obj/docking_port/mobile/proc/alert_coeff_change(new_coeff)
+ if(isnull(new_coeff))
+ return
+
+ var/time_multiplier = new_coeff / alert_coeff
+ var/time_remaining = timer - world.time
+ if(time_remaining < 0 || !last_timer_length)
+ return
+
+ time_remaining *= time_multiplier
+ last_timer_length *= time_multiplier
+ alert_coeff = new_coeff
+ setTimer(time_remaining)
+
/obj/docking_port/mobile/proc/invertTimer()
if(!last_timer_length)
return
diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm
index 7d1e6d818ac..aba37b37a55 100644
--- a/code/modules/shuttle/supply.dm
+++ b/code/modules/shuttle/supply.dm
@@ -25,6 +25,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
/obj/item/swapper,
/obj/docking_port,
/obj/machinery/launchpad,
+ /obj/machinery/exodrone_launcher,
/obj/machinery/disposal,
/obj/structure/disposalpipe,
/obj/item/mail,
@@ -186,12 +187,22 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
if(buying_account_orders.len > GOODY_FREE_SHIPPING_MAX) // no free shipping, send a crate
var/obj/structure/closet/crate/secure/owned/our_crate = new /obj/structure/closet/crate/secure/owned(pick_n_take(empty_turfs))
our_crate.buyer_account = buying_account
+ /// SKYRAT EDIT ADDITION START - FIXES COMMAND BUDGET CASES BEING UNOPENABLE
+ if(istype(our_crate.buyer_account, /datum/bank_account/department))
+ our_crate.department_purchase = TRUE
+ our_crate.department_account = our_crate.buyer_account
+ /// SKYRAT EDIT ADDITION END
our_crate.name = "goody crate - purchased by [buyer]"
miscboxes[buyer] = our_crate
else //free shipping in a case
miscboxes[buyer] = new /obj/item/storage/lockbox/order(pick_n_take(empty_turfs))
var/obj/item/storage/lockbox/order/our_case = miscboxes[buyer]
our_case.buyer_account = buying_account
+ /// SKYRAT EDIT ADDITION START - FIXES COMMAND BUDGET CASES BEING UNOPENABLE
+ if(istype(our_case.buyer_account, /datum/bank_account/department))
+ our_case.department_purchase = TRUE
+ our_case.department_account = our_case.buyer_account
+ /// SKYRAT EDIT ADDITION END
miscboxes[buyer].name = "goody case - purchased by [buyer]"
misc_contents[buyer] = list()
@@ -200,38 +211,6 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
misc_contents[buyer] += item
misc_costs[buyer] += our_order.pack.cost
misc_order_num[buyer] = "[misc_order_num[buyer]]#[our_order.id] "
- //SKYRAT EDIT START
- for(var/briefcase_order in forced_briefcases)
- var/list/buying_account_orders = forced_briefcases[briefcase_order]
- var/datum/bank_account/buying_account = briefcase_order
- var/buyer = buying_account.account_holder
- var/buying_acc_order_num = length(buying_account_orders)
- for(var/datum/supply_order/company_import/the_order in buying_account_orders)
- if(!the_order.item_amount || (the_order.item_amount == 1))
- continue
- buying_acc_order_num += the_order.item_amount - 1
-
- if(buying_acc_order_num > 2) // no free shipping, send a crate
- var/obj/structure/closet/crate/secure/owned/our_crate = new /obj/structure/closet/crate/secure/owned(pick_n_take(empty_turfs))
- our_crate.buyer_account = buying_account
- our_crate.name = "special import crate - purchased by [buyer]"
- miscboxes[buyer] = our_crate
- else //free shipping in a case
- miscboxes[buyer] = new /obj/item/storage/lockbox/order(pick_n_take(empty_turfs))
- var/obj/item/storage/lockbox/order/our_case = miscboxes[buyer]
- our_case.buyer_account = buying_account
- if(istype(our_case.buyer_account, /datum/bank_account/department))
- our_case.department_purchase = TRUE
- our_case.department_account = our_case.buyer_account
- miscboxes[buyer].name = "special import case - purchased by [buyer]"
- misc_contents[buyer] = list()
-
- for(var/datum/supply_order/order in buying_account_orders)
- for (var/item in order.pack.contains)
- misc_contents[buyer] += item
- misc_costs[buyer] += order.pack.cost
- misc_order_num[buyer] = "[misc_order_num[buyer]]#[order.id] "
- //SKYRAT EDIT END
for(var/miscbox in miscboxes)
var/datum/supply_order/order = new/datum/supply_order()
diff --git a/code/modules/spells/spell.dm b/code/modules/spells/spell.dm
index aad6135c45a..966f618376d 100644
--- a/code/modules/spells/spell.dm
+++ b/code/modules/spells/spell.dm
@@ -209,12 +209,16 @@
// Otherwise, we can check for contents if they have wizardly apparel. This isn't *quite* perfect, but it'll do, especially since many of the edge cases (gorilla holding a wizard hat) still more or less make sense.
if(spell_requirements & SPELL_REQUIRES_WIZARD_GARB)
- for(var/atom/movable/item in owner.contents)
- var/obj/item/clothing/clothem = item
- if(istype(clothem) && clothem.clothing_flags & CASTING_CLOTHES)
- return TRUE
- to_chat(owner, span_warning("You don't feel strong enough without your hat!"))
- return FALSE
+ var/any_casting = FALSE
+ for(var/obj/item/clothing/item in owner)
+ if(item.clothing_flags & CASTING_CLOTHES)
+ any_casting = TRUE
+ break
+
+ if(!any_casting)
+ if(feedback)
+ to_chat(owner, span_warning("You don't feel strong enough without your hat!"))
+ return FALSE
if(!(spell_requirements & SPELL_CASTABLE_AS_BRAIN) && isbrain(owner))
if(feedback)
@@ -298,6 +302,31 @@
/datum/action/cooldown/spell/proc/before_cast(atom/cast_on)
SHOULD_CALL_PARENT(TRUE)
+ // Bonus invocation check done here:
+ // If the caster has no tongue and it's a verbal spell,
+ // Or has no hands and is a gesture spell - cancel it,
+ // and show a funny message that they tried
+ if(ishuman(owner) && !(spell_requirements & SPELL_CASTABLE_WITHOUT_INVOCATION))
+ var/mob/living/carbon/human/caster = owner
+ switch(invocation_type)
+ if(INVOCATION_WHISPER, INVOCATION_SHOUT)
+ if(!caster.get_organ_slot(ORGAN_SLOT_TONGUE))
+ invocation(caster)
+ to_chat(caster, span_warning("Your lack of tongue is making it difficult to say the correct words to cast [src]..."))
+ StartCooldown(2 SECONDS)
+ return SPELL_CANCEL_CAST
+
+ if(INVOCATION_EMOTE)
+ if(caster.usable_hands <= 0)
+ var/arm_describer = (caster.num_hands >= 2 ? "arms limply" : (caster.num_hands == 1 ? "arm wildly" : "arm stumps"))
+ caster.visible_message(
+ span_warning("[caster] wiggles around [caster.p_their()] [arm_describer]."),
+ ignored_mobs = caster,
+ )
+ to_chat(caster, span_warning("You can't position your hands correctly to invoke [src][caster.num_hands > 0 ? "" : ", as you have none"]..."))
+ StartCooldown(2 SECONDS)
+ return SPELL_CANCEL_CAST
+
var/sig_return = SEND_SIGNAL(src, COMSIG_SPELL_BEFORE_CAST, cast_on)
if(owner)
sig_return |= SEND_SIGNAL(owner, COMSIG_MOB_BEFORE_SPELL_CAST, src, cast_on)
diff --git a/code/modules/spells/spell_types/conjure/cheese.dm b/code/modules/spells/spell_types/conjure/cheese.dm
new file mode 100644
index 00000000000..d9c90d1dbac
--- /dev/null
+++ b/code/modules/spells/spell_types/conjure/cheese.dm
@@ -0,0 +1,17 @@
+/datum/action/cooldown/spell/conjure/cheese
+ name = "Summon Cheese"
+ desc = "This spell conjures a bunch of cheese wheels. What the hell?"
+ sound = 'sound/magic/summonitems_generic.ogg'
+ button_icon_state = "cheese"
+
+ school = SCHOOL_CONJURATION
+ cooldown_time = 1 MINUTES
+ spell_requirements = null
+
+ invocation = "PL`YR DOT PL`CTM` OOO`BEE G" //player.placeatme 00064B33 9
+ invocation_type = INVOCATION_SHOUT
+ garbled_invocation_prob = 0 //i'd rather it remain like this
+
+ summon_radius = 1
+ summon_amount = 9
+ summon_type = list(/obj/item/food/cheese/wheel)
diff --git a/code/modules/spells/spell_types/jaunt/bloodcrawl.dm b/code/modules/spells/spell_types/jaunt/bloodcrawl.dm
index 8b82595a1f0..836bfd98dca 100644
--- a/code/modules/spells/spell_types/jaunt/bloodcrawl.dm
+++ b/code/modules/spells/spell_types/jaunt/bloodcrawl.dm
@@ -83,10 +83,10 @@
var/turf/jaunt_turf = get_turf(blood)
// Begin the jaunt
- jaunter.notransform = TRUE
+ ADD_TRAIT(jaunter, TRAIT_NO_TRANSFORM, REF(src))
var/obj/effect/dummy/phased_mob/holder = enter_jaunt(jaunter, jaunt_turf)
if(!holder)
- jaunter.notransform = FALSE
+ REMOVE_TRAIT(jaunter, TRAIT_NO_TRANSFORM, REF(src))
return FALSE
RegisterSignal(holder, COMSIG_MOVABLE_MOVED, PROC_REF(update_status_on_signal))
@@ -104,7 +104,7 @@
playsound(jaunt_turf, 'sound/magic/enter_blood.ogg', 50, TRUE, -1)
jaunter.extinguish_mob()
- jaunter.notransform = FALSE
+ REMOVE_TRAIT(jaunter, TRAIT_NO_TRANSFORM, REF(src))
return TRUE
/**
@@ -113,7 +113,7 @@
*/
/datum/action/cooldown/spell/jaunt/bloodcrawl/proc/try_exit_jaunt(obj/effect/decal/cleanable/blood, mob/living/jaunter, forced = FALSE)
if(!forced)
- if(jaunter.notransform)
+ if(HAS_TRAIT(jaunter, TRAIT_NO_TRANSFORM))
to_chat(jaunter, span_warning("You cannot exit yet!!"))
return FALSE
@@ -196,9 +196,9 @@
blind_message = span_notice("You hear a splash."),
)
- jaunter.notransform = TRUE
+ ADD_TRAIT(jaunter, TRAIT_NO_TRANSFORM, REF(src))
consume_victim(victim, jaunter)
- jaunter.notransform = FALSE
+ REMOVE_TRAIT(jaunter, TRAIT_NO_TRANSFORM, REF(src))
return TRUE
diff --git a/code/modules/spells/spell_types/jaunt/ethereal_jaunt.dm b/code/modules/spells/spell_types/jaunt/ethereal_jaunt.dm
index b4414c99796..43e1f9036ee 100644
--- a/code/modules/spells/spell_types/jaunt/ethereal_jaunt.dm
+++ b/code/modules/spells/spell_types/jaunt/ethereal_jaunt.dm
@@ -49,9 +49,9 @@
/datum/action/cooldown/spell/jaunt/ethereal_jaunt/proc/do_jaunt(mob/living/cast_on)
// Makes sure they don't die or get jostled or something during the jaunt entry
// Honestly probably not necessary anymore, but better safe than sorry
- cast_on.notransform = TRUE
+ ADD_TRAIT(cast_on, TRAIT_NO_TRANSFORM, REF(src))
var/obj/effect/dummy/phased_mob/holder = enter_jaunt(cast_on)
- cast_on.notransform = FALSE
+ REMOVE_TRAIT(cast_on, TRAIT_NO_TRANSFORM, REF(src))
if(!holder)
CRASH("[type] attempted do_jaunt but failed to create a jaunt holder via enter_jaunt.")
@@ -167,9 +167,10 @@
/datum/action/cooldown/spell/jaunt/ethereal_jaunt/proc/end_jaunt(mob/living/cast_on, obj/effect/dummy/phased_mob/spell_jaunt/holder, turf/final_point)
if(QDELETED(cast_on) || QDELETED(holder) || QDELETED(src))
return
- cast_on.notransform = TRUE
+
+ ADD_TRAIT(cast_on, TRAIT_NO_TRANSFORM, REF(src))
exit_jaunt(cast_on)
- cast_on.notransform = FALSE
+ REMOVE_TRAIT(cast_on, TRAIT_NO_TRANSFORM, REF(src))
REMOVE_TRAIT(cast_on, TRAIT_IMMOBILIZED, REF(src))
diff --git a/code/modules/spells/spell_types/pointed/_pointed.dm b/code/modules/spells/spell_types/pointed/_pointed.dm
index 3d1c5b91b81..04c3ed47944 100644
--- a/code/modules/spells/spell_types/pointed/_pointed.dm
+++ b/code/modules/spells/spell_types/pointed/_pointed.dm
@@ -64,17 +64,17 @@
build_all_button_icons()
return TRUE
-/datum/action/cooldown/spell/pointed/InterceptClickOn(mob/living/caller, params, atom/click_target)
+/datum/action/cooldown/spell/pointed/InterceptClickOn(mob/living/caller, params, atom/target)
var/atom/aim_assist_target
- if(aim_assist && isturf(click_target))
+ if(aim_assist && isturf(target))
// Find any human in the list. We aren't picky, it's aim assist after all
- aim_assist_target = locate(/mob/living/carbon/human) in click_target
+ aim_assist_target = locate(/mob/living/carbon/human) in target
if(!aim_assist_target)
// If we didn't find a human, we settle for any living at all
- aim_assist_target = locate(/mob/living) in click_target
+ aim_assist_target = locate(/mob/living) in target
- return ..(caller, params, aim_assist_target || click_target)
+ return ..(caller, params, aim_assist_target || target)
/datum/action/cooldown/spell/pointed/is_valid_target(atom/cast_on)
if(cast_on == owner)
diff --git a/code/modules/spells/spell_types/pointed/swap.dm b/code/modules/spells/spell_types/pointed/swap.dm
index ddeb08b4b8a..6b4a5e45e14 100644
--- a/code/modules/spells/spell_types/pointed/swap.dm
+++ b/code/modules/spells/spell_types/pointed/swap.dm
@@ -35,27 +35,27 @@
return FALSE
return TRUE
-/datum/action/cooldown/spell/pointed/swap/InterceptClickOn(mob/living/caller, params, atom/click_target)
+/datum/action/cooldown/spell/pointed/swap/InterceptClickOn(mob/living/caller, params, atom/target)
if(LAZYACCESS(params2list(params), RIGHT_CLICK))
if(!IsAvailable(feedback = TRUE))
return FALSE
if(!target)
return FALSE
- if(!isliving(click_target) || isturf(click_target))
+ if(!isliving(target) || isturf(target))
// Find any living being in the list. We aren't picky, it's aim assist after all
- click_target = locate(/mob/living) in click_target
- if(!click_target)
+ target = locate(/mob/living) in target
+ if(!target)
to_chat(owner, span_warning("You can only select living beings as secondary target!"))
return FALSE
- if(click_target == owner)
+ if(target == owner)
if(!isnull(second_target))
to_chat(owner, span_notice("You cancel your secondary swap target!"))
second_target = null
else
to_chat(owner, span_warning("You have no secondary swap target!"))
return FALSE
- second_target = click_target
- to_chat(owner, span_notice("You select [click_target.name] as a secondary swap target!"))
+ second_target = target
+ to_chat(owner, span_notice("You select [target.name] as a secondary swap target!"))
return FALSE
return ..()
diff --git a/code/modules/spells/spell_types/self/rod_form.dm b/code/modules/spells/spell_types/self/rod_form.dm
index fd9a52be412..5336036cd2c 100644
--- a/code/modules/spells/spell_types/self/rod_form.dm
+++ b/code/modules/spells/spell_types/self/rod_form.dm
@@ -138,9 +138,8 @@
our_wizard = WEAKREF(wizard)
wizard.forceMove(src)
- wizard.notransform = TRUE
wizard.status_flags |= GODMODE
- ADD_TRAIT(wizard, TRAIT_MAGICALLY_PHASED, REF(src))
+ wizard.add_traits(list(TRAIT_MAGICALLY_PHASED, TRAIT_NO_TRANSFORM), REF(src))
/**
* Eject our current wizard, removing them from the rod
@@ -152,9 +151,8 @@
return
wizard.status_flags &= ~GODMODE
- wizard.notransform = FALSE
+ wizard.remove_traits(list(TRAIT_MAGICALLY_PHASED, TRAIT_NO_TRANSFORM), REF(src))
wizard.forceMove(get_turf(src))
our_wizard = null
- REMOVE_TRAIT(wizard, TRAIT_MAGICALLY_PHASED, REF(src))
#undef BASE_WIZ_ROD_RANGE
diff --git a/code/modules/spells/spell_types/shapeshift/_shape_status.dm b/code/modules/spells/spell_types/shapeshift/_shape_status.dm
index b0e8941600b..10d42760c91 100644
--- a/code/modules/spells/spell_types/shapeshift/_shape_status.dm
+++ b/code/modules/spells/spell_types/shapeshift/_shape_status.dm
@@ -32,7 +32,7 @@
/datum/status_effect/shapechange_mob/on_apply()
caster_mob.mind?.transfer_to(owner)
caster_mob.forceMove(owner)
- caster_mob.notransform = TRUE
+ ADD_TRAIT(caster_mob, TRAIT_NO_TRANSFORM, REF(src))
caster_mob.apply_status_effect(/datum/status_effect/grouped/stasis, STASIS_SHAPECHANGE_EFFECT)
RegisterSignal(owner, COMSIG_LIVING_PRE_WABBAJACKED, PROC_REF(on_wabbajacked))
@@ -77,7 +77,7 @@
UnregisterSignal(caster_mob, list(COMSIG_QDELETING, COMSIG_LIVING_DEATH))
caster_mob.forceMove(owner.loc)
- caster_mob.notransform = FALSE
+ REMOVE_TRAIT(caster_mob, TRAIT_NO_TRANSFORM, REF(src))
caster_mob.remove_status_effect(/datum/status_effect/grouped/stasis, STASIS_SHAPECHANGE_EFFECT)
owner.mind?.transfer_to(caster_mob)
diff --git a/code/modules/spells/spell_types/touch/scream_for_me.dm b/code/modules/spells/spell_types/touch/scream_for_me.dm
index 941885e7577..231b6927e50 100644
--- a/code/modules/spells/spell_types/touch/scream_for_me.dm
+++ b/code/modules/spells/spell_types/touch/scream_for_me.dm
@@ -21,7 +21,7 @@
span_userdanger("The spell bounces from [victim]'s skin back into your arm!"),
)
var/obj/item/bodypart/to_wound = caster.get_holding_bodypart_of_item(hand)
- to_wound.force_wound_upwards(/datum/wound/slash/critical)
+ caster.cause_wound_of_type_and_severity(WOUND_SLASH, to_wound, WOUND_SEVERITY_MODERATE, WOUND_SEVERITY_CRITICAL)
/datum/action/cooldown/spell/touch/scream_for_me/cast_on_hand_hit(obj/item/melee/touch_attack/hand, mob/living/victim, mob/living/carbon/caster)
if(!ishuman(victim))
@@ -29,7 +29,7 @@
var/mob/living/carbon/human/human_victim = victim
human_victim.emote("scream")
for(var/obj/item/bodypart/to_wound as anything in human_victim.bodyparts)
- to_wound.force_wound_upwards(/datum/wound/slash/critical)
+ human_victim.cause_wound_of_type_and_severity(WOUND_SLASH, to_wound, WOUND_SEVERITY_MODERATE, WOUND_SEVERITY_CRITICAL)
return TRUE
/obj/item/melee/touch_attack/scream_for_me
diff --git a/code/modules/station_goals/bsa.dm b/code/modules/station_goals/bsa.dm
index 9ac99c86b3c..ec29b326ae9 100644
--- a/code/modules/station_goals/bsa.dm
+++ b/code/modules/station_goals/bsa.dm
@@ -57,7 +57,7 @@ GLOBAL_VAR_INIT(bsa_unlock, FALSE)
return
var/obj/item/multitool/M = I
M.set_buffer(src)
- to_chat(user, span_notice("You store linkage information in [I]'s buffer."))
+ balloon_alert(user, "saved to multitool buffer")
return TRUE
/obj/machinery/bsa/front
@@ -74,7 +74,7 @@ GLOBAL_VAR_INIT(bsa_unlock, FALSE)
return
var/obj/item/multitool/M = I
M.set_buffer(src)
- to_chat(user, span_notice("You store linkage information in [I]'s buffer."))
+ balloon_alert(user, "saved to multitool buffer")
return TRUE
/obj/machinery/bsa/middle
diff --git a/code/modules/surgery/autopsy.dm b/code/modules/surgery/autopsy.dm
index 9bd232e4c0d..2d106cfd441 100644
--- a/code/modules/surgery/autopsy.dm
+++ b/code/modules/surgery/autopsy.dm
@@ -13,7 +13,7 @@
. = ..()
if(patient.stat != DEAD)
return FALSE
- if(HAS_TRAIT(patient, TRAIT_DISSECTED))
+ if(HAS_TRAIT_FROM(patient, TRAIT_DISSECTED, AUTOPSY_TRAIT))
return FALSE
return TRUE
diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm
index 2b85e7843ff..4b9c0114024 100644
--- a/code/modules/surgery/bodyparts/_bodyparts.dm
+++ b/code/modules/surgery/bodyparts/_bodyparts.dm
@@ -22,14 +22,15 @@
/// DO NOT MODIFY DIRECTLY. Use set_owner()
var/mob/living/carbon/owner
+ /// If this limb can be scarred.
+ var/scarrable = TRUE
+
/**
* A bitfield of biological states, exclusively used to determine which wounds this limb will get,
* as well as how easily it will happen.
- * Set to BIO_FLESH_BONE because most species have both flesh and bone in their limbs.
- *
- * This currently has absolutely no meaning for robotic limbs.
+ * Set to BIO_STANDARD_UNJOINTED because most species have both flesh bone and blood in their limbs.
*/
- var/biological_state = BIO_FLESH_BONE
+ var/biological_state = BIO_STANDARD_UNJOINTED
///A bitfield of bodytypes for clothing, surgery, and misc information
var/bodytype = BODYTYPE_HUMANOID | BODYTYPE_ORGANIC
///Defines when a bodypart should not be changed. Example: BP_BLOCK_CHANGE_SPECIES prevents the limb from being overwritten on species gain
@@ -66,16 +67,14 @@
var/speed_modifier = 0
// Limb disabling variables
+ ///Whether it is possible for the limb to be disabled whatsoever. TRUE means that it is possible.
+ var/can_be_disabled = FALSE //Defaults to FALSE, as only human limbs can be disabled, and only the appendages.
///Controls if the limb is disabled. TRUE means it is disabled (similar to being removed, but still present for the sake of targeted interactions).
var/bodypart_disabled = FALSE
///Handles limb disabling by damage. If 0 (0%), a limb can't be disabled via damage. If 1 (100%), it is disabled at max limb damage. Anything between is the percentage of damage against maximum limb damage needed to disable the limb.
- //var/disabling_threshold_percentage = 0 //ORIGINAL
- var/disabling_threshold_percentage = 1 //SKYRAT EDIT CHANGE - COMBAT
- ///Whether it is possible for the limb to be disabled whatsoever. TRUE means that it is possible.
- var/can_be_disabled = FALSE //Defaults to FALSE, as only human limbs can be disabled, and only the appendages.
-
- // Damage state variables
+ var/disabling_threshold_percentage = 1 //SKYRAT EDIT CHANGE - COMBAT - ORIGINAL : var/disabling_threshold_percentage = 0
+ // Damage variables
///A mutiplication of the burn and brute damage that the limb's stored damage contributes to its attached mob's overall wellbeing.
var/body_damage_coeff = 1
///The current amount of brute damage the limb has
@@ -152,20 +151,8 @@
var/cached_bleed_rate = 0
/// How much generic bleedstacks we have on this bodypart
var/generic_bleedstacks
- //SKYRAT EDIT CHANGE BEGIN - MEDICAL
- /*
/// If we have a gauze wrapping currently applied (not including splints)
var/obj/item/stack/current_gauze
- */
- /// If we have a gauze wrapping currently applied
- var/datum/bodypart_aid/gauze/current_gauze
- /// If we have a splint currently applied
- var/datum/bodypart_aid/splint/current_splint
- /// What icon do we use to render this limb? Ususally used by robotic limb augments.
- var/rendered_bp_icon
- /// Do we use an organic render for this robotic limb?
- var/organic_render = TRUE
- //SKYRAT EDIT CHANGE END
/// If something is currently grasping this bodypart and trying to staunch bleeding (see [/obj/item/hand_item/self_grasp])
var/obj/item/hand_item/self_grasp/grasped_by
@@ -200,6 +187,18 @@
/// List of the above datums which have actually been instantiated, managed automatically
var/list/feature_offsets = list()
+ /// In the case we dont have dismemberable features, or literally cant get wounds, we will use this percent to determine when we can be dismembered.
+ /// Compared to our ABSOLUTE maximum. Stored in decimal; 0.8 = 80%.
+ var/hp_percent_to_dismemberable = 0.8
+ /// If true, we will use [hp_percent_to_dismemberable] even if we are dismemberable via wounds. Useful for things with extreme wound resistance.
+ var/use_alternate_dismemberment_calc_even_if_mangleable = FALSE
+ /// If false, no wound that can be applied to us can mangle our exterior. Used for determining if we should use [hp_percent_to_dismemberable] instead of normal dismemberment.
+ var/any_existing_wound_can_mangle_our_exterior
+ /// If false, no wound that can be applied to us can mangle our interior. Used for determining if we should use [hp_percent_to_dismemberable] instead of normal dismemberment.
+ var/any_existing_wound_can_mangle_our_interior
+ /// get_damage() / total_damage must surpass this to allow our limb to be disabled, even temporarily, by an EMP.
+ var/robotic_emp_paralyze_damage_percent_threshold = 0.3
+
/obj/item/bodypart/apply_fantasy_bonuses(bonus)
. = ..()
unarmed_damage_low = modify_fantasy_variable("unarmed_damage_low", unarmed_damage_low, bonus, minimum = 1)
@@ -241,12 +240,6 @@
if(length(wounds))
stack_trace("[type] qdeleted with [length(wounds)] uncleared wounds")
wounds.Cut()
- //SKYRAT EDIT ADDITION BEGIN - MEDICAL
- if(current_gauze)
- qdel(current_gauze)
- if(current_splint)
- qdel(current_splint)
- //SKYRAT EDIT ADDITION END
if(length(external_organs))
for(var/obj/item/organ/external/external_organ as anything in external_organs)
@@ -415,11 +408,7 @@
var/atom/drop_loc = drop_location()
if(IS_ORGANIC_LIMB(src))
playsound(drop_loc, 'sound/misc/splort.ogg', 50, TRUE, -1)
- //seep_gauze(9999) // destroy any existing gauze if any exists
- if(current_gauze)
- qdel(current_gauze)
- if(current_splint)
- qdel(current_splint)
+ seep_gauze(9999) // destroy any existing gauze if any exists
for(var/obj/item/organ/bodypart_organ in get_organs())
bodypart_organ.transfer_to_limb(src, owner)
for(var/obj/item/organ/external/external in external_organs)
@@ -505,42 +494,36 @@
else if (sharpness & SHARP_POINTY)
wounding_type = WOUND_PIERCE
- if(owner)
+ if(owner) // i tried to modularize the below, but the modifications to wounding_dmg and wounding_type cant be extracted to a proc
var/mangled_state = get_mangled_state()
var/easy_dismember = HAS_TRAIT(owner, TRAIT_EASYDISMEMBER) // if we have easydismember, we don't reduce damage when redirecting damage to different types (slashing weapons on mangled/skinless limbs attack at 100% instead of 50%)
- //Handling for bone only/flesh only(none right now)/flesh and bone targets
- switch(biological_state)
- // if we're bone only, all cutting attacks go straight to the bone
- if(BIO_BONE)
- if(wounding_type == WOUND_SLASH)
- wounding_type = WOUND_BLUNT
- wounding_dmg *= (easy_dismember ? 1 : 0.6)
- else if(wounding_type == WOUND_PIERCE)
- wounding_type = WOUND_BLUNT
- wounding_dmg *= (easy_dismember ? 1 : 0.75)
- if((mangled_state & BODYPART_MANGLED_BONE) && try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus))
- return
- // note that there's no handling for BIO_FLESH since we don't have any that are that right now (slimepeople maybe someday)
- // standard humanoids
- if(BIO_FLESH_BONE)
- //SKYRAT EDIT ADDITION BEGIN - MEDICAL
- //We do a body zone check here because muscles dont have any variants for head or chest, and rolling a muscle wound on them wound end up on a wasted wound roll
- if(body_zone != BODY_ZONE_CHEST && body_zone != BODY_ZONE_HEAD && prob(35))
- wounding_type = WOUND_MUSCLE
- //SKYRAT EDIT ADDITION END
- // if we've already mangled the skin (critical slash or piercing wound), then the bone is exposed, and we can damage it with sharp weapons at a reduced rate
- // So a big sharp weapon is still all you need to destroy a limb
- if((mangled_state & BODYPART_MANGLED_FLESH) && !(mangled_state & BODYPART_MANGLED_BONE) && sharpness)
- playsound(src, "sound/effects/wounds/crackandbleed.ogg", 100)
- if(wounding_type == WOUND_SLASH && !easy_dismember)
- wounding_dmg *= 0.6 // edged weapons pass along 60% of their wounding damage to the bone since the power is spread out over a larger area
- if(wounding_type == WOUND_PIERCE && !easy_dismember)
- wounding_dmg *= 0.75 // piercing weapons pass along 75% of their wounding damage to the bone since it's more concentrated
- wounding_type = WOUND_BLUNT
- else if((mangled_state & BODYPART_MANGLED_FLESH) && (mangled_state & BODYPART_MANGLED_BONE) && try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus))
- return
+ var/bio_status = get_bio_state_status()
+ var/has_exterior = ((bio_status & ANATOMY_EXTERIOR))
+ var/has_interior = ((bio_status & ANATOMY_INTERIOR))
+
+ var/exterior_ready_to_dismember = (!has_exterior || ((mangled_state & BODYPART_MANGLED_EXTERIOR)))
+
+ // if we're bone only, all cutting attacks go straight to the bone
+ if(!has_exterior && has_interior)
+ if(wounding_type == WOUND_SLASH)
+ wounding_type = WOUND_BLUNT
+ wounding_dmg *= (easy_dismember ? 1 : 0.6)
+ else if(wounding_type == WOUND_PIERCE)
+ wounding_type = WOUND_BLUNT
+ wounding_dmg *= (easy_dismember ? 1 : 0.75)
+ else
+ // if we've already mangled the skin (critical slash or piercing wound), then the bone is exposed, and we can damage it with sharp weapons at a reduced rate
+ // So a big sharp weapon is still all you need to destroy a limb
+ if(has_interior && exterior_ready_to_dismember && !(mangled_state & BODYPART_MANGLED_INTERIOR) && sharpness)
+ if(wounding_type == WOUND_SLASH && !easy_dismember)
+ wounding_dmg *= 0.6 // edged weapons pass along 60% of their wounding damage to the bone since the power is spread out over a larger area
+ if(wounding_type == WOUND_PIERCE && !easy_dismember)
+ wounding_dmg *= 0.75 // piercing weapons pass along 75% of their wounding damage to the bone since it's more concentrated
+ wounding_type = WOUND_BLUNT
+ if ((dismemberable_by_wound() || dismemberable_by_total_damage()) && try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus))
+ return
// now we have our wounding_type and are ready to carry on with wounds and dealing the actual damage
if(wounding_dmg >= WOUND_MINIMUM_DAMAGE && wound_bonus != CANT_WOUND)
//SKYRAT EDIT ADDITION - MEDICAL
@@ -552,15 +535,14 @@
damaged_percent = DAMAGED_BODYPART_BONUS_WOUNDING_THRESHOLD
wounding_dmg = min(DAMAGED_BODYPART_BONUS_WOUNDING_BONUS, wounding_dmg + (damaged_percent * DAMAGED_BODYPART_BONUS_WOUNDING_COEFF))
- if(current_gauze)
- current_gauze.take_damage()
- if(current_splint)
- current_splint.take_damage()
+ if (istype(current_gauze, /obj/item/stack/medical/gauze))
+ var/obj/item/stack/medical/gauze/our_gauze = current_gauze
+ our_gauze.get_hit()
//SKYRAT EDIT ADDITION END - MEDICAL
check_wounding(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus, attack_direction, damage_source = damage_source)
for(var/datum/wound/iter_wound as anything in wounds)
- iter_wound.receive_damage(wounding_type, wounding_dmg, wound_bonus)
+ iter_wound.receive_damage(wounding_type, wounding_dmg, wound_bonus, damage_source)
/*
// END WOUND HANDLING
@@ -587,6 +569,83 @@
owner.updatehealth()
return update_bodypart_damage_state() || .
+/// Returns a bitflag using ANATOMY_EXTERIOR or ANATOMY_INTERIOR. Used to determine if we as a whole have a interior or exterior biostate, or both.
+/obj/item/bodypart/proc/get_bio_state_status()
+ SHOULD_BE_PURE(TRUE)
+
+ var/bio_status = NONE
+
+ for (var/state as anything in GLOB.bio_state_anatomy)
+ var/flag = text2num(state)
+ if (!(biological_state & flag))
+ continue
+
+ var/value = GLOB.bio_state_anatomy[state]
+ if (value & ANATOMY_EXTERIOR)
+ bio_status |= ANATOMY_EXTERIOR
+ if (value & ANATOMY_INTERIOR)
+ bio_status |= ANATOMY_INTERIOR
+
+ if ((bio_status & ANATOMY_EXTERIOR_AND_INTERIOR) == ANATOMY_EXTERIOR_AND_INTERIOR)
+ break
+
+ return bio_status
+
+/// Returns if our current mangling status allows us to be dismembered. Requires both no exterior/mangled exterior and no interior/mangled interior.
+/obj/item/bodypart/proc/dismemberable_by_wound()
+ SHOULD_BE_PURE(TRUE)
+
+ var/mangled_state = get_mangled_state()
+
+ var/bio_status = get_bio_state_status()
+
+ var/has_exterior = ((bio_status & ANATOMY_EXTERIOR))
+ var/has_interior = ((bio_status & ANATOMY_INTERIOR))
+
+ var/exterior_ready_to_dismember = (!has_exterior || ((mangled_state & BODYPART_MANGLED_EXTERIOR)))
+ var/interior_ready_to_dismember = (!has_interior || ((mangled_state & BODYPART_MANGLED_INTERIOR)))
+
+ return (exterior_ready_to_dismember && interior_ready_to_dismember)
+
+/// Returns TRUE if our total percent damage is more or equal to our dismemberable percentage, but FALSE if a wound can cause us to be dismembered.
+/obj/item/bodypart/proc/dismemberable_by_total_damage()
+
+ update_wound_theory()
+
+ var/bio_status = get_bio_state_status()
+
+ var/has_interior = ((bio_status & ANATOMY_INTERIOR))
+ var/can_theoretically_be_dismembered_by_wound = (any_existing_wound_can_mangle_our_interior || (any_existing_wound_can_mangle_our_exterior && has_interior))
+
+ var/wound_dismemberable = dismemberable_by_wound()
+ var/ready_to_use_alternate_formula = (use_alternate_dismemberment_calc_even_if_mangleable || (!wound_dismemberable && !can_theoretically_be_dismembered_by_wound))
+
+ if (ready_to_use_alternate_formula)
+ var/percent_to_total_max = (get_damage() / max_damage)
+ if (percent_to_total_max >= hp_percent_to_dismemberable)
+ return TRUE
+
+ return FALSE
+
+/// Updates our "can be theoretically dismembered by wounds" variables by iterating through all wound static data.
+/obj/item/bodypart/proc/update_wound_theory()
+ // We put this here so we dont increase init time by doing this all at once on initialization
+ // Effectively, we "lazy load"
+ if (isnull(any_existing_wound_can_mangle_our_interior) || isnull(any_existing_wound_can_mangle_our_exterior))
+ any_existing_wound_can_mangle_our_interior = FALSE
+ any_existing_wound_can_mangle_our_exterior = FALSE
+ for (var/datum/wound/wound_type as anything in GLOB.all_wound_pregen_data)
+ var/datum/wound_pregen_data/pregen_data = GLOB.all_wound_pregen_data[wound_type]
+ if (!pregen_data.can_be_applied_to(src, random_roll = TRUE)) // we only consider randoms because non-randoms are usually really specific
+ continue
+ if (initial(pregen_data.wound_path_to_generate.wound_flags) & MANGLES_EXTERIOR)
+ any_existing_wound_can_mangle_our_exterior = TRUE
+ if (initial(pregen_data.wound_path_to_generate.wound_flags) & MANGLES_INTERIOR)
+ any_existing_wound_can_mangle_our_interior = TRUE
+
+ if (any_existing_wound_can_mangle_our_interior && any_existing_wound_can_mangle_our_exterior)
+ break
+
//Heals brute and burn damage for the organ. Returns 1 if the damage-icon states changed at all.
//Damage cannot go below zero.
//Cannot remove negative damage (i.e. apply damage)
@@ -1162,7 +1221,7 @@
if(!owner)
return
- if(HAS_TRAIT(owner, TRAIT_NOBLOOD) || !IS_ORGANIC_LIMB(src))
+ if(!can_bleed())
if(cached_bleed_rate != old_bleed_rate)
update_part_wound_overlay()
return
@@ -1177,9 +1236,6 @@
for(var/datum/wound/iter_wound as anything in wounds)
cached_bleed_rate += iter_wound.blood_flow
- if(!cached_bleed_rate)
- QDEL_NULL(grasped_by)
-
// Our bleed overlay is based directly off bleed_rate, so go aheead and update that would you?
if(cached_bleed_rate != old_bleed_rate)
update_part_wound_overlay()
@@ -1203,7 +1259,7 @@
/obj/item/bodypart/proc/update_part_wound_overlay()
if(!owner)
return FALSE
- if(HAS_TRAIT(owner, TRAIT_NOBLOOD) || !IS_ORGANIC_LIMB(src))
+ if(!can_bleed())
if(bleed_overlay_icon)
bleed_overlay_icon = null
owner.update_wound_overlays()
@@ -1236,6 +1292,11 @@
#undef BLEED_OVERLAY_MED
#undef BLEED_OVERLAY_GUSH
+/obj/item/bodypart/proc/can_bleed()
+ SHOULD_BE_PURE(TRUE)
+
+ return ((biological_state & BIO_BLOODED) && (!owner || !HAS_TRAIT(owner, TRAIT_NOBLOOD)))
+
/**
* apply_gauze() is used to- well, apply gauze to a bodypart
*
@@ -1247,7 +1308,6 @@
* Arguments:
* * gauze- Just the gauze stack we're taking a sheet from to apply here
*/
-/* SKYRAT EDIT REMOVAL
/obj/item/bodypart/proc/apply_gauze(obj/item/stack/gauze)
if(!istype(gauze) || !gauze.absorption_capacity)
return
@@ -1259,7 +1319,6 @@
gauze.use(1)
if(newly_gauzed)
SEND_SIGNAL(src, COMSIG_BODYPART_GAUZED, gauze)
-*/
/**
* seep_gauze() is for when a gauze wrapping absorbs blood or pus from wounds, lowering its absorption capacity.
@@ -1269,7 +1328,6 @@
* Arguments:
* * seep_amt - How much absorption capacity we're removing from our current bandages (think, how much blood or pus are we soaking up this tick?)
*/
-/* SKYRAT EDIT REMOVAL
/obj/item/bodypart/proc/seep_gauze(seep_amt = 0)
if(!current_gauze)
return
@@ -1278,7 +1336,6 @@
owner.visible_message(span_danger("\The [current_gauze.name] on [owner]'s [name] falls away in rags."), span_warning("\The [current_gauze.name] on your [name] falls away in rags."), vision_distance=COMBAT_MESSAGE_RANGE)
QDEL_NULL(current_gauze)
SEND_SIGNAL(src, COMSIG_BODYPART_GAUZE_DESTROYED)
-*/
///Loops through all of the bodypart's external organs and update's their color.
/obj/item/bodypart/proc/recolor_external_organs()
@@ -1328,14 +1385,17 @@
/obj/item/bodypart/emp_act(severity)
. = ..()
- if(. & EMP_PROTECT_WIRES || !(bodytype & BODYTYPE_ROBOTIC))
+ if(. & EMP_PROTECT_WIRES || !IS_ROBOTIC_LIMB(src))
return FALSE
- owner.visible_message(span_danger("[owner]'s [src.name] seems to malfunction!"))
-
- var/time_needed = 10 SECONDS
- var/brute_damage = 2.5 // SKYRAT EDIT : Balances direct EMP damage for Brute - SR's synth values are multiplied 3x 2.5 * 1.3 * 1.3
- var/burn_damage = 2 // SKYRAT EDIT : Balances direct EMP damage for Burn - SR's synth values are multiplied 3x 2 * 1.3 * 1.3
+ // with defines at the time of writing, this is 2 brute and 1.5 burn
+ // 2 + 1.5 = 3,5, with 6 limbs thats 21, on a heavy 42
+ // 42 * 0.8 = 33.6
+ // 3 hits to crit with an ion rifle on someone fully augged at a total of 100.8 damage, although im p sure mood can boost max hp above 100
+ // dont forget emps pierce armor, debilitate augs, and usually comes with splash damage e.g. ion rifles or grenades
+ var/time_needed = AUGGED_LIMB_EMP_PARALYZE_TIME
+ var/brute_damage = AUGGED_LIMB_EMP_BRUTE_DAMAGE
+ var/burn_damage = AUGGED_LIMB_EMP_BURN_DAMAGE
if(severity == EMP_HEAVY)
time_needed *= 2
brute_damage *= 1.3 // SKYRAT EDIT : Balance - Lowers total damage from ~125 Brute to ~30
@@ -1343,9 +1403,30 @@
receive_damage(brute_damage, burn_damage)
do_sparks(number = 1, cardinal_only = FALSE, source = owner)
- ADD_TRAIT(src, TRAIT_PARALYSIS, EMP_TRAIT)
- addtimer(CALLBACK(src, PROC_REF(un_paralyze)), time_needed)
+ var/damage_percent_to_max = (get_damage() / max_damage)
+ if (time_needed && (damage_percent_to_max >= robotic_emp_paralyze_damage_percent_threshold))
+ owner.visible_message(span_danger("[owner]'s [src] seems to malfunction!"))
+ ADD_TRAIT(src, TRAIT_PARALYSIS, EMP_TRAIT)
+ addtimer(CALLBACK(src, PROC_REF(un_paralyze)), time_needed)
return TRUE
/obj/item/bodypart/proc/un_paralyze()
REMOVE_TRAITS_IN(src, EMP_TRAIT)
+
+/// Returns the generic description of our BIO_EXTERNAL feature(s), prioritizing certain ones over others. Returns error on failure.
+/obj/item/bodypart/proc/get_external_description()
+ if (biological_state & BIO_FLESH)
+ return "flesh"
+ if (biological_state & BIO_WIRED)
+ return "wiring"
+
+ return "error"
+
+/// Returns the generic description of our BIO_INTERNAL feature(s), prioritizing certain ones over others. Returns error on failure.
+/obj/item/bodypart/proc/get_internal_description()
+ if (biological_state & BIO_BONE)
+ return "bone"
+ if (biological_state & BIO_METAL)
+ return "metal"
+
+ return "error"
diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm
index daa1a80b628..14752ef4d97 100644
--- a/code/modules/surgery/bodyparts/dismemberment.dm
+++ b/code/modules/surgery/bodyparts/dismemberment.dm
@@ -1,11 +1,11 @@
/obj/item/bodypart/proc/can_dismember(obj/item/item)
- if(bodypart_flags & BODYPART_UNREMOVABLE)
+ if(bodypart_flags & BODYPART_UNREMOVABLE || (owner && HAS_TRAIT(owner, TRAIT_NODISMEMBER)))
return FALSE
return TRUE
///Remove target limb from it's owner, with side effects.
-/obj/item/bodypart/proc/dismember(dam_type = BRUTE, silent=TRUE)
+/obj/item/bodypart/proc/dismember(dam_type = BRUTE, silent=TRUE, wounding_type)
if(!owner || (bodypart_flags & BODYPART_UNREMOVABLE))
return FALSE
var/mob/living/carbon/limb_owner = owner
@@ -22,11 +22,15 @@
playsound(get_turf(limb_owner), 'sound/effects/dismember.ogg', 80, TRUE)
limb_owner.add_mood_event("dismembered_[body_zone]", /datum/mood_event/dismembered, src)
limb_owner.add_mob_memory(/datum/memory/was_dismembered, lost_limb = src)
+
+ if (wounding_type)
+ LAZYSET(limb_owner.body_zone_dismembered_by, body_zone, wounding_type)
+
drop_limb()
limb_owner.update_equipment_speed_mods() // Update in case speed affecting item unequipped by dismemberment
var/turf/owner_location = limb_owner.loc
- if(istype(owner_location))
+ if(wounding_type != WOUND_BURN && istype(owner_location) && can_bleed())
limb_owner.add_splatter_floor(owner_location)
if(QDELETED(src)) //Could have dropped into lava/explosion/chasm/whatever
@@ -34,8 +38,9 @@
if(dam_type == BURN)
burn()
return TRUE
- add_mob_blood(limb_owner)
- limb_owner.bleed(rand(20, 40))
+ if (can_bleed())
+ add_mob_blood(limb_owner)
+ limb_owner.bleed(rand(20, 40))
var/direction = pick(GLOB.cardinals)
var/t_range = rand(2,max(throw_range/2, 2))
var/turf/target_turf = get_turf(src)
@@ -47,10 +52,10 @@
if(new_turf.density)
break
throw_at(target_turf, throw_range, throw_speed)
+
return TRUE
-
-/obj/item/bodypart/chest/dismember()
+/obj/item/bodypart/chest/dismember(dam_type = BRUTE, silent=TRUE, wounding_type)
if(!owner)
return FALSE
var/mob/living/carbon/chest_owner = owner
@@ -59,7 +64,7 @@
if(HAS_TRAIT(chest_owner, TRAIT_NODISMEMBER))
return FALSE
. = list()
- if(isturf(chest_owner.loc))
+ if(wounding_type != WOUND_BURN && isturf(chest_owner.loc) && can_bleed())
chest_owner.add_splatter_floor(chest_owner.loc)
playsound(get_turf(chest_owner), 'sound/misc/splort.ogg', 80, TRUE)
for(var/obj/item/organ/organ as anything in chest_owner.organs)
@@ -85,8 +90,6 @@
. += cavity_item
cavity_item = null
-
-
///limb removal. The "special" argument is used for swapping a limb with a new one without the effects of losing a limb kicking in.
/obj/item/bodypart/proc/drop_limb(special, dismembered)
if(!owner)
@@ -159,16 +162,16 @@
* Dismemberment for flesh and bone requires the victim to have the skin on their bodypart destroyed (either a critical cut or piercing wound), and at least a hairline fracture
* (severe bone), at which point we can start rolling for dismembering. The attack must also deal at least 10 damage, and must be a brute attack of some kind (sorry for now, cakehat, maybe later)
*
- * Returns: BODYPART_MANGLED_NONE if we're fine, BODYPART_MANGLED_FLESH if our skin is broken, BODYPART_MANGLED_BONE if our bone is broken, or BODYPART_MANGLED_BOTH if both are broken and we're up for dismembering
+ * Returns: BODYPART_MANGLED_NONE if we're fine, BODYPART_MANGLED_EXTERIOR if our skin is broken, BODYPART_MANGLED_INTERIOR if our bone is broken, or BODYPART_MANGLED_BOTH if both are broken and we're up for dismembering
*/
/obj/item/bodypart/proc/get_mangled_state()
. = BODYPART_MANGLED_NONE
for(var/datum/wound/iter_wound as anything in wounds)
- if((iter_wound.wound_flags & MANGLES_BONE))
- . |= BODYPART_MANGLED_BONE
- if((iter_wound.wound_flags & MANGLES_FLESH))
- . |= BODYPART_MANGLED_FLESH
+ if((iter_wound.wound_flags & MANGLES_INTERIOR))
+ . |= BODYPART_MANGLED_INTERIOR
+ if((iter_wound.wound_flags & MANGLES_EXTERIOR))
+ . |= BODYPART_MANGLED_EXTERIOR
/**
* try_dismember() is used, once we've confirmed that a flesh and bone bodypart has both the skin and bone mangled, to actually roll for it
@@ -184,14 +187,17 @@
* * bare_wound_bonus: ditto above
*/
/obj/item/bodypart/proc/try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus)
+ if (!can_dismember())
+ return
+
if(wounding_dmg < DISMEMBER_MINIMUM_DAMAGE)
return
var/base_chance = wounding_dmg
base_chance += (get_damage() / max_damage * 50) // how much damage we dealt with this blow, + 50% of the damage percentage we already had on this bodypart
- if(locate(/datum/wound/blunt/critical) in wounds) // we only require a severe bone break, but if there's a critical bone break, we'll add 15% more
- base_chance += 15
+ for (var/datum/wound/iterated_wound as anything in wounds)
+ base_chance += iterated_wound.get_dismember_chance_bonus(base_chance)
if(prob(base_chance))
var/datum/wound/loss/dismembering = new
@@ -332,6 +338,8 @@
set_owner(new_limb_owner)
new_limb_owner.add_bodypart(src)
+ LAZYREMOVE(new_limb_owner.body_zone_dismembered_by, body_zone)
+
if(special) //non conventional limb attachment
for(var/datum/surgery/attach_surgery as anything in new_limb_owner.surgeries) //if we had an ongoing surgery to attach a new limb, we stop it.
var/surgery_zone = check_zone(attach_surgery.location)
@@ -420,12 +428,15 @@
/mob/living/carbon/proc/regenerate_limbs(list/excluded_zones = list())
SEND_SIGNAL(src, COMSIG_CARBON_REGENERATE_LIMBS, excluded_zones)
var/list/zone_list = list(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG)
+
+ var/list/dismembered_by_copy = body_zone_dismembered_by?.Copy()
+
if(length(excluded_zones))
zone_list -= excluded_zones
for(var/limb_zone in zone_list)
- regenerate_limb(limb_zone)
+ regenerate_limb(limb_zone, dismembered_by_copy)
-/mob/living/carbon/proc/regenerate_limb(limb_zone)
+/mob/living/carbon/proc/regenerate_limb(limb_zone, list/dismembered_by_copy = body_zone_dismembered_by?.Copy())
var/obj/item/bodypart/limb
if(get_bodypart(limb_zone))
return FALSE
@@ -435,9 +446,16 @@
qdel(limb)
return FALSE
limb.update_limb(is_creating = TRUE)
- var/datum/scar/scaries = new
- var/datum/wound/loss/phantom_loss = new // stolen valor, really
- scaries.generate(limb, phantom_loss)
+ if (LAZYLEN(dismembered_by_copy))
+ var/datum/scar/scaries = new
+ var/datum/wound/loss/phantom_loss = new // stolen valor, really
+ phantom_loss.loss_wounding_type = dismembered_by_copy?[limb_zone]
+ if (phantom_loss.loss_wounding_type)
+ scaries.generate(limb, phantom_loss)
+ LAZYREMOVE(dismembered_by_copy, limb_zone) // in case we're using a passed list
+ else
+ qdel(scaries)
+ qdel(phantom_loss)
//Copied from /datum/species/proc/on_species_gain()
for(var/obj/item/organ/external/organ_path as anything in dna.species.external_organs)
diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm
index 73e7d4207e5..30fb63a8034 100644
--- a/code/modules/surgery/bodyparts/head.dm
+++ b/code/modules/surgery/bodyparts/head.dm
@@ -191,9 +191,10 @@
/obj/item/bodypart/head/update_limb(dropping_limb, is_creating)
. = ..()
if(!isnull(owner))
- real_name = owner.real_name
- if(HAS_TRAIT(owner, TRAIT_HUSK))
- real_name = "Unknown"
+ if(HAS_TRAIT(owner, TRAIT_HUSK))
+ real_name = "Unknown"
+ else
+ real_name = owner.real_name
update_hair_and_lips(dropping_limb, is_creating)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/code/modules/surgery/bodyparts/parts.dm b/code/modules/surgery/bodyparts/parts.dm
index cbe533de54d..4207f3541f6 100644
--- a/code/modules/surgery/bodyparts/parts.dm
+++ b/code/modules/surgery/bodyparts/parts.dm
@@ -53,7 +53,7 @@
if(cavity_item)
cavity_item.forceMove(drop_location())
cavity_item = null
- ..()
+ return ..()
/obj/item/bodypart/chest/monkey
icon = 'icons/mob/human/species/monkey/bodyparts.dmi'
@@ -114,6 +114,8 @@
/// Datum describing how to offset things held in the hands of this arm, the x offset IS functional here
var/datum/worn_feature_offset/held_hand_offset
+ biological_state = BIO_STANDARD_JOINTED
+
/obj/item/bodypart/arm/Destroy()
QDEL_NULL(worn_glove_offset)
QDEL_NULL(held_hand_offset)
@@ -344,6 +346,8 @@
/// Datum describing how to offset things worn on the foot of this leg, note that an x offset won't do anything here
var/datum/worn_feature_offset/worn_foot_offset
+ biological_state = BIO_STANDARD_JOINTED
+
/obj/item/bodypart/leg/Destroy()
QDEL_NULL(worn_foot_offset)
return ..()
diff --git a/code/modules/surgery/bodyparts/robot_bodyparts.dm b/code/modules/surgery/bodyparts/robot_bodyparts.dm
index cd0ac286559..37b6cef9897 100644
--- a/code/modules/surgery/bodyparts/robot_bodyparts.dm
+++ b/code/modules/surgery/bodyparts/robot_bodyparts.dm
@@ -1,3 +1,4 @@
+
#define ROBOTIC_LIGHT_BRUTE_MSG "marred"
#define ROBOTIC_MEDIUM_BRUTE_MSG "dented"
#define ROBOTIC_HEAVY_BRUTE_MSG "falling apart"
@@ -37,6 +38,8 @@
medium_burn_msg = ROBOTIC_MEDIUM_BURN_MSG
heavy_burn_msg = ROBOTIC_HEAVY_BURN_MSG
+ biological_state = (BIO_ROBOTIC|BIO_JOINTED)
+
damage_examines = list(BRUTE = ROBOTIC_BRUTE_EXAMINE_TEXT, BURN = ROBOTIC_BURN_EXAMINE_TEXT, CLONE = DEFAULT_CLONE_EXAMINE_TEXT)
disabling_threshold_percentage = 1
@@ -58,6 +61,7 @@
brute_modifier = 0.8
burn_modifier = 0.8
+
disabling_threshold_percentage = 1
light_brute_msg = ROBOTIC_LIGHT_BRUTE_MSG
@@ -68,6 +72,8 @@
medium_burn_msg = ROBOTIC_MEDIUM_BURN_MSG
heavy_burn_msg = ROBOTIC_HEAVY_BURN_MSG
+ biological_state = (BIO_ROBOTIC|BIO_JOINTED)
+
damage_examines = list(BRUTE = ROBOTIC_BRUTE_EXAMINE_TEXT, BURN = ROBOTIC_BURN_EXAMINE_TEXT, CLONE = DEFAULT_CLONE_EXAMINE_TEXT)
/obj/item/bodypart/leg/left/robot
@@ -88,6 +94,7 @@
brute_modifier = 0.8
burn_modifier = 0.8
+
disabling_threshold_percentage = 1
light_brute_msg = ROBOTIC_LIGHT_BRUTE_MSG
@@ -98,16 +105,21 @@
medium_burn_msg = ROBOTIC_MEDIUM_BURN_MSG
heavy_burn_msg = ROBOTIC_HEAVY_BURN_MSG
+ biological_state = (BIO_ROBOTIC|BIO_JOINTED)
+
damage_examines = list(BRUTE = ROBOTIC_BRUTE_EXAMINE_TEXT, BURN = ROBOTIC_BURN_EXAMINE_TEXT, CLONE = DEFAULT_CLONE_EXAMINE_TEXT)
/obj/item/bodypart/leg/left/robot/emp_act(severity)
. = ..()
if(!.)
return
- owner.Knockdown(severity == EMP_HEAVY ? 20 SECONDS : 10 SECONDS)
+ var/knockdown_time = AUGGED_LEG_EMP_KNOCKDOWN_TIME
+ if (severity == EMP_HEAVY)
+ knockdown_time *= 2
+ owner.Knockdown(knockdown_time)
if(owner.incapacitated(IGNORE_RESTRAINTS|IGNORE_GRAB)) // So the message isn't duplicated. If they were stunned beforehand by something else, then the message not showing makes more sense anyways.
return
- to_chat(owner, span_danger("As your [src.name] unexpectedly malfunctions, it causes you to fall to the ground!"))
+ to_chat(owner, span_danger("As your [src] unexpectedly malfunctions, it causes you to fall to the ground!"))
/obj/item/bodypart/leg/right/robot
name = "cyborg right leg"
@@ -127,6 +139,7 @@
brute_modifier = 0.8
burn_modifier = 0.8
+
disabling_threshold_percentage = 1
light_brute_msg = ROBOTIC_LIGHT_BRUTE_MSG
@@ -137,16 +150,21 @@
medium_burn_msg = ROBOTIC_MEDIUM_BURN_MSG
heavy_burn_msg = ROBOTIC_HEAVY_BURN_MSG
+ biological_state = (BIO_ROBOTIC|BIO_JOINTED)
+
damage_examines = list(BRUTE = ROBOTIC_BRUTE_EXAMINE_TEXT, BURN = ROBOTIC_BURN_EXAMINE_TEXT, CLONE = DEFAULT_CLONE_EXAMINE_TEXT)
/obj/item/bodypart/leg/right/robot/emp_act(severity)
. = ..()
if(!.)
return
- owner.Knockdown(severity == EMP_HEAVY ? 20 SECONDS : 10 SECONDS)
+ var/knockdown_time = AUGGED_LEG_EMP_KNOCKDOWN_TIME
+ if (severity == EMP_HEAVY)
+ knockdown_time *= 2
+ owner.Knockdown(knockdown_time)
if(owner.incapacitated(IGNORE_RESTRAINTS|IGNORE_GRAB)) // So the message isn't duplicated. If they were stunned beforehand by something else, then the message not showing makes more sense anyways.
return
- to_chat(owner, span_danger("As your [src.name] unexpectedly malfunctions, it causes you to fall to the ground!"))
+ to_chat(owner, span_danger("As your [src] unexpectedly malfunctions, it causes you to fall to the ground!"))
/obj/item/bodypart/chest/robot
name = "cyborg torso"
@@ -174,23 +192,36 @@
medium_burn_msg = ROBOTIC_MEDIUM_BURN_MSG
heavy_burn_msg = ROBOTIC_HEAVY_BURN_MSG
+ biological_state = (BIO_ROBOTIC)
+
damage_examines = list(BRUTE = ROBOTIC_BRUTE_EXAMINE_TEXT, BURN = ROBOTIC_BURN_EXAMINE_TEXT, CLONE = DEFAULT_CLONE_EXAMINE_TEXT)
var/wired = FALSE
var/obj/item/stock_parts/cell/cell = null
+ robotic_emp_paralyze_damage_percent_threshold = 0.6
+
/obj/item/bodypart/chest/robot/emp_act(severity)
. = ..()
if(!.)
return
- to_chat(owner, span_danger("Your [src.name]'s logic boards temporarily become unresponsive!"))
- if(severity == EMP_HEAVY)
- owner.Stun(6 SECONDS)
- owner.Shake(pixelshiftx = 5, pixelshifty = 2, duration = 4 SECONDS)
- return
- owner.Stun(3 SECONDS)
- owner.Shake(pixelshiftx = 3, pixelshifty = 0, duration = 2.5 SECONDS)
+ var/stun_time = 0
+ var/shift_x = 3
+ var/shift_y = 0
+ var/shake_duration = AUGGED_CHEST_EMP_SHAKE_TIME
+
+ if(severity == EMP_HEAVY)
+ stun_time = AUGGED_CHEST_EMP_STUN_TIME
+
+ shift_x = 5
+ shift_y = 2
+
+ var/damage_percent_to_max = (get_damage() / max_damage)
+ if (stun_time && (damage_percent_to_max >= robotic_emp_paralyze_damage_percent_threshold))
+ to_chat(owner, span_danger("Your [src]'s logic boards temporarily become unresponsive!"))
+ owner.Stun(stun_time)
+ owner.Shake(pixelshiftx = shift_x, pixelshifty = shift_y, duration = shake_duration)
/obj/item/bodypart/chest/robot/get_cell()
return cell
@@ -294,6 +325,8 @@
medium_burn_msg = ROBOTIC_MEDIUM_BURN_MSG
heavy_burn_msg = ROBOTIC_HEAVY_BURN_MSG
+ biological_state = (BIO_ROBOTIC)
+
damage_examines = list(BRUTE = ROBOTIC_BRUTE_EXAMINE_TEXT, BURN = ROBOTIC_BURN_EXAMINE_TEXT, CLONE = DEFAULT_CLONE_EXAMINE_TEXT)
head_flags = HEAD_EYESPRITES
@@ -307,9 +340,11 @@
. = ..()
if(!.)
return
- to_chat(owner, span_danger("Your [src.name]'s optical transponders glitch out and malfunction!"))
+ to_chat(owner, span_danger("Your [src]'s optical transponders glitch out and malfunction!"))
- var/glitch_duration = severity == EMP_HEAVY ? 15 SECONDS : 7.5 SECONDS
+ var/glitch_duration = AUGGED_HEAD_EMP_GLITCH_DURATION
+ if (severity == EMP_HEAVY)
+ glitch_duration *= 2
owner.add_client_colour(/datum/client_colour/malfunction)
@@ -380,6 +415,11 @@
flash2?.forceMove(drop_loc)
return ..()
+// Prosthetics - Cheap, mediocre, and worse than organic limbs
+// The fact they dont have a internal biotype means theyre a lot weaker defensively,
+// since they skip slash and go right to blunt
+// They are VERY easy to delimb as a result
+// HP is also reduced just in case this isnt enough
/obj/item/bodypart/arm/left/robot/surplus
name = "surplus prosthetic left arm"
@@ -388,7 +428,9 @@
icon = 'icons/mob/augmentation/surplus_augments.dmi'
burn_modifier = 1
brute_modifier = 1
- max_damage = 20
+ max_damage = PROSTHESIS_MAX_HP
+
+ biological_state = (BIO_METAL|BIO_JOINTED)
/obj/item/bodypart/arm/right/robot/surplus
name = "surplus prosthetic right arm"
@@ -397,7 +439,9 @@
icon = 'icons/mob/augmentation/surplus_augments.dmi'
burn_modifier = 1
brute_modifier = 1
- max_damage = 20
+ max_damage = PROSTHESIS_MAX_HP
+
+ biological_state = (BIO_METAL|BIO_JOINTED)
/obj/item/bodypart/leg/left/robot/surplus
name = "surplus prosthetic left leg"
@@ -406,7 +450,9 @@
icon = 'icons/mob/augmentation/surplus_augments.dmi'
brute_modifier = 1
burn_modifier = 1
- max_damage = 20
+ max_damage = PROSTHESIS_MAX_HP
+
+ biological_state = (BIO_METAL|BIO_JOINTED)
/obj/item/bodypart/leg/right/robot/surplus
name = "surplus prosthetic right leg"
@@ -415,7 +461,9 @@
icon = 'icons/mob/augmentation/surplus_augments.dmi'
brute_modifier = 1
burn_modifier = 1
- max_damage = 20
+ max_damage = PROSTHESIS_MAX_HP
+
+ biological_state = (BIO_METAL|BIO_JOINTED)
#undef ROBOTIC_LIGHT_BRUTE_MSG
#undef ROBOTIC_MEDIUM_BRUTE_MSG
diff --git a/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm
index e57c014c02b..1126d1ee036 100644
--- a/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm
+++ b/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm
@@ -1,19 +1,19 @@
///SNAIL
/obj/item/bodypart/head/snail
- biological_state = BIO_FLESH //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
+ biological_state = (BIO_BLOODED|BIO_FLESH) //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
limb_id = SPECIES_SNAIL
is_dimorphic = FALSE
burn_modifier = 2
head_flags = HEAD_EYESPRITES|HEAD_DEBRAIN
/obj/item/bodypart/chest/snail
- biological_state = BIO_FLESH //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
+ biological_state = (BIO_BLOODED|BIO_FLESH) //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
limb_id = SPECIES_SNAIL
is_dimorphic = FALSE
burn_modifier = 2
/obj/item/bodypart/arm/left/snail
- biological_state = BIO_FLESH //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
+ biological_state = (BIO_BLOODED|BIO_FLESH) //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
limb_id = SPECIES_SNAIL
unarmed_attack_verb = "slap"
unarmed_attack_effect = ATTACK_EFFECT_DISARM
@@ -22,7 +22,7 @@
burn_modifier = 2
/obj/item/bodypart/arm/right/snail
- biological_state = BIO_FLESH //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
+ biological_state = (BIO_BLOODED|BIO_FLESH) //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
limb_id = SPECIES_SNAIL
unarmed_attack_verb = "slap"
unarmed_attack_effect = ATTACK_EFFECT_DISARM
@@ -31,7 +31,7 @@
burn_modifier = 2
/obj/item/bodypart/leg/left/snail
- biological_state = BIO_FLESH //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
+ biological_state = (BIO_BLOODED|BIO_FLESH) //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
limb_id = SPECIES_SNAIL
unarmed_damage_low = 1 //SKYRAT EDIT - Roundstart Snails - Lowest possible punch damage. if this is set to 0, punches will always miss.
unarmed_damage_high = 5 //snails are soft and squishy //SKYRAT EDIT - Roundstart Snails - A Bit More Damage. - ORIGINAL: unarmed_damage_high = 0.5 //snails are soft and squishy
@@ -39,7 +39,7 @@
// speed_modifier = 3 //disgustingly slow // SKYRAT EDIT - Moved the movespeed to the shell.
/obj/item/bodypart/leg/right/snail
- biological_state = BIO_FLESH //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
+ biological_state = (BIO_BLOODED|BIO_FLESH) //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
limb_id = SPECIES_SNAIL
unarmed_damage_low = 1 //SKYRAT EDIT - Roundstart Snails - Lowest possible punch damage. if this is set to 0, punches will always miss.
unarmed_damage_high = 5 //snails are soft and squishy //SKYRAT EDIT - Roundstart Snails - A Bit More Damage. - ORIGINAL: unarmed_damage_high = 0.5 //snails are soft and squishy
@@ -48,43 +48,37 @@
///ABDUCTOR
/obj/item/bodypart/head/abductor
- biological_state = BIO_INORGANIC //i have no fucking clue why these mfs get no wounds but SURE
limb_id = SPECIES_ABDUCTOR
is_dimorphic = FALSE
should_draw_greyscale = FALSE
head_flags = NONE
/obj/item/bodypart/chest/abductor
- biological_state = BIO_INORGANIC
limb_id = SPECIES_ABDUCTOR
is_dimorphic = FALSE
should_draw_greyscale = FALSE
/obj/item/bodypart/arm/left/abductor
- biological_state = BIO_INORGANIC
limb_id = SPECIES_ABDUCTOR
should_draw_greyscale = FALSE
bodypart_traits = list(TRAIT_CHUNKYFINGERS)
/obj/item/bodypart/arm/right/abductor
- biological_state = BIO_INORGANIC
limb_id = SPECIES_ABDUCTOR
should_draw_greyscale = FALSE
bodypart_traits = list(TRAIT_CHUNKYFINGERS)
/obj/item/bodypart/leg/left/abductor
- biological_state = BIO_INORGANIC
limb_id = SPECIES_ABDUCTOR
should_draw_greyscale = FALSE
/obj/item/bodypart/leg/right/abductor
- biological_state = BIO_INORGANIC
limb_id = SPECIES_ABDUCTOR
should_draw_greyscale = FALSE
///JELLY
/obj/item/bodypart/head/jelly
- biological_state = BIO_INORGANIC
+ biological_state = (BIO_FLESH|BIO_BLOODED)
limb_id = SPECIES_JELLYPERSON
is_dimorphic = TRUE
dmg_overlay_type = null
@@ -92,90 +86,90 @@
head_flags = HEAD_ALL_FEATURES
/obj/item/bodypart/chest/jelly
- biological_state = BIO_INORGANIC
+ biological_state = (BIO_FLESH|BIO_BLOODED)
limb_id = SPECIES_JELLYPERSON
is_dimorphic = TRUE
dmg_overlay_type = null
burn_modifier = 0.5 // = 1/2x generic burn damage
/obj/item/bodypart/arm/left/jelly
- biological_state = BIO_INORGANIC
+ biological_state = (BIO_FLESH|BIO_BLOODED|BIO_JOINTED)
limb_id = SPECIES_JELLYPERSON
dmg_overlay_type = null
burn_modifier = 0.5 // = 1/2x generic burn damage
/obj/item/bodypart/arm/right/jelly
- biological_state = BIO_INORGANIC
+ biological_state = (BIO_FLESH|BIO_BLOODED|BIO_JOINTED)
limb_id = SPECIES_JELLYPERSON
dmg_overlay_type = null
burn_modifier = 0.5 // = 1/2x generic burn damage
/obj/item/bodypart/leg/left/jelly
- biological_state = BIO_INORGANIC
+ biological_state = (BIO_FLESH|BIO_BLOODED|BIO_JOINTED)
limb_id = SPECIES_JELLYPERSON
dmg_overlay_type = null
burn_modifier = 0.5 // = 1/2x generic burn damage
/obj/item/bodypart/leg/right/jelly
- biological_state = BIO_INORGANIC
+ biological_state = (BIO_FLESH|BIO_BLOODED|BIO_JOINTED)
limb_id = SPECIES_JELLYPERSON
dmg_overlay_type = null
burn_modifier = 0.5 // = 1/2x generic burn damage
///SLIME
/obj/item/bodypart/head/slime
- biological_state = BIO_INORGANIC
+ biological_state = (BIO_FLESH|BIO_BLOODED)
limb_id = SPECIES_SLIMEPERSON
is_dimorphic = FALSE
head_flags = HEAD_ALL_FEATURES
/obj/item/bodypart/chest/slime
- biological_state = BIO_INORGANIC
+ biological_state = (BIO_FLESH|BIO_BLOODED)
limb_id = SPECIES_SLIMEPERSON
is_dimorphic = TRUE
/obj/item/bodypart/arm/left/slime
- biological_state = BIO_INORGANIC
+ biological_state = (BIO_FLESH|BIO_BLOODED|BIO_JOINTED)
limb_id = SPECIES_SLIMEPERSON
/obj/item/bodypart/arm/right/slime
- biological_state = BIO_INORGANIC
+ biological_state = (BIO_FLESH|BIO_BLOODED|BIO_JOINTED)
limb_id = SPECIES_SLIMEPERSON
/obj/item/bodypart/leg/left/slime
- biological_state = BIO_INORGANIC
+ biological_state = (BIO_FLESH|BIO_BLOODED)
limb_id = SPECIES_SLIMEPERSON
/obj/item/bodypart/leg/right/slime
- biological_state = BIO_INORGANIC
+ biological_state = (BIO_FLESH|BIO_BLOODED|BIO_JOINTED)
limb_id = SPECIES_SLIMEPERSON
///LUMINESCENT
/obj/item/bodypart/head/luminescent
- biological_state = BIO_INORGANIC
+ biological_state = (BIO_FLESH|BIO_BLOODED)
limb_id = SPECIES_LUMINESCENT
is_dimorphic = TRUE
head_flags = HEAD_ALL_FEATURES
/obj/item/bodypart/chest/luminescent
- biological_state = BIO_INORGANIC
+ biological_state = (BIO_FLESH|BIO_BLOODED)
limb_id = SPECIES_LUMINESCENT
is_dimorphic = TRUE
/obj/item/bodypart/arm/left/luminescent
- biological_state = BIO_INORGANIC
+ biological_state = (BIO_FLESH|BIO_BLOODED|BIO_JOINTED)
limb_id = SPECIES_LUMINESCENT
/obj/item/bodypart/arm/right/luminescent
- biological_state = BIO_INORGANIC
+ biological_state = (BIO_FLESH|BIO_BLOODED|BIO_JOINTED)
limb_id = SPECIES_LUMINESCENT
/obj/item/bodypart/leg/left/luminescent
- biological_state = BIO_INORGANIC
+ biological_state = (BIO_FLESH|BIO_BLOODED|BIO_JOINTED)
limb_id = SPECIES_LUMINESCENT
/obj/item/bodypart/leg/right/luminescent
- biological_state = BIO_INORGANIC
+ biological_state = (BIO_FLESH|BIO_BLOODED|BIO_JOINTED)
limb_id = SPECIES_LUMINESCENT
///ZOMBIE
@@ -282,7 +276,6 @@
///SHADOW
/obj/item/bodypart/head/shadow
- biological_state = BIO_INORGANIC
limb_id = SPECIES_SHADOW
is_dimorphic = FALSE
should_draw_greyscale = FALSE
@@ -290,32 +283,27 @@
head_flags = NONE
/obj/item/bodypart/chest/shadow
- biological_state = BIO_INORGANIC
limb_id = SPECIES_SHADOW
is_dimorphic = FALSE
should_draw_greyscale = FALSE
burn_modifier = 1.5
/obj/item/bodypart/arm/left/shadow
- biological_state = BIO_INORGANIC
limb_id = SPECIES_SHADOW
should_draw_greyscale = FALSE
burn_modifier = 1.5
/obj/item/bodypart/arm/right/shadow
- biological_state = BIO_INORGANIC
limb_id = SPECIES_SHADOW
should_draw_greyscale = FALSE
burn_modifier = 1.5
/obj/item/bodypart/leg/left/shadow
- biological_state = BIO_INORGANIC
limb_id = SPECIES_SHADOW
should_draw_greyscale = FALSE
burn_modifier = 1.5
/obj/item/bodypart/leg/right/shadow
- biological_state = BIO_INORGANIC
limb_id = SPECIES_SHADOW
should_draw_greyscale = FALSE
burn_modifier = 1.5
@@ -343,25 +331,25 @@
dmg_overlay_type = null
/obj/item/bodypart/arm/left/skeleton
- biological_state = BIO_BONE
+ biological_state = (BIO_BONE|BIO_JOINTED)
limb_id = SPECIES_SKELETON
should_draw_greyscale = FALSE
dmg_overlay_type = null
/obj/item/bodypart/arm/right/skeleton
- biological_state = BIO_BONE
+ biological_state = (BIO_BONE|BIO_JOINTED)
limb_id = SPECIES_SKELETON
should_draw_greyscale = FALSE
dmg_overlay_type = null
/obj/item/bodypart/leg/left/skeleton
- biological_state = BIO_BONE
+ biological_state = (BIO_BONE|BIO_JOINTED)
limb_id = SPECIES_SKELETON
should_draw_greyscale = FALSE
dmg_overlay_type = null
/obj/item/bodypart/leg/right/skeleton
- biological_state = BIO_BONE
+ biological_state = (BIO_BONE|BIO_JOINTED)
limb_id = SPECIES_SKELETON
should_draw_greyscale = FALSE
dmg_overlay_type = null
@@ -414,7 +402,7 @@
icon = 'icons/mob/human/species/golems.dmi'
icon_static = 'icons/mob/human/species/golems.dmi'
icon_state = "golem_head"
- biological_state = BIO_INORGANIC
+ biological_state = BIO_BONE
bodytype = BODYTYPE_GOLEM | BODYTYPE_ORGANIC
limb_id = SPECIES_GOLEM
is_dimorphic = FALSE
@@ -451,7 +439,7 @@
icon = 'icons/mob/human/species/golems.dmi'
icon_static = 'icons/mob/human/species/golems.dmi'
icon_state = "golem_chest"
- biological_state = BIO_INORGANIC
+ biological_state = BIO_BONE
acceptable_bodytype = BODYTYPE_GOLEM
bodytype = BODYTYPE_GOLEM | BODYTYPE_ORGANIC
limb_id = SPECIES_GOLEM
@@ -472,7 +460,7 @@
icon = 'icons/mob/human/species/golems.dmi'
icon_static = 'icons/mob/human/species/golems.dmi'
icon_state = "golem_l_arm"
- biological_state = BIO_INORGANIC
+ biological_state = (BIO_BONE|BIO_JOINTED)
bodytype = BODYTYPE_GOLEM | BODYTYPE_ORGANIC
limb_id = SPECIES_GOLEM
should_draw_greyscale = FALSE
@@ -506,7 +494,7 @@
icon = 'icons/mob/human/species/golems.dmi'
icon_static = 'icons/mob/human/species/golems.dmi'
icon_state = "golem_r_arm"
- biological_state = BIO_INORGANIC
+ biological_state = (BIO_BONE|BIO_JOINTED)
bodytype = BODYTYPE_GOLEM | BODYTYPE_ORGANIC
limb_id = SPECIES_GOLEM
should_draw_greyscale = FALSE
@@ -540,7 +528,7 @@
icon = 'icons/mob/human/species/golems.dmi'
icon_static = 'icons/mob/human/species/golems.dmi'
icon_state = "golem_l_leg"
- biological_state = BIO_INORGANIC
+ biological_state = (BIO_BONE|BIO_JOINTED)
bodytype = BODYTYPE_GOLEM | BODYTYPE_ORGANIC
limb_id = SPECIES_GOLEM
should_draw_greyscale = FALSE
@@ -553,7 +541,7 @@
icon = 'icons/mob/human/species/golems.dmi'
icon_static = 'icons/mob/human/species/golems.dmi'
icon_state = "golem_r_leg"
- biological_state = BIO_INORGANIC
+ biological_state = (BIO_BONE|BIO_JOINTED)
bodytype = BODYTYPE_GOLEM | BODYTYPE_ORGANIC
limb_id = SPECIES_GOLEM
should_draw_greyscale = FALSE
diff --git a/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm
index 85eea7edba0..f478d522d56 100644
--- a/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm
+++ b/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm
@@ -27,7 +27,7 @@
icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi'
icon_state = "plasmaman_l_arm"
icon_static = 'icons/mob/human/species/plasmaman/bodyparts.dmi'
- biological_state = BIO_BONE
+ biological_state = (BIO_BONE|BIO_JOINTED)
limb_id = SPECIES_PLASMAMAN
should_draw_greyscale = FALSE
dmg_overlay_type = null
@@ -38,7 +38,7 @@
icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi'
icon_state = "plasmaman_r_arm"
icon_static = 'icons/mob/human/species/plasmaman/bodyparts.dmi'
- biological_state = BIO_BONE
+ biological_state = (BIO_BONE|BIO_JOINTED)
limb_id = SPECIES_PLASMAMAN
should_draw_greyscale = FALSE
dmg_overlay_type = null
@@ -49,7 +49,7 @@
icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi'
icon_state = "plasmaman_l_leg"
icon_static = 'icons/mob/human/species/plasmaman/bodyparts.dmi'
- biological_state = BIO_BONE
+ biological_state = (BIO_BONE|BIO_JOINTED)
limb_id = SPECIES_PLASMAMAN
should_draw_greyscale = FALSE
dmg_overlay_type = null
@@ -60,7 +60,7 @@
icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi'
icon_state = "plasmaman_r_leg"
icon_static = 'icons/mob/human/species/plasmaman/bodyparts.dmi'
- biological_state = BIO_BONE
+ biological_state = (BIO_BONE|BIO_JOINTED)
limb_id = SPECIES_PLASMAMAN
should_draw_greyscale = FALSE
dmg_overlay_type = null
diff --git a/code/modules/surgery/bodyparts/wounds.dm b/code/modules/surgery/bodyparts/wounds.dm
index 1961993ec64..1b50dbc8fd1 100644
--- a/code/modules/surgery/bodyparts/wounds.dm
+++ b/code/modules/surgery/bodyparts/wounds.dm
@@ -1,47 +1,40 @@
/// Allows us to roll for and apply a wound without actually dealing damage. Used for aggregate wounding power with pellet clouds
-/obj/item/bodypart/proc/painless_wound_roll(wounding_type, phantom_wounding_dmg, wound_bonus, bare_wound_bonus, sharpness=NONE)
+/obj/item/bodypart/proc/painless_wound_roll(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus, sharpness=NONE)
SHOULD_CALL_PARENT(TRUE)
- if(!owner || phantom_wounding_dmg <= WOUND_MINIMUM_DAMAGE || wound_bonus == CANT_WOUND || (owner.status_flags & GODMODE))
+ if(!owner || wounding_dmg <= WOUND_MINIMUM_DAMAGE || wound_bonus == CANT_WOUND || (owner.status_flags & GODMODE))
return
var/mangled_state = get_mangled_state()
var/easy_dismember = HAS_TRAIT(owner, TRAIT_EASYDISMEMBER) // if we have easydismember, we don't reduce damage when redirecting damage to different types (slashing weapons on mangled/skinless limbs attack at 100% instead of 50%)
- if(wounding_type == WOUND_BLUNT && sharpness)
- if(sharpness & SHARP_EDGED)
- wounding_type = WOUND_SLASH
- else if (sharpness & SHARP_POINTY)
- wounding_type = WOUND_PIERCE
+ var/bio_status = get_bio_state_status()
- //Handling for bone only/flesh only(none right now)/flesh and bone targets
- switch(biological_state)
- // if we're bone only, all cutting attacks go straight to the bone
- if(BIO_BONE)
- if(wounding_type == WOUND_SLASH)
- wounding_type = WOUND_BLUNT
- phantom_wounding_dmg *= (easy_dismember ? 1 : 0.6)
- else if(wounding_type == WOUND_PIERCE)
- wounding_type = WOUND_BLUNT
- phantom_wounding_dmg *= (easy_dismember ? 1 : 0.75)
- if((mangled_state & BODYPART_MANGLED_BONE) && try_dismember(wounding_type, phantom_wounding_dmg, wound_bonus, bare_wound_bonus))
- return
- // note that there's no handling for BIO_FLESH since we don't have any that are that right now (slimepeople maybe someday)
- // standard humanoids
- if(BIO_FLESH_BONE)
- // if we've already mangled the skin (critical slash or piercing wound), then the bone is exposed, and we can damage it with sharp weapons at a reduced rate
- // So a big sharp weapon is still all you need to destroy a limb
- if((mangled_state & BODYPART_MANGLED_FLESH) && !(mangled_state & BODYPART_MANGLED_BONE) && sharpness)
- playsound(src, "sound/effects/wounds/crackandbleed.ogg", 100)
- if(wounding_type == WOUND_SLASH && !easy_dismember)
- phantom_wounding_dmg *= 0.6 // edged weapons pass along 60% of their wounding damage to the bone since the power is spread out over a larger area
- if(wounding_type == WOUND_PIERCE && !easy_dismember)
- phantom_wounding_dmg *= 0.75 // piercing weapons pass along 75% of their wounding damage to the bone since it's more concentrated
- wounding_type = WOUND_BLUNT
- else if((mangled_state & BODYPART_MANGLED_FLESH) && (mangled_state & BODYPART_MANGLED_BONE) && try_dismember(wounding_type, phantom_wounding_dmg, wound_bonus, bare_wound_bonus))
- return
+ var/has_exterior = ((bio_status & ANATOMY_EXTERIOR))
+ var/has_interior = ((bio_status & ANATOMY_INTERIOR))
- check_wounding(wounding_type, phantom_wounding_dmg, wound_bonus, bare_wound_bonus)
+ var/exterior_ready_to_dismember = (!has_exterior || ((mangled_state & BODYPART_MANGLED_EXTERIOR)))
+
+ // if we're bone only, all cutting attacks go straight to the bone
+ if(!has_exterior && has_interior)
+ if(wounding_type == WOUND_SLASH)
+ wounding_type = WOUND_BLUNT
+ wounding_dmg *= (easy_dismember ? 1 : 0.6)
+ else if(wounding_type == WOUND_PIERCE)
+ wounding_type = WOUND_BLUNT
+ wounding_dmg *= (easy_dismember ? 1 : 0.75)
+ else
+ // if we've already mangled the skin (critical slash or piercing wound), then the bone is exposed, and we can damage it with sharp weapons at a reduced rate
+ // So a big sharp weapon is still all you need to destroy a limb
+ if(has_interior && exterior_ready_to_dismember && !(mangled_state & BODYPART_MANGLED_INTERIOR) && sharpness)
+ if(wounding_type == WOUND_SLASH && !easy_dismember)
+ wounding_dmg *= 0.6 // edged weapons pass along 60% of their wounding damage to the bone since the power is spread out over a larger area
+ if(wounding_type == WOUND_PIERCE && !easy_dismember)
+ wounding_dmg *= 0.75 // piercing weapons pass along 75% of their wounding damage to the bone since it's more concentrated
+ wounding_type = WOUND_BLUNT
+ if ((dismemberable_by_wound() || dismemberable_by_total_damage()) && try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus))
+ return
+ return check_wounding(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus)
/**
* check_wounding() is where we handle rolling for, selecting, and applying a wound if we meet the criteria
@@ -77,12 +70,18 @@
var/base_roll = rand(1, round(damage ** WOUND_DAMAGE_EXPONENT))
var/injury_roll = base_roll
injury_roll += check_woundings_mods(woundtype, damage, wound_bonus, bare_wound_bonus)
+ var/list/series_wounding_mods = check_series_wounding_mods()
+
if(injury_roll > WOUND_DISMEMBER_OUTRIGHT_THRESH && prob(get_damage() / max_damage * 100))
var/datum/wound/loss/dismembering = new
dismembering.apply_dismember(src, woundtype, outright = TRUE, attack_direction = attack_direction)
return
- var/list/wounds_checking = GLOB.global_wound_types[woundtype]
+ var/list/datum/wound/possible_wounds = list()
+ for (var/datum/wound/type as anything in GLOB.all_wound_pregen_data)
+ var/datum/wound_pregen_data/pregen_data = GLOB.all_wound_pregen_data[type]
+ if (pregen_data.can_be_applied_to(src, list(woundtype), random_roll = TRUE))
+ possible_wounds[type] = pregen_data.get_weight(src, woundtype, damage, attack_direction, damage_source)
// 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
@@ -93,39 +92,137 @@
bare_wound_bonus = 0
break
- //cycle through the wounds of the relevant category from the most severe down
- for(var/datum/wound/possible_wound as anything in wounds_checking)
+ for (var/datum/wound/iterated_path as anything in possible_wounds)
+ for (var/datum/wound/existing_wound as anything in wounds)
+ if (iterated_path == existing_wound.type)
+ possible_wounds -= iterated_path
+ break // breaks out of the nested loop
+
+ var/datum/wound_pregen_data/pregen_data = GLOB.all_wound_pregen_data[iterated_path]
+ var/specific_injury_roll = (injury_roll + series_wounding_mods[pregen_data.wound_series])
+ if (pregen_data.get_threshold_for(src, attack_direction, damage_source) > specific_injury_roll)
+ possible_wounds -= iterated_path
+ continue
+
+ if (pregen_data.compete_for_wounding)
+ for (var/datum/wound/other_path as anything in possible_wounds)
+ if (other_path == iterated_path)
+ continue
+ if (initial(iterated_path.severity) == initial(other_path.severity) && pregen_data.overpower_wounds_of_even_severity)
+ possible_wounds -= other_path
+ continue
+ else if (pregen_data.competition_mode == WOUND_COMPETITION_OVERPOWER_LESSERS)
+ if (initial(iterated_path.severity) > initial(other_path.severity))
+ possible_wounds -= other_path
+ continue
+ else if (pregen_data.competition_mode == WOUND_COMPETITION_OVERPOWER_GREATERS)
+ if (initial(iterated_path.severity) < initial(other_path.severity))
+ possible_wounds -= other_path
+ continue
+
+ while (length(possible_wounds))
+ var/datum/wound/possible_wound = pick_weight(possible_wounds)
+ var/datum/wound_pregen_data/possible_pregen_data = GLOB.all_wound_pregen_data[possible_wound]
+ possible_wounds -= possible_wound
+
var/datum/wound/replaced_wound
for(var/datum/wound/existing_wound as anything in wounds)
- if(existing_wound.type in wounds_checking)
+ var/datum/wound_pregen_data/existing_pregen_data = GLOB.all_wound_pregen_data[existing_wound.type]
+ if(existing_pregen_data.wound_series == possible_pregen_data.wound_series)
if(existing_wound.severity >= initial(possible_wound.severity))
- return
+ continue
else
replaced_wound = existing_wound
+ // if we get through this whole loop without continuing, we found our winner
- if(initial(possible_wound.threshold_minimum) < injury_roll)
- var/datum/wound/new_wound
- if(replaced_wound)
- new_wound = replaced_wound.replace_wound(possible_wound, attack_direction = attack_direction)
- else
- new_wound = new possible_wound
- new_wound.apply_wound(src, attack_direction = attack_direction, wound_source = damage_source)
- log_wound(owner, new_wound, damage, wound_bonus, bare_wound_bonus, base_roll) // dismembering wounds are logged in the apply_wound() for loss wounds since they delete themselves immediately, these will be immediately returned
- return new_wound
+ var/datum/wound/new_wound = new possible_wound
+ if(replaced_wound)
+ new_wound = replaced_wound.replace_wound(new_wound, attack_direction = attack_direction)
+ else
+ new_wound.apply_wound(src, attack_direction = attack_direction, wound_source = damage_source)
+ log_wound(owner, new_wound, damage, wound_bonus, bare_wound_bonus, base_roll) // dismembering wounds are logged in the apply_wound() for loss wounds since they delete themselves immediately, these will be immediately returned
+ return new_wound
// try forcing a specific wound, but only if there isn't already a wound of that severity or greater for that type on this bodypart
-/obj/item/bodypart/proc/force_wound_upwards(specific_woundtype, smited = FALSE, wound_source)
+/obj/item/bodypart/proc/force_wound_upwards(datum/wound/potential_wound, smited = FALSE, wound_source)
SHOULD_NOT_OVERRIDE(TRUE)
- var/datum/wound/potential_wound = specific_woundtype
+ if (isnull(potential_wound))
+ return
+
+ var/datum/wound_pregen_data/pregen_data = GLOB.all_wound_pregen_data[potential_wound]
for(var/datum/wound/existing_wound as anything in wounds)
- if(existing_wound.wound_type == initial(potential_wound.wound_type))
+ var/datum/wound_pregen_data/existing_pregen_data = existing_wound.get_pregen_data()
+ if (existing_pregen_data.wound_series == pregen_data.wound_series)
if(existing_wound.severity < initial(potential_wound.severity)) // we only try if the existing one is inferior to the one we're trying to force
- existing_wound.replace_wound(potential_wound, smited)
+ existing_wound.replace_wound(new potential_wound, smited)
return
var/datum/wound/new_wound = new potential_wound
new_wound.apply_wound(src, smited = smited, wound_source = wound_source)
+ return new_wound
+
+/**
+ * A simple proc to force a type of wound onto this mob. If you just want to force a specific mainline (fractures, bleeding, etc.) wound, you only need to care about the first 3 args.
+ *
+ * Args:
+ * * wounding_type: The wounding_type, e.g. WOUND_BLUNT, WOUND_SLASH to force onto the mob. Can be a list.
+ * * obj/item/bodypart/limb: The limb we wil be applying the wound to. If null, a random bodypart will be picked.
+ * * min_severity: The minimum severity that will be considered.
+ * * max_severity: The maximum severity that will be considered.
+ * * severity_pick_mode: The "pick mode" to be used. See get_corresponding_wound_type's documentation
+ * * wound_source: The source of the wound to be applied. Nullable.
+ *
+ * For the rest of the args, refer to get_corresponding_wound_type().
+ *
+ * Returns:
+ * A new wound instance if the application was successful, null otherwise.
+*/
+/mob/living/carbon/proc/cause_wound_of_type_and_severity(wounding_type, obj/item/bodypart/limb, min_severity, max_severity = min_severity, severity_pick_mode = WOUND_PICK_HIGHEST_SEVERITY, wound_source)
+ if (isnull(limb))
+ limb = pick(bodyparts)
+
+ var/list/type_list = wounding_type
+ if (!islist(type_list))
+ type_list = list(type_list)
+
+ var/datum/wound/corresponding_typepath = get_corresponding_wound_type(type_list, limb, min_severity, max_severity, severity_pick_mode)
+ if (corresponding_typepath)
+ return limb.force_wound_upwards(corresponding_typepath, wound_source = wound_source)
+
+/// Limb is nullable, but picks a random one. Defers to limb.get_wound_threshold_of_wound_type, see it for documentation.
+/mob/living/carbon/proc/get_wound_threshold_of_wound_type(wounding_type, severity, default, obj/item/bodypart/limb, wound_source)
+ if (isnull(limb))
+ limb = pick(bodyparts)
+
+ if (!limb)
+ return default
+
+ return limb.get_wound_threshold_of_wound_type(wounding_type, severity, default, wound_source)
+
+/**
+ * A simple proc that gets the best wound to fit the criteria laid out, then returns its wound threshold.
+ *
+ * Args:
+ * * wounding_type: The wounding_type, e.g. WOUND_BLUNT, WOUND_SLASH to force onto the mob. Can be a list of wounding_types.
+ * * severity: The severity that will be considered.
+ * * return_value_if_no_wound: If no wound is found, we will return this instead. (It is reccomended to use named args for this one, as its unclear what it is without)
+ * * wound_source: The theoretical source of the wound. Nullable.
+ *
+ * Returns:
+ * return_value_if_no_wound if no wound is found - if one IS found, the wound threshold for that wound.
+ */
+/obj/item/bodypart/proc/get_wound_threshold_of_wound_type(wounding_type, severity, return_value_if_no_wound, wound_source)
+ var/list/type_list = wounding_type
+ if (!islist(type_list))
+ type_list = list(type_list)
+
+ var/datum/wound/wound_path = get_corresponding_wound_type(type_list, src, severity, duplicates_allowed = TRUE, care_about_existing_wounds = FALSE)
+ if (wound_path)
+ var/datum/wound_pregen_data/pregen_data = GLOB.all_wound_pregen_data[wound_path]
+ return pregen_data.get_threshold_for(src, damage_source = wound_source)
+
+ return return_value_if_no_wound
/**
* check_wounding_mods() is where we handle the various modifiers of a wound roll
@@ -171,7 +268,20 @@
return injury_mod
- /// Get whatever wound of the given type is currently attached to this limb, if any
+/// Should return an assoc list of (wound_series -> penalty). Will be used in determining series-specific penalties for wounding.
+/obj/item/bodypart/proc/check_series_wounding_mods()
+ RETURN_TYPE(/list)
+
+ var/list/series_mods = list()
+
+ for (var/datum/wound/iterated_wound as anything in wounds)
+ var/datum/wound_pregen_data/pregen_data = GLOB.all_wound_pregen_data[iterated_wound.type]
+
+ series_mods[pregen_data.wound_series] += iterated_wound.series_threshold_penalty
+
+ return series_mods
+
+/// Get whatever wound of the given type is currently attached to this limb, if any
/obj/item/bodypart/proc/get_wound_type(checking_type)
RETURN_TYPE(checking_type)
SHOULD_NOT_OVERRIDE(TRUE)
@@ -194,11 +304,11 @@
/obj/item/bodypart/proc/update_wounds(replaced = FALSE)
SHOULD_CALL_PARENT(TRUE)
- var/dam_mul = 1 //initial(wound_damage_multiplier)
+ var/dam_mul = 1
// we can (normally) only have one wound per type, but remember there's multiple types (smites like :B:loodless can generate multiple cuts on a limb)
for(var/datum/wound/iter_wound as anything in wounds)
- dam_mul *= iter_wound.damage_mulitplier_penalty
+ dam_mul *= iter_wound.damage_multiplier_penalty
if(!LAZYLEN(wounds) && current_gauze && !replaced) // no more wounds = no need for the gauze anymore
owner.visible_message(span_notice("\The [current_gauze.name] on [owner]'s [name] falls away."), span_notice("The [current_gauze.name] on your [parse_zone(body_zone)] falls away."))
diff --git a/code/modules/surgery/bone_mending.dm b/code/modules/surgery/bone_mending.dm
index 2396f49c322..48114fe6d04 100644
--- a/code/modules/surgery/bone_mending.dm
+++ b/code/modules/surgery/bone_mending.dm
@@ -5,7 +5,7 @@
/datum/surgery/repair_bone_hairline
name = "Repair bone fracture (hairline)"
surgery_flags = SURGERY_REQUIRE_RESTING | SURGERY_REQUIRE_LIMB | SURGERY_REQUIRES_REAL_LIMB
- targetable_wound = /datum/wound/blunt/severe
+ targetable_wound = /datum/wound/blunt/bone/severe
possible_locs = list(
BODY_ZONE_R_ARM,
BODY_ZONE_L_ARM,
@@ -31,7 +31,7 @@
/datum/surgery/repair_bone_compound
name = "Repair Compound Fracture"
surgery_flags = SURGERY_REQUIRE_RESTING | SURGERY_REQUIRE_LIMB | SURGERY_REQUIRES_REAL_LIMB
- targetable_wound = /datum/wound/blunt/critical
+ targetable_wound = /datum/wound/blunt/bone/critical
possible_locs = list(
BODY_ZONE_R_ARM,
BODY_ZONE_L_ARM,
diff --git a/code/modules/surgery/burn_dressing.dm b/code/modules/surgery/burn_dressing.dm
index f448195d3ef..c22a8f4be97 100644
--- a/code/modules/surgery/burn_dressing.dm
+++ b/code/modules/surgery/burn_dressing.dm
@@ -5,7 +5,7 @@
/datum/surgery/debride
name = "Debride burnt flesh"
surgery_flags = SURGERY_REQUIRE_RESTING | SURGERY_REQUIRE_LIMB | SURGERY_REQUIRES_REAL_LIMB
- targetable_wound = /datum/wound/burn
+ targetable_wound = /datum/wound/burn/flesh
possible_locs = list(
BODY_ZONE_R_ARM,
BODY_ZONE_L_ARM,
@@ -24,7 +24,7 @@
return FALSE
if(..())
var/obj/item/bodypart/targeted_bodypart = target.get_bodypart(user.zone_selected)
- var/datum/wound/burn/burn_wound = targeted_bodypart.get_wound_type(targetable_wound)
+ var/datum/wound/burn/flesh/burn_wound = targeted_bodypart.get_wound_type(targetable_wound)
return(burn_wound && burn_wound.infestation > 0)
//SURGERY STEPS
@@ -48,7 +48,7 @@
var/infestation_removed = 4
/// To give the surgeon a heads up how much work they have ahead of them
-/datum/surgery_step/debride/proc/get_progress(mob/user, mob/living/carbon/target, datum/wound/burn/burn_wound)
+/datum/surgery_step/debride/proc/get_progress(mob/user, mob/living/carbon/target, datum/wound/burn/flesh/burn_wound)
if(!burn_wound?.infestation || !infestation_removed)
return
var/estimated_remaining_steps = burn_wound.infestation / infestation_removed
@@ -68,7 +68,7 @@
/datum/surgery_step/debride/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
if(surgery.operated_wound)
- var/datum/wound/burn/burn_wound = surgery.operated_wound
+ var/datum/wound/burn/flesh/burn_wound = surgery.operated_wound
if(burn_wound.infestation <= 0)
to_chat(user, span_notice("[target]'s [parse_zone(user.zone_selected)] has no infected flesh to remove!"))
surgery.status++
@@ -86,7 +86,7 @@
user.visible_message(span_notice("[user] looks for [target]'s [parse_zone(user.zone_selected)]."), span_notice("You look for [target]'s [parse_zone(user.zone_selected)]..."))
/datum/surgery_step/debride/success(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
- var/datum/wound/burn/burn_wound = surgery.operated_wound
+ var/datum/wound/burn/flesh/burn_wound = surgery.operated_wound
if(burn_wound)
var/progress_text = get_progress(user, target, burn_wound)
display_results(
@@ -120,7 +120,7 @@
/datum/surgery_step/debride/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
if(!..())
return
- var/datum/wound/burn/burn_wound = surgery.operated_wound
+ var/datum/wound/burn/flesh/burn_wound = surgery.operated_wound
while(burn_wound && burn_wound.infestation > 0.25)
if(!..())
break
@@ -139,7 +139,7 @@
/datum/surgery_step/dress/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- var/datum/wound/burn/burn_wound = surgery.operated_wound
+ var/datum/wound/burn/flesh/burn_wound = surgery.operated_wound
if(burn_wound)
display_results(
user,
@@ -153,7 +153,7 @@
user.visible_message(span_notice("[user] looks for [target]'s [parse_zone(user.zone_selected)]."), span_notice("You look for [target]'s [parse_zone(user.zone_selected)]..."))
/datum/surgery_step/dress/success(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
- var/datum/wound/burn/burn_wound = surgery.operated_wound
+ var/datum/wound/burn/flesh/burn_wound = surgery.operated_wound
if(burn_wound)
display_results(
user,
diff --git a/code/modules/surgery/dental_implant.dm b/code/modules/surgery/dental_implant.dm
index 230b2b038b8..dc28e5da576 100644
--- a/code/modules/surgery/dental_implant.dm
+++ b/code/modules/surgery/dental_implant.dm
@@ -52,6 +52,6 @@
to_chat(owner, span_notice("You grit your teeth and burst the implanted [item_target.name]!"))
owner.log_message("swallowed an implanted pill, [target]", LOG_ATTACK)
if(item_target.reagents.total_volume)
- item_target.reagents.trans_to(owner, item_target.reagents.total_volume, transfered_by = owner, methods = INGEST)
+ item_target.reagents.trans_to(owner, item_target.reagents.total_volume, transferred_by = owner, methods = INGEST)
qdel(target)
return TRUE
diff --git a/code/modules/surgery/experimental_dissection.dm b/code/modules/surgery/experimental_dissection.dm
new file mode 100644
index 00000000000..6ae5e447e0b
--- /dev/null
+++ b/code/modules/surgery/experimental_dissection.dm
@@ -0,0 +1,152 @@
+///How many research points you gain from dissecting a Human.
+#define BASE_HUMAN_REWARD 500
+
+/datum/surgery/advanced/experimental_dissection
+ name = "Experimental Dissection"
+ desc = "A surgical procedure which analyzes the biology of a corpse, and automatically adds new findings to the research database."
+ steps = list(
+ /datum/surgery_step/incise,
+ /datum/surgery_step/retract_skin,
+ /datum/surgery_step/experimental_dissection,
+ /datum/surgery_step/close,
+ )
+ surgery_flags = SURGERY_REQUIRE_RESTING | SURGERY_REQUIRE_LIMB | SURGERY_MORBID_CURIOSITY
+ possible_locs = list(BODY_ZONE_CHEST)
+ target_mobtypes = list(/mob/living)
+
+/datum/surgery/advanced/experimental_dissection/can_start(mob/user, mob/living/target)
+ . = ..()
+ if(HAS_TRAIT_FROM(target, TRAIT_DISSECTED, EXPERIMENTAL_SURGERY_TRAIT))
+ return FALSE
+ if(target.stat != DEAD)
+ return FALSE
+
+/datum/surgery_step/experimental_dissection
+ name = "dissection"
+ implements = list(
+ /obj/item/autopsy_scanner = 100,
+ TOOL_SCALPEL = 60,
+ TOOL_KNIFE = 20,
+ /obj/item/shard = 10,
+ )
+ time = 12 SECONDS
+ silicons_obey_prob = TRUE
+
+/datum/surgery_step/experimental_dissection/preop(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] starts dissecting [target].", "You start dissecting [target].")
+
+/datum/surgery_step/experimental_dissection/success(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
+ var/points_earned = check_value(target)
+ user.visible_message("[user] dissects [target], discovering [points_earned] point\s of data!", "You dissect [target], finding [points_earned] point\s worth of discoveries, you also write a few notes.")
+
+ var/obj/item/research_notes/the_dossier = new /obj/item/research_notes(user.loc, points_earned, "biology")
+ if(!user.put_in_hands(the_dossier) && istype(user.get_inactive_held_item(), /obj/item/research_notes))
+ var/obj/item/research_notes/hand_dossier = user.get_inactive_held_item()
+ hand_dossier.merge(the_dossier)
+
+ var/obj/item/bodypart/target_chest = target.get_bodypart(BODY_ZONE_CHEST)
+ target.apply_damage(80, BRUTE, target_chest)
+ ADD_TRAIT(target, TRAIT_DISSECTED, EXPERIMENTAL_SURGERY_TRAIT)
+ return ..()
+
+/datum/surgery_step/experimental_dissection/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ var/points_earned = round(check_value(target) * 0.01)
+ user.visible_message(
+ "[user] dissects [target]!",
+ "You dissect [target], but do not find anything particularly interesting.",
+ )
+
+ var/obj/item/research_notes/the_dossier = new /obj/item/research_notes(user.loc, points_earned, "biology")
+ if(!user.put_in_hands(the_dossier) && istype(user.get_inactive_held_item(), /obj/item/research_notes))
+ var/obj/item/research_notes/hand_dossier = user.get_inactive_held_item()
+ hand_dossier.merge(the_dossier)
+
+ var/obj/item/bodypart/L = target.get_bodypart(BODY_ZONE_CHEST)
+ target.apply_damage(80, BRUTE, L)
+ return TRUE
+
+///Calculates how many research points dissecting 'target' is worth.
+/datum/surgery_step/experimental_dissection/proc/check_value(mob/living/target)
+ var/cost = BASE_HUMAN_REWARD
+
+ if(ishuman(target))
+ var/mob/living/carbon/human/human_target = target
+ if(human_target.dna?.species)
+ if(ismonkey(human_target))
+ cost /= 5
+ else if(isabductor(human_target))
+ cost *= 4
+ else if(isgolem(human_target) || iszombie(human_target))
+ cost *= 3
+ else if(isjellyperson(human_target) || ispodperson(human_target))
+ cost *= 2
+ else if(isalienroyal(target))
+ cost *= 10
+ else if(isalienadult(target))
+ cost *= 5
+ else
+ cost /= 6
+
+ return cost
+
+#undef BASE_HUMAN_REWARD
+
+/obj/item/research_notes
+ name = "research notes"
+ desc = "Valuable scientific data. Use it in an ancient research server to turn it in."
+ icon = 'icons/obj/service/bureaucracy.dmi'
+ icon_state = "paper"
+ w_class = WEIGHT_CLASS_SMALL
+ ///research points it holds
+ var/value = 100
+ ///origin of the research
+ var/origin_type = "debug"
+ ///if it ws merged with different origins to apply a bonus
+ var/mixed = FALSE
+
+/obj/item/research_notes/Initialize(mapload, value, origin_type)
+ . = ..()
+ if(value)
+ src.value = value
+ if(origin_type)
+ src.origin_type = origin_type
+ change_vol()
+
+/obj/item/research_notes/examine(mob/user)
+ . = ..()
+ . += span_notice("It is worth [value] research points.")
+
+/obj/item/research_notes/attackby(obj/item/attacking_item, mob/living/user, params)
+ if(istype(attacking_item, /obj/item/research_notes))
+ var/obj/item/research_notes/notes = attacking_item
+ value = value + notes.value
+ change_vol()
+ qdel(notes)
+ return
+ return ..()
+
+/// proc that changes name and icon depending on value
+/obj/item/research_notes/proc/change_vol()
+ if(value >= 10000)
+ name = "revolutionary discovery in the field of [origin_type]"
+ icon_state = "docs_verified"
+ else if(value >= 2500)
+ name = "essay about [origin_type]"
+ icon_state = "paper_words"
+ else if(value >= 100)
+ name = "notes of [origin_type]"
+ icon_state = "paperslip_words"
+ else
+ name = "fragmentary data of [origin_type]"
+ icon_state = "scrap"
+
+///proc when you slap research notes into another one, it applies a bonus if they are of different origin (only applied once)
+/obj/item/research_notes/proc/merge(obj/item/research_notes/new_paper)
+ var/bonus = min(value , new_paper.value)
+ value = value + new_paper.value
+ if(origin_type != new_paper.origin_type && !mixed)
+ value += bonus * 0.3
+ origin_type = "[origin_type] and [new_paper.origin_type]"
+ mixed = TRUE
+ change_vol()
+ qdel(new_paper)
diff --git a/code/modules/surgery/organic_steps.dm b/code/modules/surgery/organic_steps.dm
index a4c087059d6..73e48db857f 100644
--- a/code/modules/surgery/organic_steps.dm
+++ b/code/modules/surgery/organic_steps.dm
@@ -77,7 +77,7 @@
/datum/surgery_step/clamp_bleeders/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
if(locate(/datum/surgery_step/saw) in surgery.steps)
- target.heal_bodypart_damage(20,0)
+ target.heal_bodypart_damage(20, 0, target_zone = target_zone)
if (ishuman(target))
var/mob/living/carbon/human/human_target = target
var/obj/item/bodypart/target_bodypart = human_target.get_bodypart(target_zone)
@@ -137,7 +137,7 @@
/datum/surgery_step/close/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
if(locate(/datum/surgery_step/saw) in surgery.steps)
- target.heal_bodypart_damage(45,0)
+ target.heal_bodypart_damage(45, 0, target_zone = target_zone)
if (ishuman(target))
var/mob/living/carbon/human/human_target = target
var/obj/item/bodypart/target_bodypart = human_target.get_bodypart(target_zone)
diff --git a/code/modules/surgery/organs/autosurgeon.dm b/code/modules/surgery/organs/autosurgeon.dm
index d28ffa4062c..0987df92bd9 100644
--- a/code/modules/surgery/organs/autosurgeon.dm
+++ b/code/modules/surgery/organs/autosurgeon.dm
@@ -157,9 +157,6 @@
/obj/item/autosurgeon/syndicate/anti_stun
starting_organ = /obj/item/organ/internal/cyberimp/brain/anti_stun
-/obj/item/autosurgeon/syndicate/anti_drop
- starting_organ = /obj/item/organ/internal/cyberimp/brain/anti_drop
-
/obj/item/autosurgeon/syndicate/reviver
starting_organ = /obj/item/organ/internal/cyberimp/chest/reviver
diff --git a/code/modules/surgery/organs/external/wings/functional_wings.dm b/code/modules/surgery/organs/external/wings/functional_wings.dm
index d2b4716df50..0cdca01f72c 100644
--- a/code/modules/surgery/organs/external/wings/functional_wings.dm
+++ b/code/modules/surgery/organs/external/wings/functional_wings.dm
@@ -107,12 +107,12 @@
if(!HAS_TRAIT_FROM(human, TRAIT_MOVE_FLYING, SPECIES_FLIGHT_TRAIT))
human.physiology.stun_mod *= 2
human.add_traits(list(TRAIT_NO_FLOATING_ANIM, TRAIT_MOVE_FLYING), SPECIES_FLIGHT_TRAIT)
- passtable_on(human, SPECIES_TRAIT)
+ passtable_on(human, SPECIES_FLIGHT_TRAIT)
open_wings()
else
human.physiology.stun_mod *= 0.5
human.remove_traits(list(TRAIT_NO_FLOATING_ANIM, TRAIT_MOVE_FLYING), SPECIES_FLIGHT_TRAIT)
- passtable_off(human, SPECIES_TRAIT)
+ passtable_off(human, SPECIES_FLIGHT_TRAIT)
close_wings()
human.update_body_parts()
diff --git a/code/modules/surgery/organs/internal/appendix/_appendix.dm b/code/modules/surgery/organs/internal/appendix/_appendix.dm
index 835d7e62bed..a52479c10a7 100644
--- a/code/modules/surgery/organs/internal/appendix/_appendix.dm
+++ b/code/modules/surgery/organs/internal/appendix/_appendix.dm
@@ -65,7 +65,7 @@
organ_owner.adjustToxLoss(1, updating_health = TRUE, forced = TRUE)
if(3)
if(SPT_PROB(0.5, seconds_per_tick))
- organ_owner.vomit(95)
+ organ_owner.vomit(VOMIT_CATEGORY_DEFAULT, lost_nutrition = 95)
organ_owner.adjustOrganLoss(ORGAN_SLOT_APPENDIX, 15)
diff --git a/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm b/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm
index 55624e88bf1..0a7332c0dd8 100644
--- a/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm
+++ b/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm
@@ -172,4 +172,3 @@
new /obj/item/autosurgeon/syndicate/xray_eyes(src)
new /obj/item/autosurgeon/syndicate/anti_stun(src)
new /obj/item/autosurgeon/syndicate/reviver(src)
- new /obj/item/autosurgeon/syndicate/anti_drop(src)
diff --git a/code/modules/surgery/organs/internal/ears/_ears.dm b/code/modules/surgery/organs/internal/ears/_ears.dm
index 54d35628f85..52f5d740520 100644
--- a/code/modules/surgery/organs/internal/ears/_ears.dm
+++ b/code/modules/surgery/organs/internal/ears/_ears.dm
@@ -153,4 +153,4 @@
. = ..()
if(. & EMP_PROTECT_SELF)
return
- apply_organ_damage(40/severity)
+ apply_organ_damage(20 / severity)
diff --git a/code/modules/surgery/organs/internal/eyes/_eyes.dm b/code/modules/surgery/organs/internal/eyes/_eyes.dm
index 704fb9e9e5b..f2365c3988e 100644
--- a/code/modules/surgery/organs/internal/eyes/_eyes.dm
+++ b/code/modules/surgery/organs/internal/eyes/_eyes.dm
@@ -140,12 +140,12 @@
var/mutable_appearance/eye_left = mutable_appearance(eye_icon, "[eye_icon_state]_l", -eyes_layer) // SKYRAT EDIT CHANGE - Customization - ORIGINAL: var/mutable_appearance/eye_left = mutable_appearance('icons/mob/human/human_face.dmi', "[eye_icon_state]_l", -BODY_LAYER)
var/mutable_appearance/eye_right = mutable_appearance(eye_icon, "[eye_icon_state]_r", -eyes_layer) // SKYRAT EDIT CHANGE - Customization - ORIGINAL: var/mutable_appearance/eye_right = mutable_appearance('icons/mob/human/human_face.dmi', "[eye_icon_state]_r", -BODY_LAYER)
- var/list/eye_overlays = list(eye_left, eye_right) //SKYRAT EDIT ADDITION - Add all the overlays to this list instead of adding emissive blockers/eye emissives to the eye overlays' overlays
+ var/list/overlays = list(eye_left, eye_right)
var/obscured = parent.check_obscured_slots(TRUE)
if(overlay_ignore_lighting && !(obscured & ITEM_SLOT_EYES))
- eye_overlays += emissive_appearance(eye_left.icon, eye_left.icon_state, parent, -eyes_layer, alpha = eye_left.alpha) //SKYRAT EDIT CHANGE - TODO fix upstream
- eye_overlays += emissive_appearance(eye_right.icon, eye_right.icon_state, parent, -eyes_layer, alpha = eye_right.alpha) //SKYRAT EDIT CHANGE - TODO fix upstream
+ overlays += emissive_appearance(eye_left.icon, eye_left.icon_state, parent, -eyes_layer, alpha = eye_left.alpha) // SKYRAT EDIT CHANGE - ORIGINAL: overlays += emissive_appearance(eye_left.icon, eye_left.icon_state, parent, -BODY_LAYER, alpha = eye_left.alpha)
+ overlays += emissive_appearance(eye_right.icon, eye_right.icon_state, parent, -eyes_layer, alpha = eye_right.alpha) // SKYRAT EDIT CHANGE - ORIGINAL: overlays += emissive_appearance(eye_left.icon, eye_left.icon_state, parent, -BODY_LAYER, alpha = eye_left.alpha)
var/obj/item/bodypart/head/my_head = parent.get_bodypart(BODY_ZONE_HEAD)
if(my_head)
if(my_head.head_flags & HEAD_EYECOLOR)
@@ -168,12 +168,12 @@
my_head.worn_face_offset.apply_offset(emissive_right)
my_head.worn_face_offset.apply_offset(emissive_left)
- eye_overlays += emissive_left
- eye_overlays += emissive_right
+ overlays += emissive_left
+ overlays += emissive_right
// SKYRAT EDIT END
- return eye_overlays // SKYRAT EDIT CHANGE - return all the overlays together in a list so height gets applied correctly
+ return overlays
#undef OFFSET_X
#undef OFFSET_Y
diff --git a/code/modules/surgery/organs/internal/liver/_liver.dm b/code/modules/surgery/organs/internal/liver/_liver.dm
index f871fbd84db..fe5ca01df4f 100644
--- a/code/modules/surgery/organs/internal/liver/_liver.dm
+++ b/code/modules/surgery/organs/internal/liver/_liver.dm
@@ -172,18 +172,18 @@
to_chat(owner, span_userdanger("You feel stabbing pain in your abdomen!"))
if(2)
to_chat(owner, span_userdanger("You feel a burning sensation in your gut!"))
- owner.vomit()
+ owner.vomit(VOMIT_CATEGORY_DEFAULT)
if(3)
to_chat(owner, span_userdanger("You feel painful acid in your throat!"))
- owner.vomit(blood = TRUE)
+ owner.vomit(VOMIT_CATEGORY_BLOOD)
if(4)
to_chat(owner, span_userdanger("Overwhelming pain knocks you out!"))
- owner.vomit(blood = TRUE, distance = rand(1,2))
+ owner.vomit(VOMIT_CATEGORY_BLOOD, distance = rand(1,2))
owner.emote("Scream")
owner.AdjustUnconscious(2.5 SECONDS)
if(5)
to_chat(owner, span_userdanger("You feel as if your guts are about to melt!"))
- owner.vomit(blood = TRUE,distance = rand(1,3))
+ owner.vomit(VOMIT_CATEGORY_BLOOD, distance = rand(1,3))
owner.emote("Scream")
owner.AdjustUnconscious(5 SECONDS)
diff --git a/code/modules/surgery/organs/internal/lungs/_lungs.dm b/code/modules/surgery/organs/internal/lungs/_lungs.dm
index 035551bf190..5e4e0648067 100644
--- a/code/modules/surgery/organs/internal/lungs/_lungs.dm
+++ b/code/modules/surgery/organs/internal/lungs/_lungs.dm
@@ -21,7 +21,6 @@
var/failed = FALSE
var/operated = FALSE //whether we can still have our damages fixed through surgery
-
food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/medicine/salbutamol = 5)
/// Our previous breath's partial pressures, in the form gas id -> partial pressure
@@ -482,13 +481,13 @@
if(prob(5))
to_chat(breather, span_warning("The stench of rotting carcasses is unbearable!"))
breather.add_mood_event("smell", /datum/mood_event/disgust/nauseating_stench)
- breather.vomit()
+ breather.vomit(VOMIT_CATEGORY_DEFAULT)
if(30 to INFINITY)
//Higher chance to vomit. Let the horror start
if(prob(15))
to_chat(breather, span_warning("The stench of rotting carcasses is unbearable!"))
breather.add_mood_event("smell", /datum/mood_event/disgust/nauseating_stench)
- breather.vomit()
+ breather.vomit(VOMIT_CATEGORY_DEFAULT)
else
breather.clear_mood_event("smell")
// In a full miasma atmosphere with 101.34 pKa, about 10 disgust per breath, is pretty low compared to threshholds
@@ -794,6 +793,9 @@
/obj/item/organ/internal/lungs/get_availability(datum/species/owner_species, mob/living/owner_mob)
return owner_species.mutantlungs
+#define SMOKER_ORGAN_HEALTH (STANDARD_ORGAN_THRESHOLD * 0.75)
+#define SMOKER_LUNG_HEALING (STANDARD_ORGAN_HEALING * 0.75)
+
/obj/item/organ/internal/lungs/plasmaman
name = "plasma filter"
desc = "A spongy rib-shaped mass for filtering plasma from the air."
@@ -804,6 +806,14 @@
safe_plasma_min = 4 //We breathe THIS!
safe_plasma_max = 0
+/obj/item/organ/internal/lungs/plasmaman/plasmaman_smoker
+ name = "smoker plasma filter"
+ desc = "A plasma filter that look discolored, a result from smoking a lot."
+ icon_state = "lungs_plasma_smoker"
+
+ maxHealth = SMOKER_ORGAN_HEALTH
+ healing_factor = SMOKER_LUNG_HEALING
+
/obj/item/organ/internal/lungs/slime
name = "vacuole"
desc = "A large organelle designed to store oxygen and other important gasses."
@@ -816,6 +826,14 @@
var/plasma_pp = breath.get_breath_partial_pressure(breath.gases[/datum/gas/plasma][MOLES])
breather_slime.blood_volume += (0.2 * plasma_pp) // 10/s when breathing literally nothing but plasma, which will suffocate you.
+/obj/item/organ/internal/lungs/smoker_lungs
+ name = "smoker lungs"
+ desc = "A pair of lungs that look sickly, a result from smoking a lot."
+ icon_state = "lungs_smoker"
+
+ maxHealth = SMOKER_ORGAN_HEALTH
+ healing_factor = SMOKER_LUNG_HEALING
+
/obj/item/organ/internal/lungs/cybernetic
name = "basic cybernetic lungs"
desc = "A basic cybernetic version of the lungs found in traditional humanoid entities."
@@ -937,6 +955,14 @@
heat_level_2_threshold = 473
heat_level_3_threshold = 1073
+/obj/item/organ/internal/lungs/ethereal/ethereal_smoker
+ name = "smoker aeration reticulum"
+ desc = "A pair of exotic lungs that look pale and sickly, a result from smoking a lot."
+ icon_state = "lungs_ethereal_smoker"
+
+ maxHealth = SMOKER_ORGAN_HEALTH
+ healing_factor = SMOKER_LUNG_HEALING
+
/obj/item/organ/internal/lungs/ethereal/Initialize(mapload)
. = ..()
add_gas_reaction(/datum/gas/water_vapor, while_present = PROC_REF(consume_water))
@@ -953,3 +979,5 @@
#undef BREATH_RELATIONSHIP_INITIAL_GAS
#undef BREATH_RELATIONSHIP_CONVERT
#undef BREATH_RELATIONSHIP_MULTIPLIER
+#undef SMOKER_ORGAN_HEALTH
+#undef SMOKER_LUNG_HEALING
diff --git a/code/modules/surgery/organs/internal/stomach/_stomach.dm b/code/modules/surgery/organs/internal/stomach/_stomach.dm
index 4f83b7844a4..bebeaacf110 100644
--- a/code/modules/surgery/organs/internal/stomach/_stomach.dm
+++ b/code/modules/surgery/organs/internal/stomach/_stomach.dm
@@ -110,13 +110,13 @@
//The stomach is damage has nutriment but low on theshhold, lo prob of vomit
if(SPT_PROB(0.0125 * damage * nutri_vol * nutri_vol, seconds_per_tick))
- body.vomit(damage)
+ body.vomit(VOMIT_CATEGORY_DEFAULT, lost_nutrition = damage)
to_chat(body, span_warning("Your stomach reels in pain as you're incapable of holding down all that food!"))
return
// the change of vomit is now high
if(damage > high_threshold && SPT_PROB(0.05 * damage * nutri_vol * nutri_vol, seconds_per_tick))
- body.vomit(damage)
+ body.vomit(VOMIT_CATEGORY_DEFAULT, lost_nutrition = damage)
to_chat(body, span_warning("Your stomach reels in pain as you're incapable of holding down all that food!"))
/obj/item/organ/internal/stomach/proc/handle_hunger(mob/living/carbon/human/human, seconds_per_tick, times_fired)
@@ -234,7 +234,7 @@
if(SPT_PROB(pukeprob, seconds_per_tick)) //iT hAndLeS mOrE ThaN PukInG
disgusted.adjust_confusion(2.5 SECONDS)
disgusted.adjust_stutter(2 SECONDS)
- disgusted.vomit(10, distance = 0, vomit_type = NONE)
+ disgusted.vomit(VOMIT_CATEGORY_DEFAULT, distance = 0)
disgusted.set_dizzy_if_lower(10 SECONDS)
if(disgust >= DISGUST_LEVEL_DISGUSTED)
if(SPT_PROB(13, seconds_per_tick))
@@ -300,7 +300,7 @@
if(. & EMP_PROTECT_SELF)
return
if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people.
- owner.vomit(stun = FALSE)
+ owner.vomit(vomit_flags = (MOB_VOMIT_MESSAGE | MOB_VOMIT_HARM))
COOLDOWN_START(src, severe_cooldown, 10 SECONDS)
if(prob(emp_vulnerability/severity)) //Chance of permanent effects
organ_flags |= ORGAN_EMP //Starts organ faliure - gonna need replacing soon.
diff --git a/code/modules/surgery/repair_puncture.dm b/code/modules/surgery/repair_puncture.dm
index 843336c258b..bb33c314689 100644
--- a/code/modules/surgery/repair_puncture.dm
+++ b/code/modules/surgery/repair_puncture.dm
@@ -9,7 +9,7 @@
/datum/surgery/repair_puncture
name = "Repair puncture"
surgery_flags = SURGERY_REQUIRE_RESTING | SURGERY_REQUIRE_LIMB | SURGERY_REQUIRES_REAL_LIMB
- targetable_wound = /datum/wound/pierce
+ targetable_wound = /datum/wound/pierce/bleed
target_mobtypes = list(/mob/living/carbon)
possible_locs = list(
BODY_ZONE_R_ARM,
@@ -32,7 +32,7 @@
. = ..()
if(.)
var/obj/item/bodypart/targeted_bodypart = target.get_bodypart(user.zone_selected)
- var/datum/wound/burn/pierce_wound = targeted_bodypart.get_wound_type(targetable_wound)
+ var/datum/wound/burn/flesh/pierce_wound = targeted_bodypart.get_wound_type(targetable_wound)
return(pierce_wound && pierce_wound.blood_flow > 0)
//SURGERY STEPS
@@ -47,7 +47,7 @@
time = 3 SECONDS
/datum/surgery_step/repair_innards/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- var/datum/wound/pierce/pierce_wound = surgery.operated_wound
+ var/datum/wound/pierce/bleed/pierce_wound = surgery.operated_wound
if(!pierce_wound)
user.visible_message(span_notice("[user] looks for [target]'s [parse_zone(user.zone_selected)]."), span_notice("You look for [target]'s [parse_zone(user.zone_selected)]..."))
return
@@ -67,7 +67,7 @@
display_pain(target, "You feel a horrible stabbing pain in your [parse_zone(user.zone_selected)]!")
/datum/surgery_step/repair_innards/success(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
- var/datum/wound/pierce/pierce_wound = surgery.operated_wound
+ var/datum/wound/pierce/bleed/pierce_wound = surgery.operated_wound
if(!pierce_wound)
to_chat(user, span_warning("[target] has no puncture wound there!"))
return ..()
@@ -112,7 +112,7 @@
return TRUE
/datum/surgery_step/seal_veins/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- var/datum/wound/pierce/pierce_wound = surgery.operated_wound
+ var/datum/wound/pierce/bleed/pierce_wound = surgery.operated_wound
if(!pierce_wound)
user.visible_message(span_notice("[user] looks for [target]'s [parse_zone(user.zone_selected)]."), span_notice("You look for [target]'s [parse_zone(user.zone_selected)]..."))
return
@@ -126,7 +126,7 @@
display_pain(target, "You're being burned inside your [parse_zone(user.zone_selected)]!")
/datum/surgery_step/seal_veins/success(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
- var/datum/wound/pierce/pierce_wound = surgery.operated_wound
+ var/datum/wound/pierce/bleed/pierce_wound = surgery.operated_wound
if(!pierce_wound)
to_chat(user, span_warning("[target] has no puncture there!"))
return ..()
diff --git a/code/modules/surgery/revival.dm b/code/modules/surgery/revival.dm
index 6428f4ce9ad..b642057ede4 100644
--- a/code/modules/surgery/revival.dm
+++ b/code/modules/surgery/revival.dm
@@ -3,7 +3,8 @@
desc = "An experimental surgical procedure which involves reconstruction and reactivation of the patient's brain even long after death. \
The body must still be able to sustain life."
requires_bodypart_type = NONE
- possible_locs = list(BODY_ZONE_HEAD)
+ possible_locs = list(BODY_ZONE_CHEST)
+ target_mobtypes = list(/mob/living)
surgery_flags = SURGERY_REQUIRE_RESTING | SURGERY_REQUIRE_LIMB | SURGERY_MORBID_CURIOSITY
steps = list(
/datum/surgery_step/incise,
@@ -15,15 +16,22 @@
/datum/surgery_step/close,
)
-/datum/surgery/revival/can_start(mob/user, mob/living/carbon/target)
+/datum/surgery/revival/can_start(mob/user, mob/living/target)
if(!..())
return FALSE
if(target.stat != DEAD)
return FALSE
if(HAS_TRAIT(target, TRAIT_SUICIDED) || HAS_TRAIT(target, TRAIT_HUSK) || HAS_TRAIT(target, TRAIT_DEFIB_BLACKLISTED))
return FALSE
- var/obj/item/organ/internal/brain/target_brain = target.get_organ_slot(ORGAN_SLOT_BRAIN)
- if(!target_brain)
+ if(!is_valid_target(target))
+ return FALSE
+ return TRUE
+
+/// Extra checks which can be overridden
+/datum/surgery/revival/proc/is_valid_target(mob/living/patient)
+ if (iscarbon(patient))
+ return FALSE
+ if (!(patient.mob_biotypes & (MOB_ORGANIC|MOB_HUMANOID)))
return FALSE
return TRUE
@@ -59,7 +67,7 @@
to_chat(user, span_warning("You need an electrode for this!"))
return FALSE
-/datum/surgery_step/revive/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+/datum/surgery_step/revive/preop(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(
user,
target,
@@ -69,13 +77,13 @@
)
target.notify_ghost_cloning("Someone is trying to zap your brain.", source = target)
-/datum/surgery_step/revive/play_preop_sound(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+/datum/surgery_step/revive/play_preop_sound(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery)
if(istype(tool, /obj/item/shockpaddles))
playsound(tool, 'sound/machines/defib_charge.ogg', 75, 0)
else
..()
-/datum/surgery_step/revive/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
+/datum/surgery_step/revive/success(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
display_results(
user,
target,
@@ -87,25 +95,27 @@
target.adjustOxyLoss(-50, 0)
target.updatehealth()
if(target.revive())
- target.visible_message(span_notice("...[target] wakes up, alive and aware!"))
- target.emote("gasp")
- target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 50, 199) //MAD SCIENCE
- to_chat(target, "[CONFIG_GET(string/blackoutpolicy)]") //SKYRAT EDIT ADDITION - BLACKOUT POLICY
- if(HAS_MIND_TRAIT(user, TRAIT_MORBID) && ishuman(user)) //Contrary to their typical hatred of resurrection, it wouldn't be very thematic if morbid people didn't love playing god
- var/mob/living/carbon/human/morbid_weirdo = user
- morbid_weirdo.add_mood_event("morbid_revival_success", /datum/mood_event/morbid_revival_success)
+ on_revived(user, target)
return TRUE
- else
- //SKYRAT EDIT ADDITION - DNR TRAIT - need this so that people dont just keep spamming the revival surgery; it runs success just bc the surgery steps are done // BUBBER EDIT REMOVAL
-// if(HAS_TRAIT(target, TRAIT_DNR))
-// target.visible_message(span_warning("...[target.p_they()] lies still, unaffected. Further attempts are futile, they're gone."))
-// else
-// target.visible_message(span_warning("...[target.p_they()] convulses, then lies still."))
- //SKYRAT EDIT ADDITION END - DNR TRAIT - ORIGINAL: target.visible_message(span_warning("...[target.p_they()] convulses, then lies still.")) // BUBBER EDIT REMOVAL
- target.visible_message(span_warning("...[target.p_they()] convulses, then lies still.")) // BUBBER TG RESTORE
- return FALSE
-/datum/surgery_step/revive/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ //SKYRAT EDIT CHANGE - DNR TRAIT - need this so that people don't just keep spamming the revival surgery; it runs success just bc the surgery steps are done
+/* if(HAS_TRAIT(target, TRAIT_DNR)) // BUBBER EDIT - DNR TRAIT REWORK
+ target.visible_message(span_warning("...[target.p_they()] lie[target.p_s()] still, unaffected. Further attempts are futile, target.p_theyre() gone.")) */
+ else
+ target.visible_message(span_warning("...[target.p_they()] convulse[target.p_s()], then lie[target.p_s()] still."))
+ //SKYRAT EDIT CHANGE END - DNR TRAIT - ORIGINAL: target.visible_message(span_warning("...[target.p_they()] convulse[target.p_s()], then lie[target.p_s()] still."))
+ return FALSE
+
+/// Called when you have been successfully raised from the dead
+/datum/surgery_step/revive/proc/on_revived(mob/surgeon, mob/living/patient)
+ patient.visible_message(span_notice("...[patient] wakes up, alive and aware!"))
+ patient.emote("gasp")
+ to_chat(patient, "[CONFIG_GET(string/blackoutpolicy)]") //SKYRAT EDIT ADDITION - BLACKOUT POLICY
+ if(HAS_MIND_TRAIT(surgeon, TRAIT_MORBID) && ishuman(surgeon)) // Contrary to their typical hatred of resurrection, it wouldn't be very thematic if morbid people didn't love playing god
+ var/mob/living/carbon/human/morbid_weirdo = surgeon
+ morbid_weirdo.add_mood_event("morbid_revival_success", /datum/mood_event/morbid_revival_success)
+
+/datum/surgery_step/revive/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(
user,
target,
@@ -113,5 +123,23 @@
span_notice("[user] send a powerful shock to [target]'s brain with [tool], but [target.p_they()] doesn't react."),
span_notice("[user] send a powerful shock to [target]'s brain with [tool], but [target.p_they()] doesn't react."),
)
- target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 15, 180)
return FALSE
+
+/// Additional revival effects if the target has a brain
+/datum/surgery/revival/carbon
+ possible_locs = list(BODY_ZONE_HEAD)
+ target_mobtypes = list(/mob/living/carbon)
+
+/datum/surgery/revival/carbon/is_valid_target(mob/living/carbon/patient)
+ var/obj/item/organ/internal/brain/target_brain = patient.get_organ_slot(ORGAN_SLOT_BRAIN)
+ return !isnull(target_brain)
+
+/datum/surgery_step/revive/carbon
+
+/datum/surgery_step/revive/carbon/on_revived(mob/surgeon, mob/living/patient)
+ . = ..()
+ patient.adjustOrganLoss(ORGAN_SLOT_BRAIN, 50, 199) // MAD SCIENCE
+
+/datum/surgery_step/revive/carbon/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ . = ..()
+ target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 15, 180)
diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm
index b07f3ccd79f..3f10087ab8f 100644
--- a/code/modules/surgery/surgery_step.dm
+++ b/code/modules/surgery/surgery_step.dm
@@ -145,7 +145,7 @@
surgery.complete(user)
if(target.stat == DEAD && was_sleeping && user.client)
- user.client.give_award(/datum/award/achievement/misc/sandman, user)
+ user.client.give_award(/datum/award/achievement/jobs/sandman, user)
surgery.step_in_progress = FALSE
return advance
diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm
index 4a1b567a287..49fbecc2271 100644
--- a/code/modules/surgery/tools.dm
+++ b/code/modules/surgery/tools.dm
@@ -12,6 +12,11 @@
w_class = WEIGHT_CLASS_TINY
tool_behaviour = TOOL_RETRACTOR
toolspeed = 1
+ /// How this looks when placed in a surgical tray
+ var/surgical_tray_overlay = "retractor_normal"
+
+/obj/item/retractor/get_surgery_tool_overlay(tray_extended)
+ return surgical_tray_overlay
/obj/item/retractor/augment
desc = "Micro-mechanical manipulator for retracting stuff."
@@ -34,6 +39,11 @@
attack_verb_simple = list("attack", "pinch")
tool_behaviour = TOOL_HEMOSTAT
toolspeed = 1
+ /// How this looks when placed in a surgical tray
+ var/surgical_tray_overlay = "hemostat_normal"
+
+/obj/item/hemostat/get_surgery_tool_overlay(tray_extended)
+ return surgical_tray_overlay
/obj/item/hemostat/augment
desc = "Tiny servos power a pair of pincers to stop bleeding."
@@ -56,6 +66,12 @@
attack_verb_simple = list("burn")
tool_behaviour = TOOL_CAUTERY
toolspeed = 1
+ heat = 500
+ /// How this looks when placed in a surgical tray
+ var/surgical_tray_overlay = "cautery_normal"
+
+/obj/item/cautery/get_surgery_tool_overlay(tray_extended)
+ return surgical_tray_overlay
/obj/item/cautery/ignition_effect(atom/ignitable_atom, mob/user)
. = span_notice("[user] touches the end of [src] to \the [ignitable_atom], igniting it with a puff of smoke.")
@@ -70,6 +86,7 @@
icon = 'icons/obj/medical/surgery_tools.dmi'
icon_state = "e_cautery"
inhand_icon_state = "e_cautery"
+ surgical_tray_overlay = "cautery_advanced"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT*2, /datum/material/glass =SHEET_MATERIAL_AMOUNT, /datum/material/plasma =SHEET_MATERIAL_AMOUNT, /datum/material/uranium = SHEET_MATERIAL_AMOUNT*1.5, /datum/material/titanium = SHEET_MATERIAL_AMOUNT*1.5)
@@ -80,6 +97,9 @@
light_range = 1
light_color = COLOR_SOFT_RED
+/obj/item/cautery/advanced/get_all_tool_behaviours()
+ return list(TOOL_CAUTERY, TOOL_DRILL)
+
/obj/item/cautery/advanced/Initialize(mapload)
. = ..()
AddComponent( \
@@ -131,11 +151,16 @@
sharpness = SHARP_POINTY
wound_bonus = 10
bare_wound_bonus = 10
+ /// How this looks when placed in a surgical tray
+ var/surgical_tray_overlay = "drill_normal"
/obj/item/surgicaldrill/Initialize(mapload)
. = ..()
AddElement(/datum/element/eyestab)
+/obj/item/surgicaldrill/get_surgery_tool_overlay(tray_extended)
+ return surgical_tray_overlay
+
/obj/item/surgicaldrill/suicide_act(mob/living/user)
user.visible_message(span_suicide("[user] rams [src] into [user.p_their()] chest! It looks like [user.p_theyre()] trying to commit suicide!"))
addtimer(CALLBACK(user, TYPE_PROC_REF(/mob/living/carbon, gib), null, null, TRUE, TRUE), 25)
@@ -174,6 +199,8 @@
toolspeed = 1
wound_bonus = 10
bare_wound_bonus = 15
+ /// How this looks when placed in a surgical tray
+ var/surgical_tray_overlay = "scalpel_normal"
/obj/item/scalpel/Initialize(mapload)
. = ..()
@@ -184,14 +211,17 @@
)
AddElement(/datum/element/eyestab)
-/obj/item/scalpel/augment
- desc = "Ultra-sharp blade attached directly to your bone for extra-accuracy."
- toolspeed = 0.5
+/obj/item/scalpel/get_surgery_tool_overlay(tray_extended)
+ return surgical_tray_overlay
/obj/item/scalpel/suicide_act(mob/living/user)
user.visible_message(span_suicide("[user] is slitting [user.p_their()] [pick("wrists", "throat", "stomach")] with [src]! It looks like [user.p_theyre()] trying to commit suicide!"))
return BRUTELOSS
+/obj/item/scalpel/augment
+ desc = "Ultra-sharp blade attached directly to your bone for extra-accuracy."
+ toolspeed = 0.5
+
/obj/item/circular_saw
name = "circular saw"
desc = "For heavy duty cutting."
@@ -217,6 +247,8 @@
toolspeed = 1
wound_bonus = 15
bare_wound_bonus = 10
+ /// How this looks when placed in a surgical tray
+ var/surgical_tray_overlay = "saw_normal"
/obj/item/circular_saw/Initialize(mapload)
. = ..()
@@ -228,6 +260,9 @@
)
//saws are very accurate and fast at butchering
+/obj/item/circular_saw/get_surgery_tool_overlay(tray_extended)
+ return surgical_tray_overlay
+
/obj/item/circular_saw/augment
desc = "A small but very fast spinning saw. It rips and tears until it is done."
w_class = WEIGHT_CLASS_SMALL
@@ -329,6 +364,7 @@
desc = "An advanced scalpel which uses laser technology to cut."
icon_state = "e_scalpel"
inhand_icon_state = "e_scalpel"
+ surgical_tray_overlay = "scalpel_advanced"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT*3, /datum/material/glass =HALF_SHEET_MATERIAL_AMOUNT * 1.5, /datum/material/silver =SHEET_MATERIAL_AMOUNT, /datum/material/gold =HALF_SHEET_MATERIAL_AMOUNT * 1.5, /datum/material/diamond =SMALL_MATERIAL_AMOUNT * 2, /datum/material/titanium = SHEET_MATERIAL_AMOUNT*2)
@@ -341,6 +377,9 @@
light_color = LIGHT_COLOR_BLUE
sharpness = SHARP_EDGED
+/obj/item/scalpel/advanced/get_all_tool_behaviours()
+ return list(TOOL_SAW, TOOL_SCALPEL)
+
/obj/item/scalpel/advanced/Initialize(mapload)
. = ..()
AddComponent( \
@@ -385,11 +424,15 @@
custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT*6, /datum/material/glass = SHEET_MATERIAL_AMOUNT*2, /datum/material/silver = SHEET_MATERIAL_AMOUNT*2, /datum/material/titanium =SHEET_MATERIAL_AMOUNT * 2.5)
icon_state = "adv_retractor"
inhand_icon_state = "adv_retractor"
+ surgical_tray_overlay = "retractor_advanced"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
w_class = WEIGHT_CLASS_NORMAL
toolspeed = 0.7
+/obj/item/retractor/advanced/get_all_tool_behaviours()
+ return list(TOOL_HEMOSTAT, TOOL_RETRACTOR)
+
/obj/item/retractor/advanced/Initialize(mapload)
. = ..()
AddComponent( \
@@ -518,6 +561,9 @@
tool_behaviour = TOOL_BONESET
toolspeed = 1
+/obj/item/bonesetter/get_surgery_tool_overlay(tray_extended)
+ return "bonesetter" + (tray_extended ? "" : "_out")
+
/obj/item/blood_filter
name = "blood filter"
desc = "For filtering the blood."
@@ -535,6 +581,9 @@
/// Assoc list of chem ids to names, used for deciding which chems to filter when used for surgery
var/list/whitelist = list()
+/obj/item/blood_filter/get_surgery_tool_overlay(tray_extended)
+ return "filter"
+
/obj/item/blood_filter/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
@@ -590,24 +639,28 @@
name = "twisted retractor"
desc = "Helps reveal secrets that would rather stay buried."
icon_state = "cruelretractor"
+ surgical_tray_overlay = "retractor_cruel"
item_flags = SURGICAL_TOOL | CRUEL_IMPLEMENT
/obj/item/hemostat/cruel
name = "cruel hemostat"
desc = "Clamping bleeders, but not so good at fixing breathers."
icon_state = "cruelhemostat"
+ surgical_tray_overlay = "hemostat_cruel"
item_flags = SURGICAL_TOOL | CRUEL_IMPLEMENT
/obj/item/cautery/cruel
name = "savage cautery"
desc = "Chalk this one up as another successful vivisection."
icon_state = "cruelcautery"
+ surgical_tray_overlay = "cautery_cruel"
item_flags = SURGICAL_TOOL | CRUEL_IMPLEMENT
/obj/item/scalpel/cruel
name = "hungry scalpel"
desc = "I remember every time I hold you. My born companion..."
icon_state = "cruelscalpel"
+ surgical_tray_overlay = "scalpel_cruel"
item_flags = SURGICAL_TOOL | CRUEL_IMPLEMENT
/obj/item/scalpel/cruel/Initialize(mapload)
diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm
index 074bff3152c..20ca34d5259 100644
--- a/code/modules/unit_tests/_unit_tests.dm
+++ b/code/modules/unit_tests/_unit_tests.dm
@@ -104,7 +104,6 @@
#include "bloody_footprints.dm"
#include "breath.dm"
#include "burning.dm"
-#include "byond_status.dm"
#include "cable_powernets.dm"
#include "card_mismatch.dm"
#include "cardboard_cutouts.dm"
@@ -162,6 +161,7 @@
#include "leash.dm"
#include "lesserform.dm"
#include "limbsanity.dm"
+#include "ling_decap.dm"
#include "liver.dm"
#include "load_map_security.dm"
#include "lungs.dm"
@@ -261,6 +261,7 @@
#include "unit_test.dm"
#include "verify_config_tags.dm"
#include "verify_emoji_names.dm"
+#include "weird_food.dm"
#include "wizard_loadout.dm"
#include "worn_icons.dm"
// SKYRAT EDIT START
diff --git a/code/modules/unit_tests/byond_status.dm b/code/modules/unit_tests/byond_status.dm
deleted file mode 100644
index e2788831556..00000000000
--- a/code/modules/unit_tests/byond_status.dm
+++ /dev/null
@@ -1,9 +0,0 @@
-/// Tests the SUPPOSED TO BE TEMPORARY byond_status() proc for a useful format
-/datum/unit_test/byond_status
-
-/datum/unit_test/byond_status/Run()
- if (world.system_type != UNIX)
- return
-
- var/status = byond_status()
- TEST_ASSERT(findtext(status, "Sleeping procs"), "Invalid byond_status: [status]")
diff --git a/code/modules/unit_tests/chain_pull_through_space.dm b/code/modules/unit_tests/chain_pull_through_space.dm
index 86b0cc69d1c..b767b010495 100644
--- a/code/modules/unit_tests/chain_pull_through_space.dm
+++ b/code/modules/unit_tests/chain_pull_through_space.dm
@@ -11,15 +11,16 @@
..()
//reserve a tile that is always empty for our z destination
- reserved = SSmapping.RequestBlockReservation(5,5)
+ reserved = SSmapping.request_turf_block_reservation(5, 5, 1)
// Create a space tile that goes to another z-level
claimed_tile = run_loc_floor_bottom_left.type
space_tile = run_loc_floor_bottom_left.ChangeTurf(/turf/open/space)
- space_tile.destination_x = round(reserved.bottom_left_coords[1] + (reserved.width-1) / 2)
- space_tile.destination_y = round(reserved.bottom_left_coords[2] + (reserved.height-1) / 2)
- space_tile.destination_z = reserved.bottom_left_coords[3]
+ var/turf/bottom_left = reserved.bottom_left_turfs[1]
+ space_tile.destination_x = round(bottom_left.x + (reserved.width-1) / 2)
+ space_tile.destination_y = round(bottom_left.y + (reserved.height-1) / 2)
+ space_tile.destination_z = bottom_left.z
// Create our list of humans, all adjacent to one another
alice = new(locate(run_loc_floor_bottom_left.x + 2, run_loc_floor_bottom_left.y, run_loc_floor_bottom_left.z))
diff --git a/code/modules/unit_tests/emoting.dm b/code/modules/unit_tests/emoting.dm
index aebd9333f13..4eecaca015c 100644
--- a/code/modules/unit_tests/emoting.dm
+++ b/code/modules/unit_tests/emoting.dm
@@ -3,6 +3,7 @@
/datum/unit_test/emoting/Run()
var/mob/living/carbon/human/human = allocate(/mob/living/carbon/human/consistent)
+ human.key = "EmoteTestKey"
RegisterSignal(human, COMSIG_MOB_EMOTE, PROC_REF(on_emote_used))
human.say("*shrug")
@@ -29,6 +30,8 @@
*/
//SKYRAT EDIT REMOVAL END
+ human.key = null
+
/datum/unit_test/emoting/proc/on_emote_used()
SIGNAL_HANDLER
emotes_used += 1
diff --git a/code/modules/unit_tests/fish_unit_tests.dm b/code/modules/unit_tests/fish_unit_tests.dm
index 6c4a278a396..1ef15f8d0f5 100644
--- a/code/modules/unit_tests/fish_unit_tests.dm
+++ b/code/modules/unit_tests/fish_unit_tests.dm
@@ -123,5 +123,79 @@
. = ..()
probability = 0 //works around the global list initialization skipping abstract/impossible evolutions.
+// we want no default spawns in this unit test
+/datum/chasm_detritus/restricted/bodies/no_defaults
+ default_contents_chance = 0
+
+/// Checks that we are able to fish people out of chasms with priority and that they end up in the right location
+/datum/unit_test/fish_rescue_hook
+ priority = TEST_LONGER
+ var/original_turf_type
+ var/original_turf_baseturfs
+ var/list/mobs_spawned
+
+/datum/unit_test/fish_rescue_hook/Run()
+ // create our human dummies to be dropped into the chasm
+ var/mob/living/carbon/human/consistent/get_in_the_hole = allocate(/mob/living/carbon/human/consistent)
+ var/mob/living/basic/mining/lobstrosity/you_too = allocate(/mob/living/basic/mining/lobstrosity)
+ var/mob/living/carbon/human/consistent/mindless = allocate(/mob/living/carbon/human/consistent)
+ var/mob/living/carbon/human/consistent/no_brain = allocate(/mob/living/carbon/human/consistent)
+ var/mob/living/carbon/human/consistent/empty = allocate(/mob/living/carbon/human/consistent)
+ var/mob/living/carbon/human/consistent/dummy = allocate(/mob/living/carbon/human/consistent)
+
+ mobs_spawned = list(
+ get_in_the_hole,
+ you_too,
+ mindless,
+ no_brain,
+ empty,
+ dummy,
+ )
+
+ // create our chasm and remember the previous turf so we can change it back once we're done
+ original_turf_type = run_loc_floor_bottom_left.type
+ original_turf_baseturfs = islist(run_loc_floor_bottom_left.baseturfs) ? run_loc_floor_bottom_left.baseturfs.Copy() : run_loc_floor_bottom_left.baseturfs
+ run_loc_floor_bottom_left.ChangeTurf(/turf/open/chasm)
+ var/turf/open/chasm/the_hole = run_loc_floor_bottom_left
+
+ // into the hole they go
+ for(var/mob/mob_spawned in mobs_spawned)
+ the_hole.drop(mob_spawned)
+ sleep(0.2 SECONDS) // we have to WAIT because the drop() proc sleeps.
+
+ // our 'fisherman' where we expect the item to be moved to after fishing it up
+ var/mob/living/carbon/human/consistent/a_fisherman = allocate(/mob/living/carbon/human/consistent, run_loc_floor_top_right)
+
+ // pretend like this mob has a mind. they should be fished up first
+ no_brain.mind_initialize()
+
+ SEND_SIGNAL(the_hole, COMSIG_PRE_FISHING) // we need to do this for the fishing spot component to be attached
+ var/datum/component/fishing_spot/the_hole_fishing_spot = the_hole.GetComponent(/datum/component/fishing_spot)
+ var/datum/fish_source/fishing_source = the_hole_fishing_spot.fish_source
+ var/obj/item/fishing_hook/rescue/the_hook = allocate(/obj/item/fishing_hook/rescue, run_loc_floor_top_right)
+ the_hook.chasm_detritus_type = /datum/chasm_detritus/restricted/bodies/no_defaults
+
+ // try to fish up our minded victim
+ var/atom/movable/reward = fishing_source.dispense_reward(the_hook.chasm_detritus_type, a_fisherman, the_hole)
+
+ // mobs with minds (aka players) should have precedence over any other mobs that are in the chasm
+ TEST_ASSERT_EQUAL(reward, no_brain, "Fished up [reward] ([REF(reward)]) with a rescue hook; expected to fish up [no_brain]([REF(no_brain)])")
+ // it should end up on the same turf as the fisherman
+ TEST_ASSERT_EQUAL(get_turf(reward), get_turf(a_fisherman), "[reward] was fished up with the rescue hook and ended up at [get_turf(reward)]; expected to be at [get_turf(a_fisherman)]")
+
+ // let's further test that by giving a second mob a mind. they should be fished up immediately..
+ empty.mind_initialize()
+
+ reward = fishing_source.dispense_reward(the_hook.chasm_detritus_type, a_fisherman, the_hole)
+
+ TEST_ASSERT_EQUAL(reward, empty, "Fished up [reward]([REF(reward)]) with a rescue hook; expected to fish up [empty]([REF(empty)])")
+ TEST_ASSERT_EQUAL(get_turf(reward), get_turf(a_fisherman), "[reward] was fished up with the rescue hook and ended up at [get_turf(reward)]; expected to be at [get_turf(a_fisherman)]")
+
+// clean up so we don't mess up subsequent tests
+/datum/unit_test/fish_rescue_hook/Destroy()
+ QDEL_LIST(mobs_spawned)
+ run_loc_floor_bottom_left.ChangeTurf(original_turf_type, original_turf_baseturfs)
+ return ..()
+
#undef TRAIT_FISH_TESTING
diff --git a/code/modules/unit_tests/focus_only_tests.dm b/code/modules/unit_tests/focus_only_tests.dm
index 0ad0bf961a0..927be7d8bc0 100644
--- a/code/modules/unit_tests/focus_only_tests.dm
+++ b/code/modules/unit_tests/focus_only_tests.dm
@@ -41,3 +41,6 @@
/// Checks to ensure that variables expected to exist in a job datum (for config reasons) actually exist
/datum/unit_test/focus_only/missing_job_datum_variables
+
+/// Checks that the contents of the fish_counts list are also present in fish_table
+/datum/unit_test/focus_only/fish_sources_tables
diff --git a/code/modules/unit_tests/hydroponics_harvest.dm b/code/modules/unit_tests/hydroponics_harvest.dm
index fefd8839cd2..8ff72c40b06 100644
--- a/code/modules/unit_tests/hydroponics_harvest.dm
+++ b/code/modules/unit_tests/hydroponics_harvest.dm
@@ -39,7 +39,7 @@
// Apples should harvest 10 apples with 10u nutrients and 4u vitamins.
test_seed(hydroponics_tray, planted_food_seed, human)
- // Sunflowers should harvest 10 sunflowers with 4u nutriment and 0u vitamins. It should also have 8u corn oil.
+ // Sunflowers should harvest 10 sunflowers with 4u nutriment and 0u vitamins. It should also have 8u oil.
test_seed(hydroponics_tray, planted_not_food_seed, human)
// Redbeets should harvest 5 beets (10 / 2) with 10u nutriments (5 x 2) and 10u vitamins (5 x 2) thanks to densified chemicals.
test_seed(hydroponics_tray, planted_densified_seed, human)
diff --git a/code/modules/unit_tests/leash.dm b/code/modules/unit_tests/leash.dm
index 2372ebca7df..a3d919be12f 100644
--- a/code/modules/unit_tests/leash.dm
+++ b/code/modules/unit_tests/leash.dm
@@ -1,5 +1,6 @@
/datum/unit_test/leash
abstract_type = /datum/unit_test/leash
+ priority = TEST_LONGER
var/atom/movable/owner
var/atom/movable/pet
@@ -55,7 +56,7 @@
var/timed_out = FALSE
/datum/leash_wait/New()
- addtimer(VARSET_CALLBACK(src, timed_out, TRUE), 1 SECONDS)
+ addtimer(VARSET_CALLBACK(src, timed_out, TRUE), 80 SECONDS)
/datum/leash_wait/proc/completed()
completed = TRUE
diff --git a/code/modules/unit_tests/ling_decap.dm b/code/modules/unit_tests/ling_decap.dm
new file mode 100644
index 00000000000..0c964f9a043
--- /dev/null
+++ b/code/modules/unit_tests/ling_decap.dm
@@ -0,0 +1,45 @@
+/// Test lings don't die when decapitated.
+/datum/unit_test/ling_decap
+
+/datum/unit_test/ling_decap/Run()
+ var/mob/living/carbon/human/ling = allocate(/mob/living/carbon/human/consistent)
+ ling.mind_initialize()
+ ling.mind.add_antag_datum(/datum/antagonist/changeling)
+
+ var/obj/item/bodypart/head/noggin = ling.get_bodypart(BODY_ZONE_HEAD)
+ noggin.dismember()
+ TEST_ASSERT_NULL(ling.get_bodypart(BODY_ZONE_HEAD), "Changeling failed to be decapitated.")
+ TEST_ASSERT_NULL(noggin.brainmob.mind, "Changeling's mind was moved to their head after decapitation, but it should have remained in their body.")
+
+ var/obj/item/organ/internal/brain/oldbrain = noggin.brain
+ noggin.drop_organs()
+ TEST_ASSERT_NULL(noggin.brain, "Changeling's head failed to drop its brain.")
+ TEST_ASSERT_NULL(oldbrain.brainmob.mind, "Changeling's mind was moved to their brain after decapitation and organ dropping, but it should have remained in their body.")
+
+ TEST_ASSERT_EQUAL(ling.stat, CONSCIOUS, "Changeling was not conscious after losing their head.")
+
+ // Cleanup
+ qdel(noggin)
+ for(var/obj/item/organ/leftover in ling.loc)
+ qdel(leftover)
+
+/// Tests people get decapitated properly.
+/datum/unit_test/normal_decap
+
+/datum/unit_test/normal_decap/Run()
+ var/mob/living/carbon/human/normal_guy = allocate(/mob/living/carbon/human/consistent)
+ normal_guy.mind_initialize()
+ var/my_guys_mind = normal_guy.mind
+
+ var/obj/item/bodypart/head/noggin = normal_guy.get_bodypart(BODY_ZONE_HEAD)
+ noggin.dismember()
+ TEST_ASSERT_EQUAL(noggin.brainmob.mind, my_guys_mind, "Dummy's mind was not moved to their head after decapitation.")
+
+ var/obj/item/organ/internal/brain/oldbrain = noggin.brain
+ noggin.drop_organs()
+ TEST_ASSERT_EQUAL(oldbrain.brainmob.mind, my_guys_mind, "Dummy's mind was not moved to their brain after being removed from their head.")
+
+ // Cleanup
+ qdel(noggin)
+ for(var/obj/item/organ/leftover in normal_guy.loc)
+ qdel(leftover)
diff --git a/code/modules/unit_tests/medical_wounds.dm b/code/modules/unit_tests/medical_wounds.dm
index 56c7a43104f..161492a726a 100644
--- a/code/modules/unit_tests/medical_wounds.dm
+++ b/code/modules/unit_tests/medical_wounds.dm
@@ -12,17 +12,18 @@
var/i = 1
var/list/iter_test_wound_list
- for(iter_test_wound_list in list(list(/datum/wound/blunt/moderate, /datum/wound/blunt/severe, /datum/wound/blunt/critical),\
- list(/datum/wound/slash/moderate, /datum/wound/slash/severe, /datum/wound/slash/critical),\
- list(/datum/wound/pierce/moderate, /datum/wound/pierce/severe, /datum/wound/pierce/critical),\
- list(/datum/wound/burn/moderate, /datum/wound/burn/severe, /datum/wound/burn/critical)))
+ for(iter_test_wound_list in list(list(/datum/wound/blunt/bone/moderate, /datum/wound/blunt/bone/severe, /datum/wound/blunt/bone/critical),\
+ list(/datum/wound/slash/flesh/moderate, /datum/wound/slash/flesh/severe, /datum/wound/slash/flesh/critical),\
+ list(/datum/wound/pierce/bleed/moderate, /datum/wound/pierce/bleed/severe, /datum/wound/pierce/bleed/critical),\
+ list(/datum/wound/burn/flesh/moderate, /datum/wound/burn/flesh/severe, /datum/wound/burn/flesh/critical)))
TEST_ASSERT_EQUAL(length(victim.all_wounds), 0, "Patient is somehow wounded before test")
var/datum/wound/iter_test_wound
+ var/datum/wound_pregen_data/iter_pregen_data = GLOB.all_wound_pregen_data[iter_test_wound]
var/threshold_penalty = 0
for(iter_test_wound in iter_test_wound_list)
- var/threshold = initial(iter_test_wound.threshold_minimum) - threshold_penalty // just enough to guarantee the next tier of wound, given the existing wound threshold penalty
+ var/threshold = iter_pregen_data.threshold_minimum - threshold_penalty // just enough to guarantee the next tier of wound, given the existing wound threshold penalty
if(dam_types[i] == BRUTE)
tested_part.receive_damage(WOUND_MINIMUM_DAMAGE, 0, wound_bonus = threshold, sharpness=sharps[i])
else if(dam_types[i] == BURN)
@@ -52,30 +53,33 @@
var/list/iter_test_wound_list
tested_part.biological_state &= ~BIO_FLESH // take away the base limb's flesh (ouchie!) ((not actually ouchie, this just affects their wounds and dismemberment handling))
- for(iter_test_wound_list in list(list(/datum/wound/blunt/moderate, /datum/wound/blunt/severe, /datum/wound/blunt/critical),\
- list(/datum/wound/slash/moderate, /datum/wound/slash/severe, /datum/wound/slash/critical),\
- list(/datum/wound/pierce/moderate, /datum/wound/pierce/severe, /datum/wound/pierce/critical),\
- list(/datum/wound/burn/moderate, /datum/wound/burn/severe, /datum/wound/burn/critical)))
+ for(iter_test_wound_list in list(list(/datum/wound/blunt/bone/moderate, /datum/wound/blunt/bone/severe, /datum/wound/blunt/bone/critical),\
+ list(/datum/wound/slash/flesh/moderate, /datum/wound/slash/flesh/severe, /datum/wound/slash/flesh/critical),\
+ list(/datum/wound/pierce/bleed/moderate, /datum/wound/pierce/bleed/severe, /datum/wound/pierce/bleed/critical),\
+ list(/datum/wound/burn/flesh/moderate, /datum/wound/burn/flesh/severe, /datum/wound/burn/flesh/critical)))
TEST_ASSERT_EQUAL(length(victim.all_wounds), 0, "Patient is somehow wounded before test")
var/datum/wound/iter_test_wound
+ var/datum/wound_pregen_data/iter_pregen_data = GLOB.all_wound_pregen_data[iter_test_wound]
var/threshold_penalty = 0
for(iter_test_wound in iter_test_wound_list)
- var/threshold = initial(iter_test_wound.threshold_minimum) - threshold_penalty // just enough to guarantee the next tier of wound, given the existing wound threshold penalty
+ var/threshold = iter_pregen_data.threshold_minimum - threshold_penalty // just enough to guarantee the next tier of wound, given the existing wound threshold penalty
if(dam_types[i] == BRUTE)
tested_part.receive_damage(WOUND_MINIMUM_DAMAGE, 0, wound_bonus = threshold, sharpness=sharps[i])
else if(dam_types[i] == BURN)
tested_part.receive_damage(0, WOUND_MINIMUM_DAMAGE, wound_bonus = threshold, sharpness=sharps[i])
// so if we just tried to deal a flesh wound, make sure we didn't actually suffer it. We may have suffered a bone wound instead, but we just want to make sure we don't have a flesh wound
- if(initial(iter_test_wound.wound_flags) & FLESH_WOUND)
+ var/datum/wound_pregen_data/pregen_data = GLOB.all_wound_pregen_data[iter_test_wound]
+ if (pregen_data.required_limb_biostate & BIO_FLESH)
if(!length(victim.all_wounds)) // not having a wound is good news
continue
else // we have to check that it's actually a bone wound and not the intended wound type
TEST_ASSERT_EQUAL(length(victim.all_wounds), 1, "Patient has more than one wound when only one is expected. Severity: [initial(iter_test_wound.severity)]")
var/datum/wound/actual_wound = victim.all_wounds[1]
- TEST_ASSERT((actual_wound.wound_flags & ~FLESH_WOUND), "Limb has flesh wound despite no BIO_FLESH biological_state, expected either no wound or bone wound. Offending wound: [actual_wound]")
+ var/datum/wound_pregen_data/actual_pregen_data = GLOB.all_wound_pregen_data[actual_wound.type]
+ TEST_ASSERT((actual_pregen_data.required_limb_biostate & ~BIO_FLESH), "Limb has flesh wound despite no BIO_FLESH biological_state, expected either no wound or bone wound. Offending wound: [actual_wound]")
threshold_penalty = actual_wound.threshold_penalty
else // otherwise if it's a bone wound, check that we have it per usual
TEST_ASSERT(length(victim.all_wounds), "Patient has no wounds when one wound is expected. Severity: [initial(iter_test_wound.severity)]")
diff --git a/code/modules/unit_tests/screenshots/screenshot_antag_icons_assaultoperative.png b/code/modules/unit_tests/screenshots/screenshot_antag_icons_assaultoperative.png
index 06ef0119d1c..fefeec4ad1d 100644
Binary files a/code/modules/unit_tests/screenshots/screenshot_antag_icons_assaultoperative.png and b/code/modules/unit_tests/screenshots/screenshot_antag_icons_assaultoperative.png differ
diff --git a/code/modules/unit_tests/screenshots/screenshot_antag_icons_bloodbrother.png b/code/modules/unit_tests/screenshots/screenshot_antag_icons_bloodbrother.png
index 2742f0fb8f8..e53e0a86697 100644
Binary files a/code/modules/unit_tests/screenshots/screenshot_antag_icons_bloodbrother.png and b/code/modules/unit_tests/screenshots/screenshot_antag_icons_bloodbrother.png differ
diff --git a/code/modules/unit_tests/screenshots/screenshot_antag_icons_changeling.png b/code/modules/unit_tests/screenshots/screenshot_antag_icons_changeling.png
index 38dc4457973..e1bdbea1058 100644
Binary files a/code/modules/unit_tests/screenshots/screenshot_antag_icons_changeling.png and b/code/modules/unit_tests/screenshots/screenshot_antag_icons_changeling.png differ
diff --git a/code/modules/unit_tests/screenshots/screenshot_antag_icons_stowawaychangeling.png b/code/modules/unit_tests/screenshots/screenshot_antag_icons_stowawaychangeling.png
index 38dc4457973..e1bdbea1058 100644
Binary files a/code/modules/unit_tests/screenshots/screenshot_antag_icons_stowawaychangeling.png and b/code/modules/unit_tests/screenshots/screenshot_antag_icons_stowawaychangeling.png differ
diff --git a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_lizard.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_lizard.png
index 1bddc8f5011..76694152323 100644
Binary files a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_lizard.png and b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_lizard.png differ
diff --git a/code/modules/unit_tests/simple_animal_freeze.dm b/code/modules/unit_tests/simple_animal_freeze.dm
index b3717b85d27..8de11513eaa 100644
--- a/code/modules/unit_tests/simple_animal_freeze.dm
+++ b/code/modules/unit_tests/simple_animal_freeze.dm
@@ -51,7 +51,6 @@
/mob/living/simple_animal/hostile/alien/queen/large,
/mob/living/simple_animal/hostile/alien/sentinel,
/mob/living/simple_animal/hostile/asteroid,
- /mob/living/simple_animal/hostile/asteroid/brimdemon,
/mob/living/simple_animal/hostile/asteroid/curseblob,
/mob/living/simple_animal/hostile/asteroid/elite,
/mob/living/simple_animal/hostile/asteroid/elite/broodmother,
@@ -87,7 +86,6 @@
/mob/living/simple_animal/hostile/blob/blobspore,
/mob/living/simple_animal/hostile/blob/blobspore/independent,
/mob/living/simple_animal/hostile/blob/blobspore/weak,
- /mob/living/simple_animal/hostile/boss,
/mob/living/simple_animal/hostile/construct,
/mob/living/simple_animal/hostile/construct/artificer,
/mob/living/simple_animal/hostile/construct/artificer/angelic,
@@ -137,7 +135,6 @@
/mob/living/simple_animal/hostile/jungle,
/mob/living/simple_animal/hostile/jungle/leaper,
/mob/living/simple_animal/hostile/jungle/mook,
- /mob/living/simple_animal/hostile/jungle/seedling,
/mob/living/simple_animal/hostile/megafauna,
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner,
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/doom,
@@ -164,7 +161,6 @@
/mob/living/simple_animal/hostile/mimic/copy/ranged,
/mob/living/simple_animal/hostile/mimic/crate,
/mob/living/simple_animal/hostile/mimic/xenobio,
- /mob/living/simple_animal/hostile/mining_drone,
/mob/living/simple_animal/hostile/nanotrasen,
/mob/living/simple_animal/hostile/nanotrasen/elite,
/mob/living/simple_animal/hostile/nanotrasen/ranged,
@@ -180,19 +176,6 @@
/mob/living/simple_animal/hostile/pirate/ranged,
/mob/living/simple_animal/hostile/pirate/ranged/space,
/mob/living/simple_animal/hostile/retaliate,
- /mob/living/simple_animal/hostile/retaliate/clown,
- /mob/living/simple_animal/hostile/retaliate/clown/banana,
- /mob/living/simple_animal/hostile/retaliate/clown/clownhulk,
- /mob/living/simple_animal/hostile/retaliate/clown/clownhulk/chlown,
- /mob/living/simple_animal/hostile/retaliate/clown/clownhulk/destroyer,
- /mob/living/simple_animal/hostile/retaliate/clown/clownhulk/honcmunculus,
- /mob/living/simple_animal/hostile/retaliate/clown/fleshclown,
- /mob/living/simple_animal/hostile/retaliate/clown/honkling,
- /mob/living/simple_animal/hostile/retaliate/clown/longface,
- /mob/living/simple_animal/hostile/retaliate/clown/lube,
- /mob/living/simple_animal/hostile/retaliate/clown/mutant,
- /mob/living/simple_animal/hostile/retaliate/clown/mutant/glutton,
- /mob/living/simple_animal/hostile/retaliate/clown/mutant/slow,
/mob/living/simple_animal/hostile/retaliate/goat,
/mob/living/simple_animal/hostile/retaliate/goose,
/mob/living/simple_animal/hostile/retaliate/goose/vomit,
@@ -300,7 +283,6 @@
/mob/living/simple_animal/hostile/megafauna/bubblegum/no_gps,
/mob/living/simple_animal/hostile/megafauna/gladiator,
/mob/living/simple_animal/hostile/megafauna/hierophant/astrum,
- /mob/living/simple_animal/hostile/mining_drone/interdyne,
/mob/living/simple_animal/hostile/mutantliz,
/mob/living/simple_animal/hostile/plantmutant,
/mob/living/simple_animal/hostile/scorpion,
diff --git a/code/modules/unit_tests/teleporters.dm b/code/modules/unit_tests/teleporters.dm
index 2cb047304fb..e1af0a71a35 100644
--- a/code/modules/unit_tests/teleporters.dm
+++ b/code/modules/unit_tests/teleporters.dm
@@ -1,10 +1,18 @@
-/datum/unit_test/auto_teleporter_linking/Run()
+/datum/unit_test/teleporter/Run()
// Put down the teleporter machinery
var/obj/machinery/teleport/hub/hub = allocate(/obj/machinery/teleport/hub)
var/obj/machinery/teleport/station/station = allocate(/obj/machinery/teleport/station, locate(run_loc_floor_bottom_left.x + 1, run_loc_floor_bottom_left.y, run_loc_floor_bottom_left.z))
var/obj/machinery/computer/teleporter/computer = allocate(/obj/machinery/computer/teleporter, locate(run_loc_floor_bottom_left.x + 2, run_loc_floor_bottom_left.y, run_loc_floor_bottom_left.z))
+ var/obj/item/beacon/beacon = allocate(/obj/item/beacon)
TEST_ASSERT_EQUAL(hub.power_station, station, "Hub didn't link to the station")
TEST_ASSERT_EQUAL(station.teleporter_console, computer, "Station didn't link to the teleporter console")
TEST_ASSERT_EQUAL(station.teleporter_hub, hub, "Station didn't link to the hub")
TEST_ASSERT_EQUAL(computer.power_station, station, "Teleporter console didn't link to the hub")
+
+ computer.set_teleport_target(beacon)
+ TEST_ASSERT_EQUAL(computer.target_ref, beacon.weak_reference, "Teleporter didn't target beacon correctly")
+
+ computer.set_teleport_target(beacon)
+ beacon.turn_off()
+ TEST_ASSERT_NULL(computer.target_ref, "Teleporter beacon isn't properly turned off.")
diff --git a/code/modules/unit_tests/weird_food.dm b/code/modules/unit_tests/weird_food.dm
new file mode 100644
index 00000000000..5c97c343adf
--- /dev/null
+++ b/code/modules/unit_tests/weird_food.dm
@@ -0,0 +1,40 @@
+/// Unit test to ensure that moths can eat t-shirts successfully
+/datum/unit_test/moth_food
+
+/datum/unit_test/moth_food/Run()
+ var/obj/item/clothing/suit/armor/bulletproof/light_snack = allocate(/obj/item/clothing/suit/armor/bulletproof)
+ light_snack.create_moth_snack()
+ var/datum/component/edible/eatability = light_snack.moth_snack.GetComponent(/datum/component/edible)
+ eatability.eat_time = 0
+
+ var/mob/living/carbon/human/species/moth/gourmet = allocate(/mob/living/carbon/human/species/moth)
+ gourmet.nutrition = 0 // We need to be sufficiently hungry
+ gourmet.put_in_active_hand(light_snack)
+
+ var/times_to_bite = round(light_snack.max_integrity / MOTH_EATING_CLOTHING_DAMAGE) + 1
+ for (var/i in 1 to times_to_bite)
+ TEST_ASSERT(!QDELETED(light_snack), "Moth finished eating clothes faster than expected.")
+ light_snack.attack(gourmet, gourmet)
+ TEST_ASSERT(QDELETED(light_snack), "Moth failed to finish eating clothing.")
+
+/// Unit test to ensure that golems can eat rocks successfully
+/datum/unit_test/golem_food
+
+/datum/unit_test/golem_food/Run()
+ var/obj/item/stack/sheet/mineral/uranium/five/dinner = allocate(/obj/item/stack/sheet/mineral/uranium/five)
+ var/datum/component/golem_food/golem_food_data = dinner.GetComponent(/datum/component/golem_food)
+ golem_food_data.create_golem_snack(dinner)
+ var/datum/component/edible/eatability = golem_food_data.golem_snack.GetComponent(/datum/component/edible)
+ eatability.eat_time = 0
+
+ var/mob/living/carbon/human/species/golem/rock_enjoyer = allocate(/mob/living/carbon/human/species/golem)
+ rock_enjoyer.nutrition = 0 // We need to be sufficiently hungry
+ rock_enjoyer.put_in_active_hand(dinner)
+
+ var/status_applied = golem_food_data.snack_type.status_effect
+ var/times_to_bite = dinner.amount
+ for (var/i in 1 to times_to_bite)
+ TEST_ASSERT(!QDELETED(dinner), "Golem finished eating rocks faster than expected.")
+ dinner.attack(rock_enjoyer, rock_enjoyer)
+ TEST_ASSERT(QDELETED(dinner), "Golem failed to finish eating rocks.")
+ TEST_ASSERT(rock_enjoyer.has_status_effect(status_applied), "Golem didn't gain a food buff from eating its rocks.")
diff --git a/code/modules/uplink/uplink_items/device_tools.dm b/code/modules/uplink/uplink_items/device_tools.dm
index 816f88b8057..5807cc800c6 100644
--- a/code/modules/uplink/uplink_items/device_tools.dm
+++ b/code/modules/uplink/uplink_items/device_tools.dm
@@ -66,7 +66,8 @@
cost = 1
surplus = 20
-/datum/uplink_item/device_tools/briefcase_launchpad
+/* // SKYRAT EDIT REMOVAL
+/datum/uplink_item/device_tools/briefcase_launchpad
name = "Briefcase Launchpad"
desc = "A briefcase containing a launchpad, a device able to teleport items and people to and from targets up to eight tiles away from the briefcase. \
Also includes a remote control, disguised as an ordinary folder. Touch the briefcase with the remote to link it."
@@ -82,6 +83,7 @@
Comes with 4 charges, recharges randomly. Warranty null and void if exposed to an electromagnetic pulse."
item = /obj/item/storage/box/syndie_kit/syndicate_teleporter
cost = 8
+*/ //END SKYRAT EDIT
/datum/uplink_item/device_tools/camera_app
name = "SyndEye Program"
@@ -263,3 +265,9 @@
bright lights. Effective, affordable, and nigh undetectable."
item = /obj/item/syndicate_contacts
cost = 3
+
+/datum/uplink_item/device_tools/syndicate_climbing_hook
+ name = "Syndicate Climbing Hook"
+ desc = "High-tech rope, a refined hook structure, the peak of climbing technology. Only useful for climbing up holes, provided the operation site has any."
+ item = /obj/item/climbing_hook/syndicate
+ cost = 1
diff --git a/code/modules/uplink/uplink_items/job.dm b/code/modules/uplink/uplink_items/job.dm
index 7ae06fb79df..b971e07619c 100644
--- a/code/modules/uplink/uplink_items/job.dm
+++ b/code/modules/uplink/uplink_items/job.dm
@@ -328,3 +328,10 @@
cost = 14 //High cost because of the potential for extreme damage in the hands of a skilled scientist.
restricted_roles = list(JOB_RESEARCH_DIRECTOR, JOB_SCIENTIST)
surplus = 5
+
+/datum/uplink_item/role_restricted/evil_seedling
+ name = "Evil Seedling"
+ desc = "A rare seed we have recovered that grows into a dangerous species that will aid you with your tasks!"
+ item = /obj/item/seeds/seedling/evil
+ cost = 8
+ restricted_roles = list(JOB_BOTANIST)
diff --git a/code/modules/uplink/uplink_items/nukeops.dm b/code/modules/uplink/uplink_items/nukeops.dm
index e31421bdde4..632d4cc2717 100644
--- a/code/modules/uplink/uplink_items/nukeops.dm
+++ b/code/modules/uplink/uplink_items/nukeops.dm
@@ -468,7 +468,7 @@
name = "Cybernetic Implants Bundle"
desc = "A box containing x-ray eyes, a CNS Rebooter and Reviver implant. Comes with an autosurgeon for each."
item = /obj/item/storage/box/cyber_implants
- cost = 25 //worth around 32 TC
+ cost = 20 //worth 24 TC
purchasable_from = UPLINK_NUKE_OPS
/datum/uplink_item/bundles_tc/medical
@@ -597,6 +597,14 @@
cost = 2
purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS
+/datum/uplink_item/device_tools/medgun_mod
+ name = "Medbeam Gun Module"
+ desc = "A wonder of Syndicate engineering, the Medbeam gun module, or Medi-Gun enables a medic to keep his fellow \
+ operatives in the fight, even while under fire. Don't cross the streams!"
+ item = /obj/item/mod/module/medbeam
+ cost = 15
+ purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS
+
/datum/uplink_item/suits/syndi_intellicard
name = "Pre-Loaded Syndicate Intellicard"
desc = "A syndicate intellicard that can be activated to download a captured Nanotrasen AI, modified with the standard syndicate lawset. You can slot it into your modsuit for a conversational partner! It can additionally control the MODsuit's modules at will, and move your body around even if you're in critical condition or dead. \
@@ -634,14 +642,6 @@
cost = 4
purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS
-/datum/uplink_item/device_tools/medgun
- name = "Medbeam Gun"
- desc = "A wonder of Syndicate engineering, the Medbeam gun, or Medi-Gun enables a medic to keep his fellow \
- operatives in the fight, even while under fire. Don't cross the streams!"
- item = /obj/item/gun/medbeam
- cost = 15
- purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS
-
/datum/uplink_item/device_tools/medkit
name = "Syndicate Combat Medic Kit"
desc = "This first aid kit is a suspicious black and red. Included is a number of atropine medipens \
@@ -732,13 +732,6 @@
item = /obj/item/autosurgeon/syndicate/anti_stun
cost = 8
-/datum/uplink_item/implants/nuclear/antidrop
- name = "Anti-Drop Implant"
- desc = "This implant will keep you from dropping things from your hands. Be sure to hold onto the item before activating, and \
- activate it again to turn it off. Comes with an autosurgeon."
- item = /obj/item/autosurgeon/syndicate/anti_drop
- cost = 8
-
// Badass (meme items)
/datum/uplink_item/badass/costumes
diff --git a/code/modules/vehicles/cars/clowncar.dm b/code/modules/vehicles/cars/clowncar.dm
index 3fb6d37bd2c..1fd230bb47a 100644
--- a/code/modules/vehicles/cars/clowncar.dm
+++ b/code/modules/vehicles/cars/clowncar.dm
@@ -121,11 +121,11 @@
if(prob(35)) //Note: The randomstep on dump_mobs throws occupants into each other and often causes wounds regardless.
continue
for(var/obj/item/bodypart/head/head_to_wound as anything in carbon_occupant.bodyparts)
- var/type_wound = pick(list(
- /datum/wound/blunt/moderate,
- /datum/wound/blunt/severe,
- ))
- head_to_wound.force_wound_upwards(type_wound, wound_source = src)
+ var/pick_mode = text2num(pick(list(
+ "[WOUND_PICK_LOWEST_SEVERITY]",
+ "[WOUND_PICK_HIGHEST_SEVERITY]"
+ )))
+ carbon_occupant.cause_wound_of_type_and_severity(WOUND_BLUNT, head_to_wound, WOUND_SEVERITY_MODERATE, WOUND_SEVERITY_SEVERE, pick_mode)
carbon_occupant.playsound_local(src, 'sound/weapons/flash_ring.ogg', 50)
carbon_occupant.set_eye_blur_if_lower(rand(10 SECONDS, 20 SECONDS))
diff --git a/code/modules/vehicles/mecha/equipment/tools/medical_tools.dm b/code/modules/vehicles/mecha/equipment/tools/medical_tools.dm
index 3546d7853b3..ca3b4f2f479 100644
--- a/code/modules/vehicles/mecha/equipment/tools/medical_tools.dm
+++ b/code/modules/vehicles/mecha/equipment/tools/medical_tools.dm
@@ -428,7 +428,7 @@
if(!chassis.Adjacent(S))
to_chat(user, "[icon2html(src, user)][span_warning("Unable to load syringe!")]")
return FALSE
- S.reagents.trans_to(src, S.reagents.total_volume, transfered_by = user)
+ S.reagents.trans_to(src, S.reagents.total_volume, transferred_by = user)
S.forceMove(src)
LAZYADD(syringes,S)
to_chat(user, "[icon2html(src, user)][span_notice("Syringe loaded.")]")
diff --git a/code/modules/vehicles/mecha/mech_fabricator.dm b/code/modules/vehicles/mecha/mech_fabricator.dm
index 618ad33d1db..56b3cd2138c 100644
--- a/code/modules/vehicles/mecha/mech_fabricator.dm
+++ b/code/modules/vehicles/mecha/mech_fabricator.dm
@@ -50,8 +50,6 @@
var/list/datum/design/cached_designs
/obj/machinery/mecha_part_fabricator/Initialize(mapload)
- if(!CONFIG_GET(flag/no_default_techweb_link) && !stored_research)
- connect_techweb(SSresearch.science_tech)
rmat = AddComponent( \
/datum/component/remote_materials, \
mapload && link_on_init, \
@@ -59,20 +57,29 @@
)
cached_designs = list()
RefreshParts() //Recalculating local material sizes if the fab isn't linked
- if(stored_research)
- update_menu_tech()
return ..()
+/obj/machinery/mecha_part_fabricator/LateInitialize()
+ . = ..()
+ if(!CONFIG_GET(flag/no_default_techweb_link) && !stored_research)
+ CONNECT_TO_RND_SERVER_ROUNDSTART(stored_research, src)
+ if(stored_research)
+ on_connected_techweb()
+
/obj/machinery/mecha_part_fabricator/proc/connect_techweb(datum/techweb/new_techweb)
if(stored_research)
UnregisterSignal(stored_research, list(COMSIG_TECHWEB_ADD_DESIGN, COMSIG_TECHWEB_REMOVE_DESIGN))
-
stored_research = new_techweb
+ if(!isnull(stored_research))
+ on_connected_techweb()
+
+/obj/machinery/mecha_part_fabricator/proc/on_connected_techweb()
RegisterSignals(
stored_research,
list(COMSIG_TECHWEB_ADD_DESIGN, COMSIG_TECHWEB_REMOVE_DESIGN),
PROC_REF(on_techweb_update)
)
+ update_menu_tech()
/obj/machinery/mecha_part_fabricator/multitool_act(mob/living/user, obj/item/multitool/tool)
if(!QDELETED(tool.buffer) && istype(tool.buffer, /datum/techweb))
diff --git a/code/modules/vehicles/vehicle_actions.dm b/code/modules/vehicles/vehicle_actions.dm
index c1b48f04771..1fbf394d270 100644
--- a/code/modules/vehicles/vehicle_actions.dm
+++ b/code/modules/vehicles/vehicle_actions.dm
@@ -359,10 +359,10 @@
animate(vehicle, pixel_y = -6, time = 3)
playsound(vehicle, 'sound/vehicles/skateboard_ollie.ogg', 50, TRUE)
passtable_on(rider, VEHICLE_TRAIT)
- vehicle.pass_flags |= PASSTABLE
+ passtable_on(vehicle, VEHICLE_TRAIT)
rider.Move(landing_turf, vehicle_target.dir)
passtable_off(rider, VEHICLE_TRAIT)
- vehicle.pass_flags &= ~PASSTABLE
+ passtable_off(vehicle, VEHICLE_TRAIT)
/datum/action/vehicle/ridden/scooter/skateboard/kickflip
name = "Kickflip"
diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm
index c68d70f5164..ab882bf7997 100644
--- a/code/modules/vending/_vending.dm
+++ b/code/modules/vending/_vending.dm
@@ -194,8 +194,6 @@
///Items that the players have loaded into the vendor
var/list/vending_machine_input = list()
- ///Display header on the input view
- var/input_display_header = "Custom Vendor"
//The type of refill canisters used by this machine.
var/obj/item/vending_refill/refill_canister = null
@@ -954,11 +952,9 @@
return FALSE
var/mob/living/carbon/carbon_target = atom_target
for(var/obj/item/bodypart/squish_part in carbon_target.bodyparts)
- if(IS_ORGANIC_LIMB(squish_part))
- var/type_wound = pick(list(/datum/wound/blunt/critical, /datum/wound/blunt/severe, /datum/wound/blunt/moderate))
- squish_part.force_wound_upwards(type_wound, wound_source = "crushed by [src]")
- else
- squish_part.receive_damage(brute=30)
+ var/severity = pick(WOUND_SEVERITY_MODERATE, WOUND_SEVERITY_SEVERE, WOUND_SEVERITY_CRITICAL)
+ if (!carbon_target.cause_wound_of_type_and_severity(WOUND_BLUNT, squish_part, severity, wound_source = "crushed by [src]"))
+ squish_part.receive_damage(brute = 30)
carbon_target.visible_message(span_danger("[carbon_target]'s body is maimed underneath the mass of [src]!"), span_userdanger("Your body is maimed underneath the mass of [src]!"))
return TRUE
if(CRUSH_CRIT_HEADGIB) // skull squish!
@@ -1040,7 +1036,7 @@
to_chat(user, span_notice("You insert [inserted_item] into [src]'s input compartment."))
for(var/datum/data/vending_product/product_datum in product_records + coin_records + hidden_records)
- if(ispath(inserted_item.type, product_datum.product_path))
+ if(inserted_item.type == product_datum.product_path)
product_datum.amount++
LAZYADD(product_datum.returned_products, inserted_item)
return
@@ -1534,7 +1530,7 @@
* * user - the user doing the loading
*/
/obj/machinery/vending/proc/canLoadItem(obj/item/loaded_item, mob/user)
- if((loaded_item.type in products) || (loaded_item.type in premium) || (loaded_item.type in contraband))
+ if(!length(loaded_item.contents) && ((loaded_item.type in products) || (loaded_item.type in premium) || (loaded_item.type in contraband)))
return TRUE
to_chat(user, span_warning("[src] does not accept [loaded_item]!"))
return FALSE
diff --git a/code/modules/vending/clothesmate.dm b/code/modules/vending/clothesmate.dm
index 0d2f63597b6..eeca2422e0c 100644
--- a/code/modules/vending/clothesmate.dm
+++ b/code/modules/vending/clothesmate.dm
@@ -118,6 +118,15 @@
/obj/item/clothing/under/rank/civilian/purple_bartender = 2,
/obj/item/clothing/suit/jacket/miljacket = 1,
/obj/item/clothing/suit/apron/overalls = 2,
+ /obj/item/clothing/suit/costume/wellworn_shirt = 2,
+ /obj/item/clothing/suit/costume/wellworn_shirt/graphic = 2,
+ /obj/item/clothing/suit/costume/wellworn_shirt/graphic/ian = 2,
+ /obj/item/clothing/suit/costume/wellworn_shirt/wornout = 2,
+ /obj/item/clothing/suit/costume/wellworn_shirt/wornout/graphic = 2,
+ /obj/item/clothing/suit/costume/wellworn_shirt/wornout/graphic/ian = 2,
+ /obj/item/clothing/suit/costume/wellworn_shirt/messy = 2,
+ /obj/item/clothing/suit/costume/wellworn_shirt/messy/graphic = 2,
+ /obj/item/clothing/suit/costume/wellworn_shirt/messy/graphic/ian = 2,
),
),
@@ -152,7 +161,7 @@
/obj/item/clothing/suit/hooded/ethereal_raincoat = 3,
/obj/item/clothing/under/ethereal_tunic = 3,
- /obj/item/clothing/suit/costume/ianshirt = 1,
+ /obj/item/clothing/suit/costume/wellworn_shirt/graphic/ian = 1,
/obj/item/clothing/suit/costume/irs = 20,
/obj/item/clothing/head/costume/irs = 20,
/obj/item/clothing/head/costume/tmc = 20,
diff --git a/code/modules/vending/snack.dm b/code/modules/vending/snack.dm
index ec633084fd8..23b1bcf2c71 100644
--- a/code/modules/vending/snack.dm
+++ b/code/modules/vending/snack.dm
@@ -44,7 +44,6 @@
default_price = PAYCHECK_CREW * 0.6
extra_price = PAYCHECK_CREW
payment_department = ACCOUNT_SRV
- input_display_header = "Chef's Food Selection"
/obj/item/vending_refill/snack
machine_name = "Getmore Chocolate Corp"
diff --git a/code/modules/vending/wardrobes.dm b/code/modules/vending/wardrobes.dm
index 01a62672230..da2c08e04c9 100644
--- a/code/modules/vending/wardrobes.dm
+++ b/code/modules/vending/wardrobes.dm
@@ -5,7 +5,6 @@
default_price = PAYCHECK_CREW
extra_price = PAYCHECK_COMMAND
payment_department = NO_FREEBIES
- input_display_header = "Returned Clothing"
panel_type = "panel19"
light_mask = "wardrobe-light-mask"
@@ -132,6 +131,7 @@
/obj/item/clothing/accessory/pocketprotector = 3,
/obj/item/clothing/under/rank/engineering/atmospheric_technician = 3,
/obj/item/clothing/under/rank/engineering/atmospheric_technician/skirt = 3,
+ /obj/item/clothing/suit/atmos_overalls = 3,
/obj/item/clothing/suit/hooded/wintercoat/engineering/atmos = 3,
/obj/item/clothing/shoes/sneakers/black = 3,
/obj/item/storage/backpack/satchel/eng = 3,
@@ -157,8 +157,9 @@
/obj/item/clothing/mask/bandana/striped/cargo = 3,
/obj/item/clothing/head/soft = 3,
/obj/item/clothing/under/rank/cargo/tech = 3,
- /obj/item/clothing/under/rank/cargo/tech/alt = 3,
/obj/item/clothing/under/rank/cargo/tech/skirt = 3,
+ /obj/item/clothing/under/rank/cargo/tech/alt = 3,
+ /obj/item/clothing/under/rank/cargo/tech/skirt/alt = 3,
/obj/item/clothing/suit/toggle/cargo_tech = 3,
/obj/item/clothing/suit/hooded/wintercoat/cargo = 3,
/obj/item/clothing/gloves/fingerless = 3,
diff --git a/code/modules/wiremod/core/component_printer.dm b/code/modules/wiremod/core/component_printer.dm
index cf791ffdad6..25c684c5a28 100644
--- a/code/modules/wiremod/core/component_printer.dm
+++ b/code/modules/wiremod/core/component_printer.dm
@@ -22,21 +22,27 @@
/obj/machinery/component_printer/Initialize(mapload)
. = ..()
- if(!CONFIG_GET(flag/no_default_techweb_link) && !techweb)
- connect_techweb(SSresearch.science_tech)
-
materials = AddComponent( \
/datum/component/remote_materials, \
mapload, \
mat_container_flags = BREAKDOWN_FLAGS_LATHE, \
)
+/obj/machinery/component_printer/LateInitialize()
+ . = ..()
+ if(!CONFIG_GET(flag/no_default_techweb_link) && !techweb)
+ CONNECT_TO_RND_SERVER_ROUNDSTART(techweb, src)
+ if(techweb)
+ on_connected_techweb()
+
/obj/machinery/component_printer/proc/connect_techweb(datum/techweb/new_techweb)
if(techweb)
UnregisterSignal(techweb, list(COMSIG_TECHWEB_ADD_DESIGN, COMSIG_TECHWEB_REMOVE_DESIGN))
-
techweb = new_techweb
+ if(!isnull(techweb))
+ on_connected_techweb()
+/obj/machinery/component_printer/proc/on_connected_techweb()
for (var/researched_design_id in techweb.researched_designs)
var/datum/design/design = SSresearch.techweb_design_by_id(researched_design_id)
if (!(design.build_type & COMPONENT_PRINTER) || !ispath(design.build_path, /obj/item/circuit_component))
diff --git a/config/config.txt b/config/config.txt
index 27cfed87b26..d7195a9e097 100644
--- a/config/config.txt
+++ b/config/config.txt
@@ -395,7 +395,7 @@ CLIENT_ERROR_BUILD 1421
## Set to 0 or comment out to disable.
SECOND_TOPIC_LIMIT 10
-MINUTE_TOPIC_LIMIT 100
+MINUTE_TOPIC_LIMIT 200
## CLICK RATE LIMITING
@@ -483,6 +483,12 @@ DEFAULT_VIEW_SQUARE 15x15
## Enable automatic profiling - Byond 513.1506 and newer only.
#AUTO_PROFILE
+## Threshold (in deciseconds) for real time between ticks before we start dumping profiles
+DRIFT_DUMP_THRESHOLD 40
+
+## How long to wait (in deciseconds) after a profile dump before logging another tickdrift sourced one
+DRIFT_PROFILE_DELAY 150
+
## Uncomment to enable global ban DB using the provided URL. The API should expect to receive a ckey at the end of the URL.
## More API details can be found here: https://centcom.melonmesa.com
#CENTCOM_BAN_DB https://centcom.melonmesa.com/ban/search
diff --git a/config/skyrat/skyrat_config.txt b/config/skyrat/skyrat_config.txt
index bda23f49b1f..dfda06ae026 100644
--- a/config/skyrat/skyrat_config.txt
+++ b/config/skyrat/skyrat_config.txt
@@ -143,3 +143,6 @@ SIZE_COLLAR_MINIMUM 15
DONATOR_LEGACY_SYSTEM
MENTOR_LEGACY_SYSTEM
VETERAN_LEGACY_SYSTEM
+
+## How much time arrivals shuttle should stay at station after its engines recharged before returning to interlink. In deciseconds. 150 - 15 seconds. 0 - disables autoreturn.
+ARRIVALS_WAIT 150
diff --git a/config/spaceruinblacklist.txt b/config/spaceruinblacklist.txt
index 7b951c28e46..6ac8f8f08c2 100644
--- a/config/spaceruinblacklist.txt
+++ b/config/spaceruinblacklist.txt
@@ -35,6 +35,7 @@
#_maps/RandomRuins/SpaceRuins/derelict6.dmm
#_maps/RandomRuins/SpaceRuins/derelict7.dmm
#_maps/RandomRuins/SpaceRuins/derelict8.dmm
+#_maps/RandomRuins/SpaceRuins/derelict9.dmm
#_maps/RandomRuins/SpaceRuins/dj_station.dmm
#_maps/RandomRuins/SpaceRuins/emptyshell.dmm
#_maps/RandomRuins/SpaceRuins/fasttravel.dmm
diff --git a/html/changelogs/AutoChangeLog-pr-23873.yml b/html/changelogs/AutoChangeLog-pr-23873.yml
new file mode 100644
index 00000000000..71d7321df3c
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-23873.yml
@@ -0,0 +1,4 @@
+author: "SkyratBot"
+delete-after: True
+changes:
+ - code_imp: "New flags/args to electrocute_act()"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-23874.yml b/html/changelogs/AutoChangeLog-pr-23874.yml
new file mode 100644
index 00000000000..abb0b6b84d6
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-23874.yml
@@ -0,0 +1,4 @@
+author: "SkyratBot"
+delete-after: True
+changes:
+ - bugfix: "Fixed players being able to roll antagonist without ever being eligible to play any role. Players who have their preferences set up so that they're likely to return to lobby when the round starts have a lowered chance of becoming antagonist."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-23875.yml b/html/changelogs/AutoChangeLog-pr-23875.yml
new file mode 100644
index 00000000000..81b597de654
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-23875.yml
@@ -0,0 +1,4 @@
+author: "distributivgesetz"
+delete-after: True
+changes:
+ - bugfix: "Clamping/closing a wound should now heal the bodypart that was damaged instead of a random one."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-23876.yml b/html/changelogs/AutoChangeLog-pr-23876.yml
new file mode 100644
index 00000000000..b1aa9838961
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-23876.yml
@@ -0,0 +1,5 @@
+author: "SkyratBot"
+delete-after: True
+changes:
+ - bugfix: "Fixed beams rendering below mobs by default."
+ - bugfix: "The fishing line beam is no longer emissive (it doesn't glow in the dark)."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-23877.yml b/html/changelogs/AutoChangeLog-pr-23877.yml
new file mode 100644
index 00000000000..07739eb44b8
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-23877.yml
@@ -0,0 +1,4 @@
+author: "Vekter"
+delete-after: True
+changes:
+ - bugfix: "Fixes Birdshot's recycler being turned the wrong direction."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-23878.yml b/html/changelogs/AutoChangeLog-pr-23878.yml
new file mode 100644
index 00000000000..770093e2648
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-23878.yml
@@ -0,0 +1,4 @@
+author: "SkyratBot"
+delete-after: True
+changes:
+ - bugfix: "Fix secret documents steal objective failing while inside folder."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-23879.yml b/html/changelogs/AutoChangeLog-pr-23879.yml
new file mode 100644
index 00000000000..e99fcc6b1e4
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-23879.yml
@@ -0,0 +1,4 @@
+author: "Melbert"
+delete-after: True
+changes:
+ - rscadd: "Changelings can now speak through their decoy brain if it is placed in an MMI, to maintain the illusion they are actually dead and have been debrained."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-23880.yml b/html/changelogs/AutoChangeLog-pr-23880.yml
new file mode 100644
index 00000000000..3bcea4ae4b4
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-23880.yml
@@ -0,0 +1,4 @@
+author: "SkyratBot"
+delete-after: True
+changes:
+ - balance: "Makes it so Ephedrine spasms have a 10 * (1.5 - purity)% chance per second to happen, Adding a downside to pure Ephedrine"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-23881.yml b/html/changelogs/AutoChangeLog-pr-23881.yml
new file mode 100644
index 00000000000..ea7a4e680da
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-23881.yml
@@ -0,0 +1,6 @@
+author: "SkyratBot"
+delete-after: True
+changes:
+ - rscadd: "Added the Hippocrates bust to medbay heirlooms. Paramedics don't get one."
+ - rscadd: "You can now swear the Hippocratic oath with these busts! It'll give you pacifism but nothing else. The process is reversible."
+ - rscadd: "There's a very small chance that the Hippocrates bust was once wielded by a certain German doctor. This chance is increased for coroner heirlooms."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-23882.yml b/html/changelogs/AutoChangeLog-pr-23882.yml
new file mode 100644
index 00000000000..112c9d15626
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-23882.yml
@@ -0,0 +1,4 @@
+author: "SkyratBot"
+delete-after: True
+changes:
+ - bugfix: "Syndicate Modsuit AI's now downloads the current codespeak book upon being downloaded."
\ No newline at end of file
diff --git a/html/changelogs/archive/2023-08.yml b/html/changelogs/archive/2023-08.yml
index 8639a230c99..06f1d4cfd36 100644
--- a/html/changelogs/archive/2023-08.yml
+++ b/html/changelogs/archive/2023-08.yml
@@ -1390,3 +1390,75 @@
zydras:
- rscadd: Added a set of new donator items
- rscdel: Removed older, unused (and broken) donator items
+2023-08-31:
+ Guillaume Prata:
+ - qol: The "You can't move while buckled to X" is now a balloon alert instead of
+ a to_chat message. Hopefully we all get buckle stuck processing why our inputs
+ are not working less often for now on.
+ Ldip999:
+ - qol: Space hotel and Tarkon now comes with range ovens
+ Motho:
+ - rscadd: MODLink Scryer necklaces are now available in the loadout.
+ Paxilmaniac:
+ - qol: When ordering multiple items with a personal account or with a department
+ budget, all of those items will arrive in the same container, case or crate
+ depending on the number of items.
+ - balance: Company imports companies no longer need to be purchased
+ - balance: Company interest no longer exists at all
+ - balance: Company import items cannot run out of stock anymore
+ - balance: Company import items are overall significantly cheaper than they used
+ to be
+ - balance: Some items in company imports have either been added, removed, or tweaked
+ in nearly all companies due to not quite fitting anymore, or missing where I
+ felt they should have been. Most of the removed items are comically easy to
+ attain or otherwise useless and were only there to raise interest before, but
+ now that interest is gone they are not necessary.
+ - bugfix: Cyborgs can use company imports to order things off of the cargo budget
+ now
+ - image: Added a new wooden box sprite for import items that come from the cargo
+ budget, to prevent infinite money generation at the same time
+ ReezeBL:
+ - image: added 2 ear's sprites and 1 snout's sprite
+ Shadow-Quill:
+ - spellcheck: Fixed the ] appearing in cryopod action text.
+ SkyratBot:
+ - bugfix: autolathe prints the correct amount of stacks and merges it with existing
+ stacks on the turf
+ - bugfix: autolathe takes constant time when printing stacks
+ - code_imp: autolathe will attempt to award you the "getting an upgrade" award only
+ once when printing multiple items & updates UI immediately
+ - sound: Unlocking an achievement now plays a sound by default. You can change it
+ in the Sound category of the game preferences.
+ - bugfix: Compact fishing toolboxes no longer break space and time to contain any
+ normal-sized object. Instead, they only break space and time to contain fishing
+ rods. Settlers migrating to Nanotrasen space have no reasonable explanation
+ for this phenomenon.
+ - refactor: sheets are merged in a better way when ejected from machines & material
+ related stuff
+ - bugfix: Probital overdose no longer causes plasmamen and other inorganics to receive
+ the longest nap in their lives.
+ - bugfix: Changed icebox permabrig door type to be correct
+ - bugfix: Fixes Star Gazer getting buckled
+ - image: Removes Star Gazer alpha pixels
+ - bugfix: fixed skeleton wings not being visible from behind while closed
+ - bugfix: Space heaters no longer give extra cells when deconstructed
+ - bugfix: rcd can build wallmounts on reinforced walls
+ - qol: rcd can build directional windows without requiring/building a grill
+ Stalkeros:
+ - rscadd: NRI cops antag datum.
+ - rscdel: Removes green NRI armor vest and helmet, heavy variants included.
+ Stalkeros, Motho for the sound:
+ - sound: New unique sound for the operational status readout module.
+ SyncIt21:
+ - bugfix: autolathe prints the correct amount of stacks and merges it with existing
+ stacks on the turf
+ - bugfix: 'autolathe takes constant time when printing stacks code: autolathe will
+ attempt to award you the "getting an upgrade" award only once when printing
+ multiple items & updates UI immediately'
+ YakumoChen:
+ - bugfix: Made it less trivial for snailpeople to crawl around at meth speeds.
+ larentoun:
+ - refactor: Moves cargo supply edits to master_files, company imports ui_act to
+ master_files
+ olirant:
+ - rscadd: 1 donator plush
diff --git a/html/changelogs/archive/2023-09.yml b/html/changelogs/archive/2023-09.yml
new file mode 100644
index 00000000000..aa41425b439
--- /dev/null
+++ b/html/changelogs/archive/2023-09.yml
@@ -0,0 +1,974 @@
+2023-09-01:
+ GoldenAlpharex:
+ - bugfix: Fixes a rare issue that could lead to players entering an infinite disconnection
+ loop from having a null view.
+ Guillaume Prata:
+ - balance: Fanny packs are now silent, no one will get a chat message about what
+ you put in or take out.
+ Melbert:
+ - balance: If your server has non-human morgue cadavers enabled, you will be guaranteed
+ one human cadaver no matter what.
+ - balance: All maps (with the exception of Birdboat) now have an additional morgue
+ cadaver roundstart.
+ Rhials:
+ - rscadd: Nuclear operatives have expanded the scope of their hiring practices.
+ Members of all species can now roll nukie!
+ - qol: The preferences menu now has an option to always be human when being selected
+ for a nuclear operative role. Check it out!
+ - image: Plasmaman operative envirosuits.
+ Seven:
+ - bugfix: Fixes not being able to break out of graves
+ - qol: Graves are no longer dense (you can walk over them now)
+ SkyratBot:
+ - bugfix: The Cursed Slot Machine should now actually give you more than one pull.
+ - balance: megafauna will now gut instead of dusting or gibbing
+ - qol: Cryotubes will now notify medbay if the patient within is dead, and will
+ eject them if auto is on.
+ - qol: Cryotubes will now automatically turn on when a patient enters it if auto
+ is on, but you can no longer close the cryotube on yourself.
+ - bugfix: Fixes an issue where role banned players would be able to accept certain
+ ghost roles they're meant to be banned from.
+ - bugfix: Meth will no longer explode when reacting in a body
+ - qol: removes the nukie tool parcel and places the tools directly in their box
+ - rscdel: Deleted a unused file
+ - qol: The organ harvester's output is more predictable, and the direction can be
+ changed by alt-clicking with the panel screwed open.
+ - qol: Metastation has had more navigate landmarks added, namely for areas like
+ Medbay, Cargo, Engineering, department heads offices and a few more.
+ - qol: Adds accessibility to breasts for service members
+ - bugfix: containers can no longer add more water to hydroponic trays than they
+ actually contain.
+ - bugfix: watering a hydroponic tray with amounts of water lesser than 1 will no
+ longer be added to nutrients rather than water
+ - rscadd: Cargo now once again has access to a "Cargo Shortskirt", a skirt variant
+ of their shorts!
+ - image: tweaks and adjustments to the Cargo resprite have been made, as well as
+ respriting some missed icons such as the Winter Coats and QM Cloak
+ vinylspiders:
+ - bugfix: sickle null rods now have sharpness and can cut stuff
+ - bugfix: the suffocation moodlet will now be cleared when you stop drowning in
+ liquid
+ xPokee, Pirill:
+ - rscadd: Added flower crowns, craftable via the clothing menu.
+ - image: Resprited geraniums, poppies, and lilys, along with changing their worn
+ icon.
+2023-09-02:
+ GoldenAlpharex:
+ - bugfix: Fixed the crafting menu being able to get stuck if your crafting recipe
+ somehow goes missing.
+ - code_imp: Improves the quality of the item crafting code slightly.
+ Sealed101, EBAT_BASUHA for spritework:
+ - rscadd: Wizard's Den now has a book of Summon Cheese in the Studies Room
+ SkyratBot:
+ - bugfix: Hilbert's Hotel Research ruin now has a functioning tram. As a side effect,
+ the malfunctioning tram event should now only fire on maps with a tram!
+ - bugfix: Traitors should generate with "free objective" less often, and will once
+ more be assigned to steal things.
+ - bugfix: Ex-Interdyne pirates can now successfully spawn on case sensitive host
+ systems, such as Linux
+ - bugfix: Prevents admins from accidentally gibbing people by closing a confirmation
+ window.
+ Thebleh:
+ - bugfix: fixed access on a couple of Engineering and Atmos airlocks on DeltaStation
+ softcerv:
+ - qol: the NIFSoft Hud Adapter now works with more cosmetic eyewear.
+ vinylspiders:
+ - bugfix: anti-fauna arrows now do their bonus damage against mining mobs
+ - bugfix: bows will now display their ammo count correctly (1 when loaded instead
+ of 2)
+2023-09-03:
+ Guillaume Prata:
+ - rscadd: 'New funny internals for the clowns to spawn with. They come with O2 and
+ a secondary gas between 3 options: BZ, Helium and N2O. Talk with a "different
+ tone" with Helium, giggle and laugh "uncontrollably" while under the minor effects
+ of N2O or have "fun" hallucinations while under the minor effects of BZ.'
+ - balance: To not cut on how long the clown's O2 internals last due to the mixed
+ gases, the funny internals have 50% more gas volume, same as engineers' internals.
+ Iajret:
+ - rscadd: Added arrivals shuttle autoreturn.
+ - config: waiting time before returning to interlink can be changed in config file,
+ by default - it's 15 seconds
+ Melbert:
+ - balance: Ascended Blade Heretics no longer have blanket stun immunity, they now
+ have 45 seconds of stun absorption that recharges after 2 minutes - think His
+ Grace. This doesn't affect stamcrit (still immune to that) (assuming you haven't
+ consumed all of your immunity charge) but does affect hard CC such as slips,
+ flashbangs, or beepsky.
+ - balance: Ascended Blade Heretics now have a 0.75 modifier to incoming knockdowns.
+ - bugfix: Fix bastard sword granting infinite stun immunity
+ Nerev4r:
+ - rscadd: Razor claw augment for the loadout! Spend those quirk points!
+ RatFromTheJungle:
+ - rscdel: Removed Surplus bundles from opfor.
+ - rscdel: Remove microbomb implants from Contractors and Ninjas.
+ SkyratBot:
+ - bugfix: You can now actually fish soggy wallets from toilets, rare ores on ice
+ moon, some boney stuff in oil puddles (good luck finding them) and lube-fishes
+ by the seawater.
+ - sound: 2 new ambient tracks for maintenance tunnels
+ - bugfix: fixed implanted legion cores being available for use when unconscious/dead.
+ - bugfix: Soups are accepted by Kitchen Smartfridges
+ - bugfix: Soups are not accepted by drink showcases
+ - bugfix: You can no longer create non-synthesizable chemicals with bees.
+ - bugfix: basic ranged mobs will now chase victims
+ - qol: The pirate candidate gathering poll will now mention which pirate gang it
+ is gathering candidates for.
+ - bugfix: The HUDs of mobs with dynamic human appearance will appear properly.
+ - bugfix: Fixed the air inside of a penguin pen being way too cold
+ - bugfix: you can now examine screen objects properly
+2023-09-04:
+ CliffracerX:
+ - bugfix: mutantcolors are being pulled from your features dna again, no more pink
+ feathers!
+ DrDiasyl, LT3:
+ - sound: 'Adds/modifies next sound files: airraid.ogg, bloblarm.ogg, alert.ogg,
+ notice3.ogg, announce_syndi.ogg'
+ - sound: Code Red, Delta, and other extreme emergencies now possess more unique
+ alarm sound effect
+ - sound: Captain's arrival now is announced by Captain's announcement sound, but
+ not for Acting Captain's
+ - sound: Making Captain announcement through emagged console; hijacking or fully
+ corrupting evacuation shuttle now plays more ominous sound
+ - sound: Making announcements through Requests Console now plays a more noticeable
+ sound
+ - image: Status Displays sprites have been fully changed. Now they include displays
+ for every Security Level
+ - qol: The "Red Alert" button in the Communications console status display menu
+ has been replaced with a "Current Alert" button showing the current station
+ Security Level display on Status Displays
+ - qol: Communications console status display menu got a new "Radiation" button which
+ shows radiation symbol on Status Displays
+ Guillaume Prata:
+ - rscadd: Atmos Tech now have new drip and will spawn with Atmos Overalls to protect
+ their clothing from gas leaks! (It will actually not protect you against fire
+ or leaks, but hey! It's the thought that counts!!)
+ Iamgoofball:
+ - bugfix: You cannot put enterprise resource planning drugs in the Odysseus syringe
+ gun, and they will no longer be used in the random reagent recipes.
+ SkyratBot:
+ - rscdel: Removed the threshold for confusion symptom that adds illiteracy to the
+ disease.
+ - balance: Clamps confusion symptom's confusion to a maximum of 30 seconds.
+ - qol: Confusion as a debuff no longer guarantees random movement if you're resting.
+ - image: resprites the genesploicer.
+ - sound: Adds a sound effect for hypospray/medipen injections. Doesn't affect sleepy
+ pens or HMS injectors
+ - bugfix: fixed basic mobs not dropping their butcher results when gibbed
+ - bugfix: Multi-z Icebox ruins including the Demonic Frost Miner can now be placed
+ again
+ - rscdel: Removes the swarmer beacon achievements from the game (no one ever got
+ them, and they haven't been obtainable for years)
+ distributivgesetz:
+ - code_imp: Moved some job-related achievements from the misc category to the jobs
+ category.
+ softcerv:
+ - image: adds the hairfre hairstyle from hyperstation
+ - bugfix: fixes the organic interface gas mask not allowing for the wearer to inhale
+ or exhale.
+ - balance: the evoker soulcatcher is now available through the R&D protolathe.
+2023-09-05:
+ Azlier:
+ - qol: added dumping bags into large wooden mortars and millstones
+ LT3:
+ - image: New medical bed and emergency roller bed
+ - code_imp: Added context hints for beds
+ SkyratBot:
+ - balance: The fishing minigame should be easier now.
+ - bugfix: fixed fishing skeleton mob spawners that immediately crumble back into
+ the void of whatever chasm you fished them from.
+ - bugfix: boiled rice doesn't burn instantly after being baked
+ - code_imp: simplifies the way burning food is handled, grilled/baked food now turns
+ to a burnt mess rather than being set on fire, unless they have a baking/grilling
+ recipe
+ - bugfix: PDAs being on silent no longer prevents PDAs from being sent to your chat,
+ again.
+ - rscadd: pAIs inserted into a PDA can now control the PDA, and will receive PDA
+ messages sent to it (and can respond under the PDA's name).
+ - bugfix: '''meat product'' and imitation carp meat are now considered synthetic
+ meats for the purposes of reagent purity'
+ - bugfix: It's now humanly possible to reach the legendary fisherman rank, get the
+ achievement and the hat.
+ - rscadd: Mood buff power and duration depends on the ingredient quality and recipe
+ complexity of the food.
+ - rscadd: Hand-crafted food also gives a non-mood buff. The buff type depends on
+ recipe complexity and duration - on ingredient quality.
+ - code_imp: Added infrastructure to assign custom buff to certain dishes for unique
+ effects
+ - rscadd: Consumable reagents now care about purity, being more nutritious with
+ higher purity. Dispensers give synthetic food, natural sources are organic and
+ better and give longer buffs.
+ - rscadd: Grown food reagent purity now depends on lifespan, endurance and instability
+ stats of the seed.
+ - rscadd: Natural booze now uses the same purity formula and 100% purity can increase
+ booze power by up to 200%.
+ - rscadd: Added Fat reagent that is now a base type for lard, vegetable oil, olive
+ oil. Corn oil and cooking oil merged into vegetable oil.
+ - balance: Reagents and their purities are preserved during food chemical reactions,
+ processing, cooking and crafting.
+ - balance: Sugar nutrition rebalanced due to it being 100% pure in chem dispenser,
+ overdose happens at 100u now.
+ - bugfix: '`grind_results` of grown food give full amount equal to all removed nutrients
+ instead of just `/datum/reagent/consumable/nutriment`'
+ - qol: 'Seed Extractor now shows additional seed data: possible mutations, juicing
+ result, grinding result, fermentation result'
+ - bugfix: Reverts the unintended change of monkey cube biomass cost back to 50
+ - bugfix: kinesis plus properly lets you move again when grabbed once
+ - rscadd: Adds the medbeam module for nukies, don't cross the damn beams. (Also
+ removes the handheld one from the uplink)
+ - bugfix: Updates the changelog link for the pre-4407 changelog as it was moved
+ - rscadd: adds medical carts and surgery trays
+ - image: gives the surgery razor a unique sprite
+ - qol: pollinating bees will now only attack players that are standing near the
+ beehive
+ Thlumyn:
+ - bugfix: mold no longer appears under catwalk floor tiles
+ softcerv:
+ - rscadd: Adds in meson NIFSoft HUDs
+2023-09-06:
+ Krysonism:
+ - image: resprites the noticeboard
+ SkyratBot:
+ - spellcheck: Improved phrasing and syntax on dismemberment mood messages.
+ - bugfix: Fixed walking into grilles to destroy them
+ - bugfix: You can no longer walk into Birdshot's secure tech storage like you own
+ the place - unless you do own the place.
+ - spellcheck: re-writes cosmic heretic lore
+ - refactor: the minebots have been refactored please report any bugs
+ - rscadd: minebots can now mine walls and collect ores automatically and they will
+ alert everyone if they find u dead
+ - bugfix: fixed bileworm evolution deleting anything they devoured; they will now
+ eject their contents upon evolution to vileworms
+ - bugfix: Fixed all-in-one grinders not giving all the correct reagents when grinding.
+ - balance: Prosthetics and slimepeople can now have limbs dismembered
+ - balance: Slimepeople can now receive slash wounds, but cannot bleed
+ - balance: Most limbs can now be dislocated
+ - refactor: Scar backend reworked, scars will be wiped as they update to the new
+ format
+ - bugfix: Slash wounds are now compatable with pierce wounds
+ - image: cleans up the engineering emergency internals sprite slightly
+ - bugfix: emissive appearances on glowy eyes and such now properly rotate
+2023-09-07:
+ LovliestPlant:
+ - qol: '[DS-2] Replaces the pair of plastitatinum sheets with small stacks of plasteel
+ and titanium in the engine room.'
+ - qol: '[DS-2] Adds a korta seed packet to the botany box in the permabrig.'
+ - bugfix: '[Interdyne] Fixes the floating tube light above the kitchen counter in
+ the cafeteria.'
+ SkyratBot:
+ - bugfix: Snow legions now drop only one corpse, and no longer drop Lavaland corpses.
+ - bugfix: The Birdshot Gaming Den now has arcade circuit boards and computer frames
+ that actually work.
+ - bugfix: fixed mirrors not breaking when a curse effect is triggered
+ - bugfix: Public mining storage's camera is now on the mining network instead of
+ the gulag.
+ - qol: Adds cables under birdshot xeno containment shielding.
+ - bugfix: Machine frames in NorthStar Cyto are now functional.
+ - qol: Minor cable/pipe changes to NorthStar the xeno containment.
+ - qol: NorthStar's departmental head offices have had their respective PDA & ID
+ imprinters added!
+ - qol: The NorthStar Head of Security office has gotten a small expansion.
+ vinylspiders:
+ - bugfix: mold on multi-z maps will no longer spawn in or spread resin to openspace
+ turfs
+2023-09-08:
+ LT3:
+ - bugfix: Meteors no longer take damage from crossing certain unoccupied turfs
+ SkyratBot:
+ - bugfix: fixes creamatorium not producing any suspicious ice cream, and fixes a
+ dead mouse related harrdel
+ - refactor: If you transform into another mob and notice bugs with interacting with
+ the game world, please create a bug report as this framework was recently refactored.
+ - image: The glow shoes from the ClothesMate now actually glow and can be recolored,
+ even with a spraycan.
+ - bugfix: Megafauna now correctly prints the victim's name after a kill
+ - bugfix: leash unit test will time out less often and increases the timer until
+ it is considered 'timed out', to reduce false CI failures
+ - spellcheck: Corrected the name of the telescopic fishing rod to "telescopic fishing
+ rod" from the more generic "fishing rod"
+ - balance: colossus' near-death attack now starts after a 0.5 seconds delay
+ - image: adds special sprites for lungs when you use the smoker quirk
+ - bugfix: basic mobs can now use ranged burst attacks
+ - balance: gas mixer output now accurate to set ratio regardless of input temperatures
+ - rscadd: Traitors, Changelings, Heretics, Wizards, Malfunctioning AIs, and Ninjas
+ can now all reject their original objectives and provide one of their own in
+ its place. A Heretic doing this will no longer be able to ascend.
+ - rscadd: '"Custom" objectives which aren''t mechanically tracked will no longer
+ report success or failure upon round end.'
+ - qol: Space Ninja spider charges will now display where they can be detonated when
+ examined, if you are a ninja.
+2023-09-09:
+ LT3:
+ - qol: Supermatter common channel alerts are less frequent if the crystal's integrity
+ is rising rapidly
+ Melbert:
+ - rscadd: '[Icebox] Remaps arrivals and the maintenance around it. Aux base out,
+ mass driver into a plasma lake in.'
+ SkyratBot:
+ - rscadd: Added the Numb quirk, that makes you (almost) unable to perceive how much
+ your injuries hurt.
+ - rscadd: Ever see a robot yawn? Don't worry, it makes sense now.
+ - bugfix: The messenger app can now be used when laying down.
+ - bugfix: Cauteries now have 'heat', like lighters, welders, etc.
+ - qol: You can smoke with a space helmet as long as you have internals on.
+ - bugfix: Getting a node researched now properly makes it no longer hidden.
+ - bugfix: Ninjas draining RD servers now drains it from the connected techweb, rather
+ than sniping Science.
+ - balance: Machines will first try to connect to a techweb with servers on their
+ z-level, with the Science techweb remaining as fallback.
+ - rscadd: Oldstation RND, comes with their own Techweb and special surgery to gain
+ research points through dissecting Xenomorphs.
+ - balance: Traitors who are activated as sleeper agents or arrive late on the arrivals
+ shuttle will begin with more reputation and likely be able to immediately access
+ most of the uplink catalogue.
+ - image: updates medigel sprites
+2023-09-10:
+ A.C.M.O.:
+ - bugfix: Fixed Poly's voice commands. Poly will now perch on the Chief Engineer's
+ shoulder when expected.
+ LT3:
+ - image: Delam emergency procedure wall biscuit replaced with SAFETY MOTH
+ - code_imp: Delam panic button works when APC is dead
+ - code_imp: Removed extra calls to nightshift subsystem during delam
+ - bugfix: Votes play an alert sound again
+ SkyratBot:
+ - bugfix: Golems can eat
+ - bugfix: Cooked and crafted food should be edible
+ - bugfix: Medborgs can now spawn vanilla ice cream instead of nothing ice cream
+ - bugfix: Ghosts can examine food
+ - bugfix: Exploration drones can't be used to reach Centcom anymore.
+ - admin: Admins can add/remove the spawner component from arbitrary items again.
+ - qol: adds some more traitor objective brainwashing default objectives.
+ - spellcheck: fixes the double-punctuation on traitor objective brainwashing broadcasts.
+ - spellcheck: brainwashing deadchat broadcasts will now auto-punctuate.
+ - admin: The "Create Command Report" verb now has the option to not print report
+ papers at communications consoles.
+ - bugfix: It is now possible to smoke cigarettes even if you aren't wearing a safety
+ helmet
+ StrangeWeirdKitten:
+ - bugfix: Fixes Interdyne mining reward boards making golem reward vendors
+ vinylspiders:
+ - bugfix: fixed a bug that was preventing large mortar from getting any of the extra
+ reagents from grinding/juicing certain items
+2023-09-11:
+ Hatterhat:
+ - rscdel: Thanks to lobbying from other factions within the Syndicate, the black
+ markets accessible by telecrystal-based uplinks are no longer stocking modified
+ hand teleporters, citing a new "stand and deliver" doctrine established by more
+ violent, militant arms of the organization.
+ Melbert:
+ - qol: Haunted 8-ball no longer requires the ghost orbit the petitioner to submit
+ votes
+ - qol: Haunted 8-ball ghosts can now change their vote after submitting it
+ - bugfix: Haunted 8-ball no longer always reports "yes"
+ - bugfix: Haunted 8-ball no longer always reports default "yes", "no", or "maybe"
+ and now gives a proper eight ball response
+ - bugfix: Haunted 8-ball can be picked up via the stat panel
+ RatFromTheJungle:
+ - rscdel: Guns, collectively, can no longer right-click holdup people
+ SkyratBot:
+ - rscadd: 'Added the service borg "drink apparatus" upgrade, which adds an extra
+ drinking apparatus to the borg, up to a maximum of 5 extra.
+
+ :cl:'
+ - bugfix: Changeling tentacle and bloodchiller from xenobio will no longer stop
+ working if you have antimagic
+ - qol: Rice Dough may be made in beaker instead of being crafted, but the rice and
+ flour must be added first
+ - rscadd: humpback emergency shuttle
+ - image: Hivelords have a new sprite.
+ - image: Hivelord and Legion brood have a death animation.
+ - bugfix: Mortar and pestle can grind stuff again
+ Wallem, MTandi:
+ - image: Updates chem factory tank sprites
+ jjpark-kb:
+ - bugfix: revive mob ritual works on basic mobs now
+ - bugfix: ashwalkers have the ashwalker faction
+ softcerv:
+ - bugfix: ghost cafe NIFs no longer have access to hivemind
+2023-09-12:
+ Adelphon:
+ - rscadd: new underwear
+ GoldenAlpharex:
+ - bugfix: All potted plants should now be visible again.
+ - admin: Player ranks are now displayed in the Player Panel of each user.
+ - code_imp: Player ranks can now be checked without taking into account the admin
+ bypass while in-game.
+ - bugfix: Fixed the rounding errors that caused decimals to wrongly appear when
+ hitting the Shift Layer Upwards or the Shift Layer Downwards verbs.
+ - bugfix: The message sent to admins when a new admin has been added via the Permissions
+ Panel will now properly show the new admin's ckey.
+ - qol: Character Previews are now always displayed in the Examine panel, rather
+ than disappearing when the flavor text would otherwise be hidden.
+ LT3:
+ - code_imp: Status display shuttle timer no longer scrolls
+ - bugfix: Fixed Void Raptor cargo door labels and IDs
+ - bugfix: Singularities are no longer invisible. You can again see your impending
+ doom
+ Melbert:
+ - rscdel: Spacers are slightly shorter. They're still taller than other people,
+ just not as much.
+ OrionTheFox:
+ - bugfix: fixed being unable to re-select the "Quartermaster" title in job prefs
+ after selecting an alt-title
+ - image: updated the greyscale Cattleman Hat to be not-bad. It now isn't 1px too
+ low, and actually looks like a cattleman rather than a lump of butter on a plate!
+ SkyratBot:
+ - bugfix: The vorpal scythe is no longer as greedy about you murdering people, and
+ will once again accept striking any living creature to be sated.
+ - bugfix: Fix capture devices allowing mob actions while inside
+ - bugfix: Your clothes and such should correctly reposition themselves if a black
+ charged slime extract turns you into a monkey.
+ - bugfix: Ninjas should be correctly credited for using their spider bombs
+ - balance: Supermatter zap power generation scales with the delta time between its
+ last zaps, preventing faster zapping from scaling power generation to extreme
+ levels.
+ - bugfix: Fixes supermatter zap rate not scaling properly. It should zap much faster
+ at higher energy levels as intended.
+ - qol: Changeling chemical generation scales with the world's delta time, making
+ its rate independent of subsystem lag.
+ - qol: Revenant essence generation scales with the world's delta time, making its
+ rate independent of subsystem lag.
+ - qol: Xenomorph plasma generation and resin healing scales with the world's delta
+ time, making their rates independent of subsystem lag.
+ - balance: polymorph belt now blacklists mobs that are undead, humanoid, robotic
+ or spiritual (in nature, not religiously), as well as megafauna
+ - balance: however, this means that it works with more mobs that it should logically
+ work with, like slimes/bugs/lightgeists etc
+ - bugfix: fixed headslug shenanigans with the polymorph belt hopefully for good
+ this time
+ - bugfix: fixed headslug description mentioning its movement despite the slug being
+ dead
+ sergeirocks100:
+ - bugfix: Briefs now make use of their digitigrade sprite.
+2023-09-13:
+ CoiledLamb, Time-Green:
+ - image: resprites the radioactive nebula shielding
+ Ghommie (Based on an old PR by Trilbyspaceclone from Citadel):
+ - qol: The notepad app now includes basic nautical directions in its default message.
+ - qol: A tip about nautical directions, too.
+ LT3:
+ - bugfix: All missing surgery trays have been found. Don't ask where.
+ Literallynotpickles:
+ - qol: Adjusted medical tongue bounties to mention that cybernetic ones _do_ work
+ for them.
+ Melbert:
+ - bugfix: Birdboat's Augment Theater is named less odd now
+ Rhials:
+ - bugfix: The psyker headset is no longer a syndicate headset subtype, and no longer
+ has syndie comms.
+ SkyratBot:
+ - rscadd: The SC/FISHER disruptor pistol, a very compact, permanently silenced energy
+ gun, is now stocked in Nanotrasen-accessible black markets with a price generally
+ somewhere between 400 and 800 credits. Aspiring users are warned that it's really
+ bad for trying to actually kill people. Caveat emptor.
+ - rscadd: Guns now have a dry_fire_sound_volume variable, allowing for guns to be
+ less loud when trying to fire while empty.
+ - bugfix: Closets and crates now properly count as structures for pass flags again.
+ - balance: Add hypnosis vulnerability for drugged victims
+ - rscadd: Operative MODsuits now have an attached "jump jet" which sends you upwards
+ and allows you to use your jetpack under gravity for a few seconds, perfect
+ for navigating the pits and valleys of Icebox Station.
+ - qol: Shuttle engines now tell you how to install them in their screentips and
+ their examine text.
+ - image: resprites pestkiller, weedkiller, and nolabel sprays
+ - image: updates shading on medigels
+ - image: resprites all spray bottles
+ - bugfix: Medicine allergy can no longer roll quantum medicine
+ - bugfix: fixed grown food items not getting the right seed type passed to them
+ upon creation
+ - bugfix: The holographic pufferfish from the holographic beach from the holodeck
+ no longer looks like a goldfish.
+ - bugfix: the ablative coat's hood now hides the wearer's hair and ear
+ - bugfix: Soup recipes, that make items, spawn the correct number of items per reaction
+ instead of just one item
+ - bugfix: Soup recipes, that make items, consumes the correct number of reagents
+ instead of the largest multiple of the reagents
+ - balance: removed anti-drop implants from the nuclear operative uplink
+ - balance: removed anti-drop implant from the nukie implants bundle and changed
+ its cost to 20 TC
+ SuicidalPickles:
+ - qol: Cargo Coats/Jackets can now equip universal scanners on their suit-slots.
+ burgerenergy:
+ - balance: Buffed MCR damage in line with an upstream generic laser buff
+ vinylspiders:
+ - bugfix: Headsets now have their old worn sprites back, did you ever notice it?
+2023-09-14:
+ LT3:
+ - bugfix: Emergency shuttle should correctly scale timer up/down when changing security
+ levels
+ OrionTheFox:
+ - rscdel: Removed the now-obsolete Skyrat Cargo Gorka-Jacket; TG now has one!
+ - image: updated all of the cargo sprites to match TG's, including digitigrade sprites!
+ - bugfix: the QM's Formal Skirt now actually uses the Skirt icon rather than the
+ Suit
+ Rhials:
+ - rscadd: Shuttle Firesale positive station trait. Some emergency shuttle options
+ have been put on sale!
+ - rscadd: Misplaced Wallet positive station trait. You wouldn't steal from a missing
+ wallet, would you??
+ - rscadd: Wisdom Cow Invasion positive station trait.
+ - rscadd: Advanced Medbots positive station trait. Better roundstart medbots!
+ - rscadd: Loaner Shuttle positive station trait. More shuttle loan offers and more
+ payout!
+ - qol: Station Trait titles are now italicized for easier reading.
+ - spellcheck: Fixes a "prerequisites" typo in the shuttle purchase menu.
+ Seven:
+ - balance: The supermatter delamination countdown has been lowered from 30 to 13
+ seconds
+ - balance: Removing a sliver from the supermatter further lowers that down to 3
+ seconds
+ - balance: Supermatter panic button warning reduced from 5 to 3 seconds
+ - balance: Supermatter suppression system healing runtime reduced from 9 to 7 seconds
+ - balance: The supermatter crystal uses bigger text on its final countdown
+ - spellcheck: Some supermatter delamination related mood descriptions have been
+ edited to explain the mood effect better
+ SkyratBot:
+ - bugfix: You can no longer teleport to disabled beacon if the teleporter was previously
+ locked-on to it.
+ - bugfix: Dynamic now biases less heavily towards the exact average.
+ - bugfix: Nightmares can no longer receive wounds
+ - bugfix: Nightmares can no longer have limbs dismembered
+ - qol: Conveyor belts now have screentips and a better examine tip to teach you
+ how to set one up properly.
+ - qol: Using a conveyor belt stack on a placed conveyor belt will extend the conveyor
+ belt to the output of that conveyor belt.. You can use this to place fully integrated
+ conveyor belts much easier now.
+ - image: When you throw up nanites, your vomit should now be appropriately nanite-colored.
+ - bugfix: Fix poor dynamic threat distribution at lower population levels, causing
+ dynamic to generate better threat curves at lower population levels than it
+ did before.
+ - bugfix: Roundstart medbots and cleanbots are now more likely to be able to be
+ possessed by observers.
+ - admin: It's easier to modify the properties of bots to stop them from being possessed
+ or depossessed.
+ Wallem:
+ - qol: Examine a Dish Drive to see all the items inside of it, as well as the item
+ you'll pull out when you interact with it.
+ - qol: Dish Drive servo tier increases suction range
+ honkpocket:
+ - bugfix: Players who run the DNR quirk no longer appear as revivable when examined
+ nikothedude:
+ - qol: 'Temporary flavor text preview character limit: From 37 to 110'
+ tf-4:
+ - rscadd: You can now craft ammo pouches from four leather.
+ - spellcheck: Fixed typo in cocaine snorting message.
+2023-09-15:
+ LovliestPlant:
+ - rscadd: '[Void Raptor] Adds an exam room and charting office to medbay, just opposite
+ of the escape pod.'
+ - rscadd: '[Void Raptor] Adds a refrigeration system to medbay''s cold storage room.'
+ - qol: '[Void Raptor] Removes some clutter from medbay (storage plants, extra anesthetic
+ closets), adds blankets to TC beds.'
+ - qol: '[Void Raptor] Access to the Southern entrance to the Security office now
+ matches that of the North entrance.'
+ - qol: '[Void Raptor] Overhauls medbay''s cold storage room. Adds a coldroom freezer
+ system; adds a handful of emergency oxygen tanks, emergency nitrogen tanks,
+ and masks to the internals crate; replaces the empty medical crate with a spare
+ robotics limbs crate; and replaces the Oxygen canisters with anesthetic mix
+ canisters.'
+ - qol: '[Void Raptor] Adds towel bin to perma, replaces the linen bin in the public
+ pool with a towel bin.'
+ - bugfix: '[Void Raptor] Replaces flooring with bare plating in sections of maints,
+ should fix mouse spawning.'
+ - bugfix: '[Void Raptor] Fixes the back entrance to the medbay''s treatment center
+ requiring morgue access.'
+ - bugfix: '[Void Raptor] CO''s can now open the brig officer locker in their office.'
+ - bugfix: '[Void Raptor] Fixes a minor clipping issue with the records console in
+ the CO office.'
+ Lunar248:
+ - qol: Gave Freighter a few things to reduce some tediousness, such as a welding
+ tank in engineering, water tank in botany, and a proper sink in the kitchen.
+ - bugfix: Added missing lights, and light switches to Freighter.
+ SkyratBot:
+ - bugfix: you can no longer bypass html sanitization using the table element. >:(
+2023-09-16:
+ LT3:
+ - code_imp: Engaging in Role Play on the Interlink should no longer lead to heart
+ attack and death
+ LT3, unit0016:
+ - qol: You can now choose between limb, prosthetic, or no limb at all
+ Literallynotpickles:
+ - balance: Changeling Horror-Form no longer has reduced click-delay.
+ RatFromTheJungle:
+ - balance: The captains sabre now does five more damage totaling to 20 (while losing
+ a bit of wound chance!), while the shamshir does the same with equally less
+ wound chance, less armor pen, and worse block.
+ SkyratBot:
+ - bugfix: fixes a bug that would cause grown inedible plant seeds (like tower cap)
+ to vanish from existence upon being added to the seed extractor
+ - bugfix: fixes a issue that would cause fruit wine to bug out when trying to blend
+ its reagent color
+ - bugfix: The nuclear operative MODsuit intellicard now actually downloads an AI
+ rather than simply kicking candidates from the game.
+ - bugfix: Fixed a race condition that made fishing yield no reward way too often.
+ - bugfix: The legendary fisher achievement is awarded even if you don't win the
+ minigame.
+ - bugfix: Fixed a fish hook exploit.
+ - bugfix: Baits are now properly consumed by caught fish and (alive) mobs.
+ - bugfix: Fixes tesla coils duplicating the power of >7GeV supermatter zaps.
+ - bugfix: Space ruin Anomaly Research - Fixes stacked windows and underplating
+ - rscadd: There's a new space ruin in town, be on the lookout for a hidden supply
+ cache.
+ - rscadd: Added a new type of wall which can only be destroyed by blowing it up.
+ - balance: Pulling embedded items e.g. shrapnel with hemostats is now a lot faster,
+ and scales appropriately with toolspeed.
+ - balance: You can now pull embedded items with wirecutters, at a speed penalty.
+ - bugfix: Unary vents & Injectors now link properly with air sensors via multitool
+ both ways
+ - balance: Watchers will no longer put you at gunpoint.
+ - balance: The spontaneous brain trauma event will no longer occur if there are
+ fewer than 13 players.
+ - bugfix: Flares and candles no longer sound like flashlights when being turned
+ on.
+ - bugfix: Getting shot by an SC/FISHER now disables PDA lights for consistency's
+ sake.
+ - spellcheck: Replaced an irrelevant tip of the round about scars with a better
+ one
+ - balance: You will be knocked down again on certain vomits. Don't worry, you'll
+ deserve it when it happens.
+ - qol: The supply beacon will no longer delete itself due to explosions, and you
+ can now anchor it with a wrench.
+ - spellcheck: Express console now correctly states that it needs cargo access instead
+ of QM access.
+ - bugfix: returning items to vendors works correctly
+ - bugfix: you can't return items that has stuff in it for e.g. a serving tray with
+ food in it
+ - bugfix: fixed fishing.
+ - bugfix: the bank machine cannot print holochips worth 0 credits now
+ - bugfix: adds the bolted and welded helper to the bar backroom/kitchen coldroom
+ airlock on birdshot, as to prevent chefs from being able to access armor and
+ sunglasses roundstart with barely any work involved
+ nikothedude:
+ - rscadd: 2 Bonesetters, 4 stacks of gauze, 2 health analyzers that cant be used
+ for medibots, all in the robodrobe
+2023-09-17:
+ SkyratBot:
+ - refactor: Refactored wounds yet again
+ - bugfix: Wounds are now picked from the most severe down again, meaning eswords
+ can jump to avulsions
+ - bugfix: Scar descs are now properly applied
+ honkpocket:
+ - rscadd: The bullet-drive machine can once again be bought from the cargo-imports
+ menu
+ nikothedude:
+ - bugfix: Msucle scars no longer cause general disfigurement
+2023-09-18:
+ Majkl-J:
+ - bugfix: laser magazines can now be reloaded correctly
+ SkyratBot:
+ - bugfix: Monkeys have their tails back.
+ - bugfix: Fixed a resource dupe in the ORM.
+ - rscadd: added the inspectors hat to the detectives cabinet, a special hat that
+ allows the wearer to say a phrase to dispense a stored item
+ - rscadd: climbing hooks that allow you to go up holes for multiz, found in internals
+ boxes (on planetary maps), the uplink, cargo and nukie personal lockers
+ - rscadd: A new ruin has appeared on lavaland, featuring the site of an ancient
+ battle.
+ - qol: '[Deltastation, Icebox, Metastation, Tramstation] Adds cell timers to isolation
+ cells. (they do not auto-open the doors)'
+ - qol: '[Birdshot, Deltastation, Icebox, Metastation, Northstar, Tramstation] Adds
+ translator glove modules to the stacks of "accessibility" (e.g. plasma fixation
+ / thermal regulator) modules found in security, medical, and engineering storage
+ rooms.'
+ - qol: '[Birdshot] Adds a roll of packaging paper to the cargo office.'
+ - qol: '[Icebox] Adds a hand labeler to security''s gear room.'
+ - qol: '[Northstar] Nudges the set of binoculars covering the mass driver controls
+ in ordnance over a few inches.'
+ - bugfix: '[Birdshot] Remaps the janitor''s closet such that the recycling machine
+ will now work.'
+ - bugfix: '[Icebox] Removes a duplicated hand labeler from the rack near security''s
+ brig cells.'
+ - bugfix: '[Metastation] Patches a broken corpse disposal pipe running from aux
+ surgery to the morgue.'
+ - bugfix: '[Northstar] Fixes the SM being hotwired at round-start (partially rewires
+ the SM room, moves the APC to the North wall).'
+ - code_imp: added some null checks for general juicing & grinding items
+ - bugfix: grinding stacks now grinds as many pieces/sheets from the stack as possible
+ that can fit in a beaker/container without wasting the whole stack
+ - bugfix: plumbing chemical grinder now actually works again
+ - bugfix: the plumbing chemical grinder allows stuff to enter from any direction
+ but not mobs and also accepts items put inside it via hand including bags
+ - bugfix: You can remove the beaker from the all in 1 grinder when power is off
+ via right click
+ - bugfix: All in 1 grinder now mixes faster with upgraded parts
+ - refactor: you can no longer walk into a plumbing chemical grinder
+ - bugfix: adds a few firelocks and alarms around IceBox
+ - bugfix: the nukie medibot (oppenheimer) has access to the doors of the infiltrator
+ and is not shot at by the turrets
+ - refactor: heretic sacrifice room is now lazyloaded
+ - bugfix: Lipolicide and other chems now puts you in crit, even if it is the only
+ source of damage
+ - bugfix: made the radiation protection crate's contents match it's description
+ - rscadd: Ghosts (observers) can eat ghost burgers and booberry muffins.
+ - balance: Ghost burgers will not decay or pick up germs due to the fact that they
+ moved themselves off a table.
+ - rscadd: NanoTrasen improved the quality of the local durathread strain; resulting
+ in it now being twice as filling!
+ - image: Hercuri spray now uses the same sprite as the yellow medical spray
+ - spellcheck: Added a missing space to hercuri spray's description
+ - bugfix: Manually constructed windoors have correct unrestricted accesses applied
+ to them
+ - bugfix: Windoors created via RCD now actually have electronics inside them
+ - bugfix: Airlocks constructed via RCD have the shell component correctly installed
+ inside them and have no other missing variables
+ - rscadd: Wall mounted objects (Things like APCs, Air Alarms, Light switches, Signs,
+ Posters, Newscasters, you name it) will now fall to the ground and break or
+ deconstruct when their attaching wall is changed or broken.
+ - spellcheck: Fixed some typos on QM's Overcoat
+ - bugfix: Forgetting to take dough out of the oven no longer progresses the server
+ to a crash-worthy state with infinite bread and ash and burned food products
+ for all.
+ - bugfix: Recipe paper in the ruins now shows a normal recipe for Metalgen and Secret
+ sauce.
+ - code_imp: Cleans up some unnecessary code left over from caseless ammo.
+ - qol: the recycler can now be rotated
+ - qol: Machines now transfer their local materials to silo during linking with multitool
+ SpaceLove:
+ - balance: Bluespace Miners have been made cheaper by Nanotrasen as they have found
+ a huge mine of materials recently!
+ TheOneAndOnlyCreeperJoe:
+ - bugfix: Hydra quirk now properly works instead of making you British.
+ Thebleh:
+ - bugfix: Bluespace RPEDs can now be rigged again
+ nikothedude:
+ - rscadd: Several common 'household' reagents can be used as improvised medicine
+ treatment.
+ - rscadd: Drinking tea will help mend (non-bone) wounds over time.
+ - rscadd: Flour and corn starch may be splashed onto wounds to help dry them up,
+ though they'll have a negative effect on burn wounds.
+ - rscadd: Added a new reagent, saltwater, made by combining table salt with water.
+ - rscadd: Table salt and saltwater can be splashed onto wounds as well, reducing
+ bleeding and improving sanitization and disinfection significantly. However,
+ the coarse undiluted salt will irritate the wounds, reducing clot rate and flesh
+ healing, and both of the reagents will increase a burn wound's infestation rate.
+ - rscadd: Altered Table Salt's recipe to just need sodium and chloride. Changed
+ the recipe of Pentetic Acid and Heparin to need table salt (sodium x chloride)
+ and thus slightly altered the total output of those reagents (pentacid went
+ from 5u per reaction to 4u, heparin 4u->3u)
+ - rscadd: Saline-Glucose Solution now needs 2u of saltwater and 1u of sugar, meaning
+ the overall recipe should be completely unchanged in practice. Contact me on
+ discord if any issues arise from these chemical changes!
+ - qol: First aid analyzers now give easy-to-understand direct information, with
+ the specific recommended treatments bolded in the analysis text. They also have
+ a 'unique' extra bit of info, telling you about improvised ways to remedy your
+ wound.
+ tf-4:
+ - bugfix: fixes being able to eat, use pills etc through gas masks and such
+2023-09-19:
+ Ghommie (Thanks Sealed101):
+ - refactor: Reworked the fishing minigame into a game screen object from a TGUI
+ interface
+ Melbert:
+ - balance: Humanoids without tongues cannot cast spells with vocal components
+ - balance: Humanoids without arms cannot cast spells with emotive components
+ SkyratBot:
+ - bugfix: Makes sure pump-up properly grants the baton resistance trait.
+ - bugfix: The Nightmare's Light Eater can no longer suck the light out of space
+ tiles.
+ - bugfix: Fix wooden barricade description "This looks like it can be barricaded
+ with planks of wood" being spammed on objects.
+ - bugfix: basic mobs retaliate targetting now selects targets they can attack
+ - bugfix: Makes ethanol and sugar pure by default.
+ - balance: Player-controlled basic mobs attack as fast as those mobs can when controlled
+ by the AI
+ - balance: Player-controlled Faithless can paralyse people they attack, like the
+ AI does
+ - balance: Player-controlled Star Gazers (if an admin felt like making one) apply
+ the star mark on attack and deal damage to everything around them, like the
+ AI does
+ - rscadd: Many kinds of mobs can now be brought back to life through revival surgery.
+ - rscadd: Dogs can wear eyepatches.
+ - code_imp: Scars now stack trace if they fail to get a valid description
+ - rscdel: Removes the computer vendor.
+ - bugfix: pancake stack layering
+ - bugfix: pizzabox stack layering
+ - bugfix: pizzabox bombs that spawn unarmed now label their pizza correctly and
+ cannot spawn a spriteless pizza
+ - bugfix: Fixes a misplaced status display in Meta's medical storage.
+ - rscadd: mass drivers are now buildable, you activate them by attaching a signaler
+ to their launch wire, and can increase their power by pulsing the safeties wire,
+ and reset it back to normal by cutting the safeties wire.
+ - server: Default-configuration MINUTE_TOPIC_LIMIT has been increased
+ - bugfix: Fix a runtime when trying to cycle move intents with a hotkey as a dead
+ mob.
+ - bugfix: Nanotrasen has finally recalled their faulty multitools and replaced them
+ with working ones! The multitool's buffer now properly clears itself.
+ - qol: Moved multitool link messages to balloon alerts
+ - bugfix: added some missing firealarms on icebox in the hall towards departures
+ and the upper section of chapel
+ - bugfix: normal ethereal blood now works for electrolysis, the hydrogen and oxygen
+ output of the electrolysis recipe has been increased.
+ - balance: Only traitor, changeling, heretic, blood brother, headrev, wizard, obsessed,
+ magic/gun survivalists and greentext book holders can now double their hardcore
+ random score
+ - qol: Redtexting as antag with hardcore random score will pay you default points,
+ instead of none (normal survival rules)
+ - bugfix: End report screen will properly report hardcore random survival in case
+ of station destruction
+2023-09-20:
+ LT3:
+ - rscadd: 'New random event: Supermatter Surge'
+ - refactor: It's different than the Supermatter Surge you're used to
+ - refactor: 'The scale is now 1: low severity to 4: most severe. Keep that in mind!'
+ - rscdel: Removed Skyrat version of Supermatter Surge
+ - code_imp: Individual supermatter crystals can have custom gas properties
+ SkyratBot:
+ - image: resprites t-ray scanner, gas analyzer, geiger counter and hand drill.
+ - qol: Surgery trays can now be crafted via the crafting menu (two rods, one silver),
+ and deconstructed via secondary click with a screwdriver!
+ - spellcheck: Unreverted and improved resonance cascade message.
+ - qol: Crafting R&D guns from gun kits no longer requires tools or cable coil. The
+ decloner and energy crossbow still need reagents.
+ - qol: Halved R&D gun crafting time. 20->10 seconds.
+ - bugfix: Fixed Mafia achievements
+ - balance: Unholy and Eldritch water are self-consuming like holy water! They don't
+ need a liver to be processed.
+ - bugfix: Fixes a selection window in the game rock-paper-scissors with death.
+ - bugfix: fixes inedible grown items (such as tower caps) becoming unclickable when
+ harvested, fixes their seeds disappearing when inserted into the seed machine
+ - refactor: Refactors the camera console UI.
+ - rscadd: heretic knock path and its respective items and award
+ - bugfix: Lava can no longer occasionally generate inside of previously loaded templates
+ and breach and/or destroy shit
+ - qol: mice and rats now are visually spaced out from eachother for visual clarity
+ - balance: Supermatter now takes 15 seconds to delaminate normally and 5 if a sliver
+ has been taken from it. Gives a little more time to escape in the case of the
+ sliver and also evens out the times to please perfectionists.
+ - bugfix: Supermatter now accurately reports it's detonation time.
+ - spellcheck: Supermatter mood descriptions have been reverted back to their old,
+ more flavorful selves.
+ Zergspower:
+ - qol: reworks the verb panel to be less of a CVS receipt
+ vinylspiders:
+ - bugfix: removed a deprecated loadout item 'Black Two-Piece Suit' which had an
+ invalid item path. The old item has been replaced with 'Black Suit'.
+2023-09-21:
+ LT3:
+ - bugfix: Interdyne scientists get their Interdyne labcoat
+ Rhials:
+ - qol: Restores holiday hats for drones.
+ - qol: Extends holiday hat behavior to assistants. Get festive!
+ SkyratBot:
+ - bugfix: RCD Construction effects will no longer fall into chasms.
+ - bugfix: Gauze no longer falls off if a wound is demoted or promoted
+ - bugfix: The caller in a holopad call should now be able to hear people on the
+ other end.
+ - bugfix: wall mounted objects air alarms, fire alarms etc now actually falls off/gets
+ destroyed when their attached wall is deconstructed
+ - bugfix: wall mounts crafted in game also properly falls off/gets destroyed when
+ their attached wall is deconstructed
+ - bugfix: Fixes a bug allowing holopara injectors to be refundable when used.
+ - balance: Improvised shotgun shells now deal half as much damage to humans and
+ cause less wounds, but do 50% more damage to structures and machines. They also
+ require a glass shard for crafting.
+ - balance: 'EMP damage on augs: 2/1.5 from 3/2'
+ - balance: Augs now only get paralyzed by EMP for 3/6 seconds if they are damaged
+ below 70% HP,
+ - balance: Aug EMP knockdown reduced to 3 seconds
+ - balance: Synthetic ears now take far less EMP damage
+ - bugfix: rescue hooks will once again drop the mob next to the fisherman instead
+ of just displaying a balloon alert and doing nothing
+ - bugfix: Recipe that converts Vegetable Oil into Olive Oil works properly
+ - rscadd: Splashing antihol on a patient before surgery will make it to go slower.
+ honkpocket:
+ - rscadd: Adds garment bags to the blueshield and NTC lockers
+ - rscadd: Adds turtlenecks and the intern outfit to the NTC garment bag
+ vinylspiders:
+ - bugfix: spiritual quirk is no longer missing from the game
+ zydras:
+ - bugfix: properly paths NT Consultant and Blueshield areas
+2023-09-22:
+ A.C.M.O.:
+ - bugfix: Fixed dildos, allowing them to be used orally only when the target mouth
+ is uncovered.
+ - bugfix: Fixed custom dildos, allowing their size and color to be customized with
+ Alt-Click.
+ GoldenAlpharex:
+ - code_imp: Removed some old fire overlay code, which might or might not fix some
+ fire overlay issues. We'll have to see.
+ - bugfix: The green pin is no longer unremovable for those that had it on before
+ they hit the 100 hours threshold. It will now be automatically disabled for
+ them.
+ LT3:
+ - image: Added donator items for grasshand
+ Literallynotpickles:
+ - rscadd: Added SHORTER Shorts to the Loadout Menu. (Misc Under)
+ SkyratBot:
+ - balance: Peacekeeper cyborg's emagged hug is no longer a hardstun.
+ - image: resprites t-ray scanner.
+ - admin: Admins can transform misbehaving players into arbitrary objects at will.
+ - bugfix: Projectiles no longer cause a blood graphic or blood splatters if they
+ hit a limb that cant bleed
+ - rscadd: Prosthetics/Augments now spark when shot
+ - bugfix: fixed moonicorns making space/chasm/lava/water bridges with their fairy
+ grass
+ jjpark-kb:
+ - qol: you can now construct, deconstruct, and anchor/unanchor the millstone
+ - rscadd: rough stones will now occasionally drop from mineral walls (the mining
+ kind)
+ - bugfix: you can now cut/process rough stones
+ vinylspiders:
+ - image: added digi resprite for shorter shorts
+2023-09-23:
+ LT3:
+ - bugfix: Ghosts and godmode mobs will no longer create resonance when touching
+ the supermatter crystal
+ - rscadd: Poly now causes a power surge when dusted by the supermatter crystal
+ - balance: Delam panic button run time increased by 2 seconds to match the new 15
+ second delam timer
+ - balance: Delam suppression freon changed to be less instantly lethal to organics,
+ less of a plasma fire waiting to happen
+ Lunar248:
+ - bugfix: Replaces the incorrect MOD cores with working ones.
+ Paxilmaniac:
+ - rscdel: The ability to change a flashlight's intensity has been removed due to
+ the fact they no longer have cells to draw more or less power from in those
+ modes.
+ - qol: Flashlights no longer pointlessly require power cells to function
+ SkyratBot:
+ - refactor: seedlings have been refactored into basic mobs please report any bugs
+ - rscadd: seedlings now can have different colored petals and can look after botanys
+ plants
+ - rscadd: seedlings are re-added to the game! they grow out of seedling seeds obtainable
+ from exotic seed crates or traitor uplink
+ - rscadd: The Message Monitor console's board can now be obtained via the telecoms
+ research node.
+ - bugfix: Conveyor belts now properly show their new screentips on mouseover with
+ tools.
+ - bugfix: clown bomb payload is no longer named badmin payload and no longer disperses
+ clowns in cardinal directions only
+ - bugfix: Foods that have special conditions for liking/disliking them (such as
+ donuts for sec officers) have these conditions again.
+ - bugfix: Characters with ageusia properly ignore non-toxic food types that they
+ eat.
+ - bugfix: If you examine toxic food, it can no longer appear to you as edible.
+ - admin: Boneless smite should work properly again.
+ distributivgesetz, CoiledLamb:
+ - rscadd: 'Added two new awards specifically for engineering and medical: The "Emergency
+ Services Award" and the "Atmospheric Mastery Award". CEs get 3 Emergency Services
+ Awards and 1 Atmospheric Mastery Award and CMOs get 3 Emergency Services Awards.'
+ softcerv:
+ - rscdel: The electric welding tool has been removed from the techweb and the experimental
+ welding tool has been reinstated in it's place.
+ vinylspiders:
+ - bugfix: using sand or volcanic ash on a seed mesh will no longer have the possibility
+ to spawn a generic buggy 'lavaland seed' item
+2023-09-24:
+ LT3:
+ - bugfix: Fixed supermatter surges always being the lowest severity
+ Melbert:
+ - bugfix: Maybe fixes some weird occurrences where you lose the ability to pass
+ over tables when you shouldn't, and visa versa
+ SkyratBot:
+ - bugfix: Epinephrine will now update health properly.
+ - rscadd: Brimdemon corpses release an explosion shortly after death, just to keep
+ you on your toes.
+ - refactor: Brimdemons now use the basic mob framework which (should) improve their
+ pathfinding somewhat. Please bug report any unusual behaviour.
+ - admin: The brimdemon's beam ability can be given to any mob, for your Binding
+ of Isaac event
+ - refactor: clowns are basicmobs now
+ - admin: Admins can now reset or modify the chaplain's sect from a UI panel
+ lukevale:
+ - rscadd: Adds bras as a selectable preference in the same vein as underwear. Separates
+ all tops from undershirts.
diff --git a/icons/effects/96x96.dmi b/icons/effects/96x96.dmi
index 68ac6699c23..38d1d44a000 100644
Binary files a/icons/effects/96x96.dmi and b/icons/effects/96x96.dmi differ
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index f7615fc045b..29e59dc6c71 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/icons/effects/eldritch.dmi b/icons/effects/eldritch.dmi
index 40d4ea80df2..8b7738f3b46 100644
Binary files a/icons/effects/eldritch.dmi and b/icons/effects/eldritch.dmi differ
diff --git a/icons/effects/random_spawners.dmi b/icons/effects/random_spawners.dmi
index f96676da097..c03b196a137 100644
Binary files a/icons/effects/random_spawners.dmi and b/icons/effects/random_spawners.dmi differ
diff --git a/icons/hud/fishing_hud.dmi b/icons/hud/fishing_hud.dmi
new file mode 100644
index 00000000000..b68acee09b7
Binary files /dev/null and b/icons/hud/fishing_hud.dmi differ
diff --git a/icons/hud/screen_alert.dmi b/icons/hud/screen_alert.dmi
index 7a1f40d6fcd..a1fc01434e4 100755
Binary files a/icons/hud/screen_alert.dmi and b/icons/hud/screen_alert.dmi differ
diff --git a/icons/hud/screen_gen.dmi b/icons/hud/screen_gen.dmi
index d80a2dbe762..1484e3f4042 100644
Binary files a/icons/hud/screen_gen.dmi and b/icons/hud/screen_gen.dmi differ
diff --git a/icons/mob/actions/actions_ecult.dmi b/icons/mob/actions/actions_ecult.dmi
index a684dd1fbe6..747b57949be 100644
Binary files a/icons/mob/actions/actions_ecult.dmi and b/icons/mob/actions/actions_ecult.dmi differ
diff --git a/icons/mob/actions/actions_silicon.dmi b/icons/mob/actions/actions_silicon.dmi
index 7be634e9f6c..9c4b7ec7fbe 100644
Binary files a/icons/mob/actions/actions_silicon.dmi and b/icons/mob/actions/actions_silicon.dmi differ
diff --git a/icons/mob/actions/actions_spells.dmi b/icons/mob/actions/actions_spells.dmi
index 9152ef8d966..39ea5810417 100644
Binary files a/icons/mob/actions/actions_spells.dmi and b/icons/mob/actions/actions_spells.dmi differ
diff --git a/icons/mob/clothing/accessories.dmi b/icons/mob/clothing/accessories.dmi
index 389cffe7cf2..2c6bf510724 100644
Binary files a/icons/mob/clothing/accessories.dmi and b/icons/mob/clothing/accessories.dmi differ
diff --git a/icons/mob/clothing/back.dmi b/icons/mob/clothing/back.dmi
index 8e50d48b587..dc519380cfd 100644
Binary files a/icons/mob/clothing/back.dmi and b/icons/mob/clothing/back.dmi differ
diff --git a/icons/mob/clothing/belt.dmi b/icons/mob/clothing/belt.dmi
index fa5d688969e..546e3da0f86 100644
Binary files a/icons/mob/clothing/belt.dmi and b/icons/mob/clothing/belt.dmi differ
diff --git a/icons/mob/clothing/belt_mirror.dmi b/icons/mob/clothing/belt_mirror.dmi
index 875aed119c1..0c1b8457be7 100644
Binary files a/icons/mob/clothing/belt_mirror.dmi and b/icons/mob/clothing/belt_mirror.dmi differ
diff --git a/icons/mob/clothing/eyes.dmi b/icons/mob/clothing/eyes.dmi
index c1de49a95a5..20bf4d18381 100644
Binary files a/icons/mob/clothing/eyes.dmi and b/icons/mob/clothing/eyes.dmi differ
diff --git a/icons/mob/clothing/feet.dmi b/icons/mob/clothing/feet.dmi
index 3c2f4b54b17..3a6faaf1ef8 100644
Binary files a/icons/mob/clothing/feet.dmi and b/icons/mob/clothing/feet.dmi differ
diff --git a/icons/mob/clothing/head/costume.dmi b/icons/mob/clothing/head/costume.dmi
index 6116fb94500..3c5ea17b19d 100644
Binary files a/icons/mob/clothing/head/costume.dmi and b/icons/mob/clothing/head/costume.dmi differ
diff --git a/icons/mob/clothing/head/hats.dmi b/icons/mob/clothing/head/hats.dmi
index 1806b193066..abf2f9f18bd 100644
Binary files a/icons/mob/clothing/head/hats.dmi and b/icons/mob/clothing/head/hats.dmi differ
diff --git a/icons/mob/clothing/head/hydroponics.dmi b/icons/mob/clothing/head/hydroponics.dmi
index e592ad444be..b710efc3d7d 100644
Binary files a/icons/mob/clothing/head/hydroponics.dmi and b/icons/mob/clothing/head/hydroponics.dmi differ
diff --git a/icons/mob/clothing/head/plasmaman_head.dmi b/icons/mob/clothing/head/plasmaman_head.dmi
index 00385b5dd81..9846cf02200 100644
Binary files a/icons/mob/clothing/head/plasmaman_head.dmi and b/icons/mob/clothing/head/plasmaman_head.dmi differ
diff --git a/icons/mob/clothing/head/winterhood.dmi b/icons/mob/clothing/head/winterhood.dmi
index f85a687f304..ba722a5a0f2 100644
Binary files a/icons/mob/clothing/head/winterhood.dmi and b/icons/mob/clothing/head/winterhood.dmi differ
diff --git a/icons/mob/clothing/neck.dmi b/icons/mob/clothing/neck.dmi
index 0750f61bd82..03cf6a861c1 100644
Binary files a/icons/mob/clothing/neck.dmi and b/icons/mob/clothing/neck.dmi differ
diff --git a/icons/mob/clothing/suits/costume.dmi b/icons/mob/clothing/suits/costume.dmi
index 0f10e239019..bf4bbe310d2 100644
Binary files a/icons/mob/clothing/suits/costume.dmi and b/icons/mob/clothing/suits/costume.dmi differ
diff --git a/icons/mob/clothing/suits/jacket.dmi b/icons/mob/clothing/suits/jacket.dmi
index 2466bcda85e..cd924e847eb 100644
Binary files a/icons/mob/clothing/suits/jacket.dmi and b/icons/mob/clothing/suits/jacket.dmi differ
diff --git a/icons/mob/clothing/suits/utility.dmi b/icons/mob/clothing/suits/utility.dmi
index 86038a5f6d5..40216806f4f 100644
Binary files a/icons/mob/clothing/suits/utility.dmi and b/icons/mob/clothing/suits/utility.dmi differ
diff --git a/icons/mob/clothing/suits/wintercoat.dmi b/icons/mob/clothing/suits/wintercoat.dmi
index b720b31f38e..9bcfca4d6a3 100644
Binary files a/icons/mob/clothing/suits/wintercoat.dmi and b/icons/mob/clothing/suits/wintercoat.dmi differ
diff --git a/icons/mob/clothing/under/cargo.dmi b/icons/mob/clothing/under/cargo.dmi
index 93499d605b7..4bf30a67a2d 100644
Binary files a/icons/mob/clothing/under/cargo.dmi and b/icons/mob/clothing/under/cargo.dmi differ
diff --git a/icons/mob/clothing/under/plasmaman.dmi b/icons/mob/clothing/under/plasmaman.dmi
index f154127f3fb..41cbfb4482b 100644
Binary files a/icons/mob/clothing/under/plasmaman.dmi and b/icons/mob/clothing/under/plasmaman.dmi differ
diff --git a/icons/mob/human/species/wings.dmi b/icons/mob/human/species/wings.dmi
index 0cc2b1224fa..26e8b011fce 100644
Binary files a/icons/mob/human/species/wings.dmi and b/icons/mob/human/species/wings.dmi differ
diff --git a/icons/mob/inhands/64x64_lefthand.dmi b/icons/mob/inhands/64x64_lefthand.dmi
index 26c177f7293..8a6bab69776 100644
Binary files a/icons/mob/inhands/64x64_lefthand.dmi and b/icons/mob/inhands/64x64_lefthand.dmi differ
diff --git a/icons/mob/inhands/64x64_righthand.dmi b/icons/mob/inhands/64x64_righthand.dmi
index 79c30f5cb19..251458590bd 100644
Binary files a/icons/mob/inhands/64x64_righthand.dmi and b/icons/mob/inhands/64x64_righthand.dmi differ
diff --git a/icons/mob/inhands/equipment/medical_lefthand.dmi b/icons/mob/inhands/equipment/medical_lefthand.dmi
index 782f2cc0c35..7ce3674c86a 100644
Binary files a/icons/mob/inhands/equipment/medical_lefthand.dmi and b/icons/mob/inhands/equipment/medical_lefthand.dmi differ
diff --git a/icons/mob/inhands/equipment/medical_righthand.dmi b/icons/mob/inhands/equipment/medical_righthand.dmi
index f5f93dda3ce..6ceb5efe4d8 100644
Binary files a/icons/mob/inhands/equipment/medical_righthand.dmi and b/icons/mob/inhands/equipment/medical_righthand.dmi differ
diff --git a/icons/mob/inhands/equipment/tanks_lefthand.dmi b/icons/mob/inhands/equipment/tanks_lefthand.dmi
index 300d3c4740d..dc32e285237 100644
Binary files a/icons/mob/inhands/equipment/tanks_lefthand.dmi and b/icons/mob/inhands/equipment/tanks_lefthand.dmi differ
diff --git a/icons/mob/inhands/equipment/tanks_righthand.dmi b/icons/mob/inhands/equipment/tanks_righthand.dmi
index 3b19be62598..30f2233c5ac 100644
Binary files a/icons/mob/inhands/equipment/tanks_righthand.dmi and b/icons/mob/inhands/equipment/tanks_righthand.dmi differ
diff --git a/icons/mob/inhands/weapons/staves_lefthand.dmi b/icons/mob/inhands/weapons/staves_lefthand.dmi
index 0b7480e211c..6e34949c9d5 100644
Binary files a/icons/mob/inhands/weapons/staves_lefthand.dmi and b/icons/mob/inhands/weapons/staves_lefthand.dmi differ
diff --git a/icons/mob/inhands/weapons/staves_righthand.dmi b/icons/mob/inhands/weapons/staves_righthand.dmi
index fd85d8913a9..df52d4d4198 100644
Binary files a/icons/mob/inhands/weapons/staves_righthand.dmi and b/icons/mob/inhands/weapons/staves_righthand.dmi differ
diff --git a/icons/mob/nonhuman-player/96x96eldritch_mobs.dmi b/icons/mob/nonhuman-player/96x96eldritch_mobs.dmi
index c20779ff246..4bbc55c15dd 100644
Binary files a/icons/mob/nonhuman-player/96x96eldritch_mobs.dmi and b/icons/mob/nonhuman-player/96x96eldritch_mobs.dmi differ
diff --git a/icons/mob/simple/corgi_head.dmi b/icons/mob/simple/corgi_head.dmi
index b582d0406f9..2e14a3ed0bb 100644
Binary files a/icons/mob/simple/corgi_head.dmi and b/icons/mob/simple/corgi_head.dmi differ
diff --git a/icons/mob/simple/jungle/seedling.dmi b/icons/mob/simple/jungle/seedling.dmi
index 01e91c6c292..c4a76ebb2d1 100644
Binary files a/icons/mob/simple/jungle/seedling.dmi and b/icons/mob/simple/jungle/seedling.dmi differ
diff --git a/icons/mob/simple/lavaland/lavaland_monsters.dmi b/icons/mob/simple/lavaland/lavaland_monsters.dmi
index 1d546bd17d4..13c37dca594 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/obj/canisters.dmi b/icons/obj/canisters.dmi
index 236ae7a1559..e57c6ad9b96 100644
Binary files a/icons/obj/canisters.dmi and b/icons/obj/canisters.dmi differ
diff --git a/icons/obj/clothing/accessories.dmi b/icons/obj/clothing/accessories.dmi
index 2711333118a..fdba37254eb 100644
Binary files a/icons/obj/clothing/accessories.dmi and b/icons/obj/clothing/accessories.dmi differ
diff --git a/icons/obj/clothing/cloaks.dmi b/icons/obj/clothing/cloaks.dmi
index dd1b905ad2c..101264aca53 100644
Binary files a/icons/obj/clothing/cloaks.dmi and b/icons/obj/clothing/cloaks.dmi differ
diff --git a/icons/obj/clothing/glasses.dmi b/icons/obj/clothing/glasses.dmi
index 93571ca6318..20f24dd2240 100644
Binary files a/icons/obj/clothing/glasses.dmi and b/icons/obj/clothing/glasses.dmi differ
diff --git a/icons/obj/clothing/head/costume.dmi b/icons/obj/clothing/head/costume.dmi
index 2bd05db126c..f676b1c6973 100644
Binary files a/icons/obj/clothing/head/costume.dmi and b/icons/obj/clothing/head/costume.dmi differ
diff --git a/icons/obj/clothing/head/hats.dmi b/icons/obj/clothing/head/hats.dmi
index e8662998fd8..15117fa69a8 100644
Binary files a/icons/obj/clothing/head/hats.dmi and b/icons/obj/clothing/head/hats.dmi differ
diff --git a/icons/obj/clothing/head/plasmaman_hats.dmi b/icons/obj/clothing/head/plasmaman_hats.dmi
index 382dae5df1e..adcf9129c45 100644
Binary files a/icons/obj/clothing/head/plasmaman_hats.dmi and b/icons/obj/clothing/head/plasmaman_hats.dmi differ
diff --git a/icons/obj/clothing/head/winterhood.dmi b/icons/obj/clothing/head/winterhood.dmi
index 2d5170948a4..34e0abf39be 100644
Binary files a/icons/obj/clothing/head/winterhood.dmi and b/icons/obj/clothing/head/winterhood.dmi differ
diff --git a/icons/obj/clothing/modsuit/mod_modules.dmi b/icons/obj/clothing/modsuit/mod_modules.dmi
index d548f615c44..f1d19c29da1 100644
Binary files a/icons/obj/clothing/modsuit/mod_modules.dmi and b/icons/obj/clothing/modsuit/mod_modules.dmi differ
diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi
index 49ec0767f78..104812240fe 100644
Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ
diff --git a/icons/obj/clothing/suits/costume.dmi b/icons/obj/clothing/suits/costume.dmi
index b4532306044..0c08b97605d 100644
Binary files a/icons/obj/clothing/suits/costume.dmi and b/icons/obj/clothing/suits/costume.dmi differ
diff --git a/icons/obj/clothing/suits/jacket.dmi b/icons/obj/clothing/suits/jacket.dmi
index 3ac958c1c38..c63f262f104 100644
Binary files a/icons/obj/clothing/suits/jacket.dmi and b/icons/obj/clothing/suits/jacket.dmi differ
diff --git a/icons/obj/clothing/suits/utility.dmi b/icons/obj/clothing/suits/utility.dmi
index 595746191d3..25fb8fd502a 100644
Binary files a/icons/obj/clothing/suits/utility.dmi and b/icons/obj/clothing/suits/utility.dmi differ
diff --git a/icons/obj/clothing/suits/wintercoat.dmi b/icons/obj/clothing/suits/wintercoat.dmi
index 27b53c2ddf4..377c9ef61e3 100644
Binary files a/icons/obj/clothing/suits/wintercoat.dmi and b/icons/obj/clothing/suits/wintercoat.dmi differ
diff --git a/icons/obj/clothing/under/cargo.dmi b/icons/obj/clothing/under/cargo.dmi
index 4f9fe47a3f6..fc04a897d5e 100644
Binary files a/icons/obj/clothing/under/cargo.dmi and b/icons/obj/clothing/under/cargo.dmi differ
diff --git a/icons/obj/clothing/under/plasmaman.dmi b/icons/obj/clothing/under/plasmaman.dmi
index d22ae7a26e1..4277c43d54b 100644
Binary files a/icons/obj/clothing/under/plasmaman.dmi and b/icons/obj/clothing/under/plasmaman.dmi differ
diff --git a/icons/obj/cosmetic.dmi b/icons/obj/cosmetic.dmi
index e53e490b956..b04bde541ad 100644
Binary files a/icons/obj/cosmetic.dmi and b/icons/obj/cosmetic.dmi differ
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index b6ccf1b8c41..d89ee6e5d64 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ
diff --git a/icons/obj/fluff/containers.dmi b/icons/obj/fluff/containers.dmi
index af9abe7073e..8aed1ffbb9a 100644
Binary files a/icons/obj/fluff/containers.dmi and b/icons/obj/fluff/containers.dmi differ
diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi
index 7ab1670900a..97ded07df21 100644
Binary files a/icons/obj/food/food.dmi and b/icons/obj/food/food.dmi differ
diff --git a/icons/obj/machines/floor.dmi b/icons/obj/machines/floor.dmi
index 38ea510f37b..6f858465dcd 100644
Binary files a/icons/obj/machines/floor.dmi and b/icons/obj/machines/floor.dmi differ
diff --git a/icons/obj/machines/nebula_shielding.dmi b/icons/obj/machines/nebula_shielding.dmi
index 32aedcc1b7a..1da2b5f2a9b 100644
Binary files a/icons/obj/machines/nebula_shielding.dmi and b/icons/obj/machines/nebula_shielding.dmi differ
diff --git a/icons/obj/machines/recycling.dmi b/icons/obj/machines/recycling.dmi
index de419374151..9a6dffaaee2 100644
Binary files a/icons/obj/machines/recycling.dmi and b/icons/obj/machines/recycling.dmi differ
diff --git a/icons/obj/machines/status_display.dmi b/icons/obj/machines/status_display.dmi
index 76d20addff7..b48cad5293e 100644
Binary files a/icons/obj/machines/status_display.dmi and b/icons/obj/machines/status_display.dmi differ
diff --git a/icons/obj/machines/wallmounts.dmi b/icons/obj/machines/wallmounts.dmi
index 53575d22bef..39e4cc2476b 100644
Binary files a/icons/obj/machines/wallmounts.dmi and b/icons/obj/machines/wallmounts.dmi differ
diff --git a/icons/obj/medical/chemical.dmi b/icons/obj/medical/chemical.dmi
index aaedc090f2d..b4b26e4f848 100644
Binary files a/icons/obj/medical/chemical.dmi and b/icons/obj/medical/chemical.dmi differ
diff --git a/icons/obj/medical/medical_bed.dmi b/icons/obj/medical/medical_bed.dmi
new file mode 100644
index 00000000000..2d8e4b576ed
Binary files /dev/null and b/icons/obj/medical/medical_bed.dmi differ
diff --git a/icons/obj/medical/organs/organs.dmi b/icons/obj/medical/organs/organs.dmi
index 17e09c7395c..94ba46568c9 100644
Binary files a/icons/obj/medical/organs/organs.dmi and b/icons/obj/medical/organs/organs.dmi differ
diff --git a/icons/obj/medical/rollerbed.dmi b/icons/obj/medical/rollerbed.dmi
deleted file mode 100644
index fcc4e833c34..00000000000
Binary files a/icons/obj/medical/rollerbed.dmi and /dev/null differ
diff --git a/icons/obj/medicart.dmi b/icons/obj/medicart.dmi
new file mode 100644
index 00000000000..c25ea0039dc
Binary files /dev/null and b/icons/obj/medicart.dmi differ
diff --git a/icons/obj/mining.dmi b/icons/obj/mining.dmi
index 6c5560438c6..54b19553b84 100644
Binary files a/icons/obj/mining.dmi and b/icons/obj/mining.dmi differ
diff --git a/icons/obj/pipes_n_cables/hydrochem/plumbers.dmi b/icons/obj/pipes_n_cables/hydrochem/plumbers.dmi
index 792868a8ae3..19775b6eff8 100644
Binary files a/icons/obj/pipes_n_cables/hydrochem/plumbers.dmi and b/icons/obj/pipes_n_cables/hydrochem/plumbers.dmi differ
diff --git a/icons/obj/scrolls.dmi b/icons/obj/scrolls.dmi
index b35d5255df4..ae488cab2f7 100644
Binary files a/icons/obj/scrolls.dmi and b/icons/obj/scrolls.dmi differ
diff --git a/icons/obj/service/hydroponics/equipment.dmi b/icons/obj/service/hydroponics/equipment.dmi
index dc164c5b1c9..afcc4de5235 100644
Binary files a/icons/obj/service/hydroponics/equipment.dmi and b/icons/obj/service/hydroponics/equipment.dmi differ
diff --git a/icons/obj/service/hydroponics/growing_flowers.dmi b/icons/obj/service/hydroponics/growing_flowers.dmi
index 1bdbe6786a4..fca3e15f9d9 100644
Binary files a/icons/obj/service/hydroponics/growing_flowers.dmi and b/icons/obj/service/hydroponics/growing_flowers.dmi differ
diff --git a/icons/obj/service/hydroponics/growing_fruits.dmi b/icons/obj/service/hydroponics/growing_fruits.dmi
index 7e535cdaf9b..92c52b55dbf 100644
Binary files a/icons/obj/service/hydroponics/growing_fruits.dmi and b/icons/obj/service/hydroponics/growing_fruits.dmi differ
diff --git a/icons/obj/service/hydroponics/harvest.dmi b/icons/obj/service/hydroponics/harvest.dmi
index beca0e836c9..28a43776a50 100644
Binary files a/icons/obj/service/hydroponics/harvest.dmi and b/icons/obj/service/hydroponics/harvest.dmi differ
diff --git a/icons/obj/service/hydroponics/seeds.dmi b/icons/obj/service/hydroponics/seeds.dmi
index d6e70af1a42..ffef219193a 100644
Binary files a/icons/obj/service/hydroponics/seeds.dmi and b/icons/obj/service/hydroponics/seeds.dmi differ
diff --git a/icons/obj/service/janitor.dmi b/icons/obj/service/janitor.dmi
index 8c73a99b416..0e814ca4545 100644
Binary files a/icons/obj/service/janitor.dmi and b/icons/obj/service/janitor.dmi differ
diff --git a/icons/obj/service/library.dmi b/icons/obj/service/library.dmi
index ebf48682325..8229c1fc394 100644
Binary files a/icons/obj/service/library.dmi and b/icons/obj/service/library.dmi differ
diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi
index a04a34edd31..e6679c8c518 100644
Binary files a/icons/obj/tools.dmi and b/icons/obj/tools.dmi differ
diff --git a/icons/obj/wallmounts.dmi b/icons/obj/wallmounts.dmi
index 10e19983c0c..e020a8818e1 100644
Binary files a/icons/obj/wallmounts.dmi and b/icons/obj/wallmounts.dmi differ
diff --git a/icons/obj/weapons/guns/energy.dmi b/icons/obj/weapons/guns/energy.dmi
index 07ac342a36d..97b75335b91 100644
Binary files a/icons/obj/weapons/guns/energy.dmi and b/icons/obj/weapons/guns/energy.dmi differ
diff --git a/icons/obj/weapons/guns/magic.dmi b/icons/obj/weapons/guns/magic.dmi
index 7dbc984c4b6..fe3eb6ae895 100644
Binary files a/icons/obj/weapons/guns/magic.dmi and b/icons/obj/weapons/guns/magic.dmi differ
diff --git a/icons/obj/weapons/khopesh.dmi b/icons/obj/weapons/khopesh.dmi
index 4bbd4d5f0f9..ab7a0c252cb 100644
Binary files a/icons/obj/weapons/khopesh.dmi and b/icons/obj/weapons/khopesh.dmi differ
diff --git a/icons/turf/overlays.dmi b/icons/turf/overlays.dmi
index 83309e4d18e..c9decbc5a3a 100644
Binary files a/icons/turf/overlays.dmi and b/icons/turf/overlays.dmi differ
diff --git a/icons/ui_icons/achievements/achievements.dmi b/icons/ui_icons/achievements/achievements.dmi
index ad34dfd16f0..b3e64c9d09f 100644
Binary files a/icons/ui_icons/achievements/achievements.dmi and b/icons/ui_icons/achievements/achievements.dmi differ
diff --git a/icons/ui_icons/fishing/default.png b/icons/ui_icons/fishing/default.png
deleted file mode 100644
index 20dabae9210..00000000000
Binary files a/icons/ui_icons/fishing/default.png and /dev/null differ
diff --git a/icons/ui_icons/fishing/lavaland.png b/icons/ui_icons/fishing/lavaland.png
deleted file mode 100644
index b6e2487bdc4..00000000000
Binary files a/icons/ui_icons/fishing/lavaland.png and /dev/null differ
diff --git a/libbyond_sleeping_procs.so b/libbyond_sleeping_procs.so
deleted file mode 100644
index 8596115fd96..00000000000
Binary files a/libbyond_sleeping_procs.so and /dev/null differ
diff --git a/modular_skyrat/master_files/code/_globalvars/configuration.dm b/modular_skyrat/master_files/code/_globalvars/configuration.dm
index fdd54c7498d..f2f60e22a42 100644
--- a/modular_skyrat/master_files/code/_globalvars/configuration.dm
+++ b/modular_skyrat/master_files/code/_globalvars/configuration.dm
@@ -66,3 +66,6 @@ GLOBAL_VAR_INIT(looc_allowed, TRUE)
/// Split the threat budget between roundstart and midrounds
/datum/config_entry/flag/split_threat_budget
+
+// How much time arrivals shuttle should stay at station after its engines recharged before returning to interlink. In deciseconds. 150 - 15 seconds. 0 - disables autoreturn
+/datum/config_entry/number/arrivals_wait
diff --git a/modular_skyrat/master_files/code/datums/votes/_vote_datum.dm b/modular_skyrat/master_files/code/datums/votes/_vote_datum.dm
index 42d83447c15..7c0b057ce2a 100644
--- a/modular_skyrat/master_files/code/datums/votes/_vote_datum.dm
+++ b/modular_skyrat/master_files/code/datums/votes/_vote_datum.dm
@@ -1,4 +1,3 @@
-
/**
* # Vote Singleton
*
diff --git a/modular_skyrat/master_files/code/game/objects/items/cards_ids.dm b/modular_skyrat/master_files/code/game/objects/items/cards_ids.dm
index 081ce4ae850..64f40cb5f86 100644
--- a/modular_skyrat/master_files/code/game/objects/items/cards_ids.dm
+++ b/modular_skyrat/master_files/code/game/objects/items/cards_ids.dm
@@ -22,7 +22,7 @@
/obj/item/card/id/advanced/colourable/Initialize(mapload)
. = ..()
- AddComponent(/datum/component/gags_recolorable)
+ AddElement(/datum/element/gags_recolorable)
/obj/item/card/id/advanced/colourable/examine(mob/user)
. = ..()
diff --git a/modular_skyrat/master_files/code/game/objects/items/holy_weapons.dm b/modular_skyrat/master_files/code/game/objects/items/holy_weapons.dm
index 6f79f0c2993..114114bf09a 100644
--- a/modular_skyrat/master_files/code/game/objects/items/holy_weapons.dm
+++ b/modular_skyrat/master_files/code/game/objects/items/holy_weapons.dm
@@ -169,6 +169,7 @@
inhand_x_dimension = 64
inhand_y_dimension = 64
slot_flags = ITEM_SLOT_BELT
+ sharpness = SHARP_EDGED
w_class = WEIGHT_CLASS_NORMAL
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb_continuous = list("attacks", "slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "rends")
diff --git a/modular_skyrat/master_files/code/game/objects/items/scratchingstone.dm b/modular_skyrat/master_files/code/game/objects/items/scratchingstone.dm
new file mode 100644
index 00000000000..ac1fd624429
--- /dev/null
+++ b/modular_skyrat/master_files/code/game/objects/items/scratchingstone.dm
@@ -0,0 +1,7 @@
+/obj/item/scratching_stone
+ name = "scratching stone"
+ icon = 'modular_skyrat/master_files/icons/obj/kitchen.dmi'
+ icon_state = "scratchingstone"
+ desc = "A specialized kind of whetstone, made of unknown alloys to hone a cyborg mercenary's claws to the best they can be. This one looks like a shitty second-hand sold by razorkids. It's got like, what, maybe one use left?"
+ force = 5
+ throwforce = 10 //Hey, you can at least use it as a brick.
diff --git a/modular_skyrat/master_files/code/game/objects/items/stacks/sheets/sheet_types.dm b/modular_skyrat/master_files/code/game/objects/items/stacks/sheets/sheet_types.dm
index 620317122b2..b74721c63ae 100644
--- a/modular_skyrat/master_files/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/modular_skyrat/master_files/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -102,6 +102,7 @@ GLOBAL_LIST_INIT(skyrat_leather_belt_recipes, list(
new/datum/stack_recipe("xenoarch belt", /obj/item/storage/belt/utility/xenoarch, 4, check_density = FALSE, category = CAT_CONTAINERS),
new/datum/stack_recipe("medical bandolier", /obj/item/storage/belt/medbandolier, 5, check_density = FALSE, category = CAT_CONTAINERS),
new/datum/stack_recipe("gear harness", /obj/item/clothing/under/misc/skyrat/gear_harness, 6, check_density = FALSE, category = CAT_CLOTHING),
+ new/datum/stack_recipe("ammo pouch", /obj/item/storage/pouch/ammo, 4, check_density = FALSE, category = CAT_CONTAINERS),
))
/obj/item/stack/sheet/leather/get_main_recipes()
diff --git a/modular_skyrat/master_files/code/game/objects/structures/mannequin.dm b/modular_skyrat/master_files/code/game/objects/structures/mannequin.dm
new file mode 100644
index 00000000000..9604fb7ac5f
--- /dev/null
+++ b/modular_skyrat/master_files/code/game/objects/structures/mannequin.dm
@@ -0,0 +1,3 @@
+/obj/structure/mannequin
+ /// String for the bra we use.
+ var/bra_name
diff --git a/modular_skyrat/master_files/code/modules/antagonists/changeling/changeling.dm b/modular_skyrat/master_files/code/modules/antagonists/changeling/changeling.dm
index 5c7b4c4bbd1..92f0b0786dc 100644
--- a/modular_skyrat/master_files/code/modules/antagonists/changeling/changeling.dm
+++ b/modular_skyrat/master_files/code/modules/antagonists/changeling/changeling.dm
@@ -1,2 +1,46 @@
/datum/antagonist/changeling/forge_objectives()
return
+
+
+/datum/changeling_profile
+ /// The bra worn by the profile source - Skyrats addition
+ var/bra
+ /// The color of the underwear used by the profile source - Skyrats addition
+ var/underwear_color
+ /// The color of the undershirt used by the profile source - Skyrats addition
+ var/undershirt_color
+ /// The color of the socks used by the profile source - Skyrats addition
+ var/socks_color
+ /// The color of the bra used by the profile source - Skyrats addition
+ var/bra_color
+ /// The profile source's left eye color - Skyrats addition
+ var/eye_color_left
+ /// The profile source's right eye color - Skyrats addition
+ var/eye_color_right
+ /// Does the profile source's eyes glow - Skyrats addition
+ var/emissive_eyes
+ /// The profile sorce's gradient styles - Skyrats addition
+ var/list/grad_style = list("None", "None")
+ /// The colors for the profile source's gradients - Skyrats addition
+ var/list/grad_color = list(null, null)
+
+ /// The physique used by the profile source - Skyrats addition
+ var/physique
+ /// Profile source digi leg icons - Skyrats addition
+ var/list/worn_icon_digi_list = list()
+ /// profile source monkey icons - Skyrats addition
+ var/list/worn_icon_monkey_list = list()
+ /// Profile source vox icons - Skyrats addition
+ var/list/worn_icon_teshari_list = list()
+ /// The bra worn by the profile source - Skyrats addition
+ var/list/worn_icon_vox_list = list()
+ /// Support variation flags used by the profile source - Skyrats addition
+ var/list/supports_variations_flags_list = list()
+ /// The profile source scream type - Skyrats addition
+ var/scream_type
+ /// The profile source laugh type - Skyrats addition
+ var/laugh_type
+ /// The profile source's age - Skyrats addition
+ var/age
+ /// The quirks used by the profile source - Skyrats addition
+ var/list/quirks = list()
diff --git a/modular_skyrat/master_files/code/modules/cargo/bounties/medical.dm b/modular_skyrat/master_files/code/modules/cargo/bounties/medical.dm
new file mode 100644
index 00000000000..e1b032bbc33
--- /dev/null
+++ b/modular_skyrat/master_files/code/modules/cargo/bounties/medical.dm
@@ -0,0 +1,2 @@
+/datum/bounty/item/medical/tongue
+ description = "A recent attack by Mime extremists has left staff at Station 23 speechless. Ship some spare tongues. We'll accept cybernetic variants if need be."
\ No newline at end of file
diff --git a/modular_skyrat/master_files/code/modules/cargo/exports/tools.dm b/modular_skyrat/master_files/code/modules/cargo/exports/tools.dm
new file mode 100644
index 00000000000..f7408c7367f
--- /dev/null
+++ b/modular_skyrat/master_files/code/modules/cargo/exports/tools.dm
@@ -0,0 +1,2 @@
+/datum/export/weldingtool/experimental
+ export_types = list(/obj/item/weldingtool/electric)
diff --git a/modular_skyrat/master_files/code/modules/cargo/goodies.dm b/modular_skyrat/master_files/code/modules/cargo/goodies.dm
new file mode 100644
index 00000000000..ecc2cfa4852
--- /dev/null
+++ b/modular_skyrat/master_files/code/modules/cargo/goodies.dm
@@ -0,0 +1,35 @@
+/datum/supply_pack/goody/dumdum38
+ special = TRUE
+
+/datum/supply_pack/goody/match38
+ special = TRUE
+
+/datum/supply_pack/goody/rubber
+ special = TRUE
+
+/datum/supply_pack/goody/mars_single
+ special = TRUE
+
+/datum/supply_pack/goody/Survivalknives_single
+ special = TRUE
+
+/datum/supply_pack/goody/ballistic_single
+ special = TRUE
+
+/datum/supply_pack/goody/disabler_single
+ special = TRUE
+
+/datum/supply_pack/goody/energy_single
+ special = TRUE
+
+/datum/supply_pack/goody/laser_single
+ special = TRUE
+
+/datum/supply_pack/goody/hell_single
+ special = TRUE
+
+/datum/supply_pack/goody/thermal_single
+ special = TRUE
+
+/datum/supply_pack/goody/dyespray
+ special = TRUE
diff --git a/modular_skyrat/master_files/code/modules/cargo/orderconsole.dm b/modular_skyrat/master_files/code/modules/cargo/orderconsole.dm
new file mode 100644
index 00000000000..6898c91076c
--- /dev/null
+++ b/modular_skyrat/master_files/code/modules/cargo/orderconsole.dm
@@ -0,0 +1,12 @@
+/obj/machinery/computer/cargo/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
+ . = ..()
+ if(.)
+ return
+
+ switch(action)
+ if("company_import_window")
+ var/datum/component/armament/company_imports/company_import_component = GetComponent(/datum/component/armament/company_imports)
+ company_import_component.ui_interact(usr)
+ . = TRUE
+ if(.)
+ post_signal(cargo_shuttle)
diff --git a/modular_skyrat/master_files/code/modules/cargo/packs/general.dm b/modular_skyrat/master_files/code/modules/cargo/packs/general.dm
new file mode 100644
index 00000000000..e854c0902ff
--- /dev/null
+++ b/modular_skyrat/master_files/code/modules/cargo/packs/general.dm
@@ -0,0 +1,2 @@
+/datum/supply_pack/misc/bicycle
+ special = TRUE
diff --git a/modular_skyrat/master_files/code/modules/cargo/packs/security.dm b/modular_skyrat/master_files/code/modules/cargo/packs/security.dm
new file mode 100644
index 00000000000..9746267dbdd
--- /dev/null
+++ b/modular_skyrat/master_files/code/modules/cargo/packs/security.dm
@@ -0,0 +1,26 @@
+/datum/supply_pack/security/ammo
+ special = TRUE
+
+/datum/supply_pack/security/armor
+ special = TRUE
+
+/datum/supply_pack/security/disabler
+ cost = CARGO_CRATE_VALUE * 5
+
+/datum/supply_pack/security/helmets
+ special = TRUE
+
+/datum/supply_pack/security/laser
+ special = TRUE
+
+/datum/supply_pack/security/securityclothes
+ special = TRUE
+
+/datum/supply_pack/security/armory/ballistic
+ special = TRUE
+
+/datum/supply_pack/security/armory/energy
+ special = TRUE
+
+/datum/supply_pack/security/armory/thermal
+ special = TRUE
diff --git a/modular_skyrat/master_files/code/modules/cargo/packs/service.dm b/modular_skyrat/master_files/code/modules/cargo/packs/service.dm
new file mode 100644
index 00000000000..49ea64b2788
--- /dev/null
+++ b/modular_skyrat/master_files/code/modules/cargo/packs/service.dm
@@ -0,0 +1,2 @@
+/datum/supply_pack/service/survivalknives
+ special = TRUE
diff --git a/modular_skyrat/master_files/code/modules/cargo/packs/vending_restock.dm b/modular_skyrat/master_files/code/modules/cargo/packs/vending_restock.dm
new file mode 100644
index 00000000000..5d7a9b95dc0
--- /dev/null
+++ b/modular_skyrat/master_files/code/modules/cargo/packs/vending_restock.dm
@@ -0,0 +1,5 @@
+/datum/supply_pack/vending/sectech
+ special = TRUE
+
+/datum/supply_pack/vending/wardrobes/security
+ special = TRUE
diff --git a/modular_skyrat/master_files/code/modules/client/playtime.dm b/modular_skyrat/master_files/code/modules/client/playtime.dm
index c640b4b95d7..b1d301120e7 100644
--- a/modular_skyrat/master_files/code/modules/client/playtime.dm
+++ b/modular_skyrat/master_files/code/modules/client/playtime.dm
@@ -20,6 +20,10 @@
return preferences?.parent?.is_green()
/datum/preference/toggle/green_pin/apply_to_human(mob/living/carbon/human/wearer, value)
+ if(value && wearer.client && !wearer.client?.is_green())
+ // This way, it doesn't stick for those that had it set to TRUE before they got their 100 hours in.
+ wearer.client?.prefs?.write_preference(GLOB.preference_entries[/datum/preference/toggle/green_pin], FALSE)
+
return
/client/proc/is_green()
diff --git a/modular_skyrat/master_files/code/modules/client/preferences/clothing.dm b/modular_skyrat/master_files/code/modules/client/preferences/clothing.dm
index 8041e751783..f542e867fc6 100644
--- a/modular_skyrat/master_files/code/modules/client/preferences/clothing.dm
+++ b/modular_skyrat/master_files/code/modules/client/preferences/clothing.dm
@@ -35,3 +35,50 @@
var/species_type = preferences.read_preference(/datum/preference/choiced/species)
var/datum/species/species = new species_type
return !(TRAIT_NO_UNDERWEAR in species.inherent_traits)
+
+/datum/preference/choiced/bra
+ savefile_key = "bra"
+ savefile_identifier = PREFERENCE_CHARACTER
+ main_feature_name = "Bra"
+ category = PREFERENCE_CATEGORY_CLOTHING
+ should_generate_icons = TRUE
+
+/datum/preference/choiced/bra/init_possible_values()
+ return assoc_to_keys_features(GLOB.bra_list)
+
+/datum/preference/choiced/bra/icon_for(value)
+ var/static/icon/body
+ if (isnull(body))
+ body = icon('icons/mob/human/bodyparts_greyscale.dmi', "human_r_arm")
+ body.Blend(icon('icons/mob/human/bodyparts_greyscale.dmi', "human_l_arm"), ICON_OVERLAY)
+ body.Blend(icon('icons/mob/human/bodyparts_greyscale.dmi', "human_r_hand"), ICON_OVERLAY)
+ body.Blend(icon('icons/mob/human/bodyparts_greyscale.dmi', "human_l_hand"), ICON_OVERLAY)
+ body.Blend(icon('icons/mob/human/bodyparts_greyscale.dmi', "human_chest_m"), ICON_OVERLAY)
+
+ var/icon/icon_with_bra = icon(body)
+
+ if (value != "Nude")
+ var/datum/sprite_accessory/accessory = GLOB.bra_list[value]
+ icon_with_bra.Blend(icon(accessory.icon, accessory.icon_state), ICON_OVERLAY)
+
+ icon_with_bra.Crop(10, 11, 22, 23) // SKYRAT EDIT CHANGE : ORIGINAL - icon_with_undershirt.Crop(9, 9, 23, 23)
+ icon_with_bra.Scale(32, 32)
+ return icon_with_bra
+
+/datum/preference/choiced/bra/apply_to_human(mob/living/carbon/human/target, value)
+ target.bra = value
+
+/datum/preference/choiced/bra/compile_constant_data()
+ var/list/data = ..()
+
+ data[SUPPLEMENTAL_FEATURE_KEY] = "bra_color"
+
+ return data
+
+/datum/preference/choiced/bra/is_accessible(datum/preferences/preferences)
+ if (!..(preferences))
+ return FALSE
+
+ var/species_type = preferences.read_preference(/datum/preference/choiced/species)
+ var/datum/species/species = new species_type
+ return !(TRAIT_NO_UNDERWEAR in species.inherent_traits)
diff --git a/modular_skyrat/master_files/code/modules/client/preferences/middleware/limbs_and_markings.dm b/modular_skyrat/master_files/code/modules/client/preferences/middleware/limbs_and_markings.dm
index 479265f0cfb..09a174b1ff3 100644
--- a/modular_skyrat/master_files/code/modules/client/preferences/middleware/limbs_and_markings.dm
+++ b/modular_skyrat/master_files/code/modules/client/preferences/middleware/limbs_and_markings.dm
@@ -31,7 +31,9 @@
"stomach" = "Stomach",
"eyes" = "Eyes",
"tongue" = "Tongue",
- "Mouth implant" = "Mouth implant"
+ "Mouth implant" = "Mouth implant",
+ "Left Arm implant" = "Left Arm implant",
+ "Right Arm implant" = "Right Arm implant",
)
var/list/aug_support = list(
diff --git a/modular_skyrat/master_files/code/modules/client/preferences/underwear_color.dm b/modular_skyrat/master_files/code/modules/client/preferences/underwear_color.dm
index a1819c64b3f..f7e5a86d5ea 100644
--- a/modular_skyrat/master_files/code/modules/client/preferences/underwear_color.dm
+++ b/modular_skyrat/master_files/code/modules/client/preferences/underwear_color.dm
@@ -49,3 +49,20 @@
var/datum/species/species = new species_type
return !(TRAIT_NO_UNDERWEAR in species.inherent_traits)
// SKYRAT EDIT ADDITION END - Colorable Undershirt/Socks
+
+
+/datum/preference/color/bra_color
+ savefile_key = "bra_color"
+ savefile_identifier = PREFERENCE_CHARACTER
+ category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES
+
+/datum/preference/color/bra_color/apply_to_human(mob/living/carbon/human/target, value)
+ target.bra_color = value
+
+/datum/preference/color/bra_color/is_accessible(datum/preferences/preferences)
+ if (!..(preferences))
+ return FALSE
+
+ var/species_type = preferences.read_preference(/datum/preference/choiced/species)
+ var/datum/species/species = new species_type
+ return !(TRAIT_NO_UNDERWEAR in species.inherent_traits)
diff --git a/modular_skyrat/master_files/code/modules/client/preferences_savefile.dm b/modular_skyrat/master_files/code/modules/client/preferences_savefile.dm
index 641a5c3537a..f7ffc6fddd6 100644
--- a/modular_skyrat/master_files/code/modules/client/preferences_savefile.dm
+++ b/modular_skyrat/master_files/code/modules/client/preferences_savefile.dm
@@ -3,10 +3,18 @@
* You can't really use the non-modular version, least you eventually want asinine merge
* conflicts and/or potentially disastrous issues to arise, so here's your own.
*/
-#define MODULAR_SAVEFILE_VERSION_MAX 3
+#define MODULAR_SAVEFILE_VERSION_MAX 4
#define MODULAR_SAVEFILE_UP_TO_DATE -1
+#define VERSION_GENITAL_TOGGLES 1
+#define VERSION_BREAST_SIZE_CHANGE 2
+#define VERSION_SYNTH_REFACTOR 3
+#define VERSION_UNDERSHIRT_BRA_SPLIT 4
+
+#define INDEX_UNDERWEAR 1
+#define INDEX_BRA 2
+
/**
* Checks if the modular side of the savefile is up to date.
* If the return value is higher than 0, update_character_skyrat() will be called later.
@@ -16,8 +24,10 @@
if(savefile_version < MODULAR_SAVEFILE_VERSION_MAX)
return savefile_version
+
return MODULAR_SAVEFILE_UP_TO_DATE
+
/// Loads the modular customizations of a character from the savefile
/datum/preferences/proc/load_character_skyrat(list/save_data)
if(!save_data)
@@ -89,9 +99,10 @@
if(needs_update >= 0)
update_character_skyrat(needs_update, save_data) // needs_update == savefile_version if we need an update (positive integer)
+
/// Brings a savefile up to date with modular preferences. Called if savefile_needs_update_skyrat() returned a value higher than 0
/datum/preferences/proc/update_character_skyrat(current_version, list/save_data)
- if(current_version < 1)
+ if(current_version < VERSION_GENITAL_TOGGLES)
// removed genital toggles, with the new choiced prefs paths as assoc
var/static/list/old_toggles
if(!old_toggles)
@@ -114,14 +125,14 @@
for(var/pref_type in subtypesof(/datum/preference/toggle/genital_skin_tone))
write_preference(GLOB.preference_entries[pref_type], TRUE)
- if(current_version < 2)
+ if(current_version < VERSION_BREAST_SIZE_CHANGE)
var/list/old_breast_prefs
old_breast_prefs = save_data["breasts_size"]
if(isnum(old_breast_prefs)) // Can't be too careful
// You weren't meant to be able to pick sizes over this anyways.
write_preference(GLOB.preference_entries[/datum/preference/choiced/breasts_size], GLOB.breast_size_translation["[min(old_breast_prefs, 10)]"])
- if(current_version < 3)
+ if(current_version < VERSION_SYNTH_REFACTOR)
var/old_species = save_data["species"]
if(istext(old_species) && (old_species in list("synthhuman", "synthliz", "synthmammal", "ipc")))
@@ -156,11 +167,99 @@
write_preference(GLOB.preference_entries[/datum/preference/color/mutant/synth_chassis], new_color)
write_preference(GLOB.preference_entries[/datum/preference/color/mutant/synth_head], new_color)
+ if(current_version < VERSION_UNDERSHIRT_BRA_SPLIT)
+ var/static/list/underwear_to_underwear_bra = list(
+ "Panties" = list("Panties - Basic", null), // Just a rename
+ "Bikini" = list("Panties - Slim", "Bra"),
+ "Lace Bikini" = list("Panties - Thin", "Bra - Thin"),
+ "Bralette w/ Boyshorts" = list("Boyshorts (Alt)", "Bra, Sports"),
+ "Sports Bra w/ Boyshorts" = list("Boyshorts", "Bra, Sports - Alt"),
+ "Strapless Bikini" = list("Panties - Slim", "Strapless Swimsuit Top (Alt)"),
+ "Babydoll" = list("Thong - Alt", null), // Got moved to an undershirt, actual underwear part is now a thong.
+ "Two-Piece Swimsuit" = list("Panties - Swimsuit", "Swimsuit Top"),
+ "Strapless Two-Piece Swimsuit" = list("Panties - Swimsuit", "Strapless Swimsuit Top"),
+ "Halter Swimsuit" = list("Panties - Basic", "Bra - Halterneck - (Alt)"),
+ "Neko Bikini (White)" = list("Panties - Neko", "Bra - Neko"),
+ "Neko Bikini (Black)" = list("Panties - Neko", "Bra - Neko"),
+ "UK Biniki" = list("Panties - UK", "Bra - UK"),
+ )
+
+ var/current_underwear = save_data["underwear"]
+ var/migrated_underwear_bra = underwear_to_underwear_bra[current_underwear]
+
+ if(migrated_underwear_bra)
+ var/migrated_color = save_data["underwear_color"]
+ var/migrated_underwear = migrated_underwear_bra[INDEX_UNDERWEAR]
+ var/migrated_bra = migrated_underwear_bra[INDEX_BRA]
+
+ if(migrated_underwear)
+ write_preference(GLOB.preference_entries[/datum/preference/choiced/underwear], migrated_underwear)
+
+ if(migrated_bra)
+ write_preference(GLOB.preference_entries[/datum/preference/choiced/bra], migrated_bra)
+ write_preference(GLOB.preference_entries[/datum/preference/color/bra_color], migrated_color)
+
+ var/current_undershirt = save_data["undershirt"]
+
+ // This one has a different treatment because it's an underwear that has been moved mainly to an undershirt,
+ // ending up as a thong for the underwear part itself. We only want to override the undershirt if there's none,
+ // though.
+ if(current_underwear == "Babydoll" && current_undershirt == "Nude")
+ var/migrated_color = save_data["underwear_color"]
+
+ write_preference(GLOB.preference_entries[/datum/preference/choiced/undershirt], "Babydoll")
+ write_preference(GLOB.preference_entries[/datum/preference/color/undershirt_color], migrated_color)
+
+ var/static/list/undershirt_to_bra = list(
+ "Bra, Sports" = "Bra, Sports",
+ "Sports Bra (Alt)" = "Sports Bra (Alt)",
+ "LIZARED Top" = "LIZARED Top",
+ "Bra" = "Bra",
+ "Bra - Alt" = "Bra - Alt",
+ "Bra - Thin" = "Bra - Thin",
+ "Bra - Kinky Black" = "Bra - Kinky Black",
+ "Bra - Freedom" = "Bra - Freedom",
+ "Bra - Commie" = "Bra - Commie",
+ "Bra - Bee-kini" = "Bra - Bee-kini",
+ "Bra - UK" = "Bra - UK",
+ "Bra - Neko" = "Bra - Neko",
+ "Bra - Halterneck" = "Bra - Halterneck",
+ "Bra - Sports - Alt" = "Bra - Sports - Alt",
+ "Bra - Strapless" = "Bra - Strapless",
+ "Bra - Latex" = "Bra - Latex",
+ "Bra - Striped" = "Bra - Striped",
+ "Bra - Sarashi" = "Bra - Sarashi",
+ "Fishnet - Sleeved" = "Fishnet - Sleeved",
+ "Fishnet - Sleeved (Greyscaled)" = "Fishnet - Sleeved (Greyscaled)",
+ "Fishnet - Sleeveless" = "Fishnet - Sleeveless",
+ "Fishnet - Sleeveless (Greyscaled)" = "Fishnet - Sleeveless (Greyscaled)",
+ "Swimsuit Top" = "Bra - Halterneck - (Alt)",
+ "Chastity Bra" = "Chastity Bra",
+ "Pasties" = "Pasties",
+ "Pasties - Alt" = "Pasties - Alt",
+ "Shibari" = "Shibari",
+ "Shibari Sleeves" = "Shibari Sleeves",
+ "Binder" = "Binder",
+ "Binder - Strapless" = "Binder - Strapless",
+ "Safekini" = "Safekini",
+ )
+
+ var/migrated_bra_from_undershirt = undershirt_to_bra[current_undershirt]
+
+ if(migrated_bra_from_undershirt)
+ var/migrated_color = save_data["undershirt_color"]
+
+ write_preference(GLOB.preference_entries[/datum/preference/choiced/bra], migrated_bra_from_undershirt)
+ write_preference(GLOB.preference_entries[/datum/preference/color/bra_color], migrated_color)
+ write_preference(GLOB.preference_entries[/datum/preference/choiced/undershirt], "Nude")
+
+
/datum/preferences/proc/check_migration()
if(!tgui_prefs_migration)
to_chat(parent, examine_block(span_redtext("CRITICAL FAILURE IN PREFERENCE MIGRATION, REPORT THIS IMMEDIATELY.")))
message_admins("PREFERENCE MIGRATION: [ADMIN_LOOKUPFLW(parent)] has failed the process for migrating PREFERENCES. Check runtimes.")
+
/// Saves the modular customizations of a character on the savefile
/datum/preferences/proc/save_character_skyrat(list/save_data)
save_data["loadout_list"] = loadout_list
@@ -176,6 +275,7 @@
save_data["headshot"] = headshot
save_data["modular_version"] = MODULAR_SAVEFILE_VERSION_MAX
+
/datum/preferences/proc/update_mutant_bodyparts(datum/preference/preference)
if (!preference.relevant_mutant_bodypart)
return
@@ -202,6 +302,7 @@
if (part in mutant_bodyparts)
mutant_bodyparts[part][MUTANT_INDEX_COLOR_LIST] = value
+
/datum/preferences/proc/update_markings(list/markings)
if (islist(markings))
for (var/marking in markings)
@@ -210,5 +311,11 @@
markings[marking][title] = list(sanitize_hexcolor(markings[marking][title]), FALSE)
return markings
+
#undef MODULAR_SAVEFILE_VERSION_MAX
#undef MODULAR_SAVEFILE_UP_TO_DATE
+
+#undef VERSION_GENITAL_TOGGLES
+#undef VERSION_BREAST_SIZE_CHANGE
+#undef VERSION_SYNTH_REFACTOR
+#undef VERSION_UNDERSHIRT_BRA_SPLIT
diff --git a/modular_skyrat/master_files/code/modules/clothing/clothing_variation_overrides/suit.dm b/modular_skyrat/master_files/code/modules/clothing/clothing_variation_overrides/suit.dm
index 54a180753a7..4c2c440c200 100644
--- a/modular_skyrat/master_files/code/modules/clothing/clothing_variation_overrides/suit.dm
+++ b/modular_skyrat/master_files/code/modules/clothing/clothing_variation_overrides/suit.dm
@@ -28,7 +28,7 @@
/obj/item/clothing/suit/jacket
supports_variations_flags = CLOTHING_DIGITIGRADE_VARIATION_NO_NEW_ICON
-/obj/item/clothing/suit/costume/ianshirt
+/obj/item/clothing/suit/costume/wellworn_shirt
supports_variations_flags = CLOTHING_DIGITIGRADE_VARIATION_NO_NEW_ICON
/obj/item/clothing/suit/costume/poncho
diff --git a/modular_skyrat/master_files/code/modules/clothing/towels.dm b/modular_skyrat/master_files/code/modules/clothing/towels.dm
index 5dafa97188c..051c367ff64 100644
--- a/modular_skyrat/master_files/code/modules/clothing/towels.dm
+++ b/modular_skyrat/master_files/code/modules/clothing/towels.dm
@@ -449,7 +449,7 @@
if(!amount)
return
- reagents.trans_to(target, amount * (1 - loss_factor), no_react = TRUE, transfered_by = user)
+ reagents.trans_to(target, amount * (1 - loss_factor), no_react = TRUE, transferred_by = user)
if(loss_factor && reagents.total_volume)
reagents.remove_any(amount * loss_factor)
@@ -483,7 +483,7 @@
if(!amount)
return
- source.trans_to(reagents, amount, no_react = TRUE, transfered_by = user)
+ source.trans_to(reagents, amount, no_react = TRUE, transferred_by = user)
if(!wet)
set_wet(TRUE, !make_used || shape == TOWEL_USED)
diff --git a/modular_skyrat/master_files/code/modules/clothing/under/jobs/cargo.dm b/modular_skyrat/master_files/code/modules/clothing/under/jobs/cargo.dm
index adbbbd0dc5b..8fe26c3b342 100644
--- a/modular_skyrat/master_files/code/modules/clothing/under/jobs/cargo.dm
+++ b/modular_skyrat/master_files/code/modules/clothing/under/jobs/cargo.dm
@@ -103,7 +103,7 @@
/obj/item/clothing/under/rank/cargo/qm/skyrat/formal/skirt
name = "quartermaster's formal jumpskirt"
desc = "A western-like alternate uniform for the old fashioned QM. Skirt included!"
- icon_state = "supply_chief"
+ icon_state = "supply_chief_skirt"
can_adjust = FALSE
body_parts_covered = CHEST|GROIN|ARMS
dying_key = DYE_REGISTRY_JUMPSKIRT
diff --git a/modular_skyrat/master_files/code/modules/clothing/under/shorts_pants.dm b/modular_skyrat/master_files/code/modules/clothing/under/shorts_pants.dm
index 2a1ddaea65d..3bc3d7c2a7b 100644
--- a/modular_skyrat/master_files/code/modules/clothing/under/shorts_pants.dm
+++ b/modular_skyrat/master_files/code/modules/clothing/under/shorts_pants.dm
@@ -68,6 +68,16 @@
greyscale_colors = "#787878#723E0E#202020"
flags_1 = IS_PLAYER_COLORABLE_1
+/obj/item/clothing/under/shorts/skyrat/shortershorts
+ name = "shorter shorts"
+ desc = "Show those legs off with these even shorter shorts!"
+ icon_state = "shortershorts"
+ greyscale_config = /datum/greyscale_config/shortershorts
+ greyscale_config_worn = /datum/greyscale_config/shortershorts/worn
+ greyscale_config_worn_digi = /datum/greyscale_config/shortershorts/worn/digi
+ greyscale_colors = "#787878#723E0E#202020"
+ flags_1 = IS_PLAYER_COLORABLE_1
+
/*
* MISC (Technically belongs in this file as a shorts/pants/shirt combo)
* Here's hoping TG gives these their own typepath, but for now this is gonna be under/pants/skyrat. No, it's not all pants, but it's better than a whole new type
diff --git a/modular_skyrat/master_files/code/modules/mapfluff/ruins/spaceruin_code/oldstation/oldstation_cytology.dm b/modular_skyrat/master_files/code/modules/mapfluff/ruins/spaceruin_code/oldstation/oldstation_cytology.dm
new file mode 100644
index 00000000000..d9c10dce112
--- /dev/null
+++ b/modular_skyrat/master_files/code/modules/mapfluff/ruins/spaceruin_code/oldstation/oldstation_cytology.dm
@@ -0,0 +1,3 @@
+// Beakers capacity 50u -> 60u
+/obj/item/reagent_containers/cup/beaker/oldstation
+ amount_per_transfer_from_this = 60
diff --git a/modular_skyrat/master_files/code/modules/mob/dead/new_player/preferences_setup.dm b/modular_skyrat/master_files/code/modules/mob/dead/new_player/preferences_setup.dm
index 180f6081277..c2b04c99382 100644
--- a/modular_skyrat/master_files/code/modules/mob/dead/new_player/preferences_setup.dm
+++ b/modular_skyrat/master_files/code/modules/mob/dead/new_player/preferences_setup.dm
@@ -23,14 +23,14 @@
if(PREVIEW_PREF_UNDERWEAR)
mannequin.underwear_visibility = NONE
if(PREVIEW_PREF_NAKED)
- mannequin.underwear_visibility = UNDERWEAR_HIDE_UNDIES | UNDERWEAR_HIDE_SHIRT | UNDERWEAR_HIDE_SOCKS
+ mannequin.underwear_visibility = UNDERWEAR_HIDE_UNDIES | UNDERWEAR_HIDE_SHIRT | UNDERWEAR_HIDE_SOCKS | UNDERWEAR_HIDE_BRA
for(var/organ_key in list(ORGAN_SLOT_VAGINA, ORGAN_SLOT_PENIS, ORGAN_SLOT_BREASTS, ORGAN_SLOT_ANUS))
var/obj/item/organ/external/genital/gent = mannequin.get_organ_slot(organ_key)
if(gent)
gent.aroused = AROUSAL_NONE
gent.update_sprite_suffix()
if(PREVIEW_PREF_NAKED_AROUSED)
- mannequin.underwear_visibility = UNDERWEAR_HIDE_UNDIES | UNDERWEAR_HIDE_SHIRT | UNDERWEAR_HIDE_SOCKS
+ mannequin.underwear_visibility = UNDERWEAR_HIDE_UNDIES | UNDERWEAR_HIDE_SHIRT | UNDERWEAR_HIDE_SOCKS | UNDERWEAR_HIDE_BRA
for(var/organ_key in list(ORGAN_SLOT_VAGINA, ORGAN_SLOT_PENIS, ORGAN_SLOT_BREASTS, ORGAN_SLOT_ANUS))
var/obj/item/organ/external/genital/gent = mannequin.get_organ_slot(organ_key)
if(gent)
diff --git a/modular_skyrat/master_files/code/modules/mob/living/carbon/human/species_type/snail.dm b/modular_skyrat/master_files/code/modules/mob/living/carbon/human/species_type/snail.dm
index 7ce026550b9..d6ae6c5a103 100644
--- a/modular_skyrat/master_files/code/modules/mob/living/carbon/human/species_type/snail.dm
+++ b/modular_skyrat/master_files/code/modules/mob/living/carbon/human/species_type/snail.dm
@@ -3,6 +3,7 @@
/obj/item/storage/backpack/snail
/// Whether or not a bluespace anomaly core has been inserted
var/storage_core = FALSE
+ obj_flags = IMMUTABLE_SLOW
/obj/item/storage/backpack/snail/Initialize(mapload)
. = ..()
diff --git a/modular_skyrat/master_files/code/modules/mob/living/carbon/human_helpers.dm b/modular_skyrat/master_files/code/modules/mob/living/carbon/human_helpers.dm
index 4cffb1a2045..d7b16d45d49 100644
--- a/modular_skyrat/master_files/code/modules/mob/living/carbon/human_helpers.dm
+++ b/modular_skyrat/master_files/code/modules/mob/living/carbon/human_helpers.dm
@@ -4,7 +4,14 @@
var/t_He = p_They()
var/t_is = p_are()
//This checks to see if the body is revivable
- if(key || !get_organ_by_type(/obj/item/organ/internal/brain) || ghost?.can_reenter_corpse)
+ if((key || !get_organ_by_type(/obj/item/organ/internal/brain) || ghost?.can_reenter_corpse) && (!HAS_TRAIT(src, TRAIT_DNR)))
return span_deadsay("[t_He] [t_is] limp and unresponsive; they're still twitching on occasion, perhaps [p_they()] can still be saved..!")
else
return span_deadsay("[t_He] [t_is] limp and unresponsive; there are no signs of life and they've degraded beyond revival...")
+
+///copies over clothing preferences like underwear to another human
+/mob/living/carbon/human/copy_clothing_prefs(mob/living/carbon/human/destination)
+ . = ..()
+
+ destination.bra = bra
+ destination.bra_color = bra_color
diff --git a/modular_skyrat/master_files/code/modules/religion/religious_sects.dm b/modular_skyrat/master_files/code/modules/religion/religious_sects.dm
index e7b718b485a..1a465d8421e 100644
--- a/modular_skyrat/master_files/code/modules/religion/religious_sects.dm
+++ b/modular_skyrat/master_files/code/modules/religion/religious_sects.dm
@@ -2,7 +2,7 @@
/datum/religion_sect/on_select()
. = ..()
-
+
// if the same religious sect gets selected, carry the favor over
if(istype(src, GLOB.prev_sect_type))
set_favor(GLOB.prev_favor)
@@ -25,10 +25,8 @@
GLOB.prev_favor = GLOB.religious_sect.favor
GLOB.prev_sect_type = GLOB.religious_sect.type
- // set the altar references to the old religious_sect to null
- for(var/obj/structure/altar_of_gods/altar in GLOB.chaplain_altars)
- altar.GetComponent(/datum/component/religious_tool).easy_access_sect = null
- altar.sect_to_altar = null
+ // set the altar references to the old religious_sect to null
+ SEND_GLOBAL_SIGNAL(COMSIG_RELIGIOUS_SECT_RESET)
QDEL_NULL(GLOB.religious_sect) // queue for removal but also set it to null, in case a new chaplain joins before it can be deleted
diff --git a/modular_skyrat/master_files/code/modules/research/designs/tool_designs.dm b/modular_skyrat/master_files/code/modules/research/designs/tool_designs.dm
index 9951c2bebe5..44c01471845 100644
--- a/modular_skyrat/master_files/code/modules/research/designs/tool_designs.dm
+++ b/modular_skyrat/master_files/code/modules/research/designs/tool_designs.dm
@@ -1,2 +1,5 @@
/datum/design/rpd
departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_CARGO
+
+/datum/design/exwelder
+ departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_SCIENCE
diff --git a/modular_skyrat/master_files/code/modules/research/techweb/all_nodes.dm b/modular_skyrat/master_files/code/modules/research/techweb/all_nodes.dm
index 357e4b6497e..e263c4062c7 100644
--- a/modular_skyrat/master_files/code/modules/research/techweb/all_nodes.dm
+++ b/modular_skyrat/master_files/code/modules/research/techweb/all_nodes.dm
@@ -112,6 +112,7 @@
"nifsoft_money_sense",
"nifsoft_hud_kit",
"nifsoft_hud_science",
+ "nifsoft_hud_meson",
"nifsoft_hud_medical",
"nifsoft_hud_security",
"nifsoft_hud_diagnostic",
diff --git a/modular_skyrat/master_files/code/modules/surgery/organs/internal/appendix/_appendix.dm b/modular_skyrat/master_files/code/modules/surgery/organs/internal/appendix/_appendix.dm
new file mode 100644
index 00000000000..296696d559f
--- /dev/null
+++ b/modular_skyrat/master_files/code/modules/surgery/organs/internal/appendix/_appendix.dm
@@ -0,0 +1,8 @@
+/obj/item/organ/internal/appendix/become_inflamed()
+ if(engaged_role_play_check(owner, station = TRUE, dorms = TRUE))
+ return
+
+ if(!(owner.mind.assigned_role.job_flags & JOB_CREW_MEMBER))
+ return
+
+ ..()
diff --git a/modular_skyrat/master_files/icons/hud/actions.dmi b/modular_skyrat/master_files/icons/hud/actions.dmi
new file mode 100644
index 00000000000..32da90c1cf8
Binary files /dev/null and b/modular_skyrat/master_files/icons/hud/actions.dmi differ
diff --git a/modular_skyrat/master_files/icons/mob/clothing/head/cowboy.dmi b/modular_skyrat/master_files/icons/mob/clothing/head/cowboy.dmi
index 835a46c9d16..94d19052982 100644
Binary files a/modular_skyrat/master_files/icons/mob/clothing/head/cowboy.dmi and b/modular_skyrat/master_files/icons/mob/clothing/head/cowboy.dmi differ
diff --git a/modular_skyrat/master_files/icons/mob/clothing/head/winterhood.dmi b/modular_skyrat/master_files/icons/mob/clothing/head/winterhood.dmi
index 114c9524dcb..f4d68afba7b 100644
Binary files a/modular_skyrat/master_files/icons/mob/clothing/head/winterhood.dmi and b/modular_skyrat/master_files/icons/mob/clothing/head/winterhood.dmi differ
diff --git a/modular_skyrat/master_files/icons/mob/clothing/neck.dmi b/modular_skyrat/master_files/icons/mob/clothing/neck.dmi
index e7de4f6035c..3e29bf945b9 100644
Binary files a/modular_skyrat/master_files/icons/mob/clothing/neck.dmi and b/modular_skyrat/master_files/icons/mob/clothing/neck.dmi differ
diff --git a/modular_skyrat/master_files/icons/mob/clothing/species/teshari/head.dmi b/modular_skyrat/master_files/icons/mob/clothing/species/teshari/head.dmi
index 16ef5634cbc..900c81bafef 100644
Binary files a/modular_skyrat/master_files/icons/mob/clothing/species/teshari/head.dmi and b/modular_skyrat/master_files/icons/mob/clothing/species/teshari/head.dmi differ
diff --git a/modular_skyrat/master_files/icons/mob/clothing/species/teshari/suit.dmi b/modular_skyrat/master_files/icons/mob/clothing/species/teshari/suit.dmi
index 69ebd3cbd16..e4db1a1654e 100644
Binary files a/modular_skyrat/master_files/icons/mob/clothing/species/teshari/suit.dmi and b/modular_skyrat/master_files/icons/mob/clothing/species/teshari/suit.dmi differ
diff --git a/modular_skyrat/master_files/icons/mob/clothing/suit.dmi b/modular_skyrat/master_files/icons/mob/clothing/suit.dmi
index cf43274be05..c00b68f50cf 100644
Binary files a/modular_skyrat/master_files/icons/mob/clothing/suit.dmi and b/modular_skyrat/master_files/icons/mob/clothing/suit.dmi differ
diff --git a/modular_skyrat/master_files/icons/mob/clothing/suit_digi.dmi b/modular_skyrat/master_files/icons/mob/clothing/suit_digi.dmi
index a873d24de49..1f6b935b5f0 100644
Binary files a/modular_skyrat/master_files/icons/mob/clothing/suit_digi.dmi and b/modular_skyrat/master_files/icons/mob/clothing/suit_digi.dmi differ
diff --git a/modular_skyrat/master_files/icons/mob/clothing/suits/armor.dmi b/modular_skyrat/master_files/icons/mob/clothing/suits/armor.dmi
index a2e03058d33..199a17cdbb2 100644
Binary files a/modular_skyrat/master_files/icons/mob/clothing/suits/armor.dmi and b/modular_skyrat/master_files/icons/mob/clothing/suits/armor.dmi differ
diff --git a/modular_skyrat/master_files/icons/mob/clothing/suits/wintercoat.dmi b/modular_skyrat/master_files/icons/mob/clothing/suits/wintercoat.dmi
index e30e4eedd7c..11e61ac81d7 100644
Binary files a/modular_skyrat/master_files/icons/mob/clothing/suits/wintercoat.dmi and b/modular_skyrat/master_files/icons/mob/clothing/suits/wintercoat.dmi differ
diff --git a/modular_skyrat/master_files/icons/mob/clothing/under/cargo.dmi b/modular_skyrat/master_files/icons/mob/clothing/under/cargo.dmi
index 66e60c5c3c0..9a8042cf0a0 100644
Binary files a/modular_skyrat/master_files/icons/mob/clothing/under/cargo.dmi and b/modular_skyrat/master_files/icons/mob/clothing/under/cargo.dmi differ
diff --git a/modular_skyrat/master_files/icons/mob/clothing/under/cargo_digi.dmi b/modular_skyrat/master_files/icons/mob/clothing/under/cargo_digi.dmi
index eaba4d79fd3..c4ecb9e4f81 100644
Binary files a/modular_skyrat/master_files/icons/mob/clothing/under/cargo_digi.dmi and b/modular_skyrat/master_files/icons/mob/clothing/under/cargo_digi.dmi differ
diff --git a/modular_skyrat/master_files/icons/mob/clothing/under/shorts_pants_shirts_digi.dmi b/modular_skyrat/master_files/icons/mob/clothing/under/shorts_pants_shirts_digi.dmi
index 8d0800f7eea..11f4729aa7c 100644
Binary files a/modular_skyrat/master_files/icons/mob/clothing/under/shorts_pants_shirts_digi.dmi and b/modular_skyrat/master_files/icons/mob/clothing/under/shorts_pants_shirts_digi.dmi differ
diff --git a/modular_skyrat/master_files/icons/mob/clothing/underwear.dmi b/modular_skyrat/master_files/icons/mob/clothing/underwear.dmi
index bb41c5562b6..3d9209905cb 100644
Binary files a/modular_skyrat/master_files/icons/mob/clothing/underwear.dmi and b/modular_skyrat/master_files/icons/mob/clothing/underwear.dmi differ
diff --git a/modular_skyrat/master_files/icons/mob/sprite_accessory/ears_big.dmi b/modular_skyrat/master_files/icons/mob/sprite_accessory/ears_big.dmi
index 90c9cf72d6d..5970f25bdd1 100644
Binary files a/modular_skyrat/master_files/icons/mob/sprite_accessory/ears_big.dmi and b/modular_skyrat/master_files/icons/mob/sprite_accessory/ears_big.dmi differ
diff --git a/modular_skyrat/master_files/icons/mob/sprite_accessory/hair.dmi b/modular_skyrat/master_files/icons/mob/sprite_accessory/hair.dmi
index dacee92debd..fdfc3fee1c8 100644
Binary files a/modular_skyrat/master_files/icons/mob/sprite_accessory/hair.dmi and b/modular_skyrat/master_files/icons/mob/sprite_accessory/hair.dmi differ
diff --git a/modular_skyrat/master_files/icons/mob/sprite_accessory/snouts.dmi b/modular_skyrat/master_files/icons/mob/sprite_accessory/snouts.dmi
index 82f452b2283..2774799dda4 100644
Binary files a/modular_skyrat/master_files/icons/mob/sprite_accessory/snouts.dmi and b/modular_skyrat/master_files/icons/mob/sprite_accessory/snouts.dmi differ
diff --git a/modular_skyrat/master_files/icons/obj/clothing/head/cowboy.dmi b/modular_skyrat/master_files/icons/obj/clothing/head/cowboy.dmi
index bd26b776ee5..fb582bf495c 100644
Binary files a/modular_skyrat/master_files/icons/obj/clothing/head/cowboy.dmi and b/modular_skyrat/master_files/icons/obj/clothing/head/cowboy.dmi differ
diff --git a/modular_skyrat/master_files/icons/obj/clothing/head/helmet.dmi b/modular_skyrat/master_files/icons/obj/clothing/head/helmet.dmi
index 3141957fbc8..b3e07e13411 100644
Binary files a/modular_skyrat/master_files/icons/obj/clothing/head/helmet.dmi and b/modular_skyrat/master_files/icons/obj/clothing/head/helmet.dmi differ
diff --git a/modular_skyrat/master_files/icons/obj/clothing/suits.dmi b/modular_skyrat/master_files/icons/obj/clothing/suits.dmi
index e2a568e2c91..45b23619f89 100644
Binary files a/modular_skyrat/master_files/icons/obj/clothing/suits.dmi and b/modular_skyrat/master_files/icons/obj/clothing/suits.dmi differ
diff --git a/modular_skyrat/master_files/icons/obj/clothing/suits/armor.dmi b/modular_skyrat/master_files/icons/obj/clothing/suits/armor.dmi
index 9b32189459f..a3274e254b1 100644
Binary files a/modular_skyrat/master_files/icons/obj/clothing/suits/armor.dmi and b/modular_skyrat/master_files/icons/obj/clothing/suits/armor.dmi differ
diff --git a/modular_skyrat/master_files/icons/obj/clothing/under/cargo.dmi b/modular_skyrat/master_files/icons/obj/clothing/under/cargo.dmi
index bc6d0043e13..fccbf88fbc9 100644
Binary files a/modular_skyrat/master_files/icons/obj/clothing/under/cargo.dmi and b/modular_skyrat/master_files/icons/obj/clothing/under/cargo.dmi differ
diff --git a/modular_skyrat/master_files/icons/obj/clothing/under/shorts_pants_shirts.dmi b/modular_skyrat/master_files/icons/obj/clothing/under/shorts_pants_shirts.dmi
index 619b0246b24..d82f9b63e17 100644
Binary files a/modular_skyrat/master_files/icons/obj/clothing/under/shorts_pants_shirts.dmi and b/modular_skyrat/master_files/icons/obj/clothing/under/shorts_pants_shirts.dmi differ
diff --git a/modular_skyrat/master_files/icons/obj/kitchen.dmi b/modular_skyrat/master_files/icons/obj/kitchen.dmi
new file mode 100644
index 00000000000..2329e8dee79
Binary files /dev/null and b/modular_skyrat/master_files/icons/obj/kitchen.dmi differ
diff --git a/modular_skyrat/master_files/icons/obj/plushes.dmi b/modular_skyrat/master_files/icons/obj/plushes.dmi
index ec7f41d048d..5dbd054159a 100644
Binary files a/modular_skyrat/master_files/icons/obj/plushes.dmi and b/modular_skyrat/master_files/icons/obj/plushes.dmi differ
diff --git a/modular_skyrat/master_files/sound/effects/flashlight.ogg b/modular_skyrat/master_files/sound/effects/flashlight.ogg
deleted file mode 100644
index 627675997cf..00000000000
Binary files a/modular_skyrat/master_files/sound/effects/flashlight.ogg and /dev/null differ
diff --git a/modular_skyrat/modules/GAGS/greyscale_configs.dm b/modular_skyrat/modules/GAGS/greyscale_configs.dm
index d560d196031..36870626d5d 100644
--- a/modular_skyrat/modules/GAGS/greyscale_configs.dm
+++ b/modular_skyrat/modules/GAGS/greyscale_configs.dm
@@ -740,6 +740,19 @@
name = "Jean Shorts (Worn, Digi)"
icon_file = SHORTS_PANTS_SHIRTS_DIGIFILE
+/datum/greyscale_config/shortershorts
+ name = "Shorter Shorts"
+ icon_file = 'modular_skyrat/modules/GAGS/icons/shorts_pants.dmi'
+ json_config = 'modular_skyrat/modules/GAGS/json_configs/pants_shorts_skirts_dresses/shortershorts.json'
+
+/datum/greyscale_config/shortershorts/worn
+ name = "Shorter Shorts (Worn)"
+ icon_file = 'modular_skyrat/modules/GAGS/icons/shorts_pants.dmi'
+
+/datum/greyscale_config/shortershorts/worn/digi
+ name = "Ripped Shorts (Worn, Digi)"
+ icon_file = SHORTS_PANTS_SHIRTS_DIGIFILE
+
/datum/greyscale_config/shorts_ripped
name = "Ripped Shorts"
icon_file = 'modular_skyrat/master_files/icons/obj/clothing/under/shorts_pants_shirts.dmi'
diff --git a/modular_skyrat/modules/GAGS/icons/shorts_pants.dmi b/modular_skyrat/modules/GAGS/icons/shorts_pants.dmi
index c4427049f06..97a799c0f0c 100644
Binary files a/modular_skyrat/modules/GAGS/icons/shorts_pants.dmi and b/modular_skyrat/modules/GAGS/icons/shorts_pants.dmi differ
diff --git a/modular_skyrat/modules/GAGS/json_configs/pants_shorts_skirts_dresses/shortershorts.json b/modular_skyrat/modules/GAGS/json_configs/pants_shorts_skirts_dresses/shortershorts.json
new file mode 100644
index 00000000000..0058e310800
--- /dev/null
+++ b/modular_skyrat/modules/GAGS/json_configs/pants_shorts_skirts_dresses/shortershorts.json
@@ -0,0 +1,22 @@
+{
+ "shortershorts": [
+ {
+ "type": "icon_state",
+ "icon_state": "buckle",
+ "blend_mode": "overlay",
+ "color_ids": [ 1 ]
+ },
+ {
+ "type": "icon_state",
+ "icon_state": "belt",
+ "blend_mode": "overlay",
+ "color_ids": [ 2 ]
+ },
+ {
+ "type": "icon_state",
+ "icon_state": "shortershorts",
+ "blend_mode": "overlay",
+ "color_ids": [ 3 ]
+ }
+ ]
+}
diff --git a/modular_skyrat/modules/advanced_shuttles/code/shuttles.dm b/modular_skyrat/modules/advanced_shuttles/code/shuttles.dm
index c6ed394a8e4..6d8d62d9a75 100644
--- a/modular_skyrat/modules/advanced_shuttles/code/shuttles.dm
+++ b/modular_skyrat/modules/advanced_shuttles/code/shuttles.dm
@@ -1,3 +1,7 @@
+#define ARRIVALS_STATION "arrivals_stationary"
+#define ARRIVALS_INTERLINK "arrivals_shuttle"
+#define CONSOLE_ANNOUNCE_COOLDOWN 5 SECONDS
+
/obj/docking_port/mobile/arrivals_skyrat
name = "NTV Relay"
shuttle_id = "arrivals_shuttle"
@@ -10,6 +14,76 @@
movement_force = list("KNOCKDOWN" = 3, "THROW" = 0)
+ ///Our shuttle's control console
+ var/obj/machinery/computer/shuttle/arrivals/console
+ ///How much time are we waiting before returning to interlink. Sets itself automatically from config file
+ var/wait_time
+ ///State variable. True when our shuttle is waiting before autoreturn
+ var/waiting = FALSE // would've been better to use shuttle's mode variable, but check() resets it to SHUTTLE_IDLE so it's more sane way to make this fully modular
+
+/obj/docking_port/mobile/arrivals_skyrat/Initialize(mapload)
+ . = ..()
+ wait_time = CONFIG_GET(number/arrivals_wait)
+ return INITIALIZE_HINT_LATELOAD
+
+/obj/docking_port/mobile/arrivals_skyrat/LateInitialize()
+ . = ..()
+ console = get_control_console()
+
+/obj/docking_port/mobile/arrivals_skyrat/check()
+ . = ..()
+
+ if(!wait_time) //0 disables autoreturn
+ return
+
+ if(mode != SHUTTLE_IDLE)
+ return
+
+ if(waiting && !timer)
+ SSshuttle.moveShuttle(shuttle_id, ARRIVALS_INTERLINK, TRUE) // times up, we're leaving
+ waiting = FALSE
+
+ var/current_dock = getDockedId()
+ if (current_dock != ARRIVALS_STATION)
+ return
+
+ if(check_occupied())
+ if(!waiting)
+ return
+
+ timer = 0
+ waiting = FALSE
+
+ if(console && console.last_cancel_announce + CONSOLE_ANNOUNCE_COOLDOWN <= world.time)
+ console.say("Lifesigns detected onboard, automatic return aborted.")
+ console.last_cancel_announce = world.time
+
+ return
+
+ if(timer || waiting)
+ return
+
+ setTimer(wait_time)
+ waiting = TRUE
+
+ if(console && console.last_depart_announce + CONSOLE_ANNOUNCE_COOLDOWN <= world.time)
+ console.say("Commencing automatic return subroutine in [wait_time / 10] seconds.")
+ console.last_depart_announce = world.time
+
+/obj/docking_port/mobile/arrivals_skyrat/getModeStr()
+ . = ..()
+ return waiting ? "RTN" : .
+
+/**
+ * Checks if our shuttle is occupied by someone alive, and returns `TRUE` if it is, `FALSE` otherwise.
+*/
+/obj/docking_port/mobile/arrivals_skyrat/proc/check_occupied()
+ for(var/alive_player in GLOB.alive_player_list)
+ if (get_area(alive_player) in shuttle_areas)
+ return TRUE
+
+ return FALSE
+
/obj/machinery/computer/shuttle/arrivals
name = "arrivals shuttle control"
desc = "The terminal used to control the arrivals interlink shuttle."
@@ -24,6 +98,11 @@
connectable = FALSE //connecting_computer change: since icon_state is not a typical console, it cannot be connectable.
no_destination_swap = TRUE
+ ///[world.time] when console last announced departure
+ var/last_depart_announce
+ ///[world.time] when console last announced canceling shuttle's return
+ var/last_cancel_announce
+
/obj/machinery/computer/shuttle/arrivals/recall
name = "arrivals shuttle recall terminal"
desc = "Use this if your friends left you behind."
@@ -96,3 +175,7 @@
/datum/map_template/shuttle/mining/skyrat/large
name = "NMC Manticore (Mining)"
suffix = "large_skyrat"
+
+#undef ARRIVALS_STATION
+#undef ARRIVALS_INTERLINK
+#undef CONSOLE_ANNOUNCE_COOLDOWN
diff --git a/modular_skyrat/modules/aesthetics/rollerbed/code/rollerbed.dm b/modular_skyrat/modules/aesthetics/rollerbed/code/rollerbed.dm
deleted file mode 100644
index b13a0657138..00000000000
--- a/modular_skyrat/modules/aesthetics/rollerbed/code/rollerbed.dm
+++ /dev/null
@@ -1,5 +0,0 @@
-/obj/structure/bed/roller
- icon = 'modular_skyrat/modules/aesthetics/rollerbed/icons/rollerbed.dmi'
-
-/obj/item/roller
- icon = 'modular_skyrat/modules/aesthetics/rollerbed/icons/rollerbed.dmi'
diff --git a/modular_skyrat/modules/aesthetics/rollerbed/icons/rollerbed.dmi b/modular_skyrat/modules/aesthetics/rollerbed/icons/rollerbed.dmi
deleted file mode 100644
index 08d9996cad8..00000000000
Binary files a/modular_skyrat/modules/aesthetics/rollerbed/icons/rollerbed.dmi and /dev/null differ
diff --git a/modular_skyrat/modules/aesthetics/status_display/icons/status_display.dmi b/modular_skyrat/modules/aesthetics/status_display/icons/status_display.dmi
index 4a7b2956981..bfb794df356 100644
Binary files a/modular_skyrat/modules/aesthetics/status_display/icons/status_display.dmi and b/modular_skyrat/modules/aesthetics/status_display/icons/status_display.dmi differ
diff --git a/modular_skyrat/modules/alerts/code/default_announcer.dm b/modular_skyrat/modules/alerts/code/default_announcer.dm
index c1b1a75889b..7ae320f01f8 100644
--- a/modular_skyrat/modules/alerts/code/default_announcer.dm
+++ b/modular_skyrat/modules/alerts/code/default_announcer.dm
@@ -44,4 +44,6 @@
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/altborgs/code/robot_model.dm b/modular_skyrat/modules/altborgs/code/robot_model.dm
index 182e9a1b0fb..2bb54d1f503 100644
--- a/modular_skyrat/modules/altborgs/code/robot_model.dm
+++ b/modular_skyrat/modules/altborgs/code/robot_model.dm
@@ -427,7 +427,7 @@
/obj/item/retractor/advanced,
/obj/item/cautery/advanced,
/obj/item/scalpel/advanced,
- /obj/item/roller/robo,
+ /obj/item/emergency_bed/silicon,
/obj/item/card/emag,
/obj/item/crowbar/cyborg,
/obj/item/extinguisher/mini,
diff --git a/modular_skyrat/modules/alternative_job_titles/code/alt_job_titles.dm b/modular_skyrat/modules/alternative_job_titles/code/alt_job_titles.dm
index e62c81552d5..d7abb4e00f0 100644
--- a/modular_skyrat/modules/alternative_job_titles/code/alt_job_titles.dm
+++ b/modular_skyrat/modules/alternative_job_titles/code/alt_job_titles.dm
@@ -300,6 +300,7 @@
/datum/job/quartermaster
alt_titles = list(
+ "Quartermaster",
"Union Requisitions Officer",
"Deck Chief",
"Warehouse Supervisor",
diff --git a/modular_skyrat/modules/ashwalkers/code/buildings/fuelwell.dm b/modular_skyrat/modules/ashwalkers/code/buildings/fuelwell.dm
index acfbee550ad..0203a636230 100644
--- a/modular_skyrat/modules/ashwalkers/code/buildings/fuelwell.dm
+++ b/modular_skyrat/modules/ashwalkers/code/buildings/fuelwell.dm
@@ -44,7 +44,7 @@
if(W.reagents.has_reagent(/datum/reagent/fuel, W.max_fuel))
to_chat(user, span_warning("Your [W.name] is already full!"))
return
- reagents.trans_to(W, W.max_fuel, transfered_by = user)
+ reagents.trans_to(W, W.max_fuel, transferred_by = user)
user.visible_message(span_notice("[user] refills [user.p_their()] [W.name]."), span_notice("You refill [W]."))
playsound(src, 'sound/effects/refill.ogg', 50, TRUE)
W.update_appearance()
diff --git a/modular_skyrat/modules/ashwalkers/code/effects/ash_rituals.dm b/modular_skyrat/modules/ashwalkers/code/effects/ash_rituals.dm
index b49156bd0a1..e34a414cf8e 100644
--- a/modular_skyrat/modules/ashwalkers/code/effects/ash_rituals.dm
+++ b/modular_skyrat/modules/ashwalkers/code/effects/ash_rituals.dm
@@ -174,7 +174,7 @@
var/mob_type = pick(
/mob/living/basic/mining/goliath,
/mob/living/simple_animal/hostile/asteroid/hivelord/legion,
- /mob/living/simple_animal/hostile/asteroid/brimdemon,
+ /mob/living/basic/mining/brimdemon,
/mob/living/basic/mining/watcher,
/mob/living/basic/mining/lobstrosity/lava,
)
@@ -331,23 +331,47 @@
/datum/ash_ritual/revive_animal/ritual_success(obj/effect/ash_rune/success_rune)
. = ..()
+ if(!revive_simple(success_rune))
+ revive_basic(success_rune)
+
+/datum/ash_ritual/revive_animal/proc/revive_simple(obj/effect/ash_rune/success_rune)
var/turf/src_turf = get_turf(success_rune)
var/mob/living/simple_animal/find_animal = locate() in src_turf
if(!find_animal)
- return
+ return FALSE
if(find_animal.stat != DEAD)
- return
+ return FALSE
if(find_animal.sentience_type != SENTIENCE_ORGANIC)
- return
+ return FALSE
- find_animal.faction = list(FACTION_NEUTRAL)
+ find_animal.faction = list(FACTION_ASHWALKER)
if(ishostile(find_animal))
var/mob/living/simple_animal/hostile/hostile_animal = find_animal
hostile_animal.attack_same = FALSE
find_animal.revive(HEAL_ALL)
+ return TRUE
+
+/datum/ash_ritual/revive_animal/proc/revive_basic(obj/effect/ash_rune/success_rune)
+ var/turf/src_turf = get_turf(success_rune)
+
+ var/mob/living/basic/find_animal = locate() in src_turf
+
+ if(!find_animal)
+ return FALSE
+
+ if(find_animal.health > 0)
+ return FALSE
+
+ if(find_animal.sentience_type != SENTIENCE_ORGANIC)
+ return FALSE
+
+ find_animal.faction = list(FACTION_ASHWALKER)
+
+ find_animal.revive()
+ return TRUE
diff --git a/modular_skyrat/modules/ashwalkers/code/items/ash_seedmesh.dm b/modular_skyrat/modules/ashwalkers/code/items/ash_seedmesh.dm
index b21994b71be..a79f0dfb883 100644
--- a/modular_skyrat/modules/ashwalkers/code/items/ash_seedmesh.dm
+++ b/modular_skyrat/modules/ashwalkers/code/items/ash_seedmesh.dm
@@ -3,6 +3,9 @@
desc = "A little mesh that, when paired with sand, has the possibility of filtering out large seeds."
icon = 'modular_skyrat/modules/ashwalkers/icons/misc_tools.dmi'
icon_state = "mesh"
+ var/list/static/seeds_blacklist = list(
+ /obj/item/seeds/lavaland,
+ )
/obj/item/seed_mesh/attackby(obj/item/attacking_item, mob/user, params)
if(istype(attacking_item, /obj/item/stack/ore/glass))
@@ -16,7 +19,7 @@
if(prob(85))
user.balloon_alert(user, "[stack_item] reveals nothing!")
return
- var/spawn_seed = pick(subtypesof(/obj/item/seeds))
+ var/spawn_seed = pick(subtypesof(/obj/item/seeds) - seeds_blacklist)
new spawn_seed(get_turf(src))
user.balloon_alert(user, "[stack_item] revealed something!")
return ..()
diff --git a/modular_skyrat/modules/ashwalkers/code/species/Ashwalkers.dm b/modular_skyrat/modules/ashwalkers/code/species/Ashwalkers.dm
index d24aa290ec0..0e60d2ed7e9 100644
--- a/modular_skyrat/modules/ashwalkers/code/species/Ashwalkers.dm
+++ b/modular_skyrat/modules/ashwalkers/code/species/Ashwalkers.dm
@@ -13,10 +13,12 @@
. = ..()
RegisterSignal(carbon_target, COMSIG_MOB_ITEM_ATTACK, PROC_REF(mob_attack))
carbon_target.AddComponent(/datum/component/ash_age)
+ carbon_target.faction |= FACTION_ASHWALKER
/datum/species/lizard/ashwalker/on_species_loss(mob/living/carbon/carbon_target)
. = ..()
UnregisterSignal(carbon_target, COMSIG_MOB_ITEM_ATTACK)
+ carbon_target.faction &= FACTION_ASHWALKER
/datum/species/lizard/ashwalker/proc/mob_attack(datum/source, mob/mob_target, mob/user)
SIGNAL_HANDLER
diff --git a/modular_skyrat/modules/basic_mobs/code/bananaspider.dm b/modular_skyrat/modules/basic_mobs/code/bananaspider.dm
index 0900f7a1a74..6e3a7e26dcd 100644
--- a/modular_skyrat/modules/basic_mobs/code/bananaspider.dm
+++ b/modular_skyrat/modules/basic_mobs/code/bananaspider.dm
@@ -42,7 +42,7 @@
food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 2)
foodtypes = GORE | MEAT | RAW
grind_results = list(/datum/reagent/blood = 20, /datum/reagent/consumable/liquidgibs = 5)
- juice_results = list(/datum/reagent/consumable/banana = 10)
+ juice_typepath = /datum/reagent/consumable/banana
/obj/item/food/deadbanana_spider/Initialize(mapload)
diff --git a/modular_skyrat/modules/blueshield/code/closet.dm b/modular_skyrat/modules/blueshield/code/closet.dm
index 54e5665135e..1ceaf37325b 100644
--- a/modular_skyrat/modules/blueshield/code/closet.dm
+++ b/modular_skyrat/modules/blueshield/code/closet.dm
@@ -1,3 +1,19 @@
+/obj/item/storage/bag/garment/blueshield
+ name = "Blueshield's garment bag"
+ desc = "A bag for storing extra clothes and shoes. This one belongs to the blueshield."
+
+/obj/item/storage/bag/garment/blueshield/PopulateContents()
+ new /obj/item/clothing/suit/hooded/wintercoat/skyrat/blueshield(src)
+ new /obj/item/clothing/head/beret/blueshield(src)
+ new /obj/item/clothing/head/beret/blueshield/navy(src)
+ new /obj/item/clothing/under/rank/blueshield(src)
+ new /obj/item/clothing/under/rank/blueshield/skirt(src)
+ new /obj/item/clothing/under/rank/blueshield/turtleneck(src)
+ new /obj/item/clothing/under/rank/blueshield/turtleneck/skirt(src)
+ new /obj/item/clothing/suit/armor/vest/blueshield(src)
+ new /obj/item/clothing/suit/armor/vest/blueshield/jacket(src)
+ new /obj/item/clothing/neck/mantle/bsmantle(src)
+
/obj/structure/closet/secure_closet/blueshield
name = "\the blueshield's locker"
icon_state = "bs"
@@ -12,5 +28,5 @@
new /obj/item/assembly/flash/handheld(src)
new /obj/item/restraints/handcuffs(src)
new /obj/item/clothing/glasses/hud/security/sunglasses(src)
- new /obj/item/clothing/suit/hooded/wintercoat/skyrat/blueshield(src)
new /obj/item/storage/medkit/tactical/blueshield(src)
+ new /obj/item/storage/bag/garment/blueshield(src)
diff --git a/modular_skyrat/modules/bluespace_miner/code/bluespace_miner.dm b/modular_skyrat/modules/bluespace_miner/code/bluespace_miner.dm
index 6b45258c051..e082ddabb42 100644
--- a/modular_skyrat/modules/bluespace_miner/code/bluespace_miner.dm
+++ b/modular_skyrat/modules/bluespace_miner/code/bluespace_miner.dm
@@ -151,7 +151,7 @@
/datum/supply_pack/misc/bluespace_miner
name = "Bluespace Miner"
desc = "Nanotrasen has revolutionized the procuring of materials with bluespace-- featuring the Bluespace Miner!"
- cost = CARGO_CRATE_VALUE * 150 // 30,000
+ cost = CARGO_CRATE_VALUE * 50 // 10,000
contains = list(/obj/item/circuitboard/machine/bluespace_miner)
crate_name = "Bluespace Miner Circuitboard Crate"
crate_type = /obj/structure/closet/crate
diff --git a/modular_skyrat/modules/bodyparts/code/roundstartslime_bodyparts.dm b/modular_skyrat/modules/bodyparts/code/roundstartslime_bodyparts.dm
index e5894249ac1..302d3488931 100644
--- a/modular_skyrat/modules/bodyparts/code/roundstartslime_bodyparts.dm
+++ b/modular_skyrat/modules/bodyparts/code/roundstartslime_bodyparts.dm
@@ -3,25 +3,25 @@
/obj/item/bodypart/head/slime/roundstart
is_dimorphic = TRUE
icon_greyscale = BODYPART_ICON_ROUNDSTARTSLIME
- biological_state = BIO_FLESH
+ biological_state = (BIO_FLESH|BIO_BLOODED)
/obj/item/bodypart/chest/slime/roundstart
is_dimorphic = TRUE
icon_greyscale = BODYPART_ICON_ROUNDSTARTSLIME
- biological_state = BIO_FLESH
+ biological_state = (BIO_FLESH|BIO_BLOODED)
/obj/item/bodypart/arm/left/slime/roundstart
icon_greyscale = BODYPART_ICON_ROUNDSTARTSLIME
- biological_state = BIO_FLESH
+ biological_state = (BIO_FLESH|BIO_BLOODED)
/obj/item/bodypart/arm/right/slime/roundstart
icon_greyscale = BODYPART_ICON_ROUNDSTARTSLIME
- biological_state = BIO_FLESH
+ biological_state = (BIO_FLESH|BIO_BLOODED)
/obj/item/bodypart/leg/left/slime/roundstart
icon_greyscale = BODYPART_ICON_ROUNDSTARTSLIME
- biological_state = BIO_FLESH
+ biological_state = (BIO_FLESH|BIO_BLOODED)
/obj/item/bodypart/leg/right/slime/roundstart
icon_greyscale = BODYPART_ICON_ROUNDSTARTSLIME
- biological_state = BIO_FLESH
+ biological_state = (BIO_FLESH|BIO_BLOODED)
diff --git a/modular_skyrat/modules/bongs/code/bong.dm b/modular_skyrat/modules/bongs/code/bong.dm
index ca709cf184b..614ccfca343 100644
--- a/modular_skyrat/modules/bongs/code/bong.dm
+++ b/modular_skyrat/modules/bongs/code/bong.dm
@@ -47,7 +47,7 @@
bong_hits = max_hits
packed_item = TRUE
if(grown_item.reagents)
- grown_item.reagents.trans_to(src, grown_item.reagents.total_volume, transfered_by = user)
+ grown_item.reagents.trans_to(src, grown_item.reagents.total_volume, transferred_by = user)
reagent_transfer_per_use = reagents.total_volume / max_hits
qdel(grown_item)
@@ -59,7 +59,7 @@
bong_hits = max_hits
packed_item = TRUE
if(used_item.reagents)
- used_item.reagents.trans_to(src, used_item.reagents.total_volume, transfered_by = user)
+ used_item.reagents.trans_to(src, used_item.reagents.total_volume, transferred_by = user)
reagent_transfer_per_use = reagents.total_volume / max_hits
qdel(used_item)
else
@@ -96,7 +96,7 @@
return
to_chat(hit_mob, span_notice("You finish taking a hit from the [src]."))
if(reagents.total_volume)
- reagents.trans_to(hit_mob, reagent_transfer_per_use, transfered_by = user, methods = VAPOR)
+ reagents.trans_to(hit_mob, reagent_transfer_per_use, transferred_by = user, methods = VAPOR)
bong_hits--
var/turf/open/pos = get_turf(src)
if(istype(pos))
diff --git a/modular_skyrat/modules/borg_buffs/code/robot.dm b/modular_skyrat/modules/borg_buffs/code/robot.dm
index eb4568d16dd..90ed52cf973 100644
--- a/modular_skyrat/modules/borg_buffs/code/robot.dm
+++ b/modular_skyrat/modules/borg_buffs/code/robot.dm
@@ -87,7 +87,6 @@
/datum/reagent/consumable/blackpepper,\
/datum/reagent/consumable/capsaicin,\
/datum/reagent/consumable/coco,\
- /datum/reagent/consumable/cooking_oil,\
/datum/reagent/consumable/cornmeal,\
/datum/reagent/consumable/corn_starch,\
/datum/reagent/consumable/eggwhite,\
diff --git a/modular_skyrat/modules/cargo/code/goodies.dm b/modular_skyrat/modules/cargo/code/goodies.dm
index 5bff4884d55..2324057a3a6 100644
--- a/modular_skyrat/modules/cargo/code/goodies.dm
+++ b/modular_skyrat/modules/cargo/code/goodies.dm
@@ -77,6 +77,13 @@
cost = CARGO_CRATE_VALUE * 6 // 1200 credits
contains = list(/obj/item/gravity_harness)
+/datum/supply_pack/goody/scratching_stone
+ name = "Scratching Stone"
+ desc = "A high-grade sharpening stone made of specialized alloys, meant to sharpen razor-claws. Unfortunately, this particular one has by far seen better days."
+ cost = CARGO_CRATE_VALUE * 4 //800 credits
+ contains = list(/obj/item/scratching_stone)
+ contraband = TRUE
+
/*
* CARPET PACKS
*/
diff --git a/modular_skyrat/modules/cargo/code/packs.dm b/modular_skyrat/modules/cargo/code/packs.dm
index f292e5ce2c4..5da7ac90af4 100644
--- a/modular_skyrat/modules/cargo/code/packs.dm
+++ b/modular_skyrat/modules/cargo/code/packs.dm
@@ -147,9 +147,9 @@
contains = list(/obj/item/mod/control/pre_equipped/security)
crate_name = "security MODsuit crate"
-/datum/supply_pack/security/armor
+/datum/supply_pack/security/armor_skyrat
name = "Armor Crate"
- desc = "Three vests of well-rounded, decently-protective armor. Requires Security access to open."
+ desc = "Three vests of well-rounded, decently-protective armor."
cost = CARGO_CRATE_VALUE * 2
access_view = ACCESS_SECURITY
contains = list(
@@ -159,15 +159,11 @@
)
crate_name = "armor crate"
-/datum/supply_pack/security/helmets
+/datum/supply_pack/security/helmets_skyrat
name = "Helmets Crate"
- desc = "Contains three standard-issue brain buckets. Requires Security access to open."
+ desc = "Contains three standard-issue brain buckets."
cost = CARGO_CRATE_VALUE * 2
- contains = list(
- /obj/item/clothing/head/helmet/sec/redsec,
- /obj/item/clothing/head/helmet/sec/redsec,
- /obj/item/clothing/head/helmet/sec/redsec,
- )
+ contains = list(/obj/item/clothing/head/helmet/sec/redsec = 3)
crate_name = "helmet crate"
/datum/supply_pack/security/deployablebarricades
@@ -442,8 +438,8 @@
desc = "Chef slop boring? Have high-maintenance crewmembers that with wings? Maybe you just want to revel in the sinful delight that are Cheese Curds? The Finest of our trade union has made the pack for you, containing a mix of fine oils, vinegar, and exceptionally rare ingredients."
cost = CARGO_CRATE_VALUE * 5
contains = list(
- /obj/item/reagent_containers/condiment/quality_oil,
- /obj/item/reagent_containers/condiment/quality_oil,
+ /obj/item/reagent_containers/condiment/olive_oil,
+ /obj/item/reagent_containers/condiment/olive_oil,
/obj/item/reagent_containers/condiment/vinegar,
/obj/item/reagent_containers/condiment/vinegar,
/obj/item/food/canned/tomatoes,
@@ -463,16 +459,16 @@
desc = "Normal cooking oil not cutting it? Chef throw all the quality stuff in the frier because they thought it was funny? Well, We got you covered, Introducing a bulk pack of Ten (10) bottles of our finest oils, blended for the perfect taste in cold recipes, and a resistance for going acrid when cooking."
cost = CARGO_CRATE_VALUE * 9
contains = list(
- /obj/item/reagent_containers/condiment/quality_oil,
- /obj/item/reagent_containers/condiment/quality_oil,
- /obj/item/reagent_containers/condiment/quality_oil,
- /obj/item/reagent_containers/condiment/quality_oil,
- /obj/item/reagent_containers/condiment/quality_oil,
- /obj/item/reagent_containers/condiment/quality_oil,
- /obj/item/reagent_containers/condiment/quality_oil,
- /obj/item/reagent_containers/condiment/quality_oil,
- /obj/item/reagent_containers/condiment/quality_oil,
- /obj/item/reagent_containers/condiment/quality_oil,
+ /obj/item/reagent_containers/condiment/olive_oil,
+ /obj/item/reagent_containers/condiment/olive_oil,
+ /obj/item/reagent_containers/condiment/olive_oil,
+ /obj/item/reagent_containers/condiment/olive_oil,
+ /obj/item/reagent_containers/condiment/olive_oil,
+ /obj/item/reagent_containers/condiment/olive_oil,
+ /obj/item/reagent_containers/condiment/olive_oil,
+ /obj/item/reagent_containers/condiment/olive_oil,
+ /obj/item/reagent_containers/condiment/olive_oil,
+ /obj/item/reagent_containers/condiment/olive_oil,
)
crate_name = "bulk quality oil pack"
crate_type = /obj/structure/closet/crate/freezer
diff --git a/modular_skyrat/modules/cargo/readme.md b/modular_skyrat/modules/cargo/readme.md
index 9605de773a2..1bcc6bbe9bd 100644
--- a/modular_skyrat/modules/cargo/readme.md
+++ b/modular_skyrat/modules/cargo/readme.md
@@ -11,22 +11,18 @@ Adds more stuff to cargo.
### TG Proc/File Changes:
- N/A
-
### Defines:
- N/A
-
### Master file additions
-- N/A
-
+- `modular_skyrat/master_files/code/modules/cargo/packs/security.dm`: `var/special`
### Included files that are not contained in this module:
- N/A
-
### Credits:
diff --git a/modular_skyrat/modules/cell_component/code/flashlight.dm b/modular_skyrat/modules/cell_component/code/flashlight.dm
deleted file mode 100644
index 01de50266e3..00000000000
--- a/modular_skyrat/modules/cell_component/code/flashlight.dm
+++ /dev/null
@@ -1,150 +0,0 @@
-#define FLASHLIGHT_MODE_LOW "low"
-#define FLASHLIGHT_MODE_MEDIUM "medium"
-#define FLASHLIGHT_MODE_HIGH "high"
-
-/obj/item/flashlight
- /// Does this flashlight utilize batteries?
- var/uses_battery = TRUE
- /// What's this flashlight's special cell, if any?
- var/cell_override
- /// How much power (per process) does this flashlight use, if uses_battery = TRUE
- power_use_amount = POWER_CELL_USE_MINIMUM
- /// Mode of the flashlight, how strong the light is and how much the power usage is affected.
- var/flashlight_mode = FLASHLIGHT_MODE_LOW
- /// Does this flashlight have modes?
- var/has_modes = TRUE
- /// Does this flashlight make the extra noise upon being turned on?
- var/makes_noise_when_lit = TRUE
-
-/obj/item/flashlight/Initialize(mapload)
- . = ..()
- if(icon_state == "[initial(icon_state)]-on")
- turn_on(FALSE)
- update_brightness()
- register_context()
-
- if(uses_battery)
- AddComponent(/datum/component/cell, cell_override, CALLBACK(src, PROC_REF(turn_off)), _has_cell_overlays = FALSE)
-
-/obj/item/flashlight/examine(mob/user)
- . = ..()
- if(has_modes)
- . += "This flashlight has modes! Ctrl-click it to change the mode."
- . += "It is currently set to [flashlight_mode] intensity."
-
-/obj/item/flashlight/CtrlClick(mob/user)
- . = ..()
- if(has_modes)
- switch(flashlight_mode)
- if(FLASHLIGHT_MODE_LOW)
- flashlight_mode = FLASHLIGHT_MODE_MEDIUM
- power_use_amount = POWER_CELL_USE_VERY_LOW
- set_light_range(initial(light_range) + 1)
- set_light_power(initial(light_power) + 1)
- to_chat(user, span_notice("You set [src] to medium."))
- if(FLASHLIGHT_MODE_MEDIUM)
- flashlight_mode = FLASHLIGHT_MODE_HIGH
- power_use_amount = POWER_CELL_USE_LOW
- set_light_range(initial(light_range) + 2)
- set_light_power(initial(light_power) + 2)
- to_chat(user, span_notice("You set [src] to high."))
- if(FLASHLIGHT_MODE_HIGH)
- flashlight_mode = FLASHLIGHT_MODE_LOW
- power_use_amount = POWER_CELL_USE_MINIMUM
- set_light_range(initial(light_range))
- set_light_power(initial(light_power))
- to_chat(user, span_notice("You set [src] to low."))
-
-/obj/item/flashlight/proc/toggle_light()
- if(on)
- turn_off()
- else
- if(uses_battery && !(item_use_power(power_use_amount, TRUE) & COMPONENT_POWER_SUCCESS))
- return
- turn_on(makes_noise_when_lit)
- playsound(src, on ? sound_on : sound_off, 40, TRUE)
- return TRUE
-
-/obj/item/flashlight/attack_self(mob/user)
- . = ..()
- toggle_light()
-
-/**
- * Handles turning on the flashlight.
- * Parameters:
- * * noisy - Boolean on whether the flashlight should make an additional noise from being turned on or not. Defaults to TRUE.
- */
-/obj/item/flashlight/proc/turn_on(noisy = TRUE)
- on = TRUE
- if (uses_battery)
- START_PROCESSING(SSobj, src)
- update_brightness()
- if(noisy)
- playsound(src, 'modular_skyrat/master_files/sound/effects/flashlight.ogg', 40, TRUE) //Credits to ERIS for the sound
- update_item_action_buttons()
-
-/// Handles turning off the flashlight.
-/obj/item/flashlight/proc/turn_off()
- on = FALSE
- update_brightness()
- update_item_action_buttons()
-
-/obj/item/flashlight/process(seconds_per_tick)
- if(!on)
- STOP_PROCESSING(SSobj, src)
- return
- if(uses_battery && !(item_use_power(power_use_amount) & COMPONENT_POWER_SUCCESS))
- turn_off()
-
-/obj/item/flashlight/update_icon_state()
- . = ..()
- if(on)
- icon_state = "[initial(icon_state)]-on"
- else
- icon_state = initial(icon_state)
-
-/obj/item/flashlight/seclite
- cell_override = /obj/item/stock_parts/cell/upgraded
-
-/obj/item/flashlight/lamp
- uses_battery = FALSE
- has_modes = FALSE
-
-/obj/item/flashlight/lantern
- uses_battery = FALSE
- has_modes = FALSE
- makes_noise_when_lit = FALSE
-
-/obj/item/flashlight/slime
- uses_battery = FALSE
- has_modes = FALSE
- makes_noise_when_lit = FALSE
-
-/obj/item/flashlight/flare
- uses_battery = FALSE
- has_modes = FALSE
- makes_noise_when_lit = FALSE
-
-/obj/item/flashlight/emp/debug
- uses_battery = FALSE
-
-/obj/item/flashlight/glowstick
- uses_battery = FALSE
- has_modes = FALSE
- makes_noise_when_lit = FALSE
-
-/obj/item/flashlight/spotlight
- uses_battery = FALSE
- has_modes = FALSE
-
-/obj/item/flashlight/eyelight
- uses_battery = FALSE
- has_modes = FALSE
-
-/obj/item/flashlight/pen
- cell_override = /obj/item/stock_parts/cell/potato
- has_modes = FALSE
-
-#undef FLASHLIGHT_MODE_LOW
-#undef FLASHLIGHT_MODE_MEDIUM
-#undef FLASHLIGHT_MODE_HIGH
diff --git a/modular_skyrat/modules/cellguns/code/medigun_cells.dm b/modular_skyrat/modules/cellguns/code/medigun_cells.dm
index 3000e0b7b90..e846c2ec685 100644
--- a/modular_skyrat/modules/cellguns/code/medigun_cells.dm
+++ b/modular_skyrat/modules/cellguns/code/medigun_cells.dm
@@ -455,11 +455,11 @@
if(!istype(target, /mob/living/carbon/human)) //Only checks if they are human, it would make sense for this to work on the dead.
return FALSE
- for(var/obj/structure/bed/roller/medigun in target.loc) //Prevents multiple beds from being spawned on the same turf
+ for(var/obj/structure/bed/medical/medigun in target.loc) //Prevents multiple beds from being spawned on the same turf
return FALSE
if(HAS_TRAIT(target, TRAIT_FLOORED) || target.resting) //Is the person already on the floor to begin with? Mostly a measure to prevent spamming.
- var /obj/structure/bed/roller/medigun/created_bed = new /obj/structure/bed/roller/medigun(target.loc)
+ var /obj/structure/bed/medical/medigun/created_bed = new /obj/structure/bed/medical/medigun(target.loc)
if(!target.stat == CONSCIOUS)
created_bed.buckle_mob(target)
@@ -537,31 +537,34 @@
if(heals_left <= 0)
qdel(src)
-//Hardlight Roller Bed.
-/obj/structure/bed/roller/medigun
- name = "hardlight roller bed"
- desc = "A Roller Bed made out of Hardlight"
+//Hardlight Emergency Bed.
+/obj/structure/bed/medical/medigun
+ name = "hardlight medical bed"
+ desc = "A medical bed made out of Hardlight"
icon = 'modular_skyrat/modules/cellguns/icons/obj/guns/mediguns/misc.dmi'
+ icon_state = "hardlight_down"
+ base_icon_state = "hardlight"
max_integrity = 1
- buildstacktype = FALSE //It would not be good if people could use this to farm materials.
- var/deploytime = 20 SECONDS //How long the roller beds lasts for without someone buckled to it.
+ flags_1 = NODECONSTRUCT_1 //Made from nothing, can't deconstruct
+ build_stack_type = null //It would not be good if people could use this to farm materials.
+ var/deploy_time = 20 SECONDS //How long the roller beds lasts for without someone buckled to it.
-/obj/structure/bed/roller/medigun/Initialize(mapload)
+/obj/structure/bed/medical/medigun/Initialize(mapload)
. = ..()
- addtimer(CALLBACK(src, PROC_REF(check_bed)), deploytime)
+ addtimer(CALLBACK(src, PROC_REF(check_bed)), deploy_time)
-/obj/structure/bed/roller/medigun/proc/check_bed() //Checks to see if anyone is buckled to the bed, if not the bed will qdel itself.
+/obj/structure/bed/medical/medigun/proc/check_bed() //Checks to see if anyone is buckled to the bed, if not the bed will qdel itself.
if(!has_buckled_mobs())
qdel(src) //Deletes the roller bed, mostly meant to prevent stockpiling and clutter
return TRUE //There is nothing on the bed.
else
return FALSE //There is something on the bed.
-/obj/structure/bed/roller/medigun/post_unbuckle_mob(mob/living/M)
+/obj/structure/bed/medical/medigun/post_unbuckle_mob(mob/living/M)
. = ..()
qdel(src)
-/obj/structure/bed/roller/medigun/MouseDrop(over_object, src_location, over_location)
+/obj/structure/bed/medical/medigun/MouseDrop(over_object, src_location, over_location)
if(over_object == usr && Adjacent(usr))
if(!ishuman(usr) || !usr.can_perform_action(src))
return FALSE
diff --git a/modular_skyrat/modules/cellguns/icons/obj/guns/mediguns/misc.dmi b/modular_skyrat/modules/cellguns/icons/obj/guns/mediguns/misc.dmi
index 5c44675c447..d5cebb12ba9 100644
Binary files a/modular_skyrat/modules/cellguns/icons/obj/guns/mediguns/misc.dmi and b/modular_skyrat/modules/cellguns/icons/obj/guns/mediguns/misc.dmi differ
diff --git a/modular_skyrat/modules/clock_cult/code/scriptures/_scripture.dm b/modular_skyrat/modules/clock_cult/code/scriptures/_scripture.dm
index 2a11854456a..ad8f096188b 100644
--- a/modular_skyrat/modules/clock_cult/code/scriptures/_scripture.dm
+++ b/modular_skyrat/modules/clock_cult/code/scriptures/_scripture.dm
@@ -361,9 +361,8 @@ GLOBAL_LIST_EMPTY(clock_scriptures_by_type)
return ..()
-/datum/action/cooldown/spell/pointed/slab/InterceptClickOn(mob/living/caller, params, atom/clicked_atom)
- parent_scripture?.click_on(clicked_atom)
-
+/datum/action/cooldown/spell/pointed/slab/InterceptClickOn(mob/living/caller, params, atom/target)
+ parent_scripture?.click_on(target)
/// Generate all scriptures in a global assoc of name:ref. Only needs to be done once
diff --git a/modular_skyrat/modules/company_imports/code/armament_component.dm b/modular_skyrat/modules/company_imports/code/armament_component.dm
index 88f17ac0033..f647a3fe1bd 100644
--- a/modular_skyrat/modules/company_imports/code/armament_component.dm
+++ b/modular_skyrat/modules/company_imports/code/armament_component.dm
@@ -81,25 +81,6 @@
data["armaments_list"] = list()
for(var/armament_category as anything in SSarmaments.entries)
- var/illegal_failure
-
- for(var/company as anything in SScargo_companies.companies)
- if(company != armament_category)
- continue
-
- var/datum/cargo_company/selected_company = SScargo_companies.companies[company]
-
- if(!(console_state == CARGO_CONSOLE) && selected_company.illegal)
- illegal_failure = TRUE
- break
-
- var/obj/machinery/computer/cargo/cargo_comp = parent
- if(selected_company.illegal && !(cargo_comp.obj_flags & EMAGGED))
- illegal_failure = TRUE
- break
-
- if(illegal_failure)
- continue
var/list/armament_subcategories = list()
@@ -118,16 +99,6 @@
if(!parent_console.contraband)
continue
- var/cant_purchase = FALSE
-
- if(gun_entry.interest_required)
- for(var/company_interested as anything in SScargo_companies.companies)
- if(company_interested != armament_category)
- continue
- var/datum/cargo_company/company_datum = SScargo_companies.companies[company_interested]
- if(company_datum.interest < gun_entry.interest_required)
- cant_purchase = TRUE
-
subcategory_items += list(list(
"ref" = REF(armament_entry),
"icon" = armament_entry.cached_base64,
@@ -135,12 +106,10 @@
"cost" = armament_entry.cost,
"buyable_ammo" = armament_entry.magazine ? TRUE : FALSE,
"magazine_cost" = armament_entry.magazine_cost,
- "quantity" = gun_entry.stock,
"purchased" = purchased_items[armament_entry] ? purchased_items[armament_entry] : 0,
"description" = armament_entry.description,
"armament_category" = armament_entry.category,
"equipment_subcategory" = armament_entry.subcategory,
- "cant_purchase" = !!cant_purchase,
"restricted" = !!armament_entry.restricted,
))
@@ -155,32 +124,10 @@
if(!LAZYLEN(armament_subcategories))
continue
- var/purchased_company = FALSE
- var/company_cost = 0
- var/handout_company = FALSE
-
- for(var/company as anything in SScargo_companies.companies)
- if(company != armament_category)
- continue
-
- if(company in SScargo_companies.purchased_companies)
- purchased_company = TRUE
-
- var/datum/cargo_company/company_datum = SScargo_companies.companies[company]
-
- if((company_datum in SScargo_companies.chosen_handouts) && !SScargo_companies.handout_picked)
- handout_company = TRUE
-
- company_cost = company_datum.cost
-
-
data["armaments_list"] += list(list(
"category" = armament_category,
- "category_purchased" = !!purchased_company,
"category_uses" = used_categories[armament_category],
"subcategories" = armament_subcategories,
- "cost" = company_cost,
- "handout" = !!handout_company,
))
return data
@@ -207,60 +154,65 @@
var/mob/living/carbon/human/the_person = user
- if(!istype(the_person))
- return
+ if(istype(the_person))
- var/obj/item/card/id/id_card
+ var/obj/item/card/id/id_card
- if(console_state == IRN_CONSOLE)
- id_card = parent_prog.computer.computer_id_slot?.GetID()
- else
- id_card = the_person.get_idcard(TRUE)
-
- if(id_card?.registered_account && (console_state == IRN_CONSOLE))
- if((ACCESS_COMMAND in id_card.access) || (ACCESS_QM in id_card.access))
- parent_prog.requestonly = FALSE
- buyer = SSeconomy.get_dep_account(id_card.registered_account.account_job.paycheck_department)
- parent_prog.can_approve_requests = TRUE
+ if(console_state == IRN_CONSOLE)
+ id_card = parent_prog.computer.computer_id_slot?.GetID()
else
- parent_prog.requestonly = TRUE
- parent_prog.can_approve_requests = FALSE
- else
- parent_prog?.requestonly = TRUE
+ id_card = the_person.get_idcard(TRUE)
- if(self_paid)
- if(!istype(id_card))
- to_chat(user, span_warning("No ID card detected."))
- return
+ if(id_card?.registered_account && (console_state == IRN_CONSOLE))
+ if((ACCESS_COMMAND in id_card.access) || (ACCESS_QM in id_card.access))
+ parent_prog.requestonly = FALSE
+ buyer = SSeconomy.get_dep_account(id_card.registered_account.account_job.paycheck_department)
+ parent_prog.can_approve_requests = TRUE
+ else
+ parent_prog.requestonly = TRUE
+ parent_prog.can_approve_requests = FALSE
+ else
+ parent_prog?.requestonly = TRUE
- if(istype(id_card, /obj/item/card/id/departmental_budget))
- to_chat(user, span_warning("[id_card] cannot be used to make purchases."))
- return
+ if(self_paid)
+ if(!istype(id_card))
+ to_chat(user, span_warning("No ID card detected."))
+ return
- var/datum/bank_account/account = id_card.registered_account
+ if(istype(id_card, /obj/item/card/id/departmental_budget))
+ to_chat(user, span_warning("[id_card] cannot be used to make purchases."))
+ return
- if(!istype(account))
- to_chat(user, span_warning("Invalid bank account."))
- return
+ var/datum/bank_account/account = id_card.registered_account
- buyer = account
+ if(!istype(account))
+ to_chat(user, span_warning("Invalid bank account."))
+ return
+
+ buyer = account
+
+ if(issilicon(user) && (console_state == IRN_CONSOLE))
+ parent_prog.can_approve_requests = TRUE
+ parent_prog.requestonly = FALSE
if(!buyer)
to_chat(user, span_warning("No budget found!"))
return
- if(!armament_entry.stock)
- to_chat(user, span_warning("No stock of this item left!"))
+ if(!ishuman(user) && !issilicon(user))
return
- if(!ishuman(user))
- return
-
- if(!buyer.has_money(armament_entry.cost)) //so you can't "stash" guns for later merchant cycles
+ if(!buyer.has_money(armament_entry.cost))
to_chat(user, span_warning("Not enough money!"))
return
- var/name = the_person.get_authentification_name()
+ var/name
+
+ if(issilicon(user))
+ name = user.real_name
+ else
+ the_person.get_authentification_name()
+
var/reason = ""
if(possible_console)
@@ -279,22 +231,27 @@
used_categories[armament_entry.category]++
purchased_items[armament_entry]++
- armament_entry.stock--
-
- playsound(src, 'sound/machines/machine_vend.ogg', 50, TRUE, extrarange = -3)
var/datum/supply_pack/armament/created_pack = new
created_pack.name = initial(armament_entry.item_type.name)
created_pack.cost = cost_calculate(armament_entry.cost) //Paid for seperately
created_pack.contains = list(armament_entry.item_type)
- var/rank = the_person.get_assignment(hand_first = TRUE)
- var/ckey = the_person.ckey
+
+ var/rank
+
+ if(issilicon(user))
+ rank = "Silicon"
+ else
+ rank = the_person.get_assignment(hand_first = TRUE)
+
+ var/ckey = user.ckey
+
var/datum/supply_order/company_import/created_order
if(buyer != SSeconomy.get_dep_account(ACCOUNT_CAR))
- created_order = new(created_pack, name, rank, ckey, paying_account = buyer, reason = reason)
+ created_order = new(created_pack, name, rank, ckey, paying_account = buyer, reason = reason, can_be_cancelled = TRUE)
else
- created_order = new(created_pack, name, rank, ckey, reason = reason)
- created_order.interest_addition = armament_entry.interest_addition
+ created_pack.goody = FALSE // Cargo ordered stuff should just show up in a box I think
+ created_order = new(created_pack, name, rank, ckey, reason = reason, can_be_cancelled = TRUE)
created_order.selected_entry = armament_entry
created_order.used_component = src
if(console_state == CARGO_CONSOLE)
@@ -311,116 +268,6 @@
else
SSshuttle.shopping_list += created_order
-/datum/component/armament/company_imports/buy_ammo(mob/user, datum/armament_entry/company_import/armament_entry)
- var/datum/bank_account/buyer = SSeconomy.get_dep_account(ACCOUNT_CAR)
- var/obj/machinery/computer/cargo/possible_console
- var/obj/item/modular_computer/possible_downloader
-
- if(console_state == CARGO_CONSOLE)
- possible_console = parent
-
- else if(console_state == IRN_CONSOLE)
- possible_downloader = parent
-
- var/mob/living/carbon/human/the_person = user
-
- if(!istype(the_person))
- return
-
- var/obj/item/card/id/id_card
-
- if(console_state == IRN_CONSOLE)
- id_card = parent_prog.computer.computer_id_slot?.GetID()
- else
- id_card = the_person.get_idcard(TRUE)
-
- if(id_card?.registered_account && (console_state == IRN_CONSOLE))
- if((ACCESS_COMMAND in id_card.access) || (ACCESS_QM in id_card.access))
- parent_prog.requestonly = FALSE
- buyer = SSeconomy.get_dep_account(id_card.registered_account.account_job.paycheck_department)
- parent_prog.can_approve_requests = TRUE
- else
- parent_prog.requestonly = TRUE
- parent_prog.can_approve_requests = FALSE
- else
- parent_prog?.requestonly = TRUE
-
- if(self_paid)
- if(!istype(id_card))
- to_chat(user, span_warning("No ID card detected."))
- return
-
- if(istype(id_card, /obj/item/card/id/departmental_budget))
- to_chat(user, span_warning("[id_card] cannot be used to make purchases."))
- return
-
- var/datum/bank_account/account = id_card.registered_account
-
- if(!istype(account))
- to_chat(user, span_warning("Invalid bank account."))
- return
-
- buyer = account
-
- if(!armament_entry.magazine)
- return
-
- if(!buyer)
- to_chat(user, span_warning("No budget found!"))
- return
-
- var/quantity_cost = armament_entry.magazine_cost * ammo_purchase_num
-
- if(!buyer.has_money(quantity_cost))
- to_chat(user, span_warning("Not enough money!"))
- return
-
- var/name = the_person.get_authentification_name()
- var/reason = ""
-
- if(possible_console)
- if(possible_console.requestonly && !self_paid)
- reason = tgui_input_text(user, "Reason", name)
- if(isnull(reason))
- return
-
- else if(possible_downloader)
- var/datum/computer_file/program/budgetorders/parent_file = parent_prog
- if((parent_file.requestonly && !self_paid) || !(possible_downloader.computer_id_slot?.GetID()))
- reason = tgui_input_text(user, "Reason", name)
- if(isnull(reason))
- return
-
-
- var/datum/supply_pack/created_pack = new
- var/assembled_name = "[initial(armament_entry.item_type.name)] Ammunition (x[ammo_purchase_num])"
- created_pack.name = assembled_name
- created_pack.cost = cost_calculate(quantity_cost)
- created_pack.contains = list()
- for(var/i in 1 to ammo_purchase_num)
- created_pack.contains += armament_entry.magazine
- var/rank = the_person.get_assignment(hand_first = TRUE)
- var/ckey = the_person.ckey
- var/datum/supply_order/company_import/created_order
- if(buyer != SSeconomy.get_dep_account(ACCOUNT_CAR))
- created_order = new(created_pack, name, rank, ckey, paying_account = buyer, reason = reason)
- else
- created_order = new(created_pack, name, rank, ckey, reason = reason)
- created_order.interest_addition = ammo_purchase_num
- created_order.item_amount = ammo_purchase_num
- var/datum/computer_file/program/budgetorders/file_p = parent_prog
- if(console_state == CARGO_CONSOLE)
- created_order.generateRequisition(get_turf(parent))
- if(possible_console.requestonly && !self_paid)
- SSshuttle.request_list += created_order
- else
- SSshuttle.shopping_list += created_order
- else if(console_state == IRN_CONSOLE)
- if(file_p.requestonly && !self_paid)
- SSshuttle.request_list += created_order
- else
- SSshuttle.shopping_list += created_order
-
/datum/component/armament/company_imports/proc/cost_calculate(cost)
. = cost
. *= SSeconomy.pack_price_modifier
@@ -431,86 +278,13 @@
return
switch(action)
- if("set_ammo_amount")
- var/target = text2num(params["chosen_amount"])
- ammo_purchase_num = clamp(target, 1, MAX_AMMO_AMOUNT)
-
- if("buy_company")
- var/target = params["selected_company"]
- var/obj/machinery/computer/cargo/possible_console
-
- if(console_state == CARGO_CONSOLE)
- possible_console = parent
- if(possible_console.requestonly && !self_paid)
- return
- else if(console_state == IRN_CONSOLE)
- if(!self_paid)
- to_chat(usr, span_warning("You cannot purchase companies on a tablet without privately ordering them!"))
- return
-
- for(var/find_company in SScargo_companies.unpurchased_companies)
- if(find_company != target)
- continue
-
- var/datum/cargo_company/found_company = SScargo_companies.unpurchased_companies[target]
- var/datum/bank_account/buyer = SSeconomy.get_dep_account(ACCOUNT_CAR)
-
- var/mob/living/carbon/human/user = usr
-
- if(!istype(user))
- return
-
- var/obj/item/card/id/id_card = user.get_idcard(TRUE)
-
- if(id_card?.registered_account && (console_state == IRN_CONSOLE))
- if((ACCESS_COMMAND in id_card.access) || (ACCESS_QM in id_card.access))
- parent_prog.requestonly = FALSE
- buyer = SSeconomy.get_dep_account(id_card.registered_account.account_job.paycheck_department)
- parent_prog.can_approve_requests = TRUE
- else
- parent_prog.requestonly = TRUE
- parent_prog.can_approve_requests = FALSE
- else
- parent_prog?.requestonly = TRUE
-
- if(self_paid)
-
- if(!istype(id_card))
- to_chat(user, span_warning("No ID card detected."))
- return
-
- if(istype(id_card, /obj/item/card/id/departmental_budget))
- to_chat(user, span_warning("[id_card] cannot be used to make purchases."))
- return
-
- var/datum/bank_account/account = id_card.registered_account
-
- if(!istype(account))
- to_chat(user, span_warning("Invalid bank account."))
- return
-
- buyer = account
-
- var/assigned_cost = -found_company.cost
- var/do_payment = TRUE
- if(!SScargo_companies.handout_picked && (found_company in SScargo_companies.chosen_handouts))
- do_payment = FALSE
- SScargo_companies.handout_picked = TRUE
- if(do_payment)
- if(!buyer.adjust_money(assigned_cost))
- return
- if(possible_console)
- possible_console.radio_wrapper(possible_console, "[find_company] has been purchased by [user] on [self_paid ? "[buyer.account_holder]'s balance" : "Cargo Budget"] for [abs(assigned_cost)].", RADIO_CHANNEL_SUPPLY)
-
- SScargo_companies.purchased_companies[find_company] = found_company
- SScargo_companies.unpurchased_companies.Remove(find_company)
- break
-
if("toggleprivate")
var/obj/item/card/id/id_card
var/mob/living/carbon/human/the_person = usr
if(!istype(the_person))
+ if(issilicon(the_person))
+ self_paid = FALSE
return
if(console_state == IRN_CONSOLE)
diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/_armament_basetype.dm b/modular_skyrat/modules/company_imports/code/armament_datums/_armament_basetype.dm
new file mode 100644
index 00000000000..f01d5c1ba1a
--- /dev/null
+++ b/modular_skyrat/modules/company_imports/code/armament_datums/_armament_basetype.dm
@@ -0,0 +1,8 @@
+/datum/armament_entry/company_import
+ max_purchase = 0
+ category_item_limit = 0
+ cost = CARGO_CRATE_VALUE
+ /// Bitflag of the company
+ var/company_bitflag
+ /// If this requires a multitooled console to be visible
+ var/contraband = FALSE
diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/bolt_nanotrasen_firearms.dm b/modular_skyrat/modules/company_imports/code/armament_datums/bolt_nanotrasen_firearms.dm
index 1bb67f040be..ccbfcc9762b 100644
--- a/modular_skyrat/modules/company_imports/code/armament_datums/bolt_nanotrasen_firearms.dm
+++ b/modular_skyrat/modules/company_imports/code/armament_datums/bolt_nanotrasen_firearms.dm
@@ -10,96 +10,105 @@
/datum/armament_entry/company_import/nanotrasen_bolt_weapons/armor/slim_vest
name = "type I vest - slim"
item_type = /obj/item/clothing/suit/armor/vest
- lower_cost = CARGO_CRATE_VALUE
- upper_cost = CARGO_CRATE_VALUE * 1.5
- stock_mult = 2
+ cost = PAYCHECK_CREW * 3
/datum/armament_entry/company_import/nanotrasen_bolt_weapons/armor/normal_vest
name = "type I vest - normal"
item_type = /obj/item/clothing/suit/armor/vest/alt
- lower_cost = CARGO_CRATE_VALUE
- upper_cost = CARGO_CRATE_VALUE * 1.5
- stock_mult = 2
+ cost = PAYCHECK_CREW * 3
// Fully non-lethal weapons
/datum/armament_entry/company_import/nanotrasen_bolt_weapons/nonlethal
subcategory = "Non-Lethal Weapons"
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
/datum/armament_entry/company_import/nanotrasen_bolt_weapons/nonlethal/responder
item_type = /obj/item/gun/energy/disabler/bolt_disabler
- lower_cost = CARGO_CRATE_VALUE * 2
- upper_cost = CARGO_CRATE_VALUE * 4
- stock_mult = 2
+ cost = PAYCHECK_CREW * 5
/datum/armament_entry/company_import/nanotrasen_bolt_weapons/nonlethal/pepperball
item_type = /obj/item/gun/ballistic/automatic/pistol/pepperball
- lower_cost = CARGO_CRATE_VALUE * 2
- upper_cost = CARGO_CRATE_VALUE * 4
- stock_mult = 2
+ cost = PAYCHECK_CREW * 5
// Lethal pistols, requires some company interest first
/datum/armament_entry/company_import/nanotrasen_bolt_weapons/lethal_sidearm
subcategory = "Lethal Sidearms"
- interest_addition = COMPANY_INTEREST_GAIN_BIG
- interest_required = COMPANY_SOME_INTEREST
/datum/armament_entry/company_import/nanotrasen_bolt_weapons/lethal_sidearm/detective_revolver
item_type = /obj/item/gun/ballistic/revolver/c38/detective
- lower_cost = CARGO_CRATE_VALUE * 1.5
- upper_cost = CARGO_CRATE_VALUE * 2.5
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
+ cost = PAYCHECK_COMMAND * 4
/* BUBBERSTATION EDIT REMOVAL
/datum/armament_entry/company_import/nanotrasen_bolt_weapons/lethal_sidearm/g17
item_type = /obj/item/gun/ballistic/automatic/pistol/g17
- lower_cost = CARGO_CRATE_VALUE * 4
- upper_cost = CARGO_CRATE_VALUE * 6
+ cost = PAYCHECK_COMMAND * 4
/datum/armament_entry/company_import/nanotrasen_bolt_weapons/lethal_sidearm/mk58
item_type = /obj/item/gun/ballistic/automatic/pistol/mk58
- lower_cost = CARGO_CRATE_VALUE * 4
- upper_cost = CARGO_CRATE_VALUE * 6
+ cost = PAYCHECK_COMMAND * 4
/datum/armament_entry/company_import/nanotrasen_bolt_weapons/lethal_sidearm/m1911
item_type = /obj/item/gun/ballistic/automatic/pistol/m1911
- lower_cost = CARGO_CRATE_VALUE * 5
- upper_cost = CARGO_CRATE_VALUE * 7
+ cost = PAYCHECK_COMMAND * 4
+
+/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines
+ subcategory = "Sidearm Magazines"
+ cost = PAYCHECK_CREW
+
+/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines/c38speedloader
+ item_type = /obj/item/ammo_box/c38
+
+/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines/c38speedloader_rubber
+ item_type = /obj/item/ammo_box/c38/match/bouncy
+
+/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines/g17
+ item_type = /obj/item/ammo_box/magazine/multi_sprite/g17
+
+/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines/g17_rubber
+ item_type = /obj/item/ammo_box/magazine/multi_sprite/g17/rubber
+
+/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines/mk58
+ item_type = /obj/item/ammo_box/magazine/multi_sprite/mk58
+
+/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines/mk58_rubber
+ item_type = /obj/item/ammo_box/magazine/multi_sprite/mk58/rubber
+
+/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines/m1911
+ item_type = /obj/item/ammo_box/magazine/m45
*/
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/lethal_sidearm/energy_holster
- item_type = /obj/item/storage/belt/holster/energy/thermal
- lower_cost = CARGO_CRATE_VALUE * 5
- upper_cost = CARGO_CRATE_VALUE * 9
-
// Lethal anything that's not a pistol, requires high company interest
/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm
subcategory = "Lethal Longarms"
- interest_addition = COMPANY_INTEREST_GAIN_BIG
- interest_required = COMPANY_HIGH_INTEREST
restricted = TRUE
-
+/*
/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm/riot_shotgun
item_type = /obj/item/gun/ballistic/shotgun/riot
- lower_cost = CARGO_CRATE_VALUE * 10
- upper_cost = CARGO_CRATE_VALUE * 15
+ cost = PAYCHECK_COMMAND * 6
/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm/m23
item_type = /obj/item/gun/ballistic/shotgun/m23
- lower_cost = CARGO_CRATE_VALUE * 10
- upper_cost = CARGO_CRATE_VALUE * 15
+ cost = PAYCHECK_COMMAND * 8
-/* BUBBERSTATION EDIT REMOVAL
/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm/wt550
item_type = /obj/item/gun/ballistic/automatic/wt550
- lower_cost = CARGO_CRATE_VALUE * 10
- upper_cost = CARGO_CRATE_VALUE * 15
+ cost = PAYCHECK_COMMAND * 6
/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm/cmg
item_type = /obj/item/gun/ballistic/automatic/cmg
- lower_cost = CARGO_CRATE_VALUE * 10
- upper_cost = CARGO_CRATE_VALUE * 15
-*/
+ cost = PAYCHECK_COMMAND * 6
+
+/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm_magazines
+ subcategory = "Longarm Magazines"
+ cost = PAYCHECK_CREW
+
+/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm_magazines/wt550
+ item_type = /obj/item/ammo_box/magazine/wt550m9
+
+/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm_magazines/cmg
+ item_type = /obj/item/ammo_box/magazine/multi_sprite/cmg/lethal
+
+/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm_magazines/cmg_rubber
+ item_type = /obj/item/ammo_box/magazine/multi_sprite/cmg
+ */
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 4c566a61c92..4bf4c720d0f 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
@@ -1,24 +1,3 @@
-#define PRICE_FIRST_AID_BASIC_LOWER 0.1
-#define PRICE_FIRST_AID_BASIC_HIGHER 0.2
-#define PRICE_FIRST_AID_MEDIUM_LOWER 0.3
-#define PRICE_FIRST_AID_MEDIUM_HIGHER 0.4
-#define PRICE_FIRST_AID_PREMIUM_LOWER 0.6
-#define PRICE_FIRST_AID_PREMIUM_HIGHER 0.7
-
-#define PRICE_CHEM_CHEAP_LOWER 4.8
-#define PRICE_CHEM_CHEAP_HIGHER 5.7
-#define PRICE_CHEM_MEDIUM_LOWER 4
-#define PRICE_CHEM_MEDIUM_HIGHER 4.4
-#define PRICE_CHEM_PREMIUM_LOWER 3
-#define PRICE_CHEM_PREMIUM_HIGHER 3.5
-#define PRICE_CYBER_ORGAN_LOWER 2
-#define PRICE_CYBER_ORGAN_HIGHER 5
-#define PRICE_CYBER_AUGMENT_LOWER 3
-#define PRICE_CYBER_AUGMENT_HIGHER 6
-
-#define MODULE_MID_LOWER 2
-#define MODULE_MID_UPPER 3 //I stole these from nakamura, bite me
-
/datum/armament_entry/company_import/deforest
category = DEFOREST_MEDICAL_NAME
company_bitflag = CARGO_COMPANY_DEFOREST
@@ -26,61 +5,66 @@
// Basic first aid supplies like gauze, sutures, mesh, so on
/datum/armament_entry/company_import/deforest/first_aid
- subcategory = "First-Aid Supplies"
+ subcategory = "First-Aid Consumables"
/datum/armament_entry/company_import/deforest/first_aid/gauze
item_type = /obj/item/stack/medical/gauze/twelve
- lower_cost = CARGO_CRATE_VALUE * PRICE_FIRST_AID_BASIC_LOWER
- upper_cost = CARGO_CRATE_VALUE * PRICE_FIRST_AID_BASIC_HIGHER
- stock_mult = 3
- interest_addition = COMPANY_INTEREST_GAIN_PITIFUL
-
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/deforest/first_aid/bruise_pack
item_type = /obj/item/stack/medical/bruise_pack
- lower_cost = CARGO_CRATE_VALUE * PRICE_FIRST_AID_MEDIUM_LOWER
- upper_cost = CARGO_CRATE_VALUE * PRICE_FIRST_AID_MEDIUM_HIGHER
- stock_mult = 3
- interest_addition = COMPANY_INTEREST_GAIN_PITIFUL
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/deforest/first_aid/ointment
item_type = /obj/item/stack/medical/ointment
- lower_cost = CARGO_CRATE_VALUE * PRICE_FIRST_AID_MEDIUM_LOWER
- upper_cost = CARGO_CRATE_VALUE * PRICE_FIRST_AID_MEDIUM_HIGHER
- stock_mult = 3
- interest_addition = COMPANY_INTEREST_GAIN_PITIFUL
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/deforest/first_aid/suture
item_type = /obj/item/stack/medical/suture
- lower_cost = CARGO_CRATE_VALUE * PRICE_FIRST_AID_BASIC_LOWER
- upper_cost = CARGO_CRATE_VALUE * PRICE_FIRST_AID_BASIC_HIGHER
- stock_mult = 3
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/deforest/first_aid/mesh
item_type = /obj/item/stack/medical/mesh
- lower_cost = CARGO_CRATE_VALUE * PRICE_FIRST_AID_BASIC_LOWER
- upper_cost = CARGO_CRATE_VALUE * PRICE_FIRST_AID_BASIC_HIGHER
- stock_mult = 3
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/deforest/first_aid/bone_gel
item_type = /obj/item/stack/medical/bone_gel
- lower_cost = CARGO_CRATE_VALUE * PRICE_FIRST_AID_MEDIUM_LOWER
- upper_cost = CARGO_CRATE_VALUE * PRICE_FIRST_AID_MEDIUM_HIGHER
- stock_mult = 2
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/deforest/first_aid/medicated_sutures
item_type = /obj/item/stack/medical/suture/medicated
- lower_cost = CARGO_CRATE_VALUE * PRICE_FIRST_AID_PREMIUM_LOWER
- upper_cost = CARGO_CRATE_VALUE * PRICE_FIRST_AID_PREMIUM_HIGHER
- stock_mult = 2
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/deforest/first_aid/advanced_mesh
item_type = /obj/item/stack/medical/mesh/advanced
- lower_cost = CARGO_CRATE_VALUE * PRICE_FIRST_AID_PREMIUM_LOWER
- upper_cost = CARGO_CRATE_VALUE * PRICE_FIRST_AID_PREMIUM_HIGHER
- stock_mult = 2
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_CREW
+
+/datum/armament_entry/company_import/deforest/medpens
+ subcategory = "Autoinjectors"
+ cost = PAYCHECK_COMMAND * 1.5
+
+/datum/armament_entry/company_import/deforest/medpens/epipen
+ item_type = /obj/item/reagent_containers/hypospray/medipen
+
+/datum/armament_entry/company_import/deforest/medpens/emergency_pen
+ item_type = /obj/item/reagent_containers/hypospray/medipen/ekit
+
+/datum/armament_entry/company_import/deforest/medpens/blood_loss
+ item_type = /obj/item/reagent_containers/hypospray/medipen/blood_loss
+
+/datum/armament_entry/company_import/deforest/medpens/atropine
+ item_type = /obj/item/reagent_containers/hypospray/medipen/atropine
+
+/datum/armament_entry/company_import/deforest/medpens/oxandrolone
+ item_type = /obj/item/reagent_containers/hypospray/medipen/oxandrolone
+
+/datum/armament_entry/company_import/deforest/medpens/salacid
+ item_type = /obj/item/reagent_containers/hypospray/medipen/salacid
+
+/datum/armament_entry/company_import/deforest/medpens/penacid
+ item_type = /obj/item/reagent_containers/hypospray/medipen/penacid
+
+/datum/armament_entry/company_import/deforest/medpens/salbutamol
+ item_type = /obj/item/reagent_containers/hypospray/medipen/salbutamol
// Various chemicals, with a box of syringes to come with
@@ -89,48 +73,39 @@
/datum/armament_entry/company_import/deforest/medical_chems/syringes
item_type = /obj/item/storage/box/syringes
- lower_cost = CARGO_CRATE_VALUE * PRICE_CHEM_CHEAP_LOWER
- upper_cost = CARGO_CRATE_VALUE * PRICE_CHEM_CHEAP_HIGHER
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/deforest/medical_chems/epinephrine
item_type = /obj/item/reagent_containers/cup/bottle/epinephrine
- lower_cost = CARGO_CRATE_VALUE * PRICE_CHEM_MEDIUM_LOWER
- upper_cost = CARGO_CRATE_VALUE * PRICE_CHEM_MEDIUM_HIGHER
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/deforest/medical_chems/mannitol
item_type = /obj/item/reagent_containers/cup/bottle/mannitol
- lower_cost = CARGO_CRATE_VALUE * PRICE_CHEM_CHEAP_LOWER
- upper_cost = CARGO_CRATE_VALUE * PRICE_CHEM_CHEAP_HIGHER
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/deforest/medical_chems/morphine
item_type = /obj/item/reagent_containers/cup/bottle/morphine
- lower_cost = CARGO_CRATE_VALUE * PRICE_CHEM_MEDIUM_LOWER
- upper_cost = CARGO_CRATE_VALUE * PRICE_CHEM_MEDIUM_HIGHER
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/deforest/medical_chems/multiver
item_type = /obj/item/reagent_containers/cup/bottle/multiver
- lower_cost = CARGO_CRATE_VALUE * PRICE_CHEM_CHEAP_LOWER
- upper_cost = CARGO_CRATE_VALUE * PRICE_CHEM_CHEAP_HIGHER
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/deforest/medical_chems/formadehyde
item_type = /obj/item/reagent_containers/cup/bottle/formaldehyde
- lower_cost = CARGO_CRATE_VALUE * PRICE_CHEM_CHEAP_LOWER
- upper_cost = CARGO_CRATE_VALUE * PRICE_CHEM_CHEAP_HIGHER
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/deforest/medical_chems/potassium_iodide
item_type = /obj/item/reagent_containers/cup/bottle/potass_iodide
- lower_cost = CARGO_CRATE_VALUE * PRICE_CHEM_CHEAP_LOWER
- upper_cost = CARGO_CRATE_VALUE * PRICE_CHEM_CHEAP_HIGHER
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/deforest/medical_chems/atropine
item_type = /obj/item/reagent_containers/cup/bottle/atropine
- lower_cost = CARGO_CRATE_VALUE * PRICE_CHEM_PREMIUM_LOWER
- upper_cost = CARGO_CRATE_VALUE * PRICE_CHEM_PREMIUM_HIGHER
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/deforest/medical_chems/syriniver
item_type = /obj/item/reagent_containers/cup/bottle/syriniver
- lower_cost = CARGO_CRATE_VALUE * PRICE_CHEM_MEDIUM_LOWER
- upper_cost = CARGO_CRATE_VALUE * PRICE_CHEM_MEDIUM_HIGHER
+ cost = PAYCHECK_CREW
// Equipment, from defibs to scanners to surgical tools
@@ -139,78 +114,49 @@
/datum/armament_entry/company_import/deforest/equipment/health_analyzer
item_type = /obj/item/healthanalyzer
- lower_cost = CARGO_CRATE_VALUE * 1
- upper_cost = CARGO_CRATE_VALUE * 1.4
- stock_mult = 2
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/deforest/equipment/loaded_defib
item_type = /obj/item/defibrillator/loaded
- lower_cost = CARGO_CRATE_VALUE * 1
- upper_cost = CARGO_CRATE_VALUE * 1.5
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/deforest/equipment/surgical_tools
item_type = /obj/item/storage/backpack/duffelbag/med/surgery
- lower_cost = CARGO_CRATE_VALUE * 2
- upper_cost = CARGO_CRATE_VALUE * 2.5
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/deforest/equipment/advanced_health_analyer
item_type = /obj/item/healthanalyzer/advanced
- lower_cost = CARGO_CRATE_VALUE * 2.5
- upper_cost = CARGO_CRATE_VALUE * 3
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_COMMAND * 3
/datum/armament_entry/company_import/deforest/equipment/penlite_defib_mount
item_type = /obj/item/wallframe/defib_mount/charging
- lower_cost = CARGO_CRATE_VALUE * 4
- upper_cost = CARGO_CRATE_VALUE * 6
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_CREW * 3
/datum/armament_entry/company_import/deforest/equipment/advanced_scalpel
item_type = /obj/item/scalpel/advanced
- lower_cost = CARGO_CRATE_VALUE * 2
- upper_cost = CARGO_CRATE_VALUE * 3
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
- interest_required = COMPANY_HIGH_INTEREST
+ cost = PAYCHECK_COMMAND * 3
/datum/armament_entry/company_import/deforest/equipment/advanced_retractor
item_type = /obj/item/retractor/advanced
- lower_cost = CARGO_CRATE_VALUE * 2
- upper_cost = CARGO_CRATE_VALUE * 3
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
- interest_required = COMPANY_HIGH_INTEREST
+ cost = PAYCHECK_COMMAND * 3
/datum/armament_entry/company_import/deforest/equipment/advanced_cautery
item_type = /obj/item/cautery/advanced
- lower_cost = CARGO_CRATE_VALUE * 2
- upper_cost = CARGO_CRATE_VALUE * 3
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
- interest_required = COMPANY_HIGH_INTEREST
+ cost = PAYCHECK_COMMAND * 3
/datum/armament_entry/company_import/deforest/equipment/medigun_upgrade
item_type = /obj/item/device/custom_kit/medigun_fastcharge
- lower_cost = CARGO_CRATE_VALUE * 2
- upper_cost = CARGO_CRATE_VALUE * 5
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_COMMAND * 2
/datum/armament_entry/company_import/deforest/equipment/afad
item_type = /obj/item/gun/medbeam/afad
- lower_cost = CARGO_CRATE_VALUE * 3
- upper_cost = CARGO_CRATE_VALUE * 7
- interest_addition = COMPANY_INTEREST_GAIN_BIG
- interest_required = COMPANY_HIGH_INTEREST
+ cost = PAYCHECK_COMMAND * 5
// Modsuit Modules from the medical category, here instead of in Nakamura because nobody buys from this company
/datum/armament_entry/company_import/deforest/medical_modules
subcategory = "MOD Medical Modules"
- interest_required = COMPANY_SOME_INTEREST
- lower_cost = CARGO_CRATE_VALUE * MODULE_MID_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_MID_UPPER
+ cost = PAYCHECK_COMMAND * 2
/datum/armament_entry/company_import/deforest/medical_modules/injector
name = "MOD injector module"
@@ -236,10 +182,7 @@
/datum/armament_entry/company_import/deforest/cyber_organs
subcategory = "Premium Cybernetic Organs"
- lower_cost = CARGO_CRATE_VALUE * PRICE_CYBER_ORGAN_LOWER
- upper_cost = CARGO_CRATE_VALUE * PRICE_CYBER_ORGAN_HIGHER
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_CREW * 3
/datum/armament_entry/company_import/deforest/cyber_organs/eyes
name = "shielded cybernetic eyes"
@@ -266,10 +209,7 @@
item_type = /obj/item/storage/organbox/advanced_cyber_stomach
/datum/armament_entry/company_import/deforest/cyber_organs/augments
- lower_cost = CARGO_CRATE_VALUE * PRICE_CYBER_AUGMENT_LOWER
- upper_cost = CARGO_CRATE_VALUE * PRICE_CYBER_AUGMENT_HIGHER
- interest_addition = COMPANY_INTEREST_GAIN_BIG
- interest_required = COMPANY_HIGH_INTEREST
+ cost = PAYCHECK_COMMAND * 2
/datum/armament_entry/company_import/deforest/cyber_organs/augments/nutriment
name = "Nutriment pump implant"
@@ -292,34 +232,17 @@
/* BUBBERSTATION EDIT REMOVAL
/datum/armament_entry/company_import/deforest/defense
subcategory = "Personal Defense Equipment"
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
- interest_required = COMPANY_SOME_INTEREST
contraband = TRUE
/datum/armament_entry/company_import/deforest/defense/firefly
item_type = /obj/item/gun/ballistic/automatic/pistol/firefly
- lower_cost = CARGO_CRATE_VALUE * 2
- upper_cost = CARGO_CRATE_VALUE * 3
+ cost = PAYCHECK_COMMAND * 4
+
+/datum/armament_entry/company_import/deforest/defense/firefly_mag
+ item_type = /obj/item/ammo_box/magazine/multi_sprite/firefly
+ cost = PAYCHECK_CREW
+
+/datum/armament_entry/company_import/deforest/defense/firefly_mag_rubber
+ item_type = /obj/item/ammo_box/magazine/multi_sprite/firefly/rubber
+ cost = PAYCHECK_CREW
*/
-
-#undef PRICE_FIRST_AID_BASIC_LOWER
-#undef PRICE_FIRST_AID_BASIC_HIGHER
-#undef PRICE_FIRST_AID_MEDIUM_LOWER
-#undef PRICE_FIRST_AID_MEDIUM_HIGHER
-#undef PRICE_FIRST_AID_PREMIUM_LOWER
-#undef PRICE_FIRST_AID_PREMIUM_HIGHER
-
-#undef PRICE_CHEM_CHEAP_LOWER
-#undef PRICE_CHEM_CHEAP_HIGHER
-#undef PRICE_CHEM_MEDIUM_LOWER
-#undef PRICE_CHEM_MEDIUM_HIGHER
-#undef PRICE_CHEM_PREMIUM_LOWER
-#undef PRICE_CHEM_PREMIUM_HIGHER
-
-#undef MODULE_MID_LOWER
-#undef MODULE_MID_UPPER
-
-#undef PRICE_CYBER_ORGAN_LOWER
-#undef PRICE_CYBER_ORGAN_HIGHER
-#undef PRICE_CYBER_AUGMENT_LOWER
-#undef PRICE_CYBER_AUGMENT_HIGHER
diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/jarnsmiour.dm b/modular_skyrat/modules/company_imports/code/armament_datums/jarnsmiour.dm
index 2f74788b3b9..8ed7c3385ad 100644
--- a/modular_skyrat/modules/company_imports/code/armament_datums/jarnsmiour.dm
+++ b/modular_skyrat/modules/company_imports/code/armament_datums/jarnsmiour.dm
@@ -9,34 +9,19 @@
/datum/armament_entry/company_import/blacksteel/blade/hunting_knife
item_type = /obj/item/knife/hunting
- lower_cost = CARGO_CRATE_VALUE * 0.5
- upper_cost = CARGO_CRATE_VALUE * 1
-
-/datum/armament_entry/company_import/blacksteel/blade/hatchet
- name = "Blacksteel (TM) hatchet"
- description = "A short handled hatchet forged from Jarnsmiour's signature Blacksteel (TM), quality guaranteed." // Hint: This is a lie
- item_type = /obj/item/hatchet/wooden
- lower_cost = CARGO_CRATE_VALUE * 0.7
- upper_cost = CARGO_CRATE_VALUE * 1.2
+ cost = PAYCHECK_CREW * 2
/datum/armament_entry/company_import/blacksteel/blade/survival_knife
item_type = /obj/item/knife/combat/survival
- lower_cost = CARGO_CRATE_VALUE * 1.2
- upper_cost = CARGO_CRATE_VALUE * 1.7
+ cost = PAYCHECK_CREW * 2
/datum/armament_entry/company_import/blacksteel/blade/bowie_knife
item_type = /obj/item/storage/belt/bowie_sheath
- lower_cost = CARGO_CRATE_VALUE * 3
- upper_cost = CARGO_CRATE_VALUE * 5
- interest_required = COMPANY_SOME_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
+ cost = PAYCHECK_COMMAND * 3
/datum/armament_entry/company_import/blacksteel/blade/shamshir_sabre
item_type = /obj/item/storage/belt/sabre/cargo
- lower_cost = CARGO_CRATE_VALUE * 5
- upper_cost = CARGO_CRATE_VALUE * 7
- interest_required = COMPANY_SOME_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
+ cost = PAYCHECK_COMMAND * 3
// Forging tools, blacksteel company sells the tools and materials they use as well!
@@ -45,18 +30,15 @@
/datum/armament_entry/company_import/blacksteel/forging_tools/billows
item_type = /obj/item/forging/billow
- lower_cost = CARGO_CRATE_VALUE * 0.25
- upper_cost = CARGO_CRATE_VALUE * 0.4
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/blacksteel/forging_tools/hammer
item_type = /obj/item/forging/hammer
- lower_cost = CARGO_CRATE_VALUE * 0.25
- upper_cost = CARGO_CRATE_VALUE * 0.4
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/blacksteel/forging_tools/tongs
item_type = /obj/item/forging/tongs
- lower_cost = CARGO_CRATE_VALUE * 0.25
- upper_cost = CARGO_CRATE_VALUE * 0.4
+ cost = PAYCHECK_LOWER
// Fancy sounding and looking bars of metal that most definitely aren't just common metals with a fancy sounding name
@@ -66,31 +48,19 @@
/datum/armament_entry/company_import/blacksteel/forging_metals/fake_cobalt
item_type = /obj/item/stack/sheet/cobolterium/three
description = "A three-pack of our finest cobolterium alloy, with an unmatched regal blue color for creating the strongest metalworks from."
- lower_cost = CARGO_CRATE_VALUE
- upper_cost = CARGO_CRATE_VALUE * 4
- interest_required = COMPANY_SOME_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/blacksteel/forging_metals/fake_copper
item_type = /obj/item/stack/sheet/copporcitite/three
description = "A three-pack of our finest copporcitite alloy, with a powerful, fiery orange color for creating the strongest metalworks from."
- lower_cost = CARGO_CRATE_VALUE
- upper_cost = CARGO_CRATE_VALUE * 4
- interest_required = COMPANY_SOME_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/blacksteel/forging_metals/fake_really_blue_aluminum
item_type = /obj/item/stack/sheet/tinumium/three
description = "A three-pack of our finest tinumium alloy, with a mystical faded blue color for creating the strongest metalworks from."
- lower_cost = CARGO_CRATE_VALUE
- upper_cost = CARGO_CRATE_VALUE * 4
- interest_required = COMPANY_SOME_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/blacksteel/forging_metals/fake_brass
item_type = /obj/item/stack/sheet/brussite/three
description = "A three-pack of our finest brussite alloy, with a robust yellow color for creating the strongest metalworks from."
- lower_cost = CARGO_CRATE_VALUE
- upper_cost = CARGO_CRATE_VALUE * 4
- interest_required = COMPANY_SOME_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
+ cost = PAYCHECK_CREW
diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/kahraman_industries.dm b/modular_skyrat/modules/company_imports/code/armament_datums/kahraman_industries.dm
index 04d288b80a2..f15da1c1750 100644
--- a/modular_skyrat/modules/company_imports/code/armament_datums/kahraman_industries.dm
+++ b/modular_skyrat/modules/company_imports/code/armament_datums/kahraman_industries.dm
@@ -5,47 +5,31 @@
// Mining PPE, SEVAs and hardhats, have you passed your OSHA inspection today?
/datum/armament_entry/company_import/kahraman/ppe
- subcategory = "OSHA Certified Protective Equipment"
-
-/datum/armament_entry/company_import/kahraman/ppe/hardhat
- item_type = /obj/item/clothing/head/utility/hardhat/orange
- lower_cost = CARGO_CRATE_VALUE * 0.25
- upper_cost = CARGO_CRATE_VALUE
+ subcategory = "FOHSA Certified Protective Equipment"
/datum/armament_entry/company_import/kahraman/ppe/weldhat
item_type = /obj/item/clothing/head/utility/hardhat/welding/orange
- lower_cost = CARGO_CRATE_VALUE * 0.75
- upper_cost = CARGO_CRATE_VALUE * 1.25
+ cost = PAYCHECK_CREW * 1.5
/datum/armament_entry/company_import/kahraman/ppe/gasmask
item_type = /obj/item/clothing/mask/gas/alt
- lower_cost = CARGO_CRATE_VALUE * 0.1
- upper_cost = CARGO_CRATE_VALUE * 0.3
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/kahraman/ppe/hazard_vest
item_type = /obj/item/clothing/suit/hazardvest
- lower_cost = CARGO_CRATE_VALUE * 0.3
- upper_cost = CARGO_CRATE_VALUE * 0.6
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/kahraman/ppe/seva_mask
item_type = /obj/item/clothing/mask/gas/seva
- lower_cost = CARGO_CRATE_VALUE * 0.5
- upper_cost = CARGO_CRATE_VALUE
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_CREW * 1.5
/datum/armament_entry/company_import/kahraman/ppe/seva_suit
item_type = /obj/item/clothing/suit/hooded/seva
- lower_cost = CARGO_CRATE_VALUE
- upper_cost = CARGO_CRATE_VALUE * 2
- interest_required = COMPANY_SOME_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
+ cost = PAYCHECK_COMMAND * 2
/datum/armament_entry/company_import/kahraman/ppe/sensors_cuffs
item_type = /obj/item/kheiral_cuffs
- lower_cost = CARGO_CRATE_VALUE * 1.5
- upper_cost = CARGO_CRATE_VALUE * 3
- interest_required = COMPANY_SOME_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_BIG
+ cost = PAYCHECK_COMMAND * 5
// Hand held mining equipment
@@ -54,99 +38,74 @@
/datum/armament_entry/company_import/kahraman/mining_tool/drill
item_type = /obj/item/pickaxe/drill
- lower_cost = CARGO_CRATE_VALUE * 0.75
- upper_cost = CARGO_CRATE_VALUE * 1.5
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/kahraman/mining_tool/resonator
item_type = /obj/item/resonator
- lower_cost = CARGO_CRATE_VALUE
- upper_cost = CARGO_CRATE_VALUE * 2
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/kahraman/mining_tool/pka
item_type = /obj/item/gun/energy/recharge/kinetic_accelerator
- lower_cost = CARGO_CRATE_VALUE
- upper_cost = CARGO_CRATE_VALUE * 2
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/kahraman/mining_tool/cutter
item_type = /obj/item/gun/energy/plasmacutter
- lower_cost = CARGO_CRATE_VALUE
- upper_cost = CARGO_CRATE_VALUE * 2
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/kahraman/mining_tool/diamond_drill
item_type = /obj/item/pickaxe/drill/diamonddrill
- lower_cost = CARGO_CRATE_VALUE
- upper_cost = CARGO_CRATE_VALUE * 2
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_COMMAND * 2
/datum/armament_entry/company_import/kahraman/mining_tool/advanced_cutter
item_type = /obj/item/gun/energy/plasmacutter/adv
- lower_cost = CARGO_CRATE_VALUE * 1.5
- upper_cost = CARGO_CRATE_VALUE * 3
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_COMMAND * 4
/datum/armament_entry/company_import/kahraman/mining_tool/super_resonator
item_type = /obj/item/resonator/upgraded
- lower_cost = CARGO_CRATE_VALUE * 1.5
- upper_cost = CARGO_CRATE_VALUE * 3
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_COMMAND * 4
/datum/armament_entry/company_import/kahraman/mining_tool/jackhammer
item_type = /obj/item/pickaxe/drill/jackhammer
- lower_cost = CARGO_CRATE_VALUE * 1.5
- upper_cost = CARGO_CRATE_VALUE * 3
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_COMMAND * 3
/datum/armament_entry/company_import/kahraman/sensing
subcategory = "Sensing Equipment"
/datum/armament_entry/company_import/kahraman/sensing/mesons
item_type = /obj/item/clothing/glasses/meson
- lower_cost = CARGO_CRATE_VALUE * 0.2
- upper_cost = CARGO_CRATE_VALUE * 0.5
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/kahraman/sensing/autoscanner
item_type = /obj/item/t_scanner/adv_mining_scanner/lesser
- lower_cost = CARGO_CRATE_VALUE * 0.4
- upper_cost = CARGO_CRATE_VALUE
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/kahraman/sensing/super_autoscanner
item_type = /obj/item/t_scanner/adv_mining_scanner
- lower_cost = CARGO_CRATE_VALUE * 0.7
- upper_cost = CARGO_CRATE_VALUE * 1.3
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_COMMAND * 3
/datum/armament_entry/company_import/kahraman/sensing/nvg_mesons
item_type = /obj/item/clothing/glasses/meson/night
- lower_cost = CARGO_CRATE_VALUE
- upper_cost = CARGO_CRATE_VALUE * 1.5
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_COMMAND * 3
/datum/armament_entry/company_import/kahraman/mecha_tools
subcategory = "Heavy Powered Mining Equipment"
/datum/armament_entry/company_import/kahraman/mecha_tools/scanner
item_type = /obj/item/mecha_parts/mecha_equipment/mining_scanner
- lower_cost = CARGO_CRATE_VALUE * 0.5
- upper_cost = CARGO_CRATE_VALUE
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/kahraman/mecha_tools/drill
item_type = /obj/item/mecha_parts/mecha_equipment/drill
- lower_cost = CARGO_CRATE_VALUE
- upper_cost = CARGO_CRATE_VALUE * 1.5
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/kahraman/mecha_tools/pka
item_type = /obj/item/mecha_parts/mecha_equipment/weapon/energy/mecha_kineticgun
- lower_cost = CARGO_CRATE_VALUE * 1.25
- upper_cost = CARGO_CRATE_VALUE * 2.5
+ cost = PAYCHECK_CREW * 3
/datum/armament_entry/company_import/kahraman/mecha_tools/diamond_drill
item_type = /obj/item/mecha_parts/mecha_equipment/drill/diamonddrill
- lower_cost = CARGO_CRATE_VALUE * 2
- upper_cost = CARGO_CRATE_VALUE * 3
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_CREW * 3
/datum/armament_entry/company_import/kahraman/mecha_tools/cutter
item_type = /obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma
- lower_cost = CARGO_CRATE_VALUE * 2
- upper_cost = CARGO_CRATE_VALUE * 3
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_CREW * 3
diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/microstar_energy.dm b/modular_skyrat/modules/company_imports/code/armament_datums/microstar_energy.dm
index 4c3c1174fa1..35c89c03b1f 100644
--- a/modular_skyrat/modules/company_imports/code/armament_datums/microstar_energy.dm
+++ b/modular_skyrat/modules/company_imports/code/armament_datums/microstar_energy.dm
@@ -1,174 +1,111 @@
-#define PRICE_CHEAPENERGYGUN_LOW 1.5
-#define PRICE_CHEAPENERGYGUN_HIGH 2.5
-#define PRICE_MEDIUMENERGYGUN_LOW 3
-#define PRICE_MEDIUMENERGYGUN_HIGH 4
-#define PRICE_PREMIUMENERGYGUN_LOW 4.5
-#define PRICE_PREMIUMENERGYGUN_HIGH 5
-
-#define PRICE_MCRKIT_LOW 1.5
-#define PRICE_MCRKIT_HIGH 2
-
/datum/armament_entry/company_import/microstar
category = MICROSTAR_ENERGY_NAME
company_bitflag = CARGO_COMPANY_MICROSTAR
- interest_addition = COMPANY_INTEREST_GAIN_BIG
// Basic lethal/disabler beam weapons, includes the base mcr
/datum/armament_entry/company_import/microstar/basic_energy_weapons
- subcategory = "Basic Energy Weapons"
+ subcategory = "Basic Energy Smallarms"
/datum/armament_entry/company_import/microstar/basic_energy_weapons/disabler
item_type = /obj/item/gun/energy/disabler
- lower_cost = CARGO_CRATE_VALUE * PRICE_CHEAPENERGYGUN_LOW
- upper_cost = CARGO_CRATE_VALUE * PRICE_CHEAPENERGYGUN_HIGH / 1.5
- stock_mult = 2
+ cost = PAYCHECK_CREW * 5
/datum/armament_entry/company_import/microstar/basic_energy_weapons/mini_egun
item_type = /obj/item/gun/energy/e_gun/mini
- lower_cost = CARGO_CRATE_VALUE * PRICE_CHEAPENERGYGUN_LOW / 1.5
- upper_cost = CARGO_CRATE_VALUE * PRICE_CHEAPENERGYGUN_HIGH / 1.5
+ cost = PAYCHECK_CREW * 5
-/datum/armament_entry/company_import/microstar/basic_energy_weapons/sc1
+/datum/armament_entry/company_import/nanotrasen_bolt_weapons/lethal_sidearm/energy_holster
+ item_type = /obj/item/storage/belt/holster/energy/thermal
+ cost = PAYCHECK_COMMAND * 6
+
+/datum/armament_entry/company_import/microstar/basic_energy_long_weapons
+ subcategory = "Basic Energy Longarms"
+
+/datum/armament_entry/company_import/microstar/basic_energy_long_weapons/sc1
item_type = /obj/item/gun/energy/laser
- lower_cost = CARGO_CRATE_VALUE * PRICE_CHEAPENERGYGUN_LOW
- upper_cost = CARGO_CRATE_VALUE * PRICE_CHEAPENERGYGUN_HIGH
- stock_mult = 2
+ cost = PAYCHECK_CREW * 5
-/datum/armament_entry/company_import/microstar/basic_energy_weapons/sc2
+/datum/armament_entry/company_import/microstar/basic_energy_long_weapons/sc2
item_type = /obj/item/gun/energy/e_gun
- lower_cost = CARGO_CRATE_VALUE * PRICE_MEDIUMENERGYGUN_LOW
- upper_cost = CARGO_CRATE_VALUE * PRICE_MEDIUMENERGYGUN_HIGH
+ cost = PAYCHECK_COMMAND * 4
-/datum/armament_entry/company_import/microstar/basic_energy_weapons/basic_mcr
+/datum/armament_entry/company_import/microstar/basic_energy_long_weapons/basic_mcr
item_type = /obj/item/gun/microfusion/mcr01
- lower_cost = CARGO_CRATE_VALUE * PRICE_MEDIUMENERGYGUN_LOW
- upper_cost = CARGO_CRATE_VALUE * PRICE_MEDIUMENERGYGUN_HIGH
+ cost = PAYCHECK_COMMAND * 4
// More expensive, unique energy weapons
-
/datum/armament_entry/company_import/microstar/experimental_energy
subcategory = "Experimental Energy Weapons"
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_COMMAND * 6
restricted = TRUE
/datum/armament_entry/company_import/microstar/experimental_energy/hellfire
item_type = /obj/item/gun/energy/laser/hellgun
- lower_cost = CARGO_CRATE_VALUE * PRICE_PREMIUMENERGYGUN_LOW
- upper_cost = CARGO_CRATE_VALUE * PRICE_PREMIUMENERGYGUN_HIGH
/datum/armament_entry/company_import/microstar/experimental_energy/ion_carbine
item_type = /obj/item/gun/energy/ionrifle/carbine
- lower_cost = CARGO_CRATE_VALUE * PRICE_MEDIUMENERGYGUN_LOW
- upper_cost = CARGO_CRATE_VALUE * PRICE_MEDIUMENERGYGUN_HIGH
/datum/armament_entry/company_import/microstar/experimental_energy/xray_gun
item_type = /obj/item/gun/energy/xray
- lower_cost = CARGO_CRATE_VALUE * PRICE_PREMIUMENERGYGUN_LOW
- upper_cost = CARGO_CRATE_VALUE * PRICE_PREMIUMENERGYGUN_HIGH
/datum/armament_entry/company_import/microstar/experimental_energy/tesla_cannon
item_type = /obj/item/gun/energy/tesla_cannon
- lower_cost = CARGO_CRATE_VALUE * PRICE_MEDIUMENERGYGUN_LOW
- upper_cost = CARGO_CRATE_VALUE * PRICE_MEDIUMENERGYGUN_HIGH
// Preset 'loadout' kits built around a barrel attachment
/datum/armament_entry/company_import/microstar/mcr_attachments
subcategory = "Microfusion Attachment Kits"
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
+ cost = PAYCHECK_COMMAND * 4
/datum/armament_entry/company_import/microstar/mcr_attachments/hellfire
name = "microfusion hellfire kit"
item_type = /obj/item/storage/secure/briefcase/white/mcr_loadout/hellfire
- lower_cost = CARGO_CRATE_VALUE * PRICE_MCRKIT_LOW
- upper_cost = CARGO_CRATE_VALUE * PRICE_MCRKIT_HIGH
- stock_mult = 2
/datum/armament_entry/company_import/microstar/mcr_attachments/scatter
name = "microfusion scatter kit"
item_type = /obj/item/storage/secure/briefcase/white/mcr_loadout/scatter
- lower_cost = CARGO_CRATE_VALUE * PRICE_MCRKIT_LOW
- upper_cost = CARGO_CRATE_VALUE * PRICE_MCRKIT_HIGH
- stock_mult = 2
/datum/armament_entry/company_import/microstar/mcr_attachments/lance
name = "microfusion lance kit"
item_type = /obj/item/storage/secure/briefcase/white/mcr_loadout/lance
- lower_cost = CARGO_CRATE_VALUE * PRICE_MCRKIT_LOW
- upper_cost = CARGO_CRATE_VALUE * PRICE_MCRKIT_HIGH
- stock_mult = 2
/datum/armament_entry/company_import/microstar/mcr_attachments/repeater
name = "microfusion repeater kit"
item_type = /obj/item/storage/secure/briefcase/white/mcr_loadout/repeater
- lower_cost = CARGO_CRATE_VALUE * PRICE_MCRKIT_LOW
- upper_cost = CARGO_CRATE_VALUE * PRICE_MCRKIT_HIGH
- stock_mult = 2
/datum/armament_entry/company_import/microstar/mcr_attachments/tacticool
name = "microfusion suppressor kit"
item_type = /obj/item/storage/secure/briefcase/white/mcr_loadout/tacticool
- lower_cost = CARGO_CRATE_VALUE * PRICE_MCRKIT_LOW
- upper_cost = CARGO_CRATE_VALUE * PRICE_MCRKIT_HIGH
- stock_mult = 2
// Improved phase emitters, cells, and cell attachments
/datum/armament_entry/company_import/microstar/mcr_upgrades
- subcategory = "Microfusion Attachment Kits"
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
+ subcategory = "Microfusion Upgrade Kits"
/datum/armament_entry/company_import/microstar/mcr_upgrades/stabilizer
item_type = /obj/item/microfusion_cell_attachment/stabiliser
- lower_cost = CARGO_CRATE_VALUE * 0.5
- upper_cost = CARGO_CRATE_VALUE
- stock_mult = 3
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/microstar/mcr_upgrades/enhanced_part_kit
name = "microfusion enhanced parts"
item_type = /obj/item/storage/secure/briefcase/white/mcr_parts/enhanced
- lower_cost = CARGO_CRATE_VALUE * 1.5
- upper_cost = CARGO_CRATE_VALUE * 3
- stock_mult = 3
+ cost = PAYCHECK_COMMAND * 2
/datum/armament_entry/company_import/microstar/mcr_upgrades/capacity_booster
item_type = /obj/item/microfusion_cell_attachment/overcapacity
- lower_cost = CARGO_CRATE_VALUE
- upper_cost = CARGO_CRATE_VALUE * 1.5
- interest_required = COMPANY_SOME_INTEREST
- stock_mult = 3
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/microstar/mcr_upgrades/advanced_part_kit
name = "microfusion advanced parts"
item_type = /obj/item/storage/secure/briefcase/white/mcr_parts/advanced
- lower_cost = CARGO_CRATE_VALUE * 3
- upper_cost = CARGO_CRATE_VALUE * 5.5
- interest_required = COMPANY_SOME_INTEREST
- stock_mult = 3
+ cost = PAYCHECK_COMMAND * 2
/datum/armament_entry/company_import/microstar/mcr_upgrades/selfcharge
item_type = /obj/item/microfusion_cell_attachment/selfcharging
- lower_cost = CARGO_CRATE_VALUE * 2
- upper_cost = CARGO_CRATE_VALUE * 4
- interest_required = COMPANY_HIGH_INTEREST
- stock_mult = 3
+ cost = PAYCHECK_COMMAND * 4
/datum/armament_entry/company_import/microstar/mcr_upgrades/bluespace_part_kit
name = "microfusion bluespace parts"
item_type = /obj/item/storage/secure/briefcase/white/mcr_parts/bluespace
- lower_cost = CARGO_CRATE_VALUE * 5.5
- upper_cost = CARGO_CRATE_VALUE * 7
- interest_required = COMPANY_HIGH_INTEREST
- stock_mult = 3
-
-#undef PRICE_CHEAPENERGYGUN_LOW
-#undef PRICE_CHEAPENERGYGUN_HIGH
-#undef PRICE_MEDIUMENERGYGUN_LOW
-#undef PRICE_MEDIUMENERGYGUN_HIGH
-#undef PRICE_PREMIUMENERGYGUN_LOW
-#undef PRICE_PREMIUMENERGYGUN_HIGH
-
-#undef PRICE_MCRKIT_LOW
-#undef PRICE_MCRKIT_HIGH
-
+ cost = PAYCHECK_COMMAND * 6
diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/nakamura_modsuits.dm b/modular_skyrat/modules/company_imports/code/armament_datums/nakamura_modsuits.dm
index a8b0e69d5a1..dca8616f452 100644
--- a/modular_skyrat/modules/company_imports/code/armament_datums/nakamura_modsuits.dm
+++ b/modular_skyrat/modules/company_imports/code/armament_datums/nakamura_modsuits.dm
@@ -1,88 +1,59 @@
-#define MODULE_CHEAP_LOWER 0.5
-#define MODULE_CHEAP_UPPER 1.5
-
-#define MODULE_MID_LOWER 2
-#define MODULE_MID_UPPER 3
-
-#define MODULE_PRICEY_LOWER 4
-#define MODULE_PRICEY_UPPER 6
-
-#define MODULE_ANOMALY_LOWER 7.5
-#define MODULE_ANOMALY_UPPER 9
-
/datum/armament_entry/company_import/nakamura_modsuits
category = NAKAMURA_ENGINEERING_MODSUITS_NAME
company_bitflag = CARGO_COMPANY_NAKAMURA_MODSUITS
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
// MOD cores
/datum/armament_entry/company_import/nakamura_modsuits/core
subcategory = "MOD Core Modules"
- interest_addition = COMPANY_INTEREST_GAIN_BIG
/datum/armament_entry/company_import/nakamura_modsuits/core/standard
item_type = /obj/item/mod/core/standard
- lower_cost = CARGO_CRATE_VALUE
- upper_cost = CARGO_CRATE_VALUE * 2
- stock_mult = 2
+ cost = PAYCHECK_CREW * 2
/datum/armament_entry/company_import/nakamura_modsuits/core/plasma
item_type = /obj/item/mod/core/plasma
- lower_cost = CARGO_CRATE_VALUE * 0.5
- upper_cost = CARGO_CRATE_VALUE * 1.5
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/nakamura_modsuits/core/ethereal
item_type = /obj/item/mod/core/ethereal
- lower_cost = CARGO_CRATE_VALUE * 0.5
- upper_cost = CARGO_CRATE_VALUE * 1.5
+ cost = PAYCHECK_CREW
// MOD plating
/datum/armament_entry/company_import/nakamura_modsuits/plating
subcategory = "MOD External Plating"
- interest_addition = COMPANY_INTEREST_GAIN_BIG
/datum/armament_entry/company_import/nakamura_modsuits/plating/standard
name = "MOD Standard Plating"
item_type = /obj/item/mod/construction/plating
- lower_cost = CARGO_CRATE_VALUE * 2
- upper_cost = CARGO_CRATE_VALUE * 3
- stock_mult = 2
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/nakamura_modsuits/plating/medical
name = "MOD Medical Plating"
item_type = /obj/item/mod/construction/plating/medical
- lower_cost = CARGO_CRATE_VALUE * 3
- upper_cost = CARGO_CRATE_VALUE * 4
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/nakamura_modsuits/plating/engineering
name = "MOD Engineering Plating"
item_type = /obj/item/mod/construction/plating/engineering
- lower_cost = CARGO_CRATE_VALUE * 3
- upper_cost = CARGO_CRATE_VALUE * 4
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/nakamura_modsuits/plating/atmospherics
name = "MOD Atmospherics Plating"
item_type = /obj/item/mod/construction/plating/atmospheric
- lower_cost = CARGO_CRATE_VALUE * 4
- upper_cost = CARGO_CRATE_VALUE * 5
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/nakamura_modsuits/plating/security
name = "MOD Security Plating"
item_type = /obj/item/mod/construction/plating/security
- lower_cost = CARGO_CRATE_VALUE * 4
- upper_cost = CARGO_CRATE_VALUE * 5
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_COMMAND * 2
restricted = TRUE
/datum/armament_entry/company_import/nakamura_modsuits/plating/clown
name = "MOD CosmoHonk (TM) Plating"
item_type = /obj/item/mod/construction/plating/cosmohonk
- lower_cost = CARGO_CRATE_VALUE * 5
- upper_cost = CARGO_CRATE_VALUE * 6
- interest_required = COMPANY_HIGH_INTEREST
+ cost = PAYCHECK_COMMAND * 2
contraband = TRUE
// MOD modules
@@ -94,43 +65,30 @@
/datum/armament_entry/company_import/nakamura_modsuits/protection_modules/welding
item_type = /obj/item/mod/module/welding
- lower_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_UPPER
- stock_mult = 2
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/nakamura_modsuits/protection_modules/longfall
item_type = /obj/item/mod/module/longfall
- lower_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_UPPER
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/nakamura_modsuits/protection_modules/rad_protection
item_type = /obj/item/mod/module/rad_protection
- lower_cost = CARGO_CRATE_VALUE * MODULE_MID_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_MID_UPPER
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/nakamura_modsuits/protection_modules/emp_shield
item_type = /obj/item/mod/module/emp_shield
- lower_cost = CARGO_CRATE_VALUE * MODULE_MID_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_MID_UPPER
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/nakamura_modsuits/protection_modules/armor_plates
item_type = /obj/item/mod/module/armor_booster/retractplates
- lower_cost = CARGO_CRATE_VALUE * MODULE_PRICEY_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_PRICEY_UPPER
- interest_required = COMPANY_HIGH_INTEREST
+ cost = PAYCHECK_COMMAND * 3
restricted = TRUE
- interest_addition = COMPANY_INTEREST_GAIN_BIG
contraband = TRUE
/datum/armament_entry/company_import/nakamura_modsuits/protection_modules/accretion
item_type = /obj/item/mod/module/ash_accretion
- lower_cost = CARGO_CRATE_VALUE * MODULE_PRICEY_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_PRICEY_UPPER
- interest_required = COMPANY_HIGH_INTEREST
+ cost = PAYCHECK_COMMAND * 3
restricted = TRUE
- interest_addition = COMPANY_INTEREST_GAIN_BIG
// Utility modules, general purpose stuff that really anyone might want
@@ -139,55 +97,39 @@
/datum/armament_entry/company_import/nakamura_modsuits/utility_modules/flashlight
item_type = /obj/item/mod/module/flashlight
- lower_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_UPPER
- stock_mult = 2
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/nakamura_modsuits/utility_modules/regulator
item_type = /obj/item/mod/module/thermal_regulator
- lower_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_UPPER
- stock_mult = 2
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/nakamura_modsuits/utility_modules/mouthhole
item_type = /obj/item/mod/module/mouthhole
- lower_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_UPPER
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/nakamura_modsuits/utility_modules/signlang
item_type = /obj/item/mod/module/signlang_radio
- lower_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_UPPER
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/nakamura_modsuits/utility_modules/plasma_stabilizer
item_type = /obj/item/mod/module/plasma_stabilizer
- lower_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_UPPER
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/nakamura_modsuits/utility_modules/basic_storage
item_type = /obj/item/mod/module/storage
- lower_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_UPPER
- stock_mult = 2
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/nakamura_modsuits/utility_modules/expanded_storage
item_type = /obj/item/mod/module/storage/large_capacity
- lower_cost = CARGO_CRATE_VALUE * MODULE_MID_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_MID_UPPER
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/nakamura_modsuits/utility_modules/retract_plates
item_type = /obj/item/mod/module/plate_compression
- lower_cost = CARGO_CRATE_VALUE * MODULE_MID_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_MID_UPPER
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/nakamura_modsuits/utility_modules/magnetic_deploy
item_type = /obj/item/mod/module/springlock/contractor
- lower_cost = CARGO_CRATE_VALUE * MODULE_PRICEY_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_PRICEY_UPPER
- interest_required = COMPANY_HIGH_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_BIG
+ cost = PAYCHECK_COMMAND * 2
// Mobility modules, jetpacks and stuff
@@ -196,45 +138,31 @@
/datum/armament_entry/company_import/nakamura_modsuits/mobility_modules/tether
item_type = /obj/item/mod/module/tether
- lower_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_UPPER
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/nakamura_modsuits/mobility_modules/magboot
item_type = /obj/item/mod/module/magboot
- lower_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_UPPER
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/nakamura_modsuits/mobility_modules/jetpack
item_type = /obj/item/mod/module/jetpack
- lower_cost = CARGO_CRATE_VALUE * MODULE_MID_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_MID_UPPER
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/nakamura_modsuits/mobility_modules/pathfinder
item_type = /obj/item/mod/module/pathfinder
- lower_cost = CARGO_CRATE_VALUE * MODULE_MID_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_MID_UPPER
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/nakamura_modsuits/mobility_modules/disposals
item_type = /obj/item/mod/module/disposal_connector
- lower_cost = CARGO_CRATE_VALUE * MODULE_MID_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_MID_UPPER
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/nakamura_modsuits/mobility_modules/sphere
item_type = /obj/item/mod/module/sphere_transform
- lower_cost = CARGO_CRATE_VALUE * MODULE_PRICEY_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_PRICEY_UPPER
- interest_required = COMPANY_HIGH_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_BIG
+ cost = PAYCHECK_COMMAND * 2
/datum/armament_entry/company_import/nakamura_modsuits/mobility_modules/atrocinator
item_type = /obj/item/mod/module/atrocinator
- lower_cost = CARGO_CRATE_VALUE * MODULE_PRICEY_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_PRICEY_UPPER
- interest_required = COMPANY_HIGH_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_BIG
+ cost = PAYCHECK_COMMAND * 2
contraband = TRUE
// Novelty modules, goofy stuff that's rare/unprintable, but doesn't fit in any of the above categories
@@ -244,70 +172,38 @@
/datum/armament_entry/company_import/nakamura_modsuits/novelty_modules/waddle
item_type = /obj/item/mod/module/waddle
- lower_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_UPPER
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/nakamura_modsuits/novelty_modules/bike_horn
item_type = /obj/item/mod/module/bikehorn
- lower_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_CHEAP_UPPER
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/nakamura_modsuits/novelty_modules/microwave_beam
item_type = /obj/item/mod/module/microwave_beam
- lower_cost = CARGO_CRATE_VALUE * MODULE_MID_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_MID_UPPER
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/nakamura_modsuits/novelty_modules/tanner
item_type = /obj/item/mod/module/tanner
- lower_cost = CARGO_CRATE_VALUE * MODULE_MID_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_MID_UPPER
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_CREW
contraband = TRUE
-
+
/datum/armament_entry/company_import/nakamura_modsuits/novelty_modules/rave
item_type = /obj/item/mod/module/visor/rave
- lower_cost = CARGO_CRATE_VALUE * MODULE_MID_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_MID_UPPER
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_CREW
contraband = TRUE
/datum/armament_entry/company_import/nakamura_modsuits/novelty_modules/hat_stabilizer
item_type = /obj/item/mod/module/hat_stabilizer
- lower_cost = CARGO_CRATE_VALUE * MODULE_MID_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_MID_UPPER
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/nakamura_modsuits/novelty_modules/kinesis
item_type = /obj/item/mod/module/anomaly_locked/kinesis/prebuilt
- lower_cost = CARGO_CRATE_VALUE * MODULE_ANOMALY_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_ANOMALY_UPPER
- interest_required = COMPANY_HIGH_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_BIG
+ cost = PAYCHECK_COMMAND * 15
/datum/armament_entry/company_import/nakamura_modsuits/novelty_modules/antigrav
item_type = /obj/item/mod/module/anomaly_locked/antigrav/prebuilt
- lower_cost = CARGO_CRATE_VALUE * MODULE_ANOMALY_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_ANOMALY_UPPER
- interest_required = COMPANY_HIGH_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_BIG
+ cost = PAYCHECK_COMMAND * 15
/datum/armament_entry/company_import/nakamura_modsuits/novelty_modules/teleporter
item_type = /obj/item/mod/module/anomaly_locked/teleporter/prebuilt
- lower_cost = CARGO_CRATE_VALUE * MODULE_ANOMALY_LOWER
- upper_cost = CARGO_CRATE_VALUE * MODULE_ANOMALY_UPPER
- interest_required = COMPANY_HIGH_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_BIG
- contraband = TRUE
-
-#undef MODULE_CHEAP_LOWER
-#undef MODULE_CHEAP_UPPER
-
-#undef MODULE_MID_LOWER
-#undef MODULE_MID_UPPER
-
-#undef MODULE_PRICEY_LOWER
-#undef MODULE_PRICEY_UPPER
-
-#undef MODULE_ANOMALY_LOWER
-#undef MODULE_ANOMALY_UPPER
+ cost = PAYCHECK_COMMAND * 20
diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/nakamura_tools.dm b/modular_skyrat/modules/company_imports/code/armament_datums/nakamura_tools.dm
index 5f97e1ba3ce..dded1ac084e 100644
--- a/modular_skyrat/modules/company_imports/code/armament_datums/nakamura_tools.dm
+++ b/modular_skyrat/modules/company_imports/code/armament_datums/nakamura_tools.dm
@@ -1,9 +1,3 @@
-#define PRICE_POWERTOOL_LOW 1.5
-#define PRICE_POWERTOOL_HIGH 2.5
-
-#define PRICE_EXPERIMENTALTOOL_LOW 3
-#define PRICE_EXPERIMENTALTOOL_HIGH 3.8
-
/datum/armament_entry/company_import/nakamura_tooling
category = NAKAMURA_ENGINEERING_TOOLING_NAME
company_bitflag = CARGO_COMPANY_NAKAMURA_TOOLING
@@ -13,120 +7,80 @@
/datum/armament_entry/company_import/nakamura_tooling/basic
subcategory = "Standard Engineering Equipment"
-/datum/armament_entry/company_import/nakamura_tooling/basic/analyzer
- item_type = /obj/item/analyzer
- lower_cost = PAYCHECK_CREW * 0.75
- upper_cost = PAYCHECK_CREW
-
/datum/armament_entry/company_import/nakamura_tooling/basic/mechanical_toolbox
item_type = /obj/item/storage/toolbox/mechanical
- lower_cost = PAYCHECK_CREW * 0.5
- upper_cost = PAYCHECK_CREW * 1.5
+ cost = PAYCHECK_COMMAND * 2
/datum/armament_entry/company_import/nakamura_tooling/basic/electrical_toolbox
item_type = /obj/item/storage/toolbox/electrical
- lower_cost = PAYCHECK_CREW * 0.5
- upper_cost = PAYCHECK_CREW * 1.5
+ cost = PAYCHECK_CREW * 3
/datum/armament_entry/company_import/nakamura_tooling/basic/multitool
item_type = /obj/item/multitool
- lower_cost = PAYCHECK_CREW
- upper_cost = PAYCHECK_CREW * 1.5
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/nakamura_tooling/basic/inducer
item_type = /obj/item/inducer
- lower_cost = PAYCHECK_CREW * 1.5
- upper_cost = PAYCHECK_CREW * 2
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/nakamura_tooling/basic/magboots
item_type = /obj/item/clothing/shoes/magboots
- lower_cost = PAYCHECK_CREW * 3
- upper_cost = PAYCHECK_CREW * 5
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/nakamura_tooling/basic/insuls
item_type = /obj/item/clothing/gloves/color/yellow
- lower_cost = PAYCHECK_CREW * 3
- upper_cost = PAYCHECK_CREW * 5
+ cost = PAYCHECK_COMMAND
// Advanced stuff like power tools and holofans
/datum/armament_entry/company_import/nakamura_tooling/advanced
subcategory = "Advanced Engineering Equipment"
- interest_required = COMPANY_SOME_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
restricted = TRUE
+ cost = PAYCHECK_COMMAND * 3
/datum/armament_entry/company_import/nakamura_tooling/advanced/ranged_analyzer
item_type = /obj/item/analyzer/ranged
- lower_cost = CARGO_CRATE_VALUE * 0.75
- upper_cost = CARGO_CRATE_VALUE * 1.25
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/nakamura_tooling/advanced/forcefield
item_type = /obj/item/forcefield_projector
- lower_cost = CARGO_CRATE_VALUE * 0.5
- upper_cost = CARGO_CRATE_VALUE * 1.5
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/nakamura_tooling/advanced/atmos_fan
item_type = /obj/item/holosign_creator/atmos
- lower_cost = CARGO_CRATE_VALUE * 0.5
- upper_cost = CARGO_CRATE_VALUE * 1.5
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/nakamura_tooling/advanced/powerdrill
item_type = /obj/item/screwdriver/power
- lower_cost = CARGO_CRATE_VALUE * PRICE_POWERTOOL_LOW
- upper_cost = CARGO_CRATE_VALUE * PRICE_POWERTOOL_HIGH
/datum/armament_entry/company_import/nakamura_tooling/advanced/jaws
item_type = /obj/item/crowbar/power
- lower_cost = CARGO_CRATE_VALUE * PRICE_POWERTOOL_LOW
- upper_cost = CARGO_CRATE_VALUE * PRICE_POWERTOOL_HIGH
/datum/armament_entry/company_import/nakamura_tooling/advanced/hugewelder
item_type = /obj/item/weldingtool/hugetank
- lower_cost = CARGO_CRATE_VALUE * PRICE_POWERTOOL_LOW
- upper_cost = CARGO_CRATE_VALUE * PRICE_POWERTOOL_HIGH
// Overpriced experimental or gimmick tools
/datum/armament_entry/company_import/nakamura_tooling/experimental
subcategory = "Experimental Engineering Equipment"
- interest_required = COMPANY_HIGH_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_BIG
+ cost = PAYCHECK_COMMAND * 8
restricted = TRUE
/datum/armament_entry/company_import/nakamura_tooling/experimental/sprayon_insuls
item_type = /obj/item/toy/sprayoncan
- lower_cost = CARGO_CRATE_VALUE * 2
- upper_cost = CARGO_CRATE_VALUE * 4
contraband = TRUE
/datum/armament_entry/company_import/nakamura_tooling/experimental/red_screwdriver
item_type = /obj/item/screwdriver/caravan
- lower_cost = CARGO_CRATE_VALUE * PRICE_EXPERIMENTALTOOL_LOW
- upper_cost = CARGO_CRATE_VALUE * PRICE_EXPERIMENTALTOOL_HIGH
/datum/armament_entry/company_import/nakamura_tooling/experimental/red_crowbar
item_type = /obj/item/crowbar/red/caravan
- lower_cost = CARGO_CRATE_VALUE * PRICE_EXPERIMENTALTOOL_LOW
- upper_cost = CARGO_CRATE_VALUE * PRICE_EXPERIMENTALTOOL_HIGH
/datum/armament_entry/company_import/nakamura_tooling/experimental/red_wirecutters
item_type = /obj/item/wirecutters/caravan
- lower_cost = CARGO_CRATE_VALUE * PRICE_EXPERIMENTALTOOL_LOW
- upper_cost = CARGO_CRATE_VALUE * PRICE_EXPERIMENTALTOOL_HIGH
/datum/armament_entry/company_import/nakamura_tooling/experimental/red_wrench
item_type = /obj/item/wrench/caravan
- lower_cost = CARGO_CRATE_VALUE * PRICE_EXPERIMENTALTOOL_LOW
- upper_cost = CARGO_CRATE_VALUE * PRICE_EXPERIMENTALTOOL_HIGH
/datum/armament_entry/company_import/nakamura_tooling/experimental/advanced_welder
item_type = /obj/item/weldingtool/advanced
- lower_cost = CARGO_CRATE_VALUE * PRICE_EXPERIMENTALTOOL_LOW
- upper_cost = CARGO_CRATE_VALUE * PRICE_EXPERIMENTALTOOL_HIGH
-
-#undef PRICE_POWERTOOL_LOW
-#undef PRICE_POWERTOOL_HIGH
-
-#undef PRICE_EXPERIMENTALTOOL_LOW
-#undef PRICE_EXPERIMENTALTOOL_HIGH
diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/nri_military_surplus.dm b/modular_skyrat/modules/company_imports/code/armament_datums/nri_military_surplus.dm
index 6027706e18b..1d2f2ab524a 100644
--- a/modular_skyrat/modules/company_imports/code/armament_datums/nri_military_surplus.dm
+++ b/modular_skyrat/modules/company_imports/code/armament_datums/nri_military_surplus.dm
@@ -10,49 +10,33 @@
/datum/armament_entry/company_import/nri_surplus/clothing/uniform
description = "A CIN designed combat uniform that can come in any number of camouflauge variations. These will ship in a station environment suitable camouflauge scheme."
item_type = /obj/item/clothing/under/syndicate/rus_army/cin_surplus
- lower_cost = CARGO_CRATE_VALUE * 1.3
- upper_cost = CARGO_CRATE_VALUE * 1.7
- stock_mult = 2
- interest_addition = COMPANY_INTEREST_GAIN_PITIFUL
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/nri_surplus/clothing/cap
item_type = /obj/item/clothing/head/soft/nri_larp
- lower_cost = CARGO_CRATE_VALUE * 0.5
- upper_cost = CARGO_CRATE_VALUE
- stock_mult = 2
- interest_addition = COMPANY_INTEREST_GAIN_PITIFUL
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/nri_surplus/clothing/belt
item_type = /obj/item/storage/belt/military/cin_surplus
- lower_cost = CARGO_CRATE_VALUE
- upper_cost = CARGO_CRATE_VALUE * 1.5
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/nri_surplus/clothing/backpack
item_type = /obj/item/storage/backpack/industrial/cin_surplus
- lower_cost = CARGO_CRATE_VALUE
- upper_cost = CARGO_CRATE_VALUE * 1.5
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/nri_surplus/clothing/gas_mask
item_type = /obj/item/clothing/mask/gas/hecu2
- lower_cost = CARGO_CRATE_VALUE
- upper_cost = CARGO_CRATE_VALUE * 1.5
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/nri_surplus/clothing/helmet
description = "A service helmet primarily used by CIN military forces. These will ship in a station environment suitable camouflauge scheme."
item_type = /obj/item/clothing/head/helmet/cin_surplus_helmet
- lower_cost = CARGO_CRATE_VALUE * 2
- upper_cost = CARGO_CRATE_VALUE * 3
- interest_required = COMPANY_HIGH_INTEREST
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/nri_surplus/clothing/vest
description = "An armor vest primarily used by CIN military forces. These will ship in a station environment suitable camouflauge scheme."
item_type = /obj/item/clothing/suit/armor/vest/cin_surplus_vest
- lower_cost = CARGO_CRATE_VALUE * 2.5
- upper_cost = CARGO_CRATE_VALUE * 3.5
- interest_required = COMPANY_HIGH_INTEREST
+ cost = PAYCHECK_COMMAND
// Random surplus store tier stuff, flags, old rations, multitools you'll never use, so on
@@ -61,76 +45,59 @@
/datum/armament_entry/company_import/nri_surplus/misc/flares
item_type = /obj/item/storage/box/nri_flares
- lower_cost = CARGO_CRATE_VALUE * 0.1
- upper_cost = CARGO_CRATE_VALUE * 0.4
- interest_addition = COMPANY_INTEREST_GAIN_PITIFUL
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/nri_surplus/misc/binoculars
item_type = /obj/item/binoculars
- lower_cost = CARGO_CRATE_VALUE * 0.3
- upper_cost = CARGO_CRATE_VALUE * 0.7
- interest_addition = COMPANY_INTEREST_GAIN_PITIFUL
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/nri_surplus/misc/screwdriver_pen
item_type = /obj/item/pen/screwdriver
- lower_cost = CARGO_CRATE_VALUE * 0.3
- upper_cost = CARGO_CRATE_VALUE * 0.7
- interest_addition = COMPANY_INTEREST_GAIN_PITIFUL
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/nri_surplus/misc/trench_tool
item_type = /obj/item/trench_tool
- lower_cost = CARGO_CRATE_VALUE * 0.5
- upper_cost = CARGO_CRATE_VALUE
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/nri_surplus/misc/food_replicator
description = "Once widespread technology used by numerous fringe colonies of NRI origin and even in some SolFed territories, that ultimately went out of fashion due to \
SolFed propaganda deeming it unprofitable and imposing severe trading fees on anyone trying to sell them. A small portion of government-backed manufacturers still produce \
'food replicators' for private and government use; a few of them is selling this via us."
item_type = /obj/item/circuitboard/machine/biogenerator/food_replicator
- lower_cost = CARGO_CRATE_VALUE * 7.5
- upper_cost = CARGO_CRATE_VALUE * 11
- interest_required = COMPANY_SOME_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_BIG
+ cost = CARGO_CRATE_VALUE * 9
/datum/armament_entry/company_import/nri_surplus/misc/nri_flag
item_type = /obj/item/sign/flag/nri
- lower_cost = CARGO_CRATE_VALUE * 1.2
- upper_cost = CARGO_CRATE_VALUE * 2
- interest_required = COMPANY_SOME_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
+ cost = PAYCHECK_LOWER
/datum/armament_entry/company_import/nri_surplus/firearm
subcategory = "Firearms"
-
-/* BUBBERSTATION EDIT REMOVAL
-/datum/armament_entry/company_import/nri_surplus/firearm/makarov
- item_type = /obj/item/gun/ballistic/automatic/pistol/makarov
- lower_cost = CARGO_CRATE_VALUE * 3
- upper_cost = CARGO_CRATE_VALUE * 4
- interest_required = COMPANY_SOME_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_BIG
-
+/* BUBBER EDIT REMOVAL
/datum/armament_entry/company_import/nri_surplus/firearm/shotgun_revolver
item_type = /obj/item/gun/ballistic/revolver/cin_shotgun_revolver
- lower_cost = CARGO_CRATE_VALUE * 3
- upper_cost = CARGO_CRATE_VALUE * 4
- interest_required = COMPANY_SOME_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_BIG
-*/
+ cost = PAYCHECK_COMMAND * 6
/datum/armament_entry/company_import/nri_surplus/firearm/plasma_thrower
item_type = /obj/item/gun/energy/laser/plasma_thrower
- lower_cost = CARGO_CRATE_VALUE * 3
- upper_cost = CARGO_CRATE_VALUE * 4
- interest_required = COMPANY_SOME_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_BIG
+ cost = PAYCHECK_COMMAND * 6
-/* BUBBERSTATION EDIT REMOVAL
/datum/armament_entry/company_import/nri_surplus/firearm/anti_materiel_rifle
item_type = /obj/item/gun/ballistic/automatic/cin_amr
- lower_cost = CARGO_CRATE_VALUE * 8
- upper_cost = CARGO_CRATE_VALUE * 10
- interest_required = COMPANY_HIGH_INTEREST
+ cost = PAYCHECK_COMMAND * 12
restricted = TRUE
- interest_addition = COMPANY_INTEREST_GAIN_BIG
+
+/datum/armament_entry/company_import/nri_surplus/firearm/sakhno_rifle
+ item_type = /obj/item/gun/ballistic/rifle/boltaction
+ cost = PAYCHECK_COMMAND * 12
+ restricted = TRUE
+
+/datum/armament_entry/company_import/nri_surplus/firearm_ammo
+ subcategory = "Firearm Magazines"
+ cost = PAYCHECK_CREW
+
+/datum/armament_entry/company_import/nri_surplus/firearm_ammo/amr_magazine
+ item_type = /obj/item/ammo_box/magazine/cin_amr
+
+/datum/armament_entry/company_import/nri_surplus/firearm_ammo/sakhno_stripper
+ item_type = /obj/item/ammo_box/strilka310
*/
diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/parent_armament.dm b/modular_skyrat/modules/company_imports/code/armament_datums/parent_armament.dm
deleted file mode 100644
index 4597855a524..00000000000
--- a/modular_skyrat/modules/company_imports/code/armament_datums/parent_armament.dm
+++ /dev/null
@@ -1,20 +0,0 @@
-/datum/armament_entry/company_import
- max_purchase = 10
- category_item_limit = 10
- cost = 1
- /// Bitflag of the company
- var/company_bitflag
- /// How much stock of this item is left
- var/stock = 10
- /// Lower bound of random pricing
- var/lower_cost = 100
- /// Upper bound of random pricing
- var/upper_cost = 200
- /// How much the stock is multiplied by
- var/stock_mult = 1
- /// How much will be added to a company's reputation on-buy
- var/interest_addition = COMPANY_INTEREST_GAIN_LOW
- /// What interest level is needed to purchase the armament, set to 0 for none
- var/interest_required = 0
- /// If this requires a multitooled console to be visible
- var/contraband = FALSE
diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/put_a_donk_on_it.dm b/modular_skyrat/modules/company_imports/code/armament_datums/put_a_donk_on_it.dm
index ec67228f52a..97d8307efd9 100644
--- a/modular_skyrat/modules/company_imports/code/armament_datums/put_a_donk_on_it.dm
+++ b/modular_skyrat/modules/company_imports/code/armament_datums/put_a_donk_on_it.dm
@@ -6,60 +6,34 @@
/datum/armament_entry/company_import/donk/food
subcategory = "Microwave Foods"
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/donk/food/ready_donk
item_type = /obj/item/food/ready_donk
- lower_cost = PAYCHECK_CREW * 0.75
- upper_cost = PAYCHECK_CREW
- stock_mult = 4
/datum/armament_entry/company_import/donk/food/ready_donkhiladas
item_type = /obj/item/food/ready_donk/donkhiladas
- lower_cost = PAYCHECK_CREW * 0.75
- upper_cost = PAYCHECK_CREW
- stock_mult = 4
/datum/armament_entry/company_import/donk/food/ready_donk_n_cheese
item_type = /obj/item/food/ready_donk/mac_n_cheese
- lower_cost = PAYCHECK_CREW * 0.75
- upper_cost = PAYCHECK_CREW
- stock_mult = 4
/datum/armament_entry/company_import/donk/food/pockets
item_type = /obj/item/storage/box/donkpockets
- lower_cost = PAYCHECK_CREW * 1.5
- upper_cost = PAYCHECK_CREW * 2
- stock_mult = 2
/datum/armament_entry/company_import/donk/food/berry_pockets
item_type = /obj/item/storage/box/donkpockets/donkpocketberry
- lower_cost = PAYCHECK_CREW * 1.5
- upper_cost = PAYCHECK_CREW * 2
- stock_mult = 2
/datum/armament_entry/company_import/donk/food/honk_pockets
item_type = /obj/item/storage/box/donkpockets/donkpockethonk
- lower_cost = PAYCHECK_CREW * 1.5
- upper_cost = PAYCHECK_CREW * 2
- stock_mult = 2
/datum/armament_entry/company_import/donk/food/pizza_pockets
item_type = /obj/item/storage/box/donkpockets/donkpocketpizza
- lower_cost = PAYCHECK_CREW * 1.5
- upper_cost = PAYCHECK_CREW * 2
- stock_mult = 2
/datum/armament_entry/company_import/donk/food/spicy_pockets
item_type = /obj/item/storage/box/donkpockets/donkpocketspicy
- lower_cost = PAYCHECK_CREW * 1.5
- upper_cost = PAYCHECK_CREW * 2
- stock_mult = 2
/datum/armament_entry/company_import/donk/food/teriyaki_pockets
item_type = /obj/item/storage/box/donkpockets/donkpocketteriyaki
- lower_cost = PAYCHECK_CREW * 1.5
- upper_cost = PAYCHECK_CREW * 2
- stock_mult = 2
// Random donk toy items, fake jumpsuits, balloons, so on
@@ -70,107 +44,81 @@
/datum/armament_entry/company_import/donk/merch/donk_carpet
item_type = /obj/item/stack/tile/carpet/donk/thirty
- lower_cost = PAYCHECK_CREW * 0.75
- upper_cost = PAYCHECK_CREW
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
-
-/datum/armament_entry/company_import/donk/merch/donkfish
- item_type = /obj/item/storage/fish_case/donkfish
- lower_cost = PAYCHECK_CREW * 0.75
- upper_cost = PAYCHECK_CREW
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/donk/merch/tacticool_turtleneck
item_type = /obj/item/clothing/under/syndicate/tacticool
- lower_cost = PAYCHECK_CREW * 0.75
- upper_cost = PAYCHECK_CREW
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/donk/merch/tacticool_turtleneck_skirt
item_type = /obj/item/clothing/under/syndicate/tacticool/skirt
- lower_cost = PAYCHECK_CREW * 0.75
- upper_cost = PAYCHECK_CREW
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/donk/merch/fake_centcom_turtleneck
item_type = /obj/item/clothing/under/rank/centcom/officer/replica
- lower_cost = PAYCHECK_CREW * 0.75
- upper_cost = PAYCHECK_CREW
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/donk/merch/fake_centcom_turtleneck_skirt
item_type = /obj/item/clothing/under/rank/centcom/officer_skirt/replica
- lower_cost = PAYCHECK_CREW * 0.75
- upper_cost = PAYCHECK_CREW
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/donk/merch/snack_rig
item_type = /obj/item/storage/belt/military/snack
- lower_cost = PAYCHECK_CREW * 1.5
- upper_cost = PAYCHECK_CREW * 2
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/donk/merch/fake_syndie_suit
item_type = /obj/item/storage/box/fakesyndiesuit
- lower_cost = PAYCHECK_CREW * 1.5
- upper_cost = PAYCHECK_CREW * 2
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/donk/merch/valid_bloon
item_type = /obj/item/toy/balloon/arrest
- lower_cost = PAYCHECK_CREW * 1.5
- upper_cost = PAYCHECK_CREW * 2
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
- interest_required = COMPANY_SOME_INTEREST
+ cost = PAYCHECK_CREW
// Donksoft weapons
/datum/armament_entry/company_import/donk/foamforce
- subcategory = "Foam Force (TM) Weapons"
-
-/datum/armament_entry/company_import/donk/foamforce/darts
- item_type = /obj/item/ammo_box/foambox
- lower_cost = CARGO_CRATE_VALUE * 1.5 // BUBBER EDIT
- upper_cost = CARGO_CRATE_VALUE * 2.5 // BUBBER EDIT
-
-/datum/armament_entry/company_import/donk/foamforce/riot_darts
- item_type = /obj/item/ammo_box/foambox/riot
- lower_cost = CARGO_CRATE_VALUE * 1.5 // BUBBER EDIT
- upper_cost = CARGO_CRATE_VALUE * 2.5 // BUBBER EDIT
- interest_required = COMPANY_SOME_INTEREST
- contraband = TRUE
+ subcategory = "Foam Force (TM) Blasters"
/datum/armament_entry/company_import/donk/foamforce/foam_pistol
item_type = /obj/item/gun/ballistic/automatic/pistol/toy
- lower_cost = CARGO_CRATE_VALUE * 2
- upper_cost = CARGO_CRATE_VALUE * 3
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/donk/foamforce/foam_shotgun
item_type = /obj/item/gun/ballistic/shotgun/toy/unrestricted
- lower_cost = CARGO_CRATE_VALUE * 2
- upper_cost = CARGO_CRATE_VALUE * 4
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/donk/foamforce/foam_smg
item_type = /obj/item/gun/ballistic/automatic/toy/unrestricted
- lower_cost = CARGO_CRATE_VALUE * 2
- upper_cost = CARGO_CRATE_VALUE * 5
- interest_required = COMPANY_SOME_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
+ cost = PAYCHECK_COMMAND * 3
/datum/armament_entry/company_import/donk/foamforce/foam_c20
item_type = /obj/item/gun/ballistic/automatic/c20r/toy/unrestricted
- lower_cost = CARGO_CRATE_VALUE * 2
- upper_cost = CARGO_CRATE_VALUE * 5
- interest_required = COMPANY_SOME_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_AVERAGE
+ cost = PAYCHECK_COMMAND * 3
/datum/armament_entry/company_import/donk/foamforce/foam_lmg
item_type = /obj/item/gun/ballistic/automatic/l6_saw/toy/unrestricted
- lower_cost = CARGO_CRATE_VALUE * 2
- upper_cost = CARGO_CRATE_VALUE * 6
- interest_required = COMPANY_HIGH_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_BIG
+ cost = PAYCHECK_COMMAND * 5
+
+/datum/armament_entry/company_import/donk/foamforce_ammo
+ subcategory = "Foam Force (TM) Dart Accessories"
+ cost = PAYCHECK_CREW
+
+/datum/armament_entry/company_import/donk/foamforce_ammo/darts
+ item_type = /obj/item/ammo_box/foambox
+ cost = PAYCHECK_LOWER
+
+/datum/armament_entry/company_import/donk/foamforce_ammo/riot_darts
+ item_type = /obj/item/ammo_box/foambox/riot
+ cost = PAYCHECK_COMMAND * 1.5
+
+/datum/armament_entry/company_import/donk/foamforce_ammo
+ item_type = /obj/item/ammo_box/magazine/toy/pistol
+
+/datum/armament_entry/company_import/donk/foamforce_ammo
+ item_type = /obj/item/ammo_box/magazine/toy/smg
+
+/datum/armament_entry/company_import/donk/foamforce_ammo
+ item_type = /obj/item/ammo_box/magazine/toy/smgm45
+
+/datum/armament_entry/company_import/donk/foamforce_ammo
+ item_type = /obj/item/ammo_box/magazine/toy/m762
diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/vitezstvi_ammo.dm b/modular_skyrat/modules/company_imports/code/armament_datums/vitezstvi_ammo.dm
index 49b48c3e03b..a343cf7628d 100644
--- a/modular_skyrat/modules/company_imports/code/armament_datums/vitezstvi_ammo.dm
+++ b/modular_skyrat/modules/company_imports/code/armament_datums/vitezstvi_ammo.dm
@@ -1,7 +1,6 @@
/datum/armament_entry/company_import/vitezstvi
category = VITEZSTVI_AMMO_NAME
company_bitflag = CARGO_COMPANY_VITEZSTVI_AMMO
- stock_mult = 3
// Ammo bench and the lethals disk
@@ -10,24 +9,21 @@
/datum/armament_entry/company_import/vitezstvi/ammo_bench/bench_itself
item_type = /obj/item/circuitboard/machine/ammo_workbench
- lower_cost = CARGO_CRATE_VALUE * 10
- upper_cost = CARGO_CRATE_VALUE * 20
- interest_required = COMPANY_SOME_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_BIG
+ cost = PAYCHECK_COMMAND * 5
/datum/armament_entry/company_import/vitezstvi/ammo_bench
item_type = /obj/item/disk/ammo_workbench/advanced
- lower_cost = CARGO_CRATE_VALUE * 10
- upper_cost = CARGO_CRATE_VALUE * 20
- interest_required = COMPANY_HIGH_INTEREST
- interest_addition = COMPANY_INTEREST_GAIN_BIG
+ cost = PAYCHECK_COMMAND * 5
+
+/datum/armament_entry/company_import/vitezstvi/ammo_bench/bullet_drive
+ item_type = /obj/item/circuitboard/machine/dish_drive/bullet
+ cost = PAYCHECK_COMMAND * 2
// Boxes of non-shotgun ammo
/datum/armament_entry/company_import/vitezstvi/ammo_boxes
subcategory = "Ammunition Boxes"
- lower_cost = CARGO_CRATE_VALUE * 0.75
- upper_cost = CARGO_CRATE_VALUE * 1.25
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/vitezstvi/ammo_boxes/pepperball
item_type = /obj/item/ammo_box/advanced/pepperballs
@@ -65,31 +61,25 @@
/datum/armament_entry/company_import/vitezstvi/ammo_boxes/sabel_lethal
item_type = /obj/item/ammo_box/c56mm
- lower_cost = CARGO_CRATE_VALUE * 1.25
- upper_cost = CARGO_CRATE_VALUE * 1.5
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/vitezstvi/ammo_boxes/sabel_rubber
item_type = /obj/item/ammo_box/c56mm/rubber
- lower_cost = CARGO_CRATE_VALUE * 1.25
- upper_cost = CARGO_CRATE_VALUE * 1.5
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/vitezstvi/ammo_boxes/sabel_hunting
item_type = /obj/item/ammo_box/c56mm/hunting
- lower_cost = CARGO_CRATE_VALUE * 1.25
- upper_cost = CARGO_CRATE_VALUE * 1.5
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/vitezstvi/ammo_boxes/sabel_blank
item_type = /obj/item/ammo_box/c56mm/blank
- lower_cost = CARGO_CRATE_VALUE * 0.1
- upper_cost = CARGO_CRATE_VALUE * 0.3
*/
// Revolver speedloaders
/datum/armament_entry/company_import/vitezstvi/speedloader
subcategory = "Speedloaders"
- lower_cost = CARGO_CRATE_VALUE * 0.5
- upper_cost = CARGO_CRATE_VALUE
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/vitezstvi/speedloader/detective_lethal
item_type = /obj/item/ammo_box/c38
@@ -104,8 +94,7 @@
/datum/armament_entry/company_import/vitezstvi/shot_shells
subcategory = "Shotgun Shells"
- lower_cost = CARGO_CRATE_VALUE * 1.25
- upper_cost = CARGO_CRATE_VALUE * 2
+ cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/vitezstvi/shot_shells/slugs
item_type = /obj/item/ammo_box/advanced/s12gauge
diff --git a/modular_skyrat/modules/company_imports/code/company_subsystem.dm b/modular_skyrat/modules/company_imports/code/company_subsystem.dm
deleted file mode 100644
index af84491c866..00000000000
--- a/modular_skyrat/modules/company_imports/code/company_subsystem.dm
+++ /dev/null
@@ -1,151 +0,0 @@
-#define MAX_HANDOUT_CHOICES 3
-
-#define COMPANY_NO_INTEREST 1
-#define COMPANY_SOME_INTEREST 2
-#define COMPANY_HIGH_INTEREST 3
-
-#define INTEREST_HIGH_MULT 10
-#define INTEREST_CAP 75
-#define INTEREST_LOWER_RAND 5
-#define INTEREST_HIGHER_RAND 25
-
-#define BASE_COST_MINIMUM 1000
-#define BASE_COST_MAXIMUM 75000
-
-#define INTEREST_LOW_MAG_COST 0.1
-#define INTEREST_MED_MAG_COST 0.11
-#define INTEREST_HIGH_MAG_COST 0.125
-
-SUBSYSTEM_DEF(cargo_companies)
- name = "Cargo Companies"
- wait = 20 MINUTES
- runlevels = RUNLEVEL_GAME
- /// Assoc list of companies that the subsystem has initialized, `"NAME" = datum_reference`
- var/list/companies = list()
- /// Assoc list of unpurchased companies
- var/list/unpurchased_companies = list()
- /// Assoc list of purchased companies
- var/list/purchased_companies = list()
- /// List of chosen handout company datums, for the user to pick 1
- var/list/chosen_handouts = list()
- /// Picked a free company yet?
- var/handout_picked = FALSE
-
-/datum/controller/subsystem/cargo_companies/Initialize()
- // Adds the company refs to the unchanging companies list and the changing unpurchased_companies list
- for(var/datum/cargo_company/company as anything in subtypesof(/datum/cargo_company))
- var/datum/cargo_company/new_company = new company
- companies[new_company.name] = new_company
- unpurchased_companies[new_company.name] = new_company
-
- // Cargo gets to pick one company from several for free
- var/list/potential_handouts = list()
- for(var/company_name in unpurchased_companies)
- var/datum/cargo_company/picked_company = unpurchased_companies[company_name]
- if(!picked_company.can_roundstart_pick)
- continue
- potential_handouts += picked_company
- for(var/i in 1 to MAX_HANDOUT_CHOICES)
- chosen_handouts += pick_n_take(potential_handouts)
- fire() //Gotta get the prices randomized to start
- return SS_INIT_SUCCESS
-
-/datum/controller/subsystem/cargo_companies/Destroy()
- for(var/company in companies)
- QDEL_NULL(company)
- for(var/company_unbought in unpurchased_companies)
- QDEL_NULL(unpurchased_companies)
- for(var/company_bought in purchased_companies)
- QDEL_NULL(purchased_companies)
- . = ..()
-
-/datum/controller/subsystem/cargo_companies/Recover()
- companies = SScargo_companies.companies
- unpurchased_companies = SScargo_companies.unpurchased_companies
- purchased_companies = SScargo_companies.purchased_companies
-
-/datum/controller/subsystem/cargo_companies/fire(resumed)
- var/list/COMPANY_SOME_INTEREST_tier = list()
- // Company handling
- for(var/company in companies)
- var/datum/cargo_company/company_datum = companies[company]
-
- // Set the prices of the companies, is intended to slowly scale up over time
- company_datum.base_cost += max(rand(company_datum.cost_change_lower, company_datum.cost_change_upper), 0)
- company_datum.base_cost = clamp(company_datum.base_cost, BASE_COST_MINIMUM, BASE_COST_MAXIMUM)
- company_datum.base_cost = company_datum.base_cost <= BASE_COST_MINIMUM ? BASE_COST_MINIMUM : company_datum.base_cost
- company_datum.cost = round(company_datum.base_cost * company_datum.cost_mult)
- // knocking down the interest of all companies
- var/interest_threshold = rand(INTEREST_LOWER_RAND, INTEREST_HIGHER_RAND)
- var/interest_knockdown = 0.1 * interest_threshold
-
- company_datum.interest = max(company_datum.interest - interest_knockdown, 0)
-
- // determining what heirarchy of interest the company falls in
- if(company_datum.interest < interest_threshold)
- COMPANY_SOME_INTEREST_tier[company_datum] = COMPANY_NO_INTEREST
-
- else
- var/non_zero_threshold = interest_threshold ? interest_threshold : 1
- var/calc_threshold = non_zero_threshold * INTEREST_HIGH_MULT
- if(calc_threshold > INTEREST_CAP)
- calc_threshold = INTEREST_CAP
- if(company_datum.interest < calc_threshold)
- COMPANY_SOME_INTEREST_tier[company_datum] = COMPANY_SOME_INTEREST
-
- else
- COMPANY_SOME_INTEREST_tier[company_datum] = COMPANY_HIGH_INTEREST
-
-
- var/list/products = subtypesof(/datum/armament_entry/company_import)
- // Setting cost and stock of armament entries
- for(var/armament_category as anything in SSarmaments.entries)
- for(var/subcategory as anything in SSarmaments.entries[armament_category][CATEGORY_ENTRY])
- for(var/datum/armament_entry/armament_entry as anything in SSarmaments.entries[armament_category][CATEGORY_ENTRY][subcategory])
- if(products && !(armament_entry.type in products))
- continue
-
- var/datum/armament_entry/company_import/entry_typecast = armament_entry
-
- for(var/company in companies)
- var/datum/cargo_company/the_datum = companies[company]
-
- if(the_datum.company_flag != entry_typecast.company_bitflag)
- continue
-
- switch(COMPANY_SOME_INTEREST_tier[the_datum])
-
- if(COMPANY_NO_INTEREST)
- var/stock_failed = rand(0, 2)
- entry_typecast.stock = max((round(stock_failed * entry_typecast.stock_mult)), 0)
- var/gun_cost_failed = rand(entry_typecast.lower_cost, entry_typecast.upper_cost)
- var/compound_cost = round(entry_typecast.cost * 0.1)
- entry_typecast.cost = max((round((gun_cost_failed + (compound_cost + CARGO_CRATE_VALUE)) - (0.25 * entry_typecast.lower_cost)) ), 0)
- entry_typecast.magazine_cost = round((entry_typecast.cost * INTEREST_LOW_MAG_COST) * the_datum.magazine_cost_mult)
-
- if(COMPANY_SOME_INTEREST)
- var/stock_passed = rand(0, 4)
- entry_typecast.stock = max((round(stock_passed * entry_typecast.stock_mult) + 1), 0)
- var/gun_cost_passed = rand(entry_typecast.lower_cost, entry_typecast.upper_cost)
- var/compound_cost = round(entry_typecast.cost * 0.1)
- entry_typecast.cost = max((round(gun_cost_passed + compound_cost) + CARGO_CRATE_VALUE), 0)
- entry_typecast.magazine_cost = round((entry_typecast.cost * INTEREST_MED_MAG_COST) * the_datum.magazine_cost_mult)
-
- if(COMPANY_HIGH_INTEREST)
- var/stock_interested = rand(0, 6)
- entry_typecast.stock = max((round(stock_interested * entry_typecast.stock_mult) + 2), 0)
- var/gun_cost_high = rand(entry_typecast.lower_cost, entry_typecast.upper_cost)
- var/compound_cost = round(entry_typecast.cost * 0.1)
- entry_typecast.cost = max(round(gun_cost_high + (compound_cost + CARGO_CRATE_VALUE)) , 0)
- entry_typecast.magazine_cost = round((entry_typecast.cost * INTEREST_HIGH_MAG_COST) * the_datum.magazine_cost_mult)
-
-#undef MAX_HANDOUT_CHOICES
-#undef INTEREST_HIGH_MULT
-#undef INTEREST_CAP
-#undef INTEREST_LOWER_RAND
-#undef INTEREST_HIGHER_RAND
-#undef BASE_COST_MINIMUM
-#undef BASE_COST_MAXIMUM
-#undef INTEREST_LOW_MAG_COST
-#undef INTEREST_MED_MAG_COST
-#undef INTEREST_HIGH_MAG_COST
diff --git a/modular_skyrat/modules/company_imports/code/datums/cargo_order.dm b/modular_skyrat/modules/company_imports/code/datums/cargo_order.dm
index 069ea4d31fc..f79599bc6e4 100644
--- a/modular_skyrat/modules/company_imports/code/datums/cargo_order.dm
+++ b/modular_skyrat/modules/company_imports/code/datums/cargo_order.dm
@@ -3,10 +3,6 @@
var/datum/armament_entry/company_import/selected_entry
/// The component used to create the order
var/datum/component/armament/company_imports/used_component
- /// How much it'll add to a company's interest on-buy
- var/interest_addition
- /// If the order has multiple items in it, how many? Is null by default, set only if there's more than one item.
- var/item_amount
/datum/supply_order/company_import/Destroy(force, ...)
selected_entry = null
@@ -17,7 +13,6 @@
if(!selected_entry || !used_component)
return
used_component.purchased_items[selected_entry]--
- selected_entry.stock++
/// A proc to be overriden if you want custom code to happen when SSshuttle spawns the order
/datum/supply_order/proc/on_spawn()
@@ -30,10 +25,3 @@
return
on_spawn()
-
-/datum/supply_order/company_import/on_spawn()
- for(var/company in SScargo_companies.companies)
- var/datum/cargo_company/comp_datum = SScargo_companies.companies[company]
- if(comp_datum.company_flag == selected_entry?.company_bitflag)
- comp_datum.interest += interest_addition
- break
diff --git a/modular_skyrat/modules/company_imports/code/datums/cargo_pack.dm b/modular_skyrat/modules/company_imports/code/datums/cargo_pack.dm
index 6a4d20ceb0b..be62e2e1248 100644
--- a/modular_skyrat/modules/company_imports/code/datums/cargo_pack.dm
+++ b/modular_skyrat/modules/company_imports/code/datums/cargo_pack.dm
@@ -1,6 +1,8 @@
#define CARGO_CUT 0.05
/datum/supply_pack/armament
+ goody = TRUE
+ crate_type = /obj/structure/closet/crate/large/import
/datum/supply_pack/armament/generate(atom/A, datum/bank_account/paying_account)
. = ..()
diff --git a/modular_skyrat/modules/company_imports/code/objects/cargo_console_and_case.dm b/modular_skyrat/modules/company_imports/code/objects/cargo_console_and_case.dm
index f44c5e74c81..b7584a65652 100644
--- a/modular_skyrat/modules/company_imports/code/objects/cargo_console_and_case.dm
+++ b/modular_skyrat/modules/company_imports/code/objects/cargo_console_and_case.dm
@@ -12,3 +12,6 @@
/// Department of the person buying the crate if buying via the NIRN app.
var/datum/bank_account/department/department_account
+/obj/structure/closet/crate/large/import
+ name = "heavy-duty wooden crate"
+ icon = 'modular_skyrat/modules/company_imports/icons/import_crate.dmi'
diff --git a/modular_skyrat/modules/company_imports/code/readme.md b/modular_skyrat/modules/company_imports/code/readme.md
new file mode 100644
index 00000000000..32b07361a20
--- /dev/null
+++ b/modular_skyrat/modules/company_imports/code/readme.md
@@ -0,0 +1,25 @@
+https://github.com/Skyrat-SS13/Skyrat-tg/pull/
+
+## \
+
+Module ID:
+
+### Description:
+
+### TG Proc/File Changes:
+
+- N/A
+
+### Modular Overrides:
+
+- `modular_skyrat/master_files/code/modules/cargo/orderconsole.dm`: `proc/ui_act`
+
+### Defines:
+
+- N/A
+
+### Included files that are not contained in this module:
+
+- N/A
+
+### Credits:
diff --git a/modular_skyrat/modules/company_imports/icons/import_crate.dmi b/modular_skyrat/modules/company_imports/icons/import_crate.dmi
new file mode 100644
index 00000000000..e79cc05ec7e
Binary files /dev/null and b/modular_skyrat/modules/company_imports/icons/import_crate.dmi differ
diff --git a/modular_skyrat/modules/contractor/code/datums/contract.dm b/modular_skyrat/modules/contractor/code/datums/contract.dm
index 087cb438dac..7d57f029f84 100644
--- a/modular_skyrat/modules/contractor/code/datums/contract.dm
+++ b/modular_skyrat/modules/contractor/code/datums/contract.dm
@@ -213,9 +213,9 @@
for(var/i in 1 to 2)
var/obj/item/bodypart/limb = target.get_bodypart(pick_n_take(parts_to_fuck_up))
- var/datum/wound/blunt/severe/severe_wound_type = /datum/wound/blunt/severe
- var/datum/wound/blunt/critical/critical_wound_type = /datum/wound/blunt/critical
- limb.receive_damage(brute = WOUND_MINIMUM_DAMAGE, wound_bonus = rand(initial(severe_wound_type.threshold_minimum), initial(critical_wound_type.threshold_minimum) + 10))
+ var/min_wound = limb.get_wound_threshold_of_wound_type(WOUND_BLUNT, WOUND_SEVERITY_SEVERE, return_value_if_no_wound = 40)
+ var/max_wound = limb.get_wound_threshold_of_wound_type(WOUND_BLUNT, WOUND_SEVERITY_CRITICAL, return_value_if_no_wound = 60)
+ limb.receive_damage(brute = WOUND_MINIMUM_DAMAGE, wound_bonus = rand(min_wound, max_wound))
target.update_damage_overlays()
addtimer(CALLBACK(src, PROC_REF(victim_stage_three), target), 6 SECONDS)
diff --git a/modular_skyrat/modules/contractor/code/datums/midround/outfit.dm b/modular_skyrat/modules/contractor/code/datums/midround/outfit.dm
index 8f2abc66937..cb3a0683a0d 100644
--- a/modular_skyrat/modules/contractor/code/datums/midround/outfit.dm
+++ b/modular_skyrat/modules/contractor/code/datums/midround/outfit.dm
@@ -23,7 +23,6 @@
implants = list(
/obj/item/implant/uplink/precharged/bonus,
- /obj/item/implant/explosive,
)
id_trim = /datum/id_trim/chameleon/contractor
diff --git a/modular_skyrat/modules/contractor/code/datums/outfit.dm b/modular_skyrat/modules/contractor/code/datums/outfit.dm
new file mode 100644
index 00000000000..3364e2fbccb
--- /dev/null
+++ b/modular_skyrat/modules/contractor/code/datums/outfit.dm
@@ -0,0 +1,2 @@
+/datum/outfit
+ var/datum/sprite_accessory/bra = null
diff --git a/modular_skyrat/modules/cryosleep/code/cryopod.dm b/modular_skyrat/modules/cryosleep/code/cryopod.dm
index aaa77103fe7..08a0bf8b8bb 100644
--- a/modular_skyrat/modules/cryosleep/code/cryopod.dm
+++ b/modular_skyrat/modules/cryosleep/code/cryopod.dm
@@ -429,7 +429,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/computer/cryopod, 32)
else if(tgui_alert(user, "Would you like to place [target] into [src]?", "Place into Cryopod?", list("Yes", "No")) == "Yes")
if(target.mind.assigned_role.req_admin_notify)
tgui_alert(user, "They are an important role! [AHELP_FIRST_MESSAGE]")
- to_chat(user, span_danger("You put [target] into [src]. [target.p_Theyre()]] in the cryopod."))
+ to_chat(user, span_danger("You put [target] into [src]. [target.p_Theyre()] in the cryopod."))
log_admin("[key_name(user)] has put [key_name(target)] into a stasis pod.")
message_admins("[key_name(user)] has put [key_name(target)] into a stasis pod. [ADMIN_JMP(src)]")
@@ -439,9 +439,9 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/computer/cryopod, 32)
name = "[name] ([target.name])"
else if(iscyborg(target))
- to_chat(user, span_danger("You can't put [target] into [src]. [target.p_Theyre()]] online."))
+ to_chat(user, span_danger("You can't put [target] into [src]. [target.p_Theyre()] online."))
else
- to_chat(user, span_danger("You can't put [target] into [src]. [target.p_Theyre()]] conscious."))
+ to_chat(user, span_danger("You can't put [target] into [src]. [target.p_Theyre()] conscious."))
return
if(target == user && (tgui_alert(target, "Would you like to enter cryosleep?", "Enter Cryopod?", list("Yes", "No")) != "Yes"))
diff --git a/modular_skyrat/modules/customization/__HELPERS/global_lists.dm b/modular_skyrat/modules/customization/__HELPERS/global_lists.dm
index 825737a6cf8..a2dca2e39be 100644
--- a/modular_skyrat/modules/customization/__HELPERS/global_lists.dm
+++ b/modular_skyrat/modules/customization/__HELPERS/global_lists.dm
@@ -152,3 +152,26 @@
if(!sprite_datum?.erp_accessory)
continue
GLOB.undershirt_m -= sprite_name
+
+
+ // Bras
+ for(var/sprite_name in GLOB.bra_list)
+ var/datum/sprite_accessory/sprite_datum = GLOB.bra_list[sprite_name]
+ if(!sprite_datum?.erp_accessory)
+ continue
+
+ GLOB.bra_list -= sprite_name
+
+ for(var/sprite_name in GLOB.bra_f)
+ var/datum/sprite_accessory/sprite_datum = GLOB.bra_f[sprite_name]
+ if(!sprite_datum?.erp_accessory)
+ continue
+
+ GLOB.bra_f -= sprite_name
+
+ for(var/sprite_name in GLOB.bra_m)
+ var/datum/sprite_accessory/sprite_datum = GLOB.bra_m[sprite_name]
+ if(!sprite_datum?.erp_accessory)
+ continue
+
+ GLOB.bra_m -= sprite_name
diff --git a/modular_skyrat/modules/customization/__HELPERS/mobs.dm b/modular_skyrat/modules/customization/__HELPERS/mobs.dm
index 4e7fd400006..2707a172fe4 100644
--- a/modular_skyrat/modules/customization/__HELPERS/mobs.dm
+++ b/modular_skyrat/modules/customization/__HELPERS/mobs.dm
@@ -42,3 +42,15 @@
body_markings[zone] = list()
body_markings[zone][set_name] = list(BM.get_default_color(features, pref_species), FALSE)
return body_markings
+
+/proc/random_bra(gender)
+ if(!length(GLOB.bra_list))
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/bra, GLOB.bra_list, GLOB.bra_m, GLOB.bra_f)
+
+ switch(gender)
+ if(MALE)
+ return pick(GLOB.bra_m)
+ if(FEMALE)
+ return pick(GLOB.bra_f)
+ else
+ return pick(GLOB.bra_list)
diff --git a/modular_skyrat/modules/customization/_globalvars/lists.dm b/modular_skyrat/modules/customization/_globalvars/lists.dm
index b684abf4e1c..86586e3f4d7 100644
--- a/modular_skyrat/modules/customization/_globalvars/lists.dm
+++ b/modular_skyrat/modules/customization/_globalvars/lists.dm
@@ -103,3 +103,11 @@ GLOBAL_LIST_INIT(color_list_ghoul, list( \
"Plutonium Blue" = "a5cfcc", \
"Marked Red" = "f05b68" \
))
+
+//Bras
+/// Stores all /datum/sprite_accessory/bra indexed by name.
+GLOBAL_LIST_EMPTY(bra_list)
+/// Stores only the bra names for male-compatible bras.
+GLOBAL_LIST_EMPTY(bra_m)
+/// Stores only the bra names for female-compatible bras.
+GLOBAL_LIST_EMPTY(bra_f)
diff --git a/modular_skyrat/modules/customization/datums/dna.dm b/modular_skyrat/modules/customization/datums/dna.dm
index ddc453c2c7a..4ae22fceab5 100644
--- a/modular_skyrat/modules/customization/datums/dna.dm
+++ b/modular_skyrat/modules/customization/datums/dna.dm
@@ -276,15 +276,15 @@ GLOBAL_LIST_EMPTY(total_uf_len_by_block)
var/features = dna.unique_features
if(dna.features["mcolor"])
- dna.features["mcolor"] = sanitize_hexcolor(get_uni_identity_block(features, DNA_MUTANT_COLOR_BLOCK))
+ dna.features["mcolor"] = sanitize_hexcolor(get_uni_feature_block(features, DNA_MUTANT_COLOR_BLOCK))
if(dna.features["mcolor2"])
- dna.features["mcolor2"] = sanitize_hexcolor(get_uni_identity_block(features, DNA_MUTANT_COLOR_2_BLOCK))
+ dna.features["mcolor2"] = sanitize_hexcolor(get_uni_feature_block(features, DNA_MUTANT_COLOR_2_BLOCK))
if(dna.features["mcolor3"])
- dna.features["mcolor3"] = sanitize_hexcolor(get_uni_identity_block(features, DNA_MUTANT_COLOR_3_BLOCK))
+ dna.features["mcolor3"] = sanitize_hexcolor(get_uni_feature_block(features, DNA_MUTANT_COLOR_3_BLOCK))
if(dna.features["ethcolor"])
- dna.features["ethcolor"] = sanitize_hexcolor(get_uni_identity_block(features, DNA_ETHEREAL_COLOR_BLOCK))
+ dna.features["ethcolor"] = sanitize_hexcolor(get_uni_feature_block(features, DNA_ETHEREAL_COLOR_BLOCK))
if(dna.features["skin_color"])
- dna.features["skin_color"] = sanitize_hexcolor(get_uni_identity_block(features, DNA_SKIN_COLOR_BLOCK))
+ dna.features["skin_color"] = sanitize_hexcolor(get_uni_feature_block(features, DNA_SKIN_COLOR_BLOCK))
if(icon_update)
if(mutcolor_update)
diff --git a/modular_skyrat/modules/customization/game/objects/items/plushes.dm b/modular_skyrat/modules/customization/game/objects/items/plushes.dm
index 2271a54273d..d718d409b49 100644
--- a/modular_skyrat/modules/customization/game/objects/items/plushes.dm
+++ b/modular_skyrat/modules/customization/game/objects/items/plushes.dm
@@ -644,3 +644,12 @@
attack_verb_continuous = list("delivers", "export scans", "dwoops", "bwuhs", "stamps")
attack_verb_simple = list("deliver", "export scan", "dwoop", "bwuh", "stamp")
squeak_override = list('modular_skyrat/modules/emotes/sound/emotes/twobeep.ogg' = 1)
+
+//Donation reward for olirant
+/obj/item/toy/plush/skyrat/plush_janiborg
+ name = "Friendly Janiborg Plush"
+ desc = "A miniature omnidroid toy straight from the Lockstep Enterprises Corporation marketing department in handsome janitorial purple. Now with real squirting action!"
+ icon_state = "plush_janiborg"
+ attack_verb_continuous = list("beeps", "washes", "mops", "squirts", "soaps")
+ attack_verb_simple = list("beep", "wash", "mop", "squirt", "soap")
+ squeak_override = list('sound/machines/twobeep.ogg' = 1)
diff --git a/modular_skyrat/modules/customization/modules/client/augment/implants.dm b/modular_skyrat/modules/customization/modules/client/augment/implants.dm
index 14770a84458..9abdce1a5db 100644
--- a/modular_skyrat/modules/customization/modules/client/augment/implants.dm
+++ b/modular_skyrat/modules/customization/modules/client/augment/implants.dm
@@ -19,10 +19,20 @@
/datum/augment_item/implant/l_arm
slot = AUGMENT_SLOT_LEFT_ARM_IMPLANT
+/datum/augment_item/implant/l_arm/razor_claws
+ name = "Left Razor Claws"
+ cost = 4
+ path = /obj/item/organ/internal/cyberimp/arm/razor_claws/left_arm
+
//RIGHT ARM IMPLANTS
/datum/augment_item/implant/r_arm
slot = AUGMENT_SLOT_RIGHT_ARM_IMPLANT
+/datum/augment_item/implant/r_arm/razor_claws
+ name = "Right Razor Claws"
+ cost = 4
+ path = /obj/item/organ/internal/cyberimp/arm/razor_claws/right_arm
+
//EYES IMPLANTS
/datum/augment_item/implant/eyes
slot = AUGMENT_SLOT_EYES_IMPLANT
diff --git a/modular_skyrat/modules/customization/modules/client/augment/limbs.dm b/modular_skyrat/modules/customization/modules/client/augment/limbs.dm
index e1bc30db944..e5f8f4f14e7 100644
--- a/modular_skyrat/modules/customization/modules/client/augment/limbs.dm
+++ b/modular_skyrat/modules/customization/modules/client/augment/limbs.dm
@@ -67,6 +67,12 @@
path = /obj/item/bodypart/arm/left/plasmaman
uses_robotic_styles = FALSE
+/datum/augment_item/limb/l_arm/self_destruct
+ name = "No Left Arm"
+ path = /obj/item/bodypart/arm/left/self_destruct
+ cost = -3
+ uses_robotic_styles = FALSE
+
//RIGHT ARMS
/datum/augment_item/limb/r_arm
slot = AUGMENT_SLOT_R_ARM
@@ -85,6 +91,12 @@
path = /obj/item/bodypart/arm/right/plasmaman
uses_robotic_styles = FALSE
+/datum/augment_item/limb/r_arm/self_destruct
+ name = "No Right Arm"
+ path = /obj/item/bodypart/arm/right/self_destruct
+ cost = -3
+ uses_robotic_styles = FALSE
+
//LEFT LEGS
/datum/augment_item/limb/l_leg
slot = AUGMENT_SLOT_L_LEG
@@ -103,6 +115,12 @@
path = /obj/item/bodypart/leg/left/plasmaman
uses_robotic_styles = FALSE
+/datum/augment_item/limb/l_leg/self_destruct
+ name = "No Left Leg"
+ path = /obj/item/bodypart/leg/left/self_destruct
+ cost = -3
+ uses_robotic_styles = FALSE
+
//RIGHT LEGS
/datum/augment_item/limb/r_leg
slot = AUGMENT_SLOT_R_LEG
@@ -120,3 +138,9 @@
name = "Plasmaman right leg"
path = /obj/item/bodypart/leg/right/plasmaman
uses_robotic_styles = FALSE
+
+/datum/augment_item/limb/r_leg/self_destruct
+ name = "No Right Leg"
+ path = /obj/item/bodypart/leg/right/self_destruct
+ cost = -3
+ uses_robotic_styles = FALSE
diff --git a/modular_skyrat/modules/customization/modules/clothing/under/utility_port/suits_port.dm b/modular_skyrat/modules/customization/modules/clothing/under/utility_port/suits_port.dm
index 07ce022f2a4..bb88ca325db 100644
--- a/modular_skyrat/modules/customization/modules/clothing/under/utility_port/suits_port.dm
+++ b/modular_skyrat/modules/customization/modules/clothing/under/utility_port/suits_port.dm
@@ -53,16 +53,6 @@
desc = "A comfortable jacket in a neutral black"
icon_state = "off_dep_jacket"
-/obj/item/clothing/suit/gorka //THIS WILL BE MOVED IN THE NEXT PR ADDING PROPER GORKAS (not cargo related so not in this PR), BUT FOR NOW ITS HERE FOR THE SUBTYPE'S FILE LINKS
- icon = 'modular_skyrat/master_files/icons/obj/clothing/suits.dmi'
- worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/suit.dmi'
- supports_variations_flags = CLOTHING_DIGITIGRADE_VARIATION_NO_NEW_ICON
-
-/obj/item/clothing/suit/gorka/supply //Put here for sorting purposes, considering the cargo gorkas are in the utility file too. The base Gorka and Jacket (to be added later) will most likely be elsewhere
- name = "supply gorka jacket"
- desc = "A snug jacket to wear over your gorka. This one matches with supply's colors."
- icon_state = "gorka_jacket_supply"
-
/obj/item/clothing/suit/toggle/jacket/supply/head
name = "quartermaster's jacket"
desc = "Even if people refuse to recognize you as a head, they can recognize you as a badass."
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 2a8f0b11ed8..64a6c5c1339 100644
--- a/modular_skyrat/modules/customization/modules/clothing/~donator/donator_clothing.dm
+++ b/modular_skyrat/modules/customization/modules/clothing/~donator/donator_clothing.dm
@@ -1646,3 +1646,13 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/poster/contraband/korpstech, 32)
)
)
+// Donation reward for grasshand
+/obj/item/clothing/under/rank/civilian/chaplain/divine_archer/noble
+ name = "noble gambeson"
+ desc = "These clothes make you feel a little closer to space."
+
+/obj/item/clothing/shoes/jackboots/noble
+ name = "noble boots"
+ desc = "These boots make you feel like you can walk on space."
+ icon_state = "archerboots"
+ inhand_icon_state = "archerboots"
diff --git a/modular_skyrat/modules/customization/modules/food_and_drinks/food/hemophage_food.dm b/modular_skyrat/modules/customization/modules/food_and_drinks/food/hemophage_food.dm
index df3ef78eba4..970b9eb5710 100644
--- a/modular_skyrat/modules/customization/modules/food_and_drinks/food/hemophage_food.dm
+++ b/modular_skyrat/modules/customization/modules/food_and_drinks/food/hemophage_food.dm
@@ -4,7 +4,6 @@
icon = 'modular_skyrat/master_files/icons/obj/food/hemophage_food.dmi'
foodtypes = GORE | BLOODY
-
/obj/item/food/hemophage/blood_rice_pearl
name = "kessen shinju"
desc = "A fun finger food. Little clumps of sticky rice with a bit of ground pork and green onion, all soaked and rolled in fresh blood; giving it a crimson hue. Recommended to serve hot!"
@@ -15,7 +14,7 @@
)
tastes = list("rice" = 3, "blood" = 5)
foodtypes = GRAIN | GORE | BLOODY
-
+ crafting_complexity = FOOD_COMPLEXITY_1
/obj/item/food/hemophage/blood_rice_pearl/raw
name = "uncooked blood rice"
@@ -29,11 +28,11 @@
tastes = list("raw rice" = 3, "blood" = 5)
color = "#810000"
foodtypes = GRAIN | GORE | BLOODY | RAW
+ crafting_complexity = FOOD_COMPLEXITY_0
/obj/item/food/hemophage/blood_rice_pearl/raw/make_microwaveable()
AddElement(/datum/element/microwavable, /obj/item/food/hemophage/blood_rice_pearl)
-
/obj/item/food/hemophage/blood_noodles
name = "boiled blood noodles"
desc = "A plain dish of blood-soaked noodles, it would probably be better with more ingredients."
@@ -46,7 +45,7 @@
)
tastes = list("blood" = 5, "pasta" = 1)
foodtypes = GRAIN | GORE | BLOODY
-
+ crafting_complexity = FOOD_COMPLEXITY_1
/obj/item/food/hemophage/blood_noodles/raw
name = "raw blood noodles"
@@ -58,11 +57,11 @@
)
tastes = list("blood" = 5, "raw pasta" = 1)
foodtypes = GRAIN | GORE | BLOODY | RAW
+ crafting_complexity = FOOD_COMPLEXITY_0
/obj/item/food/hemophage/blood_noodles/raw/make_microwaveable()
AddElement(/datum/element/microwavable, /obj/item/food/hemophage/blood_noodles)
-
/obj/item/food/hemophage/blood_noodles/boat_noodles
name = "boat noodles"
desc = "A dish with normally made with a very strong combination of pork and beef; the main attraction in this meatless version being the combination of blood curds and curly noodles, seasoned and immersed in fresh blood to the point they've turned crimson. It reeks of iron."
@@ -76,7 +75,7 @@
)
tastes = list("blood" = 5, "congealed blood" = 3, "pasta" = 1)
foodtypes = GRAIN | GORE | BLOODY
-
+ crafting_complexity = FOOD_COMPLEXITY_2
/obj/item/food/hemophage/blood_curd
name = "blood curd"
@@ -88,7 +87,7 @@
)
tastes = list("congealed blood" = 1)
foodtypes = GORE | BLOODY | RAW
-
+ crafting_complexity = FOOD_COMPLEXITY_0
/obj/item/food/hemophage/blood_cake
name = "ti hoeh koe"
@@ -101,7 +100,7 @@
)
tastes = list("blood" = 5, "crunchy rice" = 2, "peanut butter" = 2)
foodtypes = GRAIN | GORE | BLOODY | SUGAR | NUTS
-
+ crafting_complexity = FOOD_COMPLEXITY_3
/obj/item/food/soup/hemophage/blood_soup
name = "dinuguan"
@@ -115,3 +114,4 @@
)
tastes = list("blood" = 5, "congealed blood" = 2, "chili" = 3, "vinegar" = 1, "garlic" = 1)
foodtypes = GORE | BLOODY | VEGETABLES
+ crafting_complexity = FOOD_COMPLEXITY_4
diff --git a/modular_skyrat/modules/customization/modules/food_and_drinks/food/scottish.dm b/modular_skyrat/modules/customization/modules/food_and_drinks/food/scottish.dm
index 12532d1951f..9a26ebee5d2 100644
--- a/modular_skyrat/modules/customization/modules/food_and_drinks/food/scottish.dm
+++ b/modular_skyrat/modules/customization/modules/food_and_drinks/food/scottish.dm
@@ -4,10 +4,11 @@
icon = 'modular_skyrat/master_files/icons/obj/food/irnbru.dmi'
icon_state = "haggis"
food_reagents = list(
- /datum/reagent/consumable/nutriment = 50,
+ /datum/reagent/consumable/nutriment = 50,
/datum/reagent/consumable/nutriment/vitamin = 25
)
foodtypes = MEAT | GRAIN
+ crafting_complexity = FOOD_COMPLEXITY_4
/obj/item/food/snacks/store/bread/haggis/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/snacks/breadslice/haggis, 5, 30, screentip_verb = "Slice")
@@ -18,10 +19,11 @@
icon = 'modular_skyrat/master_files/icons/obj/food/irnbru.dmi'
icon_state = "haggis_chunk"
food_reagents = list(
- /datum/reagent/consumable/nutriment = 10,
+ /datum/reagent/consumable/nutriment = 10,
/datum/reagent/consumable/nutriment/vitamin = 5
)
foodtypes = MEAT | GRAIN
+ crafting_complexity = FOOD_COMPLEXITY_4
/obj/item/food/snacks/neep_tatty_haggis
@@ -30,11 +32,12 @@
icon_state = "neep_tatty_haggis"
icon = 'modular_skyrat/master_files/icons/obj/food/irnbru.dmi'
food_reagents = list(
- /datum/reagent/consumable/nutriment = 20,
- /datum/reagent/consumable/nutriment/vitamin = 10,
+ /datum/reagent/consumable/nutriment = 20,
+ /datum/reagent/consumable/nutriment/vitamin = 10,
/datum/reagent/iron = 10
)
foodtypes = GRAIN | VEGETABLES | MEAT
+ crafting_complexity = FOOD_COMPLEXITY_5
/obj/item/food/raw_sausage/battered
name = "raw battered sausage"
@@ -42,11 +45,12 @@
icon = 'modular_skyrat/master_files/icons/obj/food/irnbru.dmi'
icon_state = "batteredsausage"
food_reagents = list(
- /datum/reagent/consumable/nutriment/protein = 5,
- /datum/reagent/consumable/nutriment/vitamin = 2,
+ /datum/reagent/consumable/nutriment/protein = 5,
+ /datum/reagent/consumable/nutriment/vitamin = 2,
/datum/reagent/consumable/ethanol/beerbatter = 5
)
-
+ crafting_complexity = FOOD_COMPLEXITY_1
+
/obj/item/food/raw_sausage/battered/make_grillable()
AddComponent(/datum/component/grillable, /obj/item/food/sausage/battered, rand(60 SECONDS, 75 SECONDS), TRUE)
@@ -57,11 +61,12 @@
icon_state = "grilled_batteredsausage"
food_reagents = list(
/datum/reagent/consumable/nutriment/protein = 5,
- /datum/reagent/consumable/nutriment/vitamin = 2,
- /datum/reagent/consumable/nutriment = 2,
- /datum/reagent/consumable/cooking_oil = 2
+ /datum/reagent/consumable/nutriment/vitamin = 2,
+ /datum/reagent/consumable/nutriment = 2,
+ /datum/reagent/consumable/nutriment/fat/oil = 2
)
foodtypes = MEAT | BREAKFAST | FRIED
+ crafting_complexity = FOOD_COMPLEXITY_3
/obj/item/food/sausage/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/salami, 6, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice")
@@ -72,8 +77,9 @@
icon = 'modular_skyrat/master_files/icons/obj/food/irnbru.dmi'
icon_state = "shortbread"
food_reagents = list(
- /datum/reagent/consumable/nutriment = 6,
+ /datum/reagent/consumable/nutriment = 6,
/datum/reagent/consumable/sugar = 6
)
tastes = list("sugary dough" = 1)
foodtypes = GRAIN | JUNKFOOD | SUGAR
+ crafting_complexity = FOOD_COMPLEXITY_2
diff --git a/modular_skyrat/modules/customization/modules/food_and_drinks/food/teshari_food.dm b/modular_skyrat/modules/customization/modules/food_and_drinks/food/teshari_food.dm
index 69c251509db..ff7fe82012a 100644
--- a/modular_skyrat/modules/customization/modules/food_and_drinks/food/teshari_food.dm
+++ b/modular_skyrat/modules/customization/modules/food_and_drinks/food/teshari_food.dm
@@ -7,6 +7,7 @@
w_class = WEIGHT_CLASS_SMALL
tastes = list("minty dough" = 1)
foodtypes = VEGETABLES
+ crafting_complexity = FOOD_COMPLEXITY_1
/obj/item/food/piru_dough/make_processable()
AddElement(/datum/element/processable, TOOL_ROLLINGPIN, /obj/item/food/flat_piru_dough, 1, 3 SECONDS, table_required = TRUE, screentip_verb = "Flatten")
@@ -26,7 +27,7 @@
tastes = list("minty bread" = 1)
foodtypes = VEGETABLES
w_class = WEIGHT_CLASS_SMALL
- burns_on_grill = TRUE
+ crafting_complexity = FOOD_COMPLEXITY_2
/obj/item/food/piru_loaf/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/breadslice/piru, 4, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice")
@@ -39,6 +40,7 @@
food_reagents = list(/datum/reagent/consumable/nutriment = 5)
tastes = list("minty bread" = 1)
foodtypes = VEGETABLES
+ crafting_complexity = FOOD_COMPLEXITY_2
/obj/item/food/flat_piru_dough
name = "flattened piru dough"
@@ -48,6 +50,7 @@
food_reagents = list(/datum/reagent/consumable/nutriment = 6)
tastes = list("minty dough" = 1)
foodtypes = VEGETABLES
+ crafting_complexity = FOOD_COMPLEXITY_1
/obj/item/food/flat_piru_dough/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/piru_pasta, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice")
@@ -66,7 +69,7 @@
food_reagents = list(/datum/reagent/consumable/nutriment = 8)
tastes = list("minty flatbread" = 1)
foodtypes = VEGETABLES
- burns_on_grill = TRUE
+ crafting_complexity = FOOD_COMPLEXITY_2
/obj/item/food/piru_pasta
name = "piru pasta"
@@ -77,6 +80,7 @@
w_class = WEIGHT_CLASS_SMALL
tastes = list("minty pasta" = 1)
foodtypes = VEGETABLES
+ crafting_complexity = FOOD_COMPLEXITY_2
/obj/item/food/baked_kiri
name = "baked kiri fruit"
@@ -84,13 +88,13 @@
icon = 'modular_skyrat/master_files/icons/obj/food/irnbru.dmi'
icon_state = "baked_kiri"
food_reagents = list(
- /datum/reagent/consumable/nutriment = 6,
+ /datum/reagent/consumable/nutriment = 6,
/datum/reagent/consumable/kiri_jelly = 6
)
- burns_in_oven = TRUE
w_class = WEIGHT_CLASS_SMALL
tastes = list("crispy sweetness" = 1, "caramelized jelly" = 1)
foodtypes = FRUIT | SUGAR
+ crafting_complexity = FOOD_COMPLEXITY_2
/obj/item/food/baked_muli
name = "baked muli pod"
@@ -98,14 +102,14 @@
icon = 'modular_skyrat/master_files/icons/obj/food/irnbru.dmi'
icon_state = "baked_muli"
food_reagents = list(
- /datum/reagent/consumable/nutriment = 4,
- /datum/reagent/consumable/nutriment/vitamin = 4,
+ /datum/reagent/consumable/nutriment = 4,
+ /datum/reagent/consumable/nutriment/vitamin = 4,
/datum/reagent/consumable/muli_juice = 4
)
- burns_in_oven = TRUE
w_class = WEIGHT_CLASS_SMALL
tastes = list("zesty mintyness" = 1)
foodtypes = VEGETABLES
+ crafting_complexity = FOOD_COMPLEXITY_2
/obj/item/food/spiced_jerky
name = "spiced jerky"
@@ -113,12 +117,13 @@
icon = 'modular_skyrat/master_files/icons/obj/food/irnbru.dmi'
icon_state = "spiced_jerky"
food_reagents = list(
- /datum/reagent/consumable/nutriment = 8,
+ /datum/reagent/consumable/nutriment = 8,
/datum/reagent/consumable/nutriment/protein = 6
)
w_class = WEIGHT_CLASS_SMALL
tastes = list("tough, spicy jerky" = 1)
foodtypes = MEAT
+ crafting_complexity = FOOD_COMPLEXITY_2
/obj/item/food/sirisai_wrap
name = "sirisai wrap"
@@ -126,13 +131,14 @@
icon = 'modular_skyrat/master_files/icons/obj/food/irnbru.dmi'
icon_state = "sirisai_wrap"
food_reagents = list(
- /datum/reagent/consumable/nutriment = 8,
- /datum/reagent/consumable/nutriment/protein = 6,
+ /datum/reagent/consumable/nutriment = 8,
+ /datum/reagent/consumable/nutriment/protein = 6,
/datum/reagent/consumable/nutriment/vitamin = 6
)
w_class = WEIGHT_CLASS_SMALL
tastes = list("cooked cabbage" = 1, "spiced meat" = 1, "minty piru bread" = 1)
foodtypes = MEAT | VEGETABLES
+ crafting_complexity = FOOD_COMPLEXITY_4
/obj/item/food/sweet_piru_noodles
name = "sweet piru noodles"
@@ -141,14 +147,15 @@
icon_state = "sweet_piru_noodles"
trash_type = /obj/item/reagent_containers/cup/bowl
food_reagents = list(
- /datum/reagent/consumable/nutriment = 8,
- /datum/reagent/consumable/kiri_jelly = 4,
- /datum/reagent/consumable/muli_juice = 4,
+ /datum/reagent/consumable/nutriment = 8,
+ /datum/reagent/consumable/kiri_jelly = 4,
+ /datum/reagent/consumable/muli_juice = 4,
/datum/reagent/consumable/nutriment/vitamin = 4
)
w_class = WEIGHT_CLASS_SMALL
tastes = list("minty piru noodles" = 1, "minty muli juice" = 1, "sugary kiri jelly" = 1, "baked carrots" = 1)
foodtypes = VEGETABLES | FRUIT | SUGAR
+ crafting_complexity = FOOD_COMPLEXITY_4
/obj/item/food/kiri_curry
name = "kiri curry"
@@ -157,14 +164,15 @@
icon_state = "kiri_curry"
trash_type = /obj/item/reagent_containers/cup/bowl
food_reagents = list(
- /datum/reagent/consumable/nutriment = 8,
- /datum/reagent/consumable/nutriment/protein = 4,
- /datum/reagent/consumable/kiri_jelly = 6,
+ /datum/reagent/consumable/nutriment = 8,
+ /datum/reagent/consumable/nutriment/protein = 4,
+ /datum/reagent/consumable/kiri_jelly = 6,
/datum/reagent/consumable/nutriment/vitamin = 4
)
w_class = WEIGHT_CLASS_SMALL
tastes = list("heavily seasoned meat" = 1, "sweetened minty piru noodles" = 1, "zesty chilis" = 1)
foodtypes = VEGETABLES | FRUIT | SUGAR | MEAT
+ crafting_complexity = FOOD_COMPLEXITY_5
/obj/item/food/sirisai_flatbread
name = "sirisai flatbread"
@@ -172,14 +180,15 @@
icon = 'modular_skyrat/master_files/icons/obj/food/irnbru.dmi'
icon_state = "sirisai_flatbread"
food_reagents = list(
- /datum/reagent/consumable/nutriment = 24,
- /datum/reagent/consumable/nutriment/protein = 16,
- /datum/reagent/consumable/muli_juice = 12,
+ /datum/reagent/consumable/nutriment = 24,
+ /datum/reagent/consumable/nutriment/protein = 16,
+ /datum/reagent/consumable/muli_juice = 12,
/datum/reagent/consumable/nutriment/vitamin = 16
)
w_class = WEIGHT_CLASS_SMALL
tastes = list("crispy minty flatbread" = 1, "minty muli pods" = 1, "tomato sauce" = 1, "tangy spice" = 1, "baked meat" = 1)
foodtypes = VEGETABLES | MEAT
+ crafting_complexity = FOOD_COMPLEXITY_4
/obj/item/food/sirisai_flatbread/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/sirisai_flatbread_slice, 4, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice")
@@ -190,14 +199,15 @@
icon = 'modular_skyrat/master_files/icons/obj/food/irnbru.dmi'
icon_state = "sirisai_flatbread_slice"
food_reagents = list(
- /datum/reagent/consumable/nutriment = 6,
- /datum/reagent/consumable/nutriment/protein = 4,
- /datum/reagent/consumable/muli_juice = 3,
+ /datum/reagent/consumable/nutriment = 6,
+ /datum/reagent/consumable/nutriment/protein = 4,
+ /datum/reagent/consumable/muli_juice = 3,
/datum/reagent/consumable/nutriment/vitamin = 4
)
w_class = WEIGHT_CLASS_SMALL
tastes = list("crispy minty flatbread" = 1, "minty muli pods" = 1, "tomato sauce" = 1, "tangy spice" = 1, "baked meat" = 1)
foodtypes = VEGETABLES | MEAT
+ crafting_complexity = FOOD_COMPLEXITY_4
/obj/item/food/bluefeather_crisp
name = "bluefeather crisp"
@@ -205,12 +215,13 @@
icon = 'modular_skyrat/master_files/icons/obj/food/irnbru.dmi'
icon_state = "bluefeather_crisp"
food_reagents = list(
- /datum/reagent/consumable/nutriment = 4,
+ /datum/reagent/consumable/nutriment = 4,
/datum/reagent/consumable/nutriment/vitamin = 2
)
w_class = WEIGHT_CLASS_SMALL
tastes = list("chewy crackers" = 1, "zesty spice" = 1, "pleasant mintyness" = 1)
foodtypes = VEGETABLES
+ crafting_complexity = FOOD_COMPLEXITY_3
/obj/item/food/bluefeather_crisps_and_dip
name = "bluefeather crisps and dip"
@@ -218,13 +229,14 @@
icon = 'modular_skyrat/master_files/icons/obj/food/irnbru.dmi'
icon_state = "bluefeather_crisps_and_dip"
food_reagents = list(
- /datum/reagent/consumable/nutriment = 12,
- /datum/reagent/consumable/muli_juice = 8,
+ /datum/reagent/consumable/nutriment = 12,
+ /datum/reagent/consumable/muli_juice = 8,
/datum/reagent/consumable/nutriment/vitamin = 6
)
w_class = WEIGHT_CLASS_SMALL
tastes = list("chewy crackers" = 1, "tangy dip" = 1, "pleasant mintyness" = 1)
foodtypes = VEGETABLES
+ crafting_complexity = FOOD_COMPLEXITY_4
/obj/item/food/stewed_muli
name = "stewed muli"
@@ -233,14 +245,15 @@
icon_state = "stewed_muli"
trash_type = /obj/item/reagent_containers/cup/bowl
food_reagents = list(
- /datum/reagent/consumable/nutriment = 10,
- /datum/reagent/consumable/nutriment/protein = 8,
- /datum/reagent/consumable/nutriment/vitamin = 6,
+ /datum/reagent/consumable/nutriment = 10,
+ /datum/reagent/consumable/nutriment/protein = 8,
+ /datum/reagent/consumable/nutriment/vitamin = 6,
/datum/reagent/consumable/muli_juice = 6
)
w_class = WEIGHT_CLASS_SMALL
tastes = list("hearty spiced meat" = 1, "baked carrots" = 1, "baked cabbage" = 1, "minty broth" = 1)
foodtypes = VEGETABLES | MEAT
+ crafting_complexity = FOOD_COMPLEXITY_5
/obj/item/food/stuffed_muli_pod
name = "stuffed muli pod"
@@ -248,14 +261,15 @@
icon = 'modular_skyrat/master_files/icons/obj/food/irnbru.dmi'
icon_state = "stuffed_muli_pod"
food_reagents = list(
- /datum/reagent/consumable/nutriment = 8,
- /datum/reagent/consumable/nutriment/protein = 4,
- /datum/reagent/consumable/nutriment/vitamin = 4,
+ /datum/reagent/consumable/nutriment = 8,
+ /datum/reagent/consumable/nutriment/protein = 4,
+ /datum/reagent/consumable/nutriment/vitamin = 4,
/datum/reagent/consumable/muli_juice = 4
)
w_class = WEIGHT_CLASS_SMALL
tastes = list("spiced meat" = 1, "minty muli pod" = 1, "super-sweet kiri fruit" = 1, "chili" = 1)
foodtypes = VEGETABLES | FRUIT | MEAT | SUGAR
+ crafting_complexity = FOOD_COMPLEXITY_3
/obj/item/food/caramel_jelly_toast
name = "caramel jelly toast"
@@ -263,12 +277,13 @@
icon = 'modular_skyrat/master_files/icons/obj/food/irnbru.dmi'
icon_state = "caramel_jelly_toast"
food_reagents = list(
- /datum/reagent/consumable/nutriment = 8,
+ /datum/reagent/consumable/nutriment = 8,
/datum/reagent/consumable/nutriment/vitamin = 6
)
w_class = WEIGHT_CLASS_SMALL
tastes = list("minty piru bread" = 1, "sweet caramel" = 1, "super-sweet kiri jelly" = 1)
foodtypes = VEGETABLES | FRUIT | SUGAR
+ crafting_complexity = FOOD_COMPLEXITY_4
/obj/item/food/kiri_jellypuff
name = "kiri jellypuff"
@@ -276,10 +291,11 @@
icon = 'modular_skyrat/master_files/icons/obj/food/irnbru.dmi'
icon_state = "kiri_jellypuff"
food_reagents = list(
- /datum/reagent/consumable/nutriment = 8,
- /datum/reagent/consumable/nutriment/vitamin = 6,
+ /datum/reagent/consumable/nutriment = 8,
+ /datum/reagent/consumable/nutriment/vitamin = 6,
/datum/reagent/consumable/kiri_jelly = 4
)
w_class = WEIGHT_CLASS_SMALL
tastes = list("puffed minty piru bread" = 1, "rich cream" = 1, "super-sweet kiri jelly" = 1)
foodtypes = VEGETABLES | FRUIT | SUGAR
+ crafting_complexity = FOOD_COMPLEXITY_4
diff --git a/modular_skyrat/modules/customization/modules/food_and_drinks/recipes/drinks_recipes.dm b/modular_skyrat/modules/customization/modules/food_and_drinks/recipes/drinks_recipes.dm
index 636e0071c27..14691393f03 100644
--- a/modular_skyrat/modules/customization/modules/food_and_drinks/recipes/drinks_recipes.dm
+++ b/modular_skyrat/modules/customization/modules/food_and_drinks/recipes/drinks_recipes.dm
@@ -215,7 +215,7 @@
/datum/chemical_reaction/drink/beerbatter
results = list(/datum/reagent/consumable/ethanol/beerbatter = 4)
- required_reagents = list(/datum/reagent/consumable/cooking_oil = 1, /datum/reagent/consumable/ethanol/beer = 1, /datum/reagent/consumable/flour = 1)
+ required_reagents = list(/datum/reagent/consumable/nutriment/fat/oil = 1, /datum/reagent/consumable/ethanol/beer = 1, /datum/reagent/consumable/flour = 1)
mix_message = "Sizzling and cracking is heard as you beat the mixture into submission."
/datum/chemical_reaction/drink/shakiri_spritz
diff --git a/modular_skyrat/modules/customization/modules/hydroponics/grown/muli.dm b/modular_skyrat/modules/customization/modules/hydroponics/grown/muli.dm
index 308d34ca193..7f787804fc6 100644
--- a/modular_skyrat/modules/customization/modules/hydroponics/grown/muli.dm
+++ b/modular_skyrat/modules/customization/modules/hydroponics/grown/muli.dm
@@ -22,7 +22,7 @@
icon = 'modular_skyrat/master_files/icons/obj/hydroponics/harvest.dmi'
icon_state = "muli"
foodtypes = VEGETABLES
- juice_results = list(/datum/reagent/consumable/muli_juice = 0.3)
+ juice_typepath = /datum/reagent/consumable/muli_juice
grind_results = list(/datum/reagent/consumable/muli_juice = 0.1)
tastes = list("mint and savory sweetness" = 1)
diff --git a/modular_skyrat/modules/customization/modules/jobs/_job.dm b/modular_skyrat/modules/customization/modules/jobs/_job.dm
index c975b617f22..09d4bf100c2 100644
--- a/modular_skyrat/modules/customization/modules/jobs/_job.dm
+++ b/modular_skyrat/modules/customization/modules/jobs/_job.dm
@@ -5,6 +5,8 @@
var/loadout = TRUE
//List of banned quirks in their names(dont blame me, that's how they're stored), players can't join as the job if they have the quirk. Associative for the purposes of performance
var/list/banned_quirks
+ /// List of banned augments
+ var/list/banned_augments
///A list of slots that can't have loadout items assigned to them if no_dresscode is applied, used for important items such as ID, PDA, backpack and headset
var/list/blacklist_dresscode_slots
//Whitelist of allowed species for this job. If not specified then all roundstart races can be used. Associative with TRUE
@@ -41,6 +43,20 @@
return TRUE
return FALSE
+/datum/job/proc/has_banned_augment(datum/preferences/pref)
+ if(!pref)
+ return FALSE
+
+ if(!banned_augments)
+ return FALSE
+
+ var/list/player_augments = pref.augments
+ for(var/key in player_augments)
+ if(player_augments[key] in banned_augments)
+ return TRUE
+
+ return FALSE
+
// Misc
/datum/job/assistant
no_dresscode = TRUE
@@ -53,43 +69,56 @@
//Security
/datum/job/security_officer
banned_quirks = list(SEC_RESTRICTED_QUIRKS)
+ banned_augments = list(SEC_RESTRICTED_AUGMENTS)
/datum/job/detective
banned_quirks = list(SEC_RESTRICTED_QUIRKS)
+ banned_augments = list(SEC_RESTRICTED_AUGMENTS)
/datum/job/warden
banned_quirks = list(SEC_RESTRICTED_QUIRKS)
+ banned_augments = list(SEC_RESTRICTED_AUGMENTS)
/datum/job/blueshield
banned_quirks = list(SEC_RESTRICTED_QUIRKS)
+ banned_augments = list(SEC_RESTRICTED_AUGMENTS)
/datum/job/corrections_officer
banned_quirks = list(SEC_RESTRICTED_QUIRKS)
+ banned_augments = list(SEC_RESTRICTED_AUGMENTS)
// Command
/datum/job/captain
banned_quirks = list(HEAD_RESTRICTED_QUIRKS)
+ banned_augments = list(HEAD_RESTRICTED_AUGMENTS)
/datum/job/nanotrasen_consultant
banned_quirks = list(HEAD_RESTRICTED_QUIRKS)
+ banned_augments = list(HEAD_RESTRICTED_AUGMENTS)
/datum/job/head_of_security
banned_quirks = list(SEC_RESTRICTED_QUIRKS, HEAD_RESTRICTED_QUIRKS)
+ banned_augments = list(SEC_RESTRICTED_AUGMENTS)
/datum/job/chief_medical_officer
banned_quirks = list(HEAD_RESTRICTED_QUIRKS)
+ banned_augments = list(HEAD_RESTRICTED_AUGMENTS)
/datum/job/chief_engineer
banned_quirks = list(HEAD_RESTRICTED_QUIRKS, "Paraplegic" = TRUE)
+ banned_augments = list(HEAD_RESTRICTED_AUGMENTS)
/datum/job/research_director
banned_quirks = list(HEAD_RESTRICTED_QUIRKS)
+ banned_augments = list(HEAD_RESTRICTED_AUGMENTS)
/datum/job/head_of_personnel
banned_quirks = list(HEAD_RESTRICTED_QUIRKS)
+ banned_augments = list(HEAD_RESTRICTED_AUGMENTS)
/datum/job/quartermaster
banned_quirks = list(HEAD_RESTRICTED_QUIRKS)
+ banned_augments = list(HEAD_RESTRICTED_AUGMENTS)
//Silicon
/datum/job/ai
@@ -205,12 +234,16 @@
// Nanotrasen Fleet
/datum/job/fleetmaster
banned_quirks = list(HEAD_RESTRICTED_QUIRKS)
+ banned_augments = list(HEAD_RESTRICTED_AUGMENTS)
/datum/job/operations_inspector
banned_quirks = list(HEAD_RESTRICTED_QUIRKS)
+ banned_augments = list(HEAD_RESTRICTED_AUGMENTS)
/datum/job/deck_crew
banned_quirks = list(HEAD_RESTRICTED_QUIRKS)
+ banned_augments = list(HEAD_RESTRICTED_AUGMENTS)
/datum/job/bridge_officer
banned_quirks = list(HEAD_RESTRICTED_QUIRKS)
+ banned_augments = list(HEAD_RESTRICTED_AUGMENTS)
diff --git a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories.dm b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories.dm
index cd22694da79..dd96f77df02 100644
--- a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories.dm
+++ b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories.dm
@@ -206,6 +206,7 @@ GLOBAL_LIST_EMPTY(cached_mutant_icon_files)
/datum/sprite_accessory/socks
icon = 'modular_skyrat/master_files/icons/mob/clothing/underwear.dmi'
use_static = TRUE
+
/datum/sprite_accessory/socks/socks_norm
name = "Normal (Greyscale)"
icon_state = "white_norm"
@@ -385,17 +386,17 @@ GLOBAL_LIST_EMPTY(cached_mutant_icon_files)
gender = MALE
use_static = TRUE
+/datum/sprite_accessory/underwear/panties_basic
+ name = "Panties - Basic"
+ icon_state = "panties"
+ gender = FEMALE
+
/datum/sprite_accessory/underwear/female_beekini
name = "Panties - Bee-kini"
icon_state = "panties_bee-kini"
gender = FEMALE
use_static = TRUE
-/datum/sprite_accessory/underwear/panties
- name = "Panties"
- icon_state = "panties"
- gender = FEMALE
-
/datum/sprite_accessory/underwear/fishnet_lower
name = "Panties - Fishnet"
icon_state = "fishnet_lower"
@@ -528,57 +529,39 @@ GLOBAL_LIST_EMPTY(cached_mutant_icon_files)
has_digitigrade = TRUE
gender = FEMALE
+/datum/sprite_accessory/underwear/boyshorts_alt
+ name = "Boyshorts (Alt)"
+ icon_state = "boyshorts_alt"
+ gender = FEMALE
+
/*
Adding hides_breasts to TG underwears where applicable
*/
-/datum/sprite_accessory/underwear/female_bikini
- hides_breasts = TRUE
-
-/datum/sprite_accessory/underwear/female_lace
- hides_breasts = TRUE
-
-/datum/sprite_accessory/underwear/female_bralette
- hides_breasts = TRUE
-
-/datum/sprite_accessory/underwear/female_sport
- hides_breasts = TRUE
-
-/datum/sprite_accessory/underwear/female_strapless
- hides_breasts = TRUE
-
-/datum/sprite_accessory/underwear/female_babydoll
- hides_breasts = TRUE
/datum/sprite_accessory/underwear/swimsuit_onepiece
+ name = "One-Piece Swimsuit"
+ icon_state = "swim_onepiece"
+ gender = FEMALE
hides_breasts = TRUE
/datum/sprite_accessory/underwear/swimsuit_strapless_onepiece
+ name = "Strapless One-Piece Swimsuit"
+ icon_state = "swim_strapless_onepiece"
+ gender = FEMALE
hides_breasts = TRUE
-
-/datum/sprite_accessory/underwear/swimsuit_twopiece
- hides_breasts = TRUE
-
-/datum/sprite_accessory/underwear/swimsuit_strapless_twopiece
- hides_breasts = TRUE
-
/datum/sprite_accessory/underwear/swimsuit_stripe
+ name = "Strapless Striped Swimsuit"
+ icon_state = "swim_stripe"
+ gender = FEMALE
hides_breasts = TRUE
-/datum/sprite_accessory/underwear/swimsuit_halter
- hides_breasts = TRUE
-
-/datum/sprite_accessory/underwear/female_white_neko
- hides_breasts = TRUE
-
-/datum/sprite_accessory/underwear/female_black_neko
- hides_breasts = TRUE
-
-/datum/sprite_accessory/underwear/female_uk
- hides_breasts = TRUE
/*
End of adding hides_breasts to TG stuff, start of adding has_digitigrade to TG stuff
*/
+/datum/sprite_accessory/underwear/male_briefs
+ has_digitigrade = TRUE
+
/datum/sprite_accessory/underwear/male_boxers
has_digitigrade = TRUE
@@ -603,13 +586,216 @@ GLOBAL_LIST_EMPTY(cached_mutant_icon_files)
/datum/sprite_accessory/underwear/male_uk
has_digitigrade = TRUE
-/datum/sprite_accessory/underwear/female_sport
- has_digitigrade = TRUE
-
/*
End of adding has_digitigrade to TG stuff
*/
+
+/// BRAS and all the fun stuff of moving these about.
+/datum/sprite_accessory/bra
+ icon = 'modular_skyrat/master_files/icons/mob/clothing/underwear.dmi'
+ use_static = FALSE
+ em_block = TRUE
+
+/datum/sprite_accessory/bra/nude
+ name = "Nude"
+ icon_state = null
+ gender = NEUTER
+
+/datum/sprite_accessory/bra/bra
+ name = "Bra"
+ icon_state = "bra"
+ gender = FEMALE
+ use_static = null
+
+/datum/sprite_accessory/bra/bra_alt
+ name = "Bra - Alt"
+ icon_state = "bra_alt"
+ gender = FEMALE
+ use_static = null
+
+/datum/sprite_accessory/bra/bra_thin
+ name = "Bra - Thin"
+ icon_state = "bra_thin"
+ gender = FEMALE
+ use_static = null
+
+/datum/sprite_accessory/bra/bra_kinky
+ name = "Bra - Kinky Black"
+ icon_state = "bra_kinky"
+ gender = FEMALE
+ use_static = TRUE
+
+/datum/sprite_accessory/bra/bra_freedom
+ name = "Bra - Freedom"
+ icon_state = "bra_assblastusa"
+ gender = FEMALE
+ use_static = TRUE
+
+/datum/sprite_accessory/bra/bra_commie
+ name = "Bra - Commie"
+ icon_state = "bra_commie"
+ gender = FEMALE
+ use_static = TRUE
+
+/datum/sprite_accessory/bra/bra_beekini
+ name = "Bra - Bee-kini"
+ icon_state = "bra_bee-kini"
+ gender = FEMALE
+ use_static = TRUE
+
+/datum/sprite_accessory/bra/bra_uk
+ name = "Bra - UK"
+ icon_state = "bra_uk"
+ gender = FEMALE
+ use_static = TRUE
+
+/datum/sprite_accessory/bra/bra_neko
+ name = "Bra - Neko"
+ icon_state = "bra_neko"
+ gender = FEMALE
+ use_static = null
+
+/datum/sprite_accessory/bra/hi_vis_bra
+ name = "Safekini"
+ icon_state = "hi_vis_bra"
+ gender = FEMALE
+ use_static = TRUE
+
+/datum/sprite_accessory/bra/halterneck_bra
+ name = "Bra - Halterneck"
+ icon_state = "halterneck_bra"
+ gender = FEMALE
+ use_static = null
+
+/datum/sprite_accessory/bra/halterneck_alt
+ name = "Bra - Halterneck (Alt)"
+ icon_state = "bra_swimming"
+ gender = FEMALE
+ use_static = null
+
+/datum/sprite_accessory/bra/sports_bra
+ name = "Bra, Sports"
+ icon_state = "sports_bra"
+ gender = FEMALE
+ use_static = null
+
+/datum/sprite_accessory/bra/sports_bra_alt
+ name = "Bra, Sports - Alt"
+ icon_state = "sports_bra_alt"
+ gender = FEMALE
+ use_static = null
+
+/datum/sprite_accessory/bra/bra_strapless
+ name = "Bra, Strapless"
+ icon_state = "bra_strapless"
+ gender = FEMALE
+ use_static = null
+
+/datum/sprite_accessory/bra/bra_latex
+ name = "Bra, Latex"
+ icon_state = "bra_latex"
+ gender = FEMALE
+ use_static = TRUE
+ erp_accessory = TRUE
+
+/datum/sprite_accessory/bra/striped_bra
+ name = "Bra - Striped"
+ icon_state = "striped_bra"
+ gender = FEMALE
+ use_static = null
+
+/datum/sprite_accessory/bra/sarashi
+ name = "Bra - Sarashi"
+ icon_state = "bandages"
+ gender = NEUTER
+ use_static = null
+
+/datum/sprite_accessory/bra/fishnet_sleeves
+ name = "Fishnet - Sleeved"
+ icon_state = "fishnet_sleeves"
+ gender = FEMALE
+ use_static = TRUE
+
+/datum/sprite_accessory/bra/fishnet_sleeves/alt
+ name = "Fishnet - Sleeved (Greyscale)"
+ icon_state = "fishnet_sleeves_alt"
+ use_static = null
+
+/datum/sprite_accessory/bra/fishnet_base
+ name = "Fishnet - Sleeveless"
+ icon_state = "fishnet_body"
+ gender = FEMALE
+ use_static = TRUE
+
+/datum/sprite_accessory/bra/fishnet_base/alt
+ name = "Fishnet - Sleeveless (Greyscale)"
+ icon_state = "fishnet_body_alt"
+ use_static = null
+
+/datum/sprite_accessory/bra/chastbra
+ name = "Chastity Bra"
+ icon_state = "chastbra"
+ gender = FEMALE
+ use_static = TRUE
+ erp_accessory = TRUE
+
+/datum/sprite_accessory/bra/pasties
+ name = "Pasties"
+ icon_state = "pasties"
+ gender = FEMALE
+ use_static = null
+ erp_accessory = TRUE
+
+/datum/sprite_accessory/bra/pasties_alt
+ name = "Pasties - Alt"
+ icon_state = "pasties_alt"
+ gender = FEMALE
+ use_static = null
+ erp_accessory = TRUE
+
+/datum/sprite_accessory/bra/shibari
+ name = "Shibari"
+ icon_state = "shibari"
+ gender = FEMALE
+ use_static = null
+ erp_accessory = TRUE
+
+/datum/sprite_accessory/bra/shibari_sleeves
+ name = "Shibari Sleeves"
+ icon_state = "shibari_sleeves"
+ gender = FEMALE
+ use_static = null
+ erp_accessory = TRUE
+
+/datum/sprite_accessory/bra/swimsuit
+ name = "Swimsuit Top"
+ icon_state = "bikini_bra"
+ gender = FEMALE
+ use_static = null
+
+/datum/sprite_accessory/bra/strapless_swimsuit
+ name = "Strapless Swimsuit Top"
+ icon_state = "strapless_biki_bra"
+ gender = FEMALE
+ use_static = null
+
+/datum/sprite_accessory/bra/strapless_swimsuit_alt
+ name = "Strapless Swimsuit Top (Alt)"
+ icon_state = "strapless_biki_bra_alt"
+ gender = FEMALE
+ use_static = null
+
+/datum/sprite_accessory/bra/binder
+ name = "Binder"
+ icon_state = "binder"
+ gender = MALE
+ use_static = null
+
+/datum/sprite_accessory/bra/binder/strapless
+ name = "Binder - Strapless"
+ icon_state = "binder_strapless"
+
/datum/sprite_accessory/undershirt
icon = 'modular_skyrat/master_files/icons/mob/clothing/underwear.dmi'
use_static = TRUE
@@ -644,136 +830,11 @@ GLOBAL_LIST_EMPTY(cached_mutant_icon_files)
use_static = TRUE
/datum/sprite_accessory/undershirt/babydoll
- name = "Baby-Doll"
+ name = "Babydoll"
icon_state = "babydoll"
gender = FEMALE
use_static = null
-/datum/sprite_accessory/undershirt/bra
- name = "Bra"
- icon_state = "bra"
- gender = FEMALE
- use_static = null
-
-/datum/sprite_accessory/undershirt/bra_alt
- name = "Bra - Alt"
- icon_state = "bra_alt"
- gender = FEMALE
- use_static = null
-
-/datum/sprite_accessory/undershirt/bra_thin
- name = "Bra - Thin"
- icon_state = "bra_thin"
- gender = FEMALE
- use_static = null
-
-/datum/sprite_accessory/undershirt/bra_kinky
- name = "Bra - Kinky Black"
- icon_state = "bra_kinky"
- gender = FEMALE
- use_static = TRUE
-
-/datum/sprite_accessory/undershirt/bra_freedom
- name = "Bra - Freedom"
- icon_state = "bra_assblastusa"
- gender = FEMALE
- use_static = TRUE
-
-/datum/sprite_accessory/undershirt/bra_commie
- name = "Bra - Commie"
- icon_state = "bra_commie"
- gender = FEMALE
- use_static = TRUE
-
-/datum/sprite_accessory/undershirt/bra_beekini
- name = "Bra - Bee-kini"
- icon_state = "bra_bee-kini"
- gender = FEMALE
- use_static = TRUE
-
-/datum/sprite_accessory/undershirt/bra_uk
- name = "Bra - UK"
- icon_state = "bra_uk"
- gender = FEMALE
- use_static = TRUE
-
-/datum/sprite_accessory/undershirt/bra_neko
- name = "Bra - Neko"
- icon_state = "bra_neko"
- gender = FEMALE
- use_static = null
-
-/datum/sprite_accessory/undershirt/halterneck_bra
- name = "Bra - Halterneck"
- icon_state = "halterneck_bra"
- gender = FEMALE
- use_static = null
-
-/datum/sprite_accessory/undershirt/sports_bra
- name = "Bra, Sports"
- icon_state = "sports_bra"
- gender = FEMALE
- use_static = null
-
-/datum/sprite_accessory/undershirt/sports_bra_alt
- name = "Bra, Sports - Alt"
- icon_state = "sports_bra_alt"
- gender = FEMALE
- use_static = null
-
-/datum/sprite_accessory/undershirt/bra_strapless
- name = "Bra, Strapless"
- icon_state = "bra_strapless"
- gender = FEMALE
- use_static = null
-
-/datum/sprite_accessory/undershirt/bra_latex
- name = "Bra, Latex"
- icon_state = "bra_latex"
- gender = FEMALE
- use_static = TRUE
- erp_accessory = TRUE
-
-/datum/sprite_accessory/undershirt/striped_bra
- name = "Bra - Striped"
- icon_state = "striped_bra"
- gender = FEMALE
- use_static = null
-
-/datum/sprite_accessory/undershirt/sarashi
- name = "Bra - Sarashi"
- icon_state = "bandages"
- gender = NEUTER
- use_static = null
-
-/datum/sprite_accessory/undershirt/fishnet_sleeves
- name = "Fishnet - Sleeved"
- icon_state = "fishnet_sleeves"
- gender = FEMALE
- use_static = TRUE
-
-/datum/sprite_accessory/undershirt/fishnet_sleeves/alt
- name = "Fishnet - Sleeved (Greyscale)"
- icon_state = "fishnet_sleeves_alt"
- use_static = null
-
-/datum/sprite_accessory/undershirt/fishnet_base
- name = "Fishnet - Sleeveless"
- icon_state = "fishnet_body"
- gender = FEMALE
- use_static = TRUE
-
-/datum/sprite_accessory/undershirt/fishnet_base/alt
- name = "Fishnet - Sleeveless (Greyscale)"
- icon_state = "fishnet_body_alt"
- use_static = null
-
-/datum/sprite_accessory/undershirt/swimsuit
- name = "Swimsuit Top"
- icon_state = "bra_swimming"
- gender = FEMALE
- use_static = null
-
/datum/sprite_accessory/undershirt/corset
name = "Corset"
icon_state = "corset"
@@ -781,41 +842,6 @@ GLOBAL_LIST_EMPTY(cached_mutant_icon_files)
use_static = TRUE
hides_groin = TRUE
-/datum/sprite_accessory/undershirt/chastbra
- name = "Chastity Bra"
- icon_state = "chastbra"
- gender = FEMALE
- use_static = TRUE
- erp_accessory = TRUE
-
-/datum/sprite_accessory/undershirt/pasties
- name = "Pasties"
- icon_state = "pasties"
- gender = FEMALE
- use_static = null
- erp_accessory = TRUE
-
-/datum/sprite_accessory/undershirt/pasties_alt
- name = "Pasties - Alt"
- icon_state = "pasties_alt"
- gender = FEMALE
- use_static = null
- erp_accessory = TRUE
-
-/datum/sprite_accessory/undershirt/shibari
- name = "Shibari"
- icon_state = "shibari"
- gender = FEMALE
- use_static = null
- erp_accessory = TRUE
-
-/datum/sprite_accessory/undershirt/shibari_sleeves
- name = "Shibari Sleeves"
- icon_state = "shibari_sleeves"
- gender = FEMALE
- use_static = null
- erp_accessory = TRUE
-
/datum/sprite_accessory/undershirt/bulletclub //4 life
name = "Shirt - Black Skull"
icon_state = "shirt_bc"
@@ -831,16 +857,6 @@ GLOBAL_LIST_EMPTY(cached_mutant_icon_files)
name = "Shirt - Blue Stripes"
icon_state = "longstripe_blue"
-/datum/sprite_accessory/undershirt/binder
- name = "Binder"
- icon_state = "binder"
- gender = MALE
- use_static = null
-
-/datum/sprite_accessory/undershirt/binder/strapless
- name = "Binder - Strapless"
- icon_state = "binder_strapless"
-
/datum/sprite_accessory/undershirt/turtleneck
name = "Sweater - Turtleneck"
icon_state = "turtleneck"
diff --git a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/ears.dm b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/ears.dm
index 68d872765d6..b27d27bae0a 100644
--- a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/ears.dm
+++ b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/ears.dm
@@ -391,3 +391,15 @@
/datum/sprite_accessory/ears/mutant/big/fourears3
name = "Four Ears 3"
icon_state = "four_ears_3"
+
+/datum/sprite_accessory/ears/acrador
+ icon = 'modular_skyrat/master_files/icons/mob/sprite_accessory/ears_big.dmi'
+ color_src = USE_MATRIXED_COLORS
+
+/datum/sprite_accessory/ears/acrador/long
+ icon_state = "acrador_long"
+ name = "Acrador (Long)"
+
+/datum/sprite_accessory/ears/acrador/short
+ icon_state = "acrador_short"
+ name = "Acrador (Short)"
diff --git a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/genitals.dm b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/genitals.dm
index 6930b5ef585..f5d314f1793 100644
--- a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/genitals.dm
+++ b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/genitals.dm
@@ -45,6 +45,10 @@
else if(genital_location == CHEST && worn_underwear.hides_breasts)
return TRUE
+ //Are they wearing a bra?
+ if(target_mob.bra != "Nude" && !(target_mob.underwear_visibility & UNDERWEAR_HIDE_BRA) && genital_location == CHEST)
+ return TRUE
+
//Nothing they're wearing will cover them
else
return FALSE
diff --git a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/hair.dm b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/hair.dm
index 40fa7110461..172ea352ac2 100644
--- a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/hair.dm
+++ b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/hair.dm
@@ -475,6 +475,10 @@
name = "Tri Bun Long"
icon_state = "hair_tri_bun_long"
+/datum/sprite_accessory/hair/skyrat/hairfre // Original sprite from Hyper-Station-13
+ name = "Hairfre"
+ icon_state = "hair_hairfre"
+
// Facial hair
/datum/sprite_accessory/facial_hair/skyrat
diff --git a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/snout.dm b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/snout.dm
index c9c0f96c00d..ea2c8d99beb 100644
--- a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/snout.dm
+++ b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/snout.dm
@@ -428,3 +428,9 @@
icon_state = "leporid"
color_src = USE_MATRIXED_COLORS
flags_for_organ = NONE
+
+/datum/sprite_accessory/snouts/acrador
+ icon = 'modular_skyrat/master_files/icons/mob/sprite_accessory/snouts.dmi'
+ color_src = USE_MATRIXED_COLORS
+ name = "Acrador (Short)"
+ icon_state = "acrador_short"
diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human.dm
index 6b540a5cb7f..78c597e7864 100644
--- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human.dm
+++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human.dm
@@ -83,21 +83,24 @@
var/underwear_button = underwear_visibility & UNDERWEAR_HIDE_UNDIES ? "Show underwear" : "Hide underwear"
var/undershirt_button = underwear_visibility & UNDERWEAR_HIDE_SHIRT ? "Show shirt" : "Hide shirt"
var/socks_button = underwear_visibility & UNDERWEAR_HIDE_SOCKS ? "Show socks" : "Hide socks"
- var/list/choice_list = list("[underwear_button]" = 1,"[undershirt_button]" = 2,"[socks_button]" = 3,"Show all" = 4, "Hide all" = 5)
+ var/bra_button = underwear_visibility & UNDERWEAR_HIDE_BRA ? "Show bra" : "Hide bra"
+ var/list/choice_list = list("[underwear_button]" = "underwear", "[bra_button]" = "bra", "[undershirt_button]" = "shirt", "[socks_button]" = "socks","show all" = "show", "Hide all" = "hide")
var/picked_visibility = input(src, "Choose visibility setting", "Show/Hide underwear") as null|anything in choice_list
if(picked_visibility)
var/picked_choice = choice_list[picked_visibility]
switch(picked_choice)
- if(1)
+ if("underwear")
underwear_visibility ^= UNDERWEAR_HIDE_UNDIES
- if(2)
+ if("bra")
+ underwear_visibility ^= UNDERWEAR_HIDE_BRA
+ if("shirt")
underwear_visibility ^= UNDERWEAR_HIDE_SHIRT
- if(3)
+ if("socks")
underwear_visibility ^= UNDERWEAR_HIDE_SOCKS
- if(4)
+ if("show")
underwear_visibility = NONE
- if(5)
- underwear_visibility = UNDERWEAR_HIDE_UNDIES | UNDERWEAR_HIDE_SHIRT | UNDERWEAR_HIDE_SOCKS
+ if("hide")
+ underwear_visibility = UNDERWEAR_HIDE_UNDIES | UNDERWEAR_HIDE_SHIRT | UNDERWEAR_HIDE_SOCKS | UNDERWEAR_HIDE_BRA
update_body()
return
diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human_defines.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human_defines.dm
index 9e0f80c7c2c..2b5d1e83f9b 100644
--- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human_defines.dm
+++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human_defines.dm
@@ -21,4 +21,7 @@
var/oversized_piggyknock = 3 SECONDS
/// Alpha of the hair. Takes precedent over species hair_alpha if non-null.
var/hair_alpha
-
+ /// The selected bra.
+ var/bra = "Nude"
+ /// Color of the bra.
+ var/bra_color = "#FFFFFF"
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 712a5fd1757..3d0aaf94db5 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
@@ -133,6 +133,18 @@ GLOBAL_LIST_EMPTY(customizable_races)
underwear_overlay.color = species_human.underwear_color
standing += underwear_overlay
+ if(species_human.bra && !(species_human.underwear_visibility & UNDERWEAR_HIDE_BRA))
+ var/datum/sprite_accessory/bra/bra = GLOB.bra_list[species_human.bra]
+
+ if(bra)
+ var/mutable_appearance/bra_overlay
+ var/icon_state = bra.icon_state
+ bra_overlay = mutable_appearance(bra.icon, icon_state, -BODY_LAYER)
+ if(!bra.use_static)
+ bra_overlay.color = species_human.bra_color
+
+ standing += bra_overlay
+
if(species_human.undershirt && !(species_human.underwear_visibility & UNDERWEAR_HIDE_SHIRT))
var/datum/sprite_accessory/undershirt/undershirt = GLOB.undershirt_list[species_human.undershirt]
if(undershirt)
diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/_hemophage_defines.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/_hemophage_defines.dm
index 50fcc84f3f7..7471839e1db 100644
--- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/_hemophage_defines.dm
+++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/_hemophage_defines.dm
@@ -10,6 +10,8 @@
/// Minimum amount of blood that you can reach via blood regeneration, regeneration will stop below this.
#define MINIMUM_VOLUME_FOR_REGEN (BLOOD_VOLUME_BAD + 1) // We do this to avoid any jankiness, and because we want to ensure that they don't fall into a state where they're constantly passing out in a locker.
+/// Vomit flags for hemophages who eat food
+#define HEMOPHAGE_VOMIT_FLAGS (MOB_VOMIT_MESSAGE | MOB_VOMIT_HARM | MOB_VOMIT_FORCE)
/// The ratio of reagents that get purged while a Hemophage vomits from trying to eat/drink something that their tumor doesn't like.
#define HEMOPHAGE_VOMIT_PURGE_RATIO 0.95
/// How much disgust we're at after eating/drinking something the tumor doesn't like.
diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/corrupted_liver.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/corrupted_liver.dm
index 5210b209775..bf731c941aa 100644
--- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/corrupted_liver.dm
+++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/corrupted_liver.dm
@@ -49,7 +49,7 @@
to_chat(body, span_warning("That tasted awful..."))
// We don't lose nutrition because we don't even use nutrition as Hemopahges. It WILL however purge nearly all of what's in their stomach.
- body.vomit(lost_nutrition = 0, stun = FALSE, distance = 1, force = TRUE, purge_ratio = HEMOPHAGE_VOMIT_PURGE_RATIO)
+ body.vomit(vomit_flags = HEMOPHAGE_VOMIT_FLAGS, lost_nutrition = 0, distance = 1, purge_ratio = HEMOPHAGE_VOMIT_PURGE_RATIO)
#undef MINIMUM_BLOOD_REGENING_REAGENT_RATIO
diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/corrupted_stomach.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/corrupted_stomach.dm
index 801f65fb7e0..3af433695a9 100644
--- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/corrupted_stomach.dm
+++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/corrupted_stomach.dm
@@ -1,4 +1,3 @@
-
/datum/component/organ_corruption/stomach
corruptable_organ_type = /obj/item/organ/internal/stomach
corrupted_icon_state = "stomach"
@@ -43,4 +42,4 @@
to_chat(body, span_warning("That tasted awful..."))
// We don't lose nutrition because we don't even use nutrition as hemopahges. It WILL however purge nearly all of what's in their stomach.
- body.vomit(lost_nutrition = 0, stun = FALSE, distance = 1, force = TRUE, purge_ratio = HEMOPHAGE_VOMIT_PURGE_RATIO)
+ body.vomit(vomit_flags = HEMOPHAGE_VOMIT_FLAGS, lost_nutrition = 0, distance = 1, purge_ratio = HEMOPHAGE_VOMIT_PURGE_RATIO)
diff --git a/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/alcohol_reagents.dm
index 25af43017e7..32391bd465e 100644
--- a/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/alcohol_reagents.dm
+++ b/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/alcohol_reagents.dm
@@ -31,7 +31,7 @@
if(!(C.mob_biotypes & MOB_ROBOTIC))
C.reagents.remove_reagent(type, 3.6) //gets removed from organics very fast
if(prob(25))
- C.vomit(5, FALSE, FALSE)
+ C.vomit(VOMIT_CATEGORY_DEFAULT, lost_nutrition = 5)
return ..()
/datum/reagent/consumable/ethanol/synthanol/expose_mob(mob/living/carbon/C, method=TOUCH, volume)
diff --git a/modular_skyrat/modules/customization/modules/surgery/bodyparts/parts.dm b/modular_skyrat/modules/customization/modules/surgery/bodyparts/parts.dm
new file mode 100644
index 00000000000..85b251c08b6
--- /dev/null
+++ b/modular_skyrat/modules/customization/modules/surgery/bodyparts/parts.dm
@@ -0,0 +1,32 @@
+/// Self Destructing Bodyparts, For Augmentation. I'm leaving out heads + chests as, while it would be cool for synths, I also don't want people to start the round unrevivable sans botany because they're dumb as heck. You know who and what you are.
+/obj/item/bodypart/arm/left/self_destruct/try_attach_limb(mob/living/carbon/limb_owner, special)
+ . = ..()
+ drop_limb()
+ qdel(src)
+
+/obj/item/bodypart/arm/left/self_destruct/set_icon_static(new_icon)
+ return
+
+/obj/item/bodypart/arm/right/self_destruct/try_attach_limb(mob/living/carbon/limb_owner, special)
+ . = ..()
+ drop_limb()
+ qdel(src)
+
+/obj/item/bodypart/arm/right/self_destruct/set_icon_static(new_icon)
+ return
+
+/obj/item/bodypart/leg/left/self_destruct/try_attach_limb(mob/living/carbon/limb_owner, special)
+ . = ..()
+ drop_limb()
+ qdel(src)
+
+/obj/item/bodypart/leg/left/self_destruct/set_icon_static(new_icon)
+ return
+
+/obj/item/bodypart/leg/right/self_destruct/try_attach_limb(mob/living/carbon/limb_owner, special)
+ . = ..()
+ drop_limb()
+ qdel(src)
+
+/obj/item/bodypart/leg/right/self_destruct/set_icon_static(new_icon)
+ return
diff --git a/modular_skyrat/modules/customization/readme.md b/modular_skyrat/modules/customization/readme.md
index af197a1baca..b488c032194 100644
--- a/modular_skyrat/modules/customization/readme.md
+++ b/modular_skyrat/modules/customization/readme.md
@@ -53,8 +53,6 @@ Re-writes how mutant bodyparts exist and how they're handled. Adds in a per limb
./code/_globalvars/lists/flavor_misc.dm > Removed accessory list defines
.\code\datums\keybindings\living.dm > /datum/keybinding/living/look_up > from L to P
-./code/modules/surgery/bodyparts/_bodyparts.dm > var/rendered_bp_icon
-
./code/__DEFINES/~skyrat_defines/DNA.dm > A TON of defines
./code/__DEFINES/~skyrat_defines/obj_flags.dm > Organ flags
./code/__DEFINES/~skyrat_defines/say.dm > MAX_FLAVOR_LEN
diff --git a/modular_skyrat/modules/cyborg/code/robot_upgrades.dm b/modular_skyrat/modules/cyborg/code/robot_upgrades.dm
index 179e47bbb8d..fcf0f705eb6 100644
--- a/modular_skyrat/modules/cyborg/code/robot_upgrades.dm
+++ b/modular_skyrat/modules/cyborg/code/robot_upgrades.dm
@@ -20,7 +20,7 @@
return FALSE
borg.hasShrunk = TRUE
- borg.notransform = TRUE
+ ADD_TRAIT(borg, TRAIT_NO_TRANSFORM, REF(src))
var/prev_lockcharge = borg.lockcharge
borg.SetLockdown(1)
borg.set_anchored(TRUE)
@@ -34,7 +34,7 @@
if(!prev_lockcharge)
borg.SetLockdown(0)
borg.set_anchored(FALSE)
- borg.notransform = FALSE
+ REMOVE_TRAIT(borg, TRAIT_NO_TRANSFORM, REF(src))
borg.update_transform(0.75)
/obj/item/borg/upgrade/shrink/deactivate(mob/living/silicon/robot/borg, user = usr)
diff --git a/modular_skyrat/modules/delam_emergency_stop/code/scram.dm b/modular_skyrat/modules/delam_emergency_stop/code/scram.dm
index 1cc11c47ef9..d66f6fe2f4a 100644
--- a/modular_skyrat/modules/delam_emergency_stop/code/scram.dm
+++ b/modular_skyrat/modules/delam_emergency_stop/code/scram.dm
@@ -1,7 +1,6 @@
-#define DELAM_MACHINE_POWER_CONSUMPTION 375
#define SM_PREVENT_EXPLOSION_THRESHOLD 100
-#define SM_COOLING_MIXTURE_MOLES 64000
-#define SM_COOLING_MIXTURE_TEMP 120
+#define SM_COOLING_MIXTURE_MOLES 16000
+#define SM_COOLING_MIXTURE_TEMP 170
#define DAMAGED_SUPERMATTER_COLOR list(1,0.1,0.2,0, 0,0.9,0.1,0, 0.1,-0.05,0.85,0, 0,0,0,0.9, 0,0,0,0)
#define MISTAKES_WERE_MADE 0
#define MANUAL_INTERVENTION 0
@@ -16,11 +15,12 @@
#define SHATTER_LIGHT_RANGE 0
#define SHATTER_FLAME_RANGE 3
#define SHATTER_FLASH_RANGE 5
-#define SHATTER_MIN_TIME 13 SECONDS
-#define SHATTER_MAX_TIME 15 SECONDS
-#define POWER_CUT_MIN_DURATION 19 SECONDS
-#define POWER_CUT_MAX_DURATION 21 SECONDS
-#define AIR_INJECT_RATE 33
+#define SHATTER_MIN_TIME 17 SECONDS
+#define SHATTER_MAX_TIME 19 SECONDS
+#define EVAC_WARNING_TIMER 3 SECONDS
+#define POWER_CUT_MIN_DURATION_SECONDS 21
+#define POWER_CUT_MAX_DURATION_SECONDS 23
+#define AIR_INJECT_RATE 175
#define BUTTON_SOUND_RANGE 7
#define BUTTON_SOUND_FALLOFF_DISTANCE 7
#define MACHINE_SOUND_RANGE 15
@@ -176,11 +176,12 @@
notify_volume = 75,
)
- radio.talk_into(src, "DELAMINATION SUPPRESSION SYSTEM FIRING IN 5 SECONDS. EVACUATE THE SUPERMATTER ENGINE ROOM!", emergency_channel)
+ radio.talk_into(src, "DELAMINATION SUPPRESSION SYSTEM FIRING. EVACUATE THE SUPERMATTER ENGINE ROOM!", emergency_channel)
// fight power with power
- addtimer(CALLBACK(src, PROC_REF(put_on_a_show)), 5 SECONDS)
- INVOKE_ASYNC(SSnightshift, TYPE_PROC_REF(/datum/controller/subsystem/nightshift, suck_light_power))
+ addtimer(CALLBACK(src, PROC_REF(put_on_a_show)), EVAC_WARNING_TIMER)
+ playsound(src, 'sound/misc/bloblarm.ogg', 100, FALSE, MACHINE_RUMBLE_SOUND_RANGE, ignore_walls = TRUE, use_reverb = TRUE, falloff_distance = MACHINE_SOUND_FALLOFF_DISTANCE)
+ power_fail((EVAC_WARNING_TIMER / 10) + POWER_CUT_MAX_DURATION_SECONDS, (EVAC_WARNING_TIMER / 10) + POWER_CUT_MAX_DURATION_SECONDS)
/// Stop the delamination. Let the fireworks begin
/obj/machinery/atmospherics/components/unary/delam_scram/proc/put_on_a_show()
@@ -190,7 +191,6 @@
// Fire bell close, that nice 'are we gonna die?' rumble out far
on = TRUE
- playsound(src, 'sound/machines/hypertorus/HFR_critical_explosion.ogg', 100, FALSE, MACHINE_RUMBLE_SOUND_RANGE, ignore_walls = TRUE, use_reverb = TRUE, falloff_distance = MACHINE_SOUND_FALLOFF_DISTANCE)
alert_sound_to_playing('sound/misc/earth_rumble_distant3.ogg', override_volume = TRUE)
update_appearance()
@@ -219,9 +219,6 @@
// Let the gas work for a few seconds to cool the crystal. If it has damage beyond repair, heal it a bit
addtimer(CALLBACK(src, PROC_REF(prevent_explosion)), 9 SECONDS)
- // Restore the power that we were 'channelling' to the SM
- addtimer(CALLBACK(SSnightshift, TYPE_PROC_REF(/datum/controller/subsystem/nightshift, restore_light_power)), rand(POWER_CUT_MIN_DURATION, POWER_CUT_MAX_DURATION))
-
/// Shatter the supermatter chamber windows
/obj/structure/window/reinforced/plasma/proc/shatter_window()
visible_message(span_danger("[src] shatters in the freon fire!"))
@@ -261,24 +258,6 @@
delam_juice.temperature = SM_COOLING_MIXTURE_TEMP
airs[1] = delam_juice
-/// Dims the lights and consumes a bit of APC power, summoning that electricity to stop the delam... somehow
-/datum/controller/subsystem/nightshift/proc/suck_light_power()
- SSnightshift.can_fire = FALSE
- for(var/obj/machinery/power/apc/light_to_suck as anything in SSmachines.get_machines_by_type(/obj/machinery/power/apc))
- light_to_suck.cell.charge -= DELAM_MACHINE_POWER_CONSUMPTION
- light_to_suck.lighting = APC_CHANNEL_OFF
- light_to_suck.nightshift_lights = TRUE
- light_to_suck.update_appearance()
- light_to_suck.update()
-
-/// Restores the lighting after the delam suppression
-/datum/controller/subsystem/nightshift/proc/restore_light_power()
- SSnightshift.can_fire = TRUE
- for(var/obj/machinery/power/apc/light_to_restore as anything in SSmachines.get_machines_by_type(/obj/machinery/power/apc))
- light_to_restore.lighting = APC_CHANNEL_AUTO_ON
- light_to_restore.update_appearance()
- light_to_restore.update()
-
/// A big red button you can smash to stop the supermatter engine, oh how tempting!
/obj/machinery/button/delam_scram
name = "\improper supermatter emergency stop button"
@@ -289,6 +268,7 @@
can_alter_skin = FALSE
silicon_access_disabled = TRUE
resistance_flags = FREEZE_PROOF | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
+ use_power = NO_POWER_USE
light_color = LIGHT_COLOR_INTENSE_RED
light_power = 0.7
///one use only!
@@ -319,7 +299,6 @@
/// Proc for arming the red button, it hasn't been pushed yet
/obj/machinery/button/delam_scram/attack_hand(mob/user, list/modifiers)
. = ..()
-
if((machine_stat & BROKEN))
return
@@ -338,8 +317,8 @@
// Give them a cheeky instructions card. But only one! If you lost it, question your engineering prowess in this moment
if(button_stage == BUTTON_IDLE)
- visible_message(span_danger("A biscuit card falls out of [src]!"))
- user.put_in_hands(new /obj/item/folder/biscuit/confidential/delam(get_turf(user)))
+ visible_message(span_danger("A plastic card falls out of [src]!"))
+ user.put_in_hands(new /obj/item/paper/paperslip/corporate/fluff/delam_procedure(get_turf(user)))
button_stage = BUTTON_AWAKE
return
@@ -424,32 +403,69 @@
active = FALSE
update_appearance()
-/obj/item/folder/biscuit/confidential/delam
- name = "NT-approved delam emergency procedure"
- contained_slip = /obj/item/paper/paperslip/corporate/fluff/delam_procedure
- layer = SIGN_LAYER
-
/obj/item/paper/paperslip/corporate/fluff/delam_procedure/Initialize(mapload)
- name = "delam emergency procedure"
+ name = "NT-approved delam emergency procedure"
desc = "Now you're a REAL engineer!"
- default_raw_text = "EMERGENCY PROCEDURE: SUPERMATTER DELAMINATION
\
- So you've found yourself in a bit of a pickle with a delamination of a supermatter reactor. Don't worry, saving the day is just a few steps away!
\
- - Locate the ever-elusive red emergency stop button. It's probably hiding in plain sight, so take your time, have a laugh, and enjoy the anticipation. Remember, it's like a treasure hunt, only with the added bonus of preventing a nuclear disaster.
\
- - Once you've uncovered the button, muster all your courage and push it like there's no tomorrow. Well, actually, you're pushing it to ensure there is a tomorrow. But hey, who doesn't love a little paradoxical button-pushing?
\
- - Prepare for the impending suppression of the supermatter engine room, because things are about to get real quiet. Just make sure everyone has evacuated, or else they'll be in for a surprise. The system needs its space, and it's not known for being the friendliest neighbour.
\
- - After the delamination is successfully suppressed, take a moment to appreciate the delicate beauty of crystal-based electricity. Take a look around and fix any damage to those fragile glass components. Feel free to put on your finest overalls and channel your inner engiborg while doing so.
\
- - Keep an eye out for fires and the infamous air mix. It's always an adventure trying to strike the perfect balance between breathable air and potential suffocation. Remember, oxygen plus a spark equals fireworks – the kind you definitely don't want inside a reactor.
\
- - To avoid singeing your eyebrows off, consider enlisting the help of a synth or a trusty borg. After all, nothing says \"safety first\" like outsourcing your firefighting to non-living, non-breathing assistants.
\
- - Clear out any lightly radioactive debris (The cargo department will probably love to dispose it for you.)
\
- - Finally, revel in the satisfaction of knowing that you've single-handedly prevented a delamination. But, of course, don't forget to feel guilty because SAFETY MOTH Knows. SAFETY MOTH knows everything. It's always watching, judging, and probably taking notes for its next safety briefing. So bask in the glory of your heroism, but know that the all-knowing Moff is onto you.
\
- (Optional step, for the true daredevils out there)
\
- - When it comes time for your second attempt at starting the SM: Fold these instructions into a paper plane, give it a good toss towards the crystal, and watch it soar through the air. Because nothing says \"I'm dealing with a potentially catastrophic situation\" like engaging in some whimsical paper airplane shenanigans.
\
- Hopefully you'll never need to use this. However, good luck!"
+ return ..()
+
+/obj/item/paper/paperslip/corporate/fluff/delam_procedure/examine(mob/user)
+ . = ..()
+ ui_interact(user)
+
+/obj/item/paper/paperslip/corporate/fluff/delam_procedure/attackby(obj/item/attacking_item, mob/living/user, params)
+ if(burn_paper_product_attackby_check(attacking_item, user))
+ SStgui.close_uis(src)
+ return
+
+ // Enable picking paper up by clicking on it with the clipboard or folder
+ if(istype(attacking_item, /obj/item/clipboard) || istype(attacking_item, /obj/item/folder) || istype(attacking_item, /obj/item/paper_bin))
+ attacking_item.attackby(src, user)
+ return
+
+ ui_interact(user)
+ return ..()
+
+/obj/item/paper/paperslip/corporate/fluff/delam_procedure/ui_interact(mob/user, datum/tgui/ui)
+ ui = SStgui.try_update_ui(user, src, ui)
+ if(!ui)
+ ui = new(user, src, "DelamProcedure")
+ ui.autoupdate = FALSE
+ ui.open()
+
+/obj/structure/sign/delam_procedure
+ name = "Safety Moth - Delamination Emergency Procedure"
+ desc = "This informational sign uses Safety Mothâ„¢ to tell the viewer how to use the emergency stop button if the Supermatter Crystal is delaminating."
+ icon = 'modular_skyrat/modules/delam_emergency_stop/icons/scram.dmi'
+ icon_state = "moff-poster"
+ pixel_y = 4
+ armor_type = /datum/armor/sign_delam
+ anchored = TRUE
+
+/datum/armor/sign_delam
+ melee = 60
+ acid = 70
+ fire = 90
+
+/obj/structure/sign/delam_procedure/examine(mob/user)
+ . = ..()
+ ui_interact(user)
+
+/obj/structure/sign/delam_procedure/ui_interact(mob/user, datum/tgui/ui)
+ ui = SStgui.try_update_ui(user, src, ui)
+ if(!ui)
+ ui = new(user, src, "DelamProcedure")
+ ui.autoupdate = FALSE
+ ui.open()
+
+/obj/structure/sign/delam_procedure/ui_status(mob/user)
+ if(user.is_blind())
+ return UI_CLOSE
+
return ..()
MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/atmospherics/components/unary/delam_scram, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/delam_procedure, 32)
-#undef DELAM_MACHINE_POWER_CONSUMPTION
#undef DAMAGED_SUPERMATTER_COLOR
#undef SM_PREVENT_EXPLOSION_THRESHOLD
#undef SM_COOLING_MIXTURE_MOLES
@@ -469,8 +485,9 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/atmospherics/components/unary/delam_s
#undef SHATTER_FLASH_RANGE
#undef SHATTER_MIN_TIME
#undef SHATTER_MAX_TIME
-#undef POWER_CUT_MIN_DURATION
-#undef POWER_CUT_MAX_DURATION
+#undef EVAC_WARNING_TIMER
+#undef POWER_CUT_MIN_DURATION_SECONDS
+#undef POWER_CUT_MAX_DURATION_SECONDS
#undef AIR_INJECT_RATE
#undef BUTTON_SOUND_RANGE
#undef BUTTON_SOUND_FALLOFF_DISTANCE
diff --git a/modular_skyrat/modules/delam_emergency_stop/icons/scram.dmi b/modular_skyrat/modules/delam_emergency_stop/icons/scram.dmi
index 8828ba8410b..b654175abd4 100644
Binary files a/modular_skyrat/modules/delam_emergency_stop/icons/scram.dmi and b/modular_skyrat/modules/delam_emergency_stop/icons/scram.dmi differ
diff --git a/modular_skyrat/modules/electric_welder/code/electric_welder.dm b/modular_skyrat/modules/electric_welder/code/electric_welder.dm
index 368a37a7e19..a3426e2cf78 100644
--- a/modular_skyrat/modules/electric_welder/code/electric_welder.dm
+++ b/modular_skyrat/modules/electric_welder/code/electric_welder.dm
@@ -86,12 +86,3 @@
inhand_icon_state = "[initial(inhand_icon_state)]"
return ..()
-/datum/design/exwelder
- name = "Electrical Welding Tool"
- desc = "An experimental welding tool capable of welding using electricity."
- id = "exwelder"
- build_type = PROTOLATHE | AWAY_LATHE
- materials = list(/datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT, /datum/material/glass = SMALL_MATERIAL_AMOUNT * 5, /datum/material/plasma = HALF_SHEET_MATERIAL_AMOUNT, /datum/material/uranium = SMALL_MATERIAL_AMOUNT * 2)
- build_path = /obj/item/weldingtool/electric
- category = list(RND_CATEGORY_TOOLS + RND_SUBCATEGORY_TOOLS_ENGINEERING_ADVANCED)
- departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING
diff --git a/modular_skyrat/modules/electric_welder/readme.md b/modular_skyrat/modules/electric_welder/readme.md
new file mode 100644
index 00000000000..fb6a4c5b0b1
--- /dev/null
+++ b/modular_skyrat/modules/electric_welder/readme.md
@@ -0,0 +1,25 @@
+https://github.com/Skyrat-SS13/Skyrat-tg/pull/
+
+## \
+
+Module ID:
+
+### Description:
+
+### TG Proc/File Changes:
+
+- `code/game/objects/items/storage/belt.dm`: `proc/get_types_to_preload`
+
+### Modular Overrides:
+
+- `modular_skyrat/master_files/code/modules/cargo/exports/tools.dm`: `var/export_types`
+
+### Defines:
+
+- N/A
+
+### Included files that are not contained in this module:
+
+- N/A
+
+### Credits:
diff --git a/modular_skyrat/modules/encounters/code/nri_raiders.dm b/modular_skyrat/modules/encounters/code/nri_raiders.dm
index 1cea08893b8..ce89ac660a2 100644
--- a/modular_skyrat/modules/encounters/code/nri_raiders.dm
+++ b/modular_skyrat/modules/encounters/code/nri_raiders.dm
@@ -1,3 +1,39 @@
+/// Possible places/departments to inspect
+#define INSPECTION_LIST list( \
+ "Cargo", \
+ "Command", \
+ "Engineering", \
+ "Medical", \
+ "Science", \
+ "Service", \
+ "Security", \
+)
+
+/// List of possible decorative job titles for additional roleplay potential
+#define NRI_JOB_LIST list( \
+ "NRI Patrol Officer", \
+ "NRI Satellite-Patrol Officer", \
+ "NRI Yefreitor-Patrol Officer", \
+ "NRI Junior Patrol Officer", \
+ "NRI Government Investigator", \
+ "NRI Field Inspector", \
+ "NRI Counter-Truancy Officer", \
+)
+
+/// List of possible decorative leader job titles for additional roleplay potential
+#define NRI_LEADER_JOB_LIST list( \
+ "NRI Lieutenant Officer", \
+ "NRI Sergeant Officer", \
+ "NRI Senior Patrol Officer", \
+ "NRI Lead Investigator", \
+ "NRI Lead Inspector", \
+)
+
+/// Amount of items to "confiscate", lower amount
+#define CONFISCATE_LOWER 10
+/// Amount of items to "confiscate", higher amount
+#define CONFISCATE_HIGHER 25
+
/// To know whether or not we have an officer already
GLOBAL_VAR(first_officer)
@@ -175,9 +211,11 @@ GLOBAL_VAR(first_officer)
/obj/effect/mob_spawn/ghost_role/human/nri_raider/officer
name = "NRI Officer sleeper"
- mob_name = "Novaya Rossiyskaya Imperiya raiding party's field officer"
+ prompt_name = "a NRI Field Officer"
+ mob_name = "Novaya Rossiyskaya Imperiya police patrol's field officer"
outfit = /datum/outfit/pirate/nri/officer
- important_text = "Allowed races are humans, Akulas, IPCs. Important mention - while you are listed as the pirates gamewise, you really aren't lore-and-everything-else-wise. Roleplay accordingly. There is an important document in your pocket I'd advise you to read and keep safe."
+ flavour_text = "The station has refused to pay the fine for breaking Imperial regulations, as a consequence you are here to perform a prolonged inspection."
+ important_text = "Allowed races are humans, Akulas, IPCs. Roleplay accordingly. There is an important document in your pocket I'd advise you to read and keep safe."
/obj/effect/mob_spawn/ghost_role/human/nri_raider/officer/apply_codename(mob/living/carbon/human/spawned_human)
var/callsign = pick(GLOB.callsigns_nri)
@@ -186,6 +224,7 @@ GLOBAL_VAR(first_officer)
/obj/effect/mob_spawn/ghost_role/human/nri_raider/officer/special(mob/living/carbon/human/spawned_human)
. = ..()
+ spawned_human.mind.add_antag_datum(/datum/antagonist/cop)
spawned_human.grant_language(/datum/language/uncommon, source = LANGUAGE_SPAWNER)
spawned_human.grant_language(/datum/language/yangyu, source = LANGUAGE_SPAWNER)
spawned_human.grant_language(/datum/language/panslavic, source = LANGUAGE_SPAWNER)
@@ -193,7 +232,16 @@ GLOBAL_VAR(first_officer)
// if this is the first officer, keep a reference to them
if(!GLOB.first_officer)
GLOB.first_officer = spawned_human
+ to_chat(spawned_human, span_bold("With you being the leader of the group and having a special designation, 'Actual', it's your duty to make sure this entire operation \
+ goes smoothly. As in, doesn't result in an intergalactic political scandal, or an unneecessary shooting. It's also very likely expected for you to be performing \
+ all the necessary negotiations, so do prepare yourself for that."))
+ to_chat(spawned_human, "[span_bold("The station has overriden the response system for the reasons unknown, keep the ship intact, communicate with the station, \
+ perform an inspection to determine the legitimacy of the fine, and try to get the funds yourself, if it's legitimate. \
+ In any case, perform your predefined duties and uphold some semblance of intergalactic law and professionalism, even if just for show.")]
\
+ [span_small("Also, a small OOC clarification: none of your objectives are meant to be completable mechanically, so don't stress yourself over not greentexting or anything; \
+ If you have a better plan than 'completing' them, like an idea for a gimmick, it's better to communicate with the admins and your colleagues to possibly allow you to \
+ do something custom.")]")
apply_codename(spawned_human)
@@ -201,6 +249,16 @@ GLOBAL_VAR(first_officer)
. = ..()
apply_codename(spawned_human)
+/obj/effect/mob_spawn/ghost_role/human/nri_raider/officer/equip(mob/living/carbon/human/spawned_human)
+ . = ..()
+ var/obj/item/card/id/advanced/card = spawned_human.get_idcard()
+ if(GLOB.first_officer == spawned_human)
+ card.assignment = pick(NRI_LEADER_JOB_LIST)
+ else
+ card.assignment = pick(NRI_JOB_LIST)
+
+ card.update_label()
+
/datum/map_template/shuttle/pirate/nri_raider
prefix = "_maps/shuttles/skyrat/"
suffix = "nri_raider"
@@ -236,7 +294,7 @@ GLOBAL_VAR(first_officer)
name = "anti-projectile turret"
desc = "An automatic defense turret designed for point-defense, it's probably not that wise to try approaching it."
scan_range = 9
- shot_delay = 3
+ shot_delay = 15
faction = list(FACTION_RAIDER)
icon = 'modular_skyrat/modules/encounters/icons/turrets.dmi'
icon_state = "gun_turret"
@@ -251,15 +309,15 @@ GLOBAL_VAR(first_officer)
if(target)
setDir(get_dir(base, target))//even if you can't shoot, follow the target
shootAt(target)
- addtimer(CALLBACK(src, PROC_REF(shootAt), target), 4)
- addtimer(CALLBACK(src, PROC_REF(shootAt), target), 8)
- addtimer(CALLBACK(src, PROC_REF(shootAt), target), 12)
+ addtimer(CALLBACK(src, PROC_REF(shootAt), target), shot_delay)
+ addtimer(CALLBACK(src, PROC_REF(shootAt), target), shot_delay * 2)
+ addtimer(CALLBACK(src, PROC_REF(shootAt), target), shot_delay * 3)
return TRUE
/obj/projectile/bullet/ciws
name = "anti-projectile salvo"
icon_state = "guardian"
- damage = 30
+ damage = 15
armour_penetration = 10
/obj/docking_port/mobile/pirate/nri_raider
@@ -498,3 +556,156 @@ GLOBAL_VAR(first_officer)
priority_announce("We're intercepting all of the current and future supply deliveries until you're more cooperative with the dispatch. So, please do be.","NRI IAC HQ",ANNOUNCER_NRI_RAIDERS,"Priority")
else
priority_announce("We've received a signal to stop the blockade; you're once again free to do whatever you were doing before.","NRI IAC HQ",ANNOUNCER_NRI_RAIDERS,"Priority")
+
+/datum/antagonist/cop
+ name = "\improper NRI Police Officer"
+ //Even if their goal's almost a complete antithesis to what pirates normally do, their spawn is, well, done via pirate code.
+ job_rank = ROLE_SPACE_PIRATE
+ roundend_category = "nri cops"
+ antagpanel_category = "NRI Police"
+ show_in_antagpanel = FALSE
+ show_to_ghosts = TRUE
+ suicide_cry = "God, save the Empress!!"
+ ///Team datum for admin tracking
+ var/datum/team/cop/crew
+
+/datum/antagonist/cop/greet()
+ . = ..()
+ owner.announce_objectives()
+
+/datum/antagonist/cop/get_team()
+ return crew
+
+/datum/antagonist/cop/create_team(datum/team/cop/new_team)
+ if(!new_team)
+ for(var/datum/antagonist/cop/cop in GLOB.antagonists)
+ if(!cop.owner)
+ stack_trace("Antagonist datum without owner in GLOB.antagonists: [cop]")
+ continue
+
+ if(cop.crew)
+ crew = cop.crew
+ return
+
+ // No existing team was found, time to create one.
+ crew = new /datum/team/cop
+ crew.forge_objectives()
+ return
+
+ if(!istype(new_team))
+ stack_trace("Wrong team type passed to [type] initialization: [new_team.type].")
+
+ crew = new_team
+
+/datum/antagonist/cop/on_gain()
+ if(crew)
+ objectives |= crew.objectives
+
+ return ..()
+
+/datum/antagonist/cop/apply_innate_effects(mob/living/mob_override)
+ . = ..()
+ var/mob/living/owner_mob = mob_override || owner.current
+ var/datum/language_holder/holder = owner_mob.get_language_holder()
+ holder.grant_language(/datum/language/uncommon, TRUE, TRUE, LANGUAGE_PIRATE)
+ holder.grant_language(/datum/language/panslavic, TRUE, TRUE, LANGUAGE_PIRATE)
+ holder.grant_language(/datum/language/yangyu, TRUE, TRUE, LANGUAGE_PIRATE)
+
+/datum/antagonist/cop/remove_innate_effects(mob/living/mob_override)
+ var/mob/living/owner_mob = mob_override || owner.current
+ owner_mob.remove_language(/datum/language/uncommon, TRUE, TRUE, LANGUAGE_PIRATE)
+ owner_mob.remove_language(/datum/language/panslavic, TRUE, TRUE, LANGUAGE_PIRATE)
+ owner_mob.remove_language(/datum/language/yangyu, TRUE, TRUE, LANGUAGE_PIRATE)
+ return ..()
+
+/datum/team/cop
+ name = "\improper NRI police patrol"
+
+/datum/team/cop/proc/forge_objectives()
+ add_objective(new /datum/objective/policing)
+ add_objective(new /datum/objective/inspect_area)
+ add_objective(new /datum/objective/survey)
+ add_objective(new /datum/objective/steal_n_of_type/contraband)
+ add_objective(new /datum/objective/dock)
+ add_objective(new /datum/objective/survive)
+
+ for(var/datum/mind/member_mind in members)
+ var/datum/antagonist/cop/cop = member_mind.has_antag_datum(/datum/antagonist/cop)
+
+ if(!cop)
+ continue
+
+ cop.objectives |= objectives
+
+/datum/objective/policing
+ name = "policing"
+ explanation_text = "Contact the station to perform an inspection. Delegate responsibilities among the ship's crew. Minimise civilian casualties."
+ martyr_compatible = TRUE
+
+/datum/objective/inspect_area
+ name = "inspect area"
+ explanation_text = "Inspect certain department and make sure it's up to our specifications. Special scrutiny and pickyness is advised."
+ ///Area picked for an entirely roleplay objective.
+ var/inspection_area
+ martyr_compatible = TRUE
+
+/datum/objective/inspect_area/New(text)
+ . = ..()
+ inspection_area = pick(INSPECTION_LIST)
+
+/datum/objective/inspect_area/update_explanation_text()
+ ..()
+ if(inspection_area)
+ explanation_text = "Inspect [inspection_area] department and make sure it's up to our specifications. Special scrutiny and pickyness is advised."
+ else
+ explanation_text = "Perform a general station inspection and make sure it's up to any loose specifications you can think of."
+
+/datum/objective/survey
+ name = "survey"
+ martyr_compatible = TRUE
+ admin_grantable = TRUE
+ ///Area picked for an entirely roleplay objective.
+ var/survey_area
+
+/datum/objective/survey/New(text)
+ . = ..()
+ survey_area = pick(INSPECTION_LIST)
+
+/datum/objective/survey/update_explanation_text()
+ ..()
+ if(survey_area)
+ explanation_text = "Execute continuous crime prevention and citizen surveying procedures over [survey_area] department. Prevent crime in a given department and perform a public survey to collect people's opinions on various matters."
+ else
+ explanation_text = "Execute continuous crime prevention and citizen surveying procedures around the station. Prevent crime around the area and perform a public survey to collect people's opinions on various matters."
+
+/datum/objective/steal_n_of_type/contraband
+ name = "confiscate contraband"
+ explanation_text = "Confiscate at least cool number pieces of contraband. Drugs, illicit weaponry, armor or equipment of any sort."
+
+/datum/objective/steal_n_of_type/contraband/New()
+ . = ..()
+ amount = rand(CONFISCATE_LOWER, CONFISCATE_HIGHER)
+ explanation_text = "Confiscate at least [amount] pieces of contraband. Drugs, illicit weaponry, armor or equipment of any sort."
+ update_explanation_text()
+ return
+
+/datum/objective/steal_n_of_type/contraband/check_completion()
+ return completed //I am letting them roleplay this out, just like the other objectives.
+
+/datum/objective/dock
+ name = "dock"
+ explanation_text = "Dock to, or generally attempt to stay in the same sector the station is; to extend your on-site presence."
+ martyr_compatible = TRUE
+
+/datum/objective/dock/New()
+ . = ..()
+ explanation_text = "Dock to, or generally attempt to stay in the same sector the [station_name()] is; to extend your on-site presence."
+ update_explanation_text()
+ return
+
+
+#undef INSPECTION_LIST
+#undef NRI_JOB_LIST
+#undef NRI_LEADER_JOB_LIST
+#undef CONFISCATE_LOWER
+#undef CONFISCATE_HIGHER
diff --git a/modular_skyrat/modules/goofsec/code/sol_fed.dm b/modular_skyrat/modules/goofsec/code/sol_fed.dm
index f802d448382..840a974b2ea 100644
--- a/modular_skyrat/modules/goofsec/code/sol_fed.dm
+++ b/modular_skyrat/modules/goofsec/code/sol_fed.dm
@@ -407,7 +407,7 @@ GLOBAL_LIST_INIT(call911_do_and_do_not, list(
belt = /obj/item/storage/belt/medical/paramedic
suit_store = /obj/item/flashlight/pen/paramedic
backpack_contents = list(/obj/item/storage/box/survival = 1,
- /obj/item/roller = 1,
+ /obj/item/emergency_bed = 1,
/obj/item/storage/medkit/surgery = 1,
/obj/item/solfed_reporter/swat_caller = 1,
/obj/item/beamout_tool = 1)
diff --git a/modular_skyrat/modules/gunhud/code/gun_hud_component.dm b/modular_skyrat/modules/gunhud/code/gun_hud_component.dm
index 9f1f5ce551d..6868efa99cb 100644
--- a/modular_skyrat/modules/gunhud/code/gun_hud_component.dm
+++ b/modular_skyrat/modules/gunhud/code/gun_hud_component.dm
@@ -41,6 +41,20 @@
hud.turn_off()
hud = null
+/// Returns get_ammo() with the appropriate args passed to it - some guns like the revolver and bow are special cases
+/datum/component/ammo_hud/proc/get_accurate_ammo_count(obj/item/gun/ballistic/the_gun)
+ // fucking revolvers indeed - do not count empty or chambered rounds for the display HUD
+ if(istype(the_gun, /obj/item/gun/ballistic/revolver))
+ var/obj/item/gun/ballistic/revolver/the_revolver = the_gun
+ return the_revolver.get_ammo(countchambered = FALSE, countempties = FALSE)
+
+ // bows are also weird and shouldn't count the chambered
+ if(istype(the_gun, /obj/item/gun/ballistic/bow))
+ return the_gun.get_ammo(countchambered = FALSE)
+
+ return the_gun.get_ammo(countchambered = TRUE)
+
+
/datum/component/ammo_hud/proc/update_hud()
SIGNAL_HANDLER
if(istype(parent, /obj/item/gun/ballistic))
@@ -56,7 +70,7 @@
return
var/indicator
- var/rounds = num2text(istype(parent, /obj/item/gun/ballistic/revolver) ? pew.get_ammo(FALSE, FALSE) : pew.get_ammo(TRUE)) // fucking revolvers indeed - do not count empty or chambered rounds for the display HUD
+ var/rounds = num2text(get_accurate_ammo_count(pew))
var/oth_o
var/oth_t
var/oth_h
diff --git a/modular_skyrat/modules/gunsgalore/code/projectile.dm b/modular_skyrat/modules/gunsgalore/code/projectile.dm
deleted file mode 100644
index 9de14ea5607..00000000000
--- a/modular_skyrat/modules/gunsgalore/code/projectile.dm
+++ /dev/null
@@ -1,94 +0,0 @@
-
-/**
- * Called when the projectile hits something
- *
- * @params
- * target - thing hit
- * blocked - percentage of hit blocked
- * pierce_hit - are we piercing through or regular hitting
- */
-/obj/projectile/proc/on_hit(atom/target, blocked = FALSE, pierce_hit)
- if(fired_from)
- SEND_SIGNAL(fired_from, COMSIG_PROJECTILE_ON_HIT, firer, target, Angle)
- // i know that this is probably more with wands and gun mods in mind, but it's a bit silly that the projectile on_hit signal doesn't ping the projectile itself.
- // maybe we care what the projectile thinks! See about combining these via args some time when it's not 5AM
- var/obj/item/bodypart/hit_limb
- if(isliving(target))
- var/mob/living/L = target
- hit_limb = L.check_limb_hit(def_zone)
- SEND_SIGNAL(src, COMSIG_PROJECTILE_SELF_ON_HIT, firer, target, Angle, hit_limb)
-
- if(QDELETED(src)) // in case one of the above signals deleted the projectile for whatever reason
- return
- var/turf/target_loca = get_turf(target)
-
- var/hitx
- var/hity
- if(target == original)
- hitx = target.pixel_x + p_x - 16
- hity = target.pixel_y + p_y - 16
- else
- hitx = target.pixel_x + rand(-8, 8)
- hity = target.pixel_y + rand(-8, 8)
-
- var/impact_sound
- if(hitsound)
- impact_sound = hitsound
- else
- impact_sound = target.impact_sound
- get_sfx()
- playsound(src, get_sfx_skyrat(impact_sound), vol_by_damage(), TRUE, -1)
-
- if(damage > 0 && (damage_type == BRUTE || damage_type == BURN) && iswallturf(target_loca) && prob(75))
- var/turf/closed/wall/W = target_loca
- if(impact_effect_type && !hitscan)
- new impact_effect_type(target_loca, hitx, hity)
-
- W.add_dent(WALL_DENT_SHOT, hitx, hity)
-
- return BULLET_ACT_HIT
-
- if(!isliving(target))
- if(impact_effect_type && !hitscan)
- new impact_effect_type(target_loca, hitx, hity)
- return BULLET_ACT_HIT
-
- var/mob/living/L = target
-
- if(blocked != 100) // not completely blocked
- if(damage && L.blood_volume && damage_type == BRUTE)
- var/splatter_dir = dir
- if(starting)
- splatter_dir = get_dir(starting, target_loca)
- if(isalien(L))
- new /obj/effect/temp_visual/dir_setting/bloodsplatter/xenosplatter(target_loca, splatter_dir)
- else
- new /obj/effect/temp_visual/dir_setting/bloodsplatter(target_loca, splatter_dir)
- if(prob(33))
- L.add_splatter_floor(target_loca)
- else if(impact_effect_type && !hitscan)
- new impact_effect_type(target_loca, hitx, hity)
-
- var/organ_hit_text = ""
- var/limb_hit = hit_limb
- if(limb_hit)
- organ_hit_text = " in \the [parse_zone(limb_hit)]"
- else if(suppressed && suppressed != SUPPRESSED_VERY)
- to_chat(L, span_userdanger("You're shot by \a [src][organ_hit_text]!"))
- else
- L.visible_message(span_danger("[L] is hit by \a [src][organ_hit_text]!"), \
- span_userdanger("You're hit by \a [src][organ_hit_text]!"), null, COMBAT_MESSAGE_RANGE)
- L.on_hit(src)
-
- var/reagent_note
- if(reagents?.reagent_list)
- reagent_note = " REAGENTS:"
- for(var/datum/reagent/R in reagents.reagent_list)
- reagent_note += "[R.name] ([num2text(R.volume)])"
-
- if(ismob(firer))
- log_combat(firer, L, "shot", src, reagent_note)
- else
- L.log_message("has been shot by [firer] with [src]", LOG_ATTACK, color="orange")
-
- return BULLET_ACT_HIT
diff --git a/modular_skyrat/modules/hev_suit/code/hev_suit.dm b/modular_skyrat/modules/hev_suit/code/hev_suit.dm
index 87f7d7788ab..fd8e5462a6d 100644
--- a/modular_skyrat/modules/hev_suit/code/hev_suit.dm
+++ b/modular_skyrat/modules/hev_suit/code/hev_suit.dm
@@ -614,51 +614,32 @@
/obj/item/clothing/suit/space/hev_suit/proc/process_wound(carbon, wound, bodypart)
SIGNAL_HANDLER
- var/list/minor_fractures = list(
- /datum/wound/blunt,
- /datum/wound/blunt/moderate,
- /datum/wound/muscle,
- /datum/wound/muscle/moderate
- )
- var/list/major_fractures = list(
- /datum/wound/blunt/severe,
- /datum/wound/blunt/critical,
- /datum/wound/muscle/severe,
- /datum/wound/loss
- )
- var/list/minor_lacerations = list(
- /datum/wound/burn,
- /datum/wound/burn/moderate,
- /datum/wound/pierce,
- /datum/wound/pierce/moderate,
- /datum/wound/slash,
- /datum/wound/slash/moderate
- )
- var/list/major_lacerations = list(
- /datum/wound/burn/severe,
- /datum/wound/burn/critical,
- /datum/wound/pierce/severe,
- /datum/wound/pierce/critical,
- /datum/wound/slash/severe,
- /datum/wound/slash/critical
- )
+ if (!istype(wound, /datum/wound))
+ return
- if(wound in minor_fractures)
- send_hev_sound(minor_fracture_sound)
- else if(wound in major_fractures)
- send_hev_sound(major_fracture_sound)
- else if(wound in minor_lacerations)
- send_hev_sound(minor_lacerations_sound)
- else if(wound in major_lacerations)
- send_hev_sound(major_lacerations_sound)
- else
- var/sound2play = pick(list(
- minor_fracture_sound,
- major_fracture_sound,
- minor_lacerations_sound,
- major_lacerations_sound
- ))
- send_hev_sound(sound2play)
+ var/datum/wound/new_wound = wound
+
+ var/sound_to_play
+
+ var/datum/wound_pregen_data/pregen_data = new_wound.get_pregen_data()
+ var/wound_severity = new_wound.severity
+
+ var/is_laceration = pregen_data.wounding_types_valid(list(WOUND_SLASH, WOUND_PIERCE))
+ var/is_fracture = pregen_data.wounding_types_valid(list(WOUND_BLUNT))
+
+ if (is_laceration)
+ if (wound_severity >= WOUND_SEVERITY_SEVERE)
+ sound_to_play = major_lacerations_sound
+ else
+ sound_to_play = minor_lacerations_sound
+ else if (is_fracture)
+ if (wound_severity >= WOUND_SEVERITY_SEVERE)
+ sound_to_play = major_fracture_sound
+ else
+ sound_to_play = minor_fracture_sound
+
+ if (sound_to_play)
+ send_hev_sound(sound_to_play)
/obj/item/clothing/suit/space/hev_suit/proc/process_acid()
SIGNAL_HANDLER
diff --git a/modular_skyrat/modules/horrorform/code/horror_form.dm b/modular_skyrat/modules/horrorform/code/horror_form.dm
index d6c8e438dec..b99f4360c35 100644
--- a/modular_skyrat/modules/horrorform/code/horror_form.dm
+++ b/modular_skyrat/modules/horrorform/code/horror_form.dm
@@ -14,7 +14,7 @@
req_stat = UNCONSCIOUS
/datum/action/changeling/horror_form/sting_action(mob/living/carbon/human/user)
- if(!user || user.notransform)
+ if(!user || HAS_TRAIT(user, TRAIT_NO_TRANSFORM))
return 0
user.visible_message(span_warning("[user] writhes and contorts, their body expanding to inhuman proportions!"), \
span_danger("We begin our transformation to our true form!"))
diff --git a/modular_skyrat/modules/horrorform/code/true_changeling.dm b/modular_skyrat/modules/horrorform/code/true_changeling.dm
index bc51c730b7d..4765f9f9df6 100644
--- a/modular_skyrat/modules/horrorform/code/true_changeling.dm
+++ b/modular_skyrat/modules/horrorform/code/true_changeling.dm
@@ -32,7 +32,6 @@
attack_verb_continuous = "rips into"
attack_verb_simple = "rip into"
attack_sound = 'sound/effects/blobattack.ogg'
- next_move_modifier = 0.5 //Faster attacks
butcher_results = list(/obj/item/food/meat/slab/human = 15) //It's a pretty big dude. Actually killing one is a feat.
gold_core_spawnable = FALSE //Should stay exclusive to changelings tbh, otherwise makes it much less significant to sight one
var/datum/action/innate/turn_to_human
diff --git a/modular_skyrat/modules/hydra/code/neutral.dm b/modular_skyrat/modules/hydra/code/neutral.dm
index e87de1a4bf2..aea55dcc147 100644
--- a/modular_skyrat/modules/hydra/code/neutral.dm
+++ b/modular_skyrat/modules/hydra/code/neutral.dm
@@ -16,8 +16,6 @@
spell.owner = hydra
resetspell.Grant(hydra)
resetspell.owner = hydra
- hydra.name_archive = hydra.real_name
-
/datum/action/innate/hydra
name = "Switch head"
@@ -33,12 +31,16 @@
/datum/action/innate/hydrareset/Activate()
var/mob/living/carbon/human/hydra = owner
+ if(!hydra.name_archive) // sets the archived 'real' name if not set.
+ hydra.name_archive = hydra.real_name
hydra.real_name = hydra.name_archive
hydra.visible_message(span_notice("[hydra.name] pushes all three heads forwards; they seem to be talking as a collective."), \
span_notice("You are now talking as [hydra.name_archive]!"), ignored_mobs=owner)
/datum/action/innate/hydra/Activate() //Oops, all hydra!
var/mob/living/carbon/human/hydra = owner
+ if(!hydra.name_archive) // sets the archived 'real' name if not set.
+ hydra.name_archive = hydra.real_name
var/list/names = splittext(hydra.name_archive,"-")
var/selhead = input("Who would you like to speak as?","Heads:") in names
hydra.real_name = selhead
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 7f4e2bfde67..bd49fc1de17 100644
--- a/modular_skyrat/modules/ices_events/code/ICES_event_config.dm
+++ b/modular_skyrat/modules/ices_events/code/ICES_event_config.dm
@@ -576,7 +576,7 @@
* Supermatter Surge
*/
/datum/round_event_control/supermatter_surge
- max_occurrences = 2
+ max_occurrences = 1
weight = MED_EVENT_FREQ
/**
diff --git a/modular_skyrat/modules/ices_events/code/events/ev_roleplay_check.dm b/modular_skyrat/modules/ices_events/code/events/ev_roleplay_check.dm
new file mode 100644
index 00000000000..d55fd75aeb3
--- /dev/null
+++ b/modular_skyrat/modules/ices_events/code/events/ev_roleplay_check.dm
@@ -0,0 +1,13 @@
+/**
+ * Checks if a player meets certain conditions to exclude them from event selection.
+ */
+/proc/engaged_role_play_check(mob/living/carbon/human/player, station = TRUE, dorms = TRUE)
+ var/turf/player_turf = get_turf(player)
+ var/area/player_area = get_area(player_turf)
+ if(!is_station_level(player_turf.z) && station)
+ return TRUE
+
+ if(istype(player_area, /area/station/commons/dorms) && dorms)
+ return TRUE
+
+ return FALSE
diff --git a/modular_skyrat/modules/implants/code/augments_arms.dm b/modular_skyrat/modules/implants/code/augments_arms.dm
index 3de8c3b93ff..d59c4353732 100644
--- a/modular_skyrat/modules/implants/code/augments_arms.dm
+++ b/modular_skyrat/modules/implants/code/augments_arms.dm
@@ -1,3 +1,19 @@
+#define KNIFE_HITSOUND 'sound/weapons/bladeslice.ogg'
+#define KNIFE_USESOUND 'sound/weapons/bladeslice.ogg'
+#define KNIFE_ATTACK_VERB_CONTINUOUS list("slashes", "tears", "slices", "tears", "lacerates", "rips", "dices", "cuts", "rends")
+#define KNIFE_ATTACK_VERB_SIMPLE list("slash", "tear", "slice", "tear", "lacerate", "rip", "dice", "cut", "rend")
+#define KNIFE_SHARPNESS SHARP_EDGED
+#define KNIFE_BARE_WOUND_BONUS 15
+#define CUTTER_HITSOUND 'sound/items/wirecutter.ogg'
+#define CUTTER_USESOUND 'sound/items/wirecutter.ogg'
+#define CUTTER_ATTACK_VERB_CONTINUOUS list("bashes", "batters", "bludgeons", "thrashes", "whacks")
+#define CUTTER_ATTACK_VERB_SIMPLE list("bash", "batter", "bludgeon", "thrash", "whack")
+#define CUTTER_FORCE 6
+#define CUTTER_WOUND_BONUS 0
+#define ENHANCED_KNIFE_FORCE 15
+#define ENHANCED_KNIFE_WOUND_BONUS 15
+#define ENHANCED_KNIFE_ARMOR_PENETRATION 10
+
/obj/item/melee/implantarmblade
name = "implanted arm blade"
desc = "A long, sharp, mantis-like blade implanted into someones arm. Cleaves through flesh like its particularly strong butter."
@@ -36,6 +52,98 @@
items_list += WEAKREF(new /obj/item/melee/implantarmblade/energy(src))
return TRUE
+/obj/item/knife/razor_claws
+ name = "implanted razor claws"
+ desc = "A set of sharp, retractable claws built into the fingertips, five double-edged blades sure to turn people into mincemeat. Capable of shifting into 'Precision' mode to act similar to wirecutters."
+ icon = 'modular_skyrat/modules/implants/icons/razorclaws.dmi'
+ righthand_file = 'modular_skyrat/modules/implants/icons/razorclaws_righthand.dmi'
+ lefthand_file = 'modular_skyrat/modules/implants/icons/razorclaws_lefthand.dmi'
+ icon_state = "wolverine"
+ inhand_icon_state = "wolverine"
+ var/knife_force = 10
+ w_class = WEIGHT_CLASS_BULKY
+ var/knife_wound_bonus = 5
+ var/cutter_force = CUTTER_FORCE
+ var/cutter_wound_bonus = CUTTER_WOUND_BONUS
+ var/cutter_bare_wound_bonus = CUTTER_WOUND_BONUS
+ tool_behaviour = TOOL_KNIFE
+ toolspeed = 1
+ item_flags = NEEDS_PERMIT //Beepers gets angry if you get caught with this.
+
+/obj/item/knife/razor_claws/attack_self(mob/user)
+ playsound(get_turf(user), 'sound/items/change_drill.ogg', 50, TRUE)
+ if(tool_behaviour != TOOL_WIRECUTTER)
+ tool_behaviour = TOOL_WIRECUTTER
+ to_chat(user, span_notice("You shift [src] into Precision mode, for wirecutting."))
+ icon_state = "precision_wolverine"
+ inhand_icon_state = "precision_wolverine"
+ force = cutter_force
+ wound_bonus = cutter_wound_bonus
+ bare_wound_bonus = cutter_bare_wound_bonus
+ sharpness = NONE
+ hitsound = CUTTER_HITSOUND
+ usesound = CUTTER_USESOUND
+ attack_verb_continuous = CUTTER_ATTACK_VERB_CONTINUOUS
+ attack_verb_simple = CUTTER_ATTACK_VERB_SIMPLE
+ else
+ tool_behaviour = TOOL_KNIFE
+ to_chat(user, span_notice("You shift [src] into Killing mode, for slicing."))
+ icon_state = "wolverine"
+ inhand_icon_state = "wolverine"
+ force = knife_force
+ sharpness = KNIFE_SHARPNESS
+ wound_bonus = knife_wound_bonus
+ bare_wound_bonus = KNIFE_BARE_WOUND_BONUS
+ hitsound = KNIFE_HITSOUND
+ usesound = KNIFE_USESOUND
+ attack_verb_continuous = KNIFE_ATTACK_VERB_CONTINUOUS
+ attack_verb_simple = KNIFE_ATTACK_VERB_SIMPLE
+
+/obj/item/knife/razor_claws/attackby(obj/item/stone, mob/user, param)
+ if(!istype(stone, /obj/item/scratching_stone))
+ return ..()
+
+ knife_force = ENHANCED_KNIFE_FORCE
+ knife_wound_bonus = ENHANCED_KNIFE_WOUND_BONUS
+ armour_penetration = ENHANCED_KNIFE_ARMOR_PENETRATION //Let's give them some AP for the trouble.
+
+ if(tool_behaviour == TOOL_KNIFE)
+ force = knife_force
+ wound_bonus = knife_wound_bonus
+
+ name = "enhanced razor claws"
+ desc += span_warning("\n\nThese have undergone a special honing process; they'll kill people even faster than they used to.")
+ user.visible_message(span_warning("[user] sharpens [src], [stone] disintegrating!"), span_warning("You sharpen [src], making it much more deadly than before, but [stone] disintegrates under the stress."))
+ playsound(src, 'sound/items/unsheath.ogg', 25, TRUE)
+ qdel(stone)
+ return ..()
+
+/obj/item/organ/internal/cyberimp/arm/razor_claws
+ name = "razor claws implant"
+ desc = "A set of hidden, retractable blades built into the fingertips; cyborg mercenary approved."
+ items_to_create = list(/obj/item/knife/razor_claws)
+ actions_types = list(/datum/action/item_action/organ_action/toggle/razor_claws)
+ icon = 'modular_skyrat/modules/implants/icons/razorclaws.dmi'
+ icon_state = "wolverine"
+ extend_sound = 'sound/items/unsheath.ogg'
+ retract_sound = 'sound/items/sheath.ogg'
+
+/// bespoke subtypes for augs menu since it's a bit wonky
+/obj/item/organ/internal/cyberimp/arm/razor_claws/right_arm
+ zone = BODY_ZONE_R_ARM
+ slot = ORGAN_SLOT_RIGHT_ARM_AUG
+
+/obj/item/organ/internal/cyberimp/arm/razor_claws/left_arm
+ zone = BODY_ZONE_L_ARM
+ slot = ORGAN_SLOT_LEFT_ARM_AUG
+
+
+/datum/action/item_action/organ_action/toggle/razor_claws
+ name = "Extend Claws"
+ desc = "You can also activate the claws in your hand to change their mode."
+ button_icon = 'modular_skyrat/master_files/icons/hud/actions.dmi'
+ button_icon_state = "wolverine"
+
/obj/item/organ/internal/cyberimp/arm/hacker
name = "hacking arm implant"
desc = "An small arm implant containing an advanced screwdriver, wirecutters, and multitool designed for engineers and on-the-field machine modification. Actually legal, despite what the name may make you think."
@@ -110,3 +218,19 @@
items_list += WEAKREF(new /obj/item/lighter(src)) //Now you can choose between bad and worse!
obj_flags |= EMAGGED
return TRUE
+
+#undef KNIFE_HITSOUND
+#undef KNIFE_USESOUND
+#undef KNIFE_ATTACK_VERB_CONTINUOUS
+#undef KNIFE_ATTACK_VERB_SIMPLE
+#undef KNIFE_SHARPNESS
+#undef KNIFE_BARE_WOUND_BONUS
+#undef CUTTER_HITSOUND
+#undef CUTTER_USESOUND
+#undef CUTTER_ATTACK_VERB_CONTINUOUS
+#undef CUTTER_ATTACK_VERB_SIMPLE
+#undef CUTTER_FORCE
+#undef CUTTER_WOUND_BONUS
+#undef ENHANCED_KNIFE_FORCE
+#undef ENHANCED_KNIFE_WOUND_BONUS
+#undef ENHANCED_KNIFE_ARMOR_PENETRATION
diff --git a/modular_skyrat/modules/implants/code/medical_designs.dm b/modular_skyrat/modules/implants/code/medical_designs.dm
index 6066441688d..fe795717df3 100644
--- a/modular_skyrat/modules/implants/code/medical_designs.dm
+++ b/modular_skyrat/modules/implants/code/medical_designs.dm
@@ -11,6 +11,23 @@
)
departmental_flags = DEPARTMENT_BITFLAG_SECURITY
+/datum/design/cyberimp_claws
+ name = "Razor Claws Implant"
+ desc = "Long, sharp, double-edged razors installed within the fingers, functional for cutting. All kinds of cutting."
+ id = "ci-razor"
+ build_type = PROTOLATHE | AWAY_LATHE | MECHFAB
+ materials = list (
+ /datum/material/iron = SHEET_MATERIAL_AMOUNT,
+ /datum/material/glass = HALF_SHEET_MATERIAL_AMOUNT,
+ /datum/material/silver = HALF_SHEET_MATERIAL_AMOUNT
+ )
+ construction_time = 20 SECONDS
+ build_path = /obj/item/organ/internal/cyberimp/arm/razor_claws
+ category = list(
+ RND_CATEGORY_CYBERNETICS + RND_SUBCATEGORY_CYBERNETICS_IMPLANTS_TOOLS
+ )
+ departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SECURITY
+
/datum/design/cyberimp_hacker
name = "Hacking Hand Implant"
desc = "An advanced hacking and machine modification toolkit fitted into an arm implant, designed to be installed on a subject's arm."
diff --git a/modular_skyrat/modules/implants/code/medical_nodes.dm b/modular_skyrat/modules/implants/code/medical_nodes.dm
index 1b6258ea41d..4eb34b69568 100644
--- a/modular_skyrat/modules/implants/code/medical_nodes.dm
+++ b/modular_skyrat/modules/implants/code/medical_nodes.dm
@@ -1,5 +1,18 @@
/datum/techweb_node/cyber_implants
- design_ids = list("ci-nutriment", "ci-scanner", "ci-breather", "ci-gloweyes", "ci-welding", "ci-medhud", "ci-sechud", "ci-diaghud", "ci-botany", "ci-janitor", "ci-lighter")
+ design_ids = list(
+ "ci-nutriment",
+ "ci-scanner",
+ "ci-breather",
+ "ci-gloweyes",
+ "ci-welding",
+ "ci-medhud",
+ "ci-sechud",
+ "ci-diaghud",
+ "ci-botany",
+ "ci-janitor",
+ "ci-lighter",
+ "ci-razor",
+ )
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
/datum/techweb_node/adv_cyber_implants
diff --git a/modular_skyrat/modules/implants/icons/razorclaws.dmi b/modular_skyrat/modules/implants/icons/razorclaws.dmi
new file mode 100644
index 00000000000..af0a7bf194a
Binary files /dev/null and b/modular_skyrat/modules/implants/icons/razorclaws.dmi differ
diff --git a/modular_skyrat/modules/implants/icons/razorclaws_lefthand.dmi b/modular_skyrat/modules/implants/icons/razorclaws_lefthand.dmi
new file mode 100644
index 00000000000..9ef1ab7530b
Binary files /dev/null and b/modular_skyrat/modules/implants/icons/razorclaws_lefthand.dmi differ
diff --git a/modular_skyrat/modules/implants/icons/razorclaws_righthand.dmi b/modular_skyrat/modules/implants/icons/razorclaws_righthand.dmi
new file mode 100644
index 00000000000..9098ad1ceec
Binary files /dev/null and b/modular_skyrat/modules/implants/icons/razorclaws_righthand.dmi differ
diff --git a/modular_skyrat/modules/imported_vendors/code/vendor_food.dm b/modular_skyrat/modules/imported_vendors/code/vendor_food.dm
index 011b494936e..2fe1e97965d 100644
--- a/modular_skyrat/modules/imported_vendors/code/vendor_food.dm
+++ b/modular_skyrat/modules/imported_vendors/code/vendor_food.dm
@@ -27,9 +27,9 @@
/obj/item/trash/empty_side_pack/tizira
icon_state = "foodpack_tizira_trash"
-
+
/* MEALS */
-
+
/*
* NT Meals
*/
@@ -75,7 +75,7 @@
food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/capsaicin = 10)
tastes = list("bread" = 2, "chicken?" = 2, "overwhelming spice" = 2, "laziness" = 1)
foodtypes = MEAT | GRAIN | DAIRY
-
+
/*
* Yangyu Meals
*/
@@ -125,7 +125,7 @@
icon_state = "foodtray_fuel_jacks_meal"
tastes = list("potato" = 2, "cabbage" = 2, "cheese?" = 2, "laziness" = 1)
foodtypes = DAIRY | VEGETABLES
-
+
/*
* Tiziran Meals
*/
@@ -157,7 +157,7 @@
name = "random side spawner"
desc = "I hope I get one that actually matches my meal."
icon_state = "loot"
-
+
/*
* NT Sides
*/
@@ -195,7 +195,7 @@
desc = "A small stack of tough flatbread, and a small spread of cheese for each."
tastes = list("tough bread" = 2, "cheese" = 2)
foodtypes = GRAIN | DAIRY
-
+
/*
* Yangyu Sides
*/
@@ -234,7 +234,7 @@
trash_type = /obj/item/trash/empty_side_pack/yangyu
tastes = list("vinegar" = 4)
foodtypes = VEGETABLES
-
+
/*
* Mothic Sides
*/
@@ -273,7 +273,7 @@
trash_type = /obj/item/trash/empty_side_pack/moth
tastes = list("seeds" = 2, "char" = 2)
foodtypes = NUTS
-
+
/*
* Tiziran Sides
*/
diff --git a/modular_skyrat/modules/interaction_menu/code/interaction_component.dm b/modular_skyrat/modules/interaction_menu/code/interaction_component.dm
index fe3b6fea50d..b6122decd07 100644
--- a/modular_skyrat/modules/interaction_menu/code/interaction_component.dm
+++ b/modular_skyrat/modules/interaction_menu/code/interaction_component.dm
@@ -77,6 +77,7 @@
var/list/data = list()
var/list/descriptions = list()
var/list/categories = list()
+ var/list/display_categories = list()
var/list/colors = list()
for(var/datum/interaction/interaction in interactions)
if(!can_interact(interaction, user))
@@ -85,13 +86,15 @@
categories[interaction.category] = list(interaction.name)
else
categories[interaction.category] += interaction.name
+ var/list/sorted_category = sort_list(categories[interaction.category])
+ categories[interaction.category] = sorted_category
descriptions[interaction.name] = interaction.description
colors[interaction.name] = interaction.color
- data["categories"] = list()
data["descriptions"] = descriptions
data["colors"] = colors
for(var/category in categories)
- data["categories"] += category
+ display_categories += category
+ data["categories"] = sort_list(display_categories)
data["ref_user"] = REF(user)
data["ref_self"] = REF(self)
data["self"] = self.name
diff --git a/modular_skyrat/modules/layer_shift/code/mob_movement.dm b/modular_skyrat/modules/layer_shift/code/mob_movement.dm
index 5725a349e52..2bc2ed4cdee 100644
--- a/modular_skyrat/modules/layer_shift/code/mob_movement.dm
+++ b/modular_skyrat/modules/layer_shift/code/mob_movement.dm
@@ -1,7 +1,10 @@
-#define MOB_LAYER_SHIFT_INCREMENT 0.01
-#define MOB_LAYER_SHIFT_MIN 3.95
-//#define MOB_LAYER 4 // This is a byond standard define
-#define MOB_LAYER_SHIFT_MAX 4.05
+#define MOB_LAYER_SHIFT_INCREMENT 1
+/// The amount by which layers are multiplied before being modified.
+/// Helps avoiding floating point errors.
+#define MOB_LAYER_MULTIPLIER 100
+#define MOB_LAYER_SHIFT_MIN 3.95
+//#define MOB_LAYER 4 // This is a byond standard define
+#define MOB_LAYER_SHIFT_MAX 4.05
/mob/living/verb/layershift_up()
set name = "Shift Layer Upwards"
@@ -15,8 +18,8 @@
to_chat(src, span_warning("You cannot increase your layer priority any further."))
return
- layer += MOB_LAYER_SHIFT_INCREMENT
- var/layer_priority = (layer - MOB_LAYER) * 100 // Just for text feedback
+ layer = min(((layer * MOB_LAYER_MULTIPLIER) + MOB_LAYER_SHIFT_INCREMENT) / MOB_LAYER_MULTIPLIER, MOB_LAYER_SHIFT_MAX)
+ var/layer_priority = round(layer * MOB_LAYER_MULTIPLIER - MOB_LAYER * MOB_LAYER_MULTIPLIER, MOB_LAYER_SHIFT_INCREMENT) // Just for text feedback
to_chat(src, span_notice("Your layer priority is now [layer_priority]."))
/mob/living/verb/layershift_down()
@@ -31,6 +34,6 @@
to_chat(src, span_warning("You cannot decrease your layer priority any further."))
return
- layer -= MOB_LAYER_SHIFT_INCREMENT
- var/layer_priority = (layer - MOB_LAYER) * 100 // Just for text feedback
+ layer = max(((layer * MOB_LAYER_MULTIPLIER) - MOB_LAYER_SHIFT_INCREMENT) / MOB_LAYER_MULTIPLIER, MOB_LAYER_SHIFT_MIN)
+ var/layer_priority = round(layer * MOB_LAYER_MULTIPLIER - MOB_LAYER * MOB_LAYER_MULTIPLIER, MOB_LAYER_SHIFT_INCREMENT) // Just for text feedback
to_chat(src, span_notice("Your layer priority is now [layer_priority]."))
diff --git a/modular_skyrat/modules/liquids/code/ocean_turfs.dm b/modular_skyrat/modules/liquids/code/ocean_turfs.dm
index dc25e69d7dd..35066f09857 100644
--- a/modular_skyrat/modules/liquids/code/ocean_turfs.dm
+++ b/modular_skyrat/modules/liquids/code/ocean_turfs.dm
@@ -9,7 +9,7 @@
for(var/obj/structure/flora/plant in contents)
qdel(plant)
- var/turf/T = below()
+ var/turf/T = GET_TURF_BELOW(src)
if(T)
if(T.turf_flags & NO_RUINS)
ChangeTurf(replacement_turf, null, CHANGETURF_IGNORE_AIR)
diff --git a/modular_skyrat/modules/loadouts/loadout_items/donator/personal/donator_personal.dm b/modular_skyrat/modules/loadouts/loadout_items/donator/personal/donator_personal.dm
index d369dcbcceb..b2680e38526 100644
--- a/modular_skyrat/modules/loadouts/loadout_items/donator/personal/donator_personal.dm
+++ b/modular_skyrat/modules/loadouts/loadout_items/donator/personal/donator_personal.dm
@@ -714,3 +714,13 @@
name = "Hardlight Wheelchair Projector"
item_path = /obj/item/holosign_creator/hardlight_wheelchair
// ckeywhitelist = list("sqnztb")
+
+/datum/loadout_item/under/jumpsuit/noble_gambeson
+ name = "Noble Gambeson"
+ item_path = /obj/item/clothing/under/rank/civilian/chaplain/divine_archer/noble
+// ckeywhitelist = list("grasshand")
+
+/datum/loadout_item/shoes/noble_boots
+ name = "Noble Boots"
+ item_path = /obj/item/clothing/shoes/jackboots/noble
+// ckeywhitelist = list("grasshand")
diff --git a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_neck.dm b/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_neck.dm
index 971d15be993..5fe25c3991d 100644
--- a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_neck.dm
+++ b/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_neck.dm
@@ -265,6 +265,10 @@ GLOBAL_LIST_INIT(loadout_necks, generate_loadout_items(/datum/loadout_item/neck)
name = "Maid Neck Cover"
item_path = /obj/item/clothing/neck/maid
+/datum/loadout_item/neck/link_scryer
+ name = "MODlink Scryer"
+ item_path = /obj/item/clothing/neck/link_scryer
+
/*
* DONATOR
*/
diff --git a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_suit.dm b/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_suit.dm
index 2dbf870ad1d..0569e90d9a0 100644
--- a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_suit.dm
+++ b/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_suit.dm
@@ -295,9 +295,41 @@ GLOBAL_LIST_INIT(loadout_exosuits, generate_loadout_items(/datum/loadout_item/su
name = "Red cloak"
item_path = /obj/item/clothing/suit/hooded/cloak/david
+/datum/loadout_item/suit/wellwornshirt
+ name = "Well-worn Shirt"
+ item_path = /obj/item/clothing/suit/costume/wellworn_shirt
+
+/datum/loadout_item/suit/wellworn_graphicshirt
+ name = "Well-worn Graphic Shirt"
+ item_path = /obj/item/clothing/suit/costume/wellworn_shirt/graphic
+
/datum/loadout_item/suit/ianshirt
- name = "Ian Shirt"
- item_path = /obj/item/clothing/suit/costume/ianshirt
+ name = "Well-worn Ian Shirt"
+ item_path = /obj/item/clothing/suit/costume/wellworn_shirt/graphic/ian
+
+/datum/loadout_item/suit/wornoutshirt
+ name = "Worn-out Shirt"
+ item_path = /obj/item/clothing/suit/costume/wellworn_shirt/wornout
+
+/datum/loadout_item/suit/wornout_graphicshirt
+ name = "Worn-out graphic Shirt"
+ item_path = /obj/item/clothing/suit/costume/wellworn_shirt/wornout/graphic
+
+/datum/loadout_item/suit/wornout_ianshirt
+ name = "Worn-out Ian Shirt"
+ item_path = /obj/item/clothing/suit/costume/wellworn_shirt/wornout/graphic/ian
+
+/datum/loadout_item/suit/messyshirt
+ name = "Messy Shirt"
+ item_path = /obj/item/clothing/suit/costume/wellworn_shirt/messy
+
+/datum/loadout_item/suit/messy_graphicshirt
+ name = "Messy Graphic Shirt"
+ item_path = /obj/item/clothing/suit/costume/wellworn_shirt/messy/graphic
+
+/datum/loadout_item/suit/messy_ianshirt
+ name = "Messy Ian Shirt"
+ item_path = /obj/item/clothing/suit/costume/wellworn_shirt/messy/graphic/ian
/datum/loadout_item/suit/wornshirt
name = "Worn Shirt"
@@ -608,11 +640,6 @@ GLOBAL_LIST_INIT(loadout_exosuits, generate_loadout_items(/datum/loadout_item/su
item_path = /obj/item/clothing/suit/toggle/jacket/supply
restricted_roles = list(JOB_QUARTERMASTER, JOB_CARGO_TECHNICIAN, JOB_SHAFT_MINER, JOB_CUSTOMS_AGENT)
-/datum/loadout_item/suit/supply_gorka_jacket
- name = "Supply Gorka Jacket"
- item_path = /obj/item/clothing/suit/gorka/supply
- restricted_roles = list(JOB_QUARTERMASTER, JOB_CARGO_TECHNICIAN, JOB_SHAFT_MINER, JOB_CUSTOMS_AGENT)
-
/datum/loadout_item/suit/cargo_gorka_jacket
name = "Cargo Gorka Jacket"
item_path = /obj/item/clothing/suit/toggle/cargo_tech
diff --git a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_toys.dm b/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_toys.dm
index 03dc535ea33..be2ab118d57 100644
--- a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_toys.dm
+++ b/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_toys.dm
@@ -265,6 +265,10 @@ GLOBAL_LIST_INIT(loadout_toys, generate_loadout_items(/datum/loadout_item/toys))
name = "Courier Synth Plushie"
item_path = /obj/item/toy/plush/skyrat/courier_synth
+/datum/loadout_item/toys/plush_janiborg
+ name = "Friendly Janiborg Plush"
+ item_path = /obj/item/toy/plush/skyrat/plush_janiborg
+
/*
* CARDS
*/
diff --git a/modular_skyrat/modules/loadouts/loadout_items/under/loadout_datum_under.dm b/modular_skyrat/modules/loadouts/loadout_items/under/loadout_datum_under.dm
index 0ae7470aa69..f549ca8a1f9 100644
--- a/modular_skyrat/modules/loadouts/loadout_items/under/loadout_datum_under.dm
+++ b/modular_skyrat/modules/loadouts/loadout_items/under/loadout_datum_under.dm
@@ -174,6 +174,28 @@ GLOBAL_LIST_INIT(loadout_miscunders, generate_loadout_items(/datum/loadout_item/
item_path = /obj/item/clothing/under/rank/rnd/research_director/skyrat/jumpsuit/skirt
restricted_roles = list(JOB_RESEARCH_DIRECTOR)
+/datum/loadout_item/under/jumpsuit/cargo
+ name = "Cargo Technician's Jumpsuit"
+ item_path = /obj/item/clothing/under/rank/cargo/tech
+ restricted_roles = list(JOB_CARGO_TECHNICIAN, JOB_QUARTERMASTER, JOB_CUSTOMS_AGENT)
+
+/datum/loadout_item/under/jumpsuit/cargo/shorts
+ name = "Cargo Technician's Shorts"
+ item_path = /obj/item/clothing/under/rank/cargo/tech/alt
+
+/datum/loadout_item/under/jumpsuit/cargo/skirt
+ name = "Cargo Technician's Skirt"
+ item_path = /obj/item/clothing/under/rank/cargo/tech/skirt
+
+/datum/loadout_item/under/jumpsuit/cargo/skirt/alt
+ name = "Cargo Technician's Shortskirt"
+ item_path = /obj/item/clothing/under/rank/cargo/tech/skirt/alt
+
+/datum/loadout_item/under/jumpsuit/cargo/qm
+ name = "Quartermaster's Uniform"
+ item_path = /obj/item/clothing/under/rank/cargo/qm
+ restricted_roles = list(JOB_QUARTERMASTER)
+
/datum/loadout_item/under/jumpsuit/utility
name = "Utility Uniform"
item_path = /obj/item/clothing/under/misc/skyrat/utility
@@ -279,6 +301,10 @@ GLOBAL_LIST_INIT(loadout_miscunders, generate_loadout_items(/datum/loadout_item/
name = "Recolorable Ripped Jean Shorts"
item_path = /obj/item/clothing/under/shorts/skyrat/shorts_ripped
+/datum/loadout_item/under/miscellaneous/shortershorts
+ name = "Recolorable Shorter Shorts"
+ item_path = /obj/item/clothing/under/shorts/skyrat/shortershorts
+
/datum/loadout_item/under/miscellaneous/shorts
name = "Recolorable Shorts"
item_path = /obj/item/clothing/under/shorts
@@ -650,10 +676,6 @@ GLOBAL_LIST_INIT(loadout_miscunders, generate_loadout_items(/datum/loadout_item/
name = "Black Suitskirt"
item_path = /obj/item/clothing/under/suit/black/skirt
-/datum/loadout_item/under/formal/black_twopiece
- name = "Black Two-Piece Suit"
- item_path = /obj/item/clothing/under/suit/blacktwopiece
-
/datum/loadout_item/under/formal/black_lawyer_suit
name = "Black Lawyer Suit"
item_path = /obj/item/clothing/under/rank/civilian/lawyer/black
diff --git a/modular_skyrat/modules/mapping/code/areas/station.dm b/modular_skyrat/modules/mapping/code/areas/station.dm
index 8a310ece882..8c24b2dcbec 100644
--- a/modular_skyrat/modules/mapping/code/areas/station.dm
+++ b/modular_skyrat/modules/mapping/code/areas/station.dm
@@ -26,13 +26,13 @@
icon_state = "secure_bunker"
// NT Consultant area
-/area/command/heads_quarters/captain/private/nt_rep
+/area/station/command/heads_quarters/nt_rep
name = "Nanotrasen Consultant's Office"
icon = 'modular_skyrat/modules/mapping/icons/areas/areas_station.dmi'
icon_state = "nt_rep"
-// BlueShield area
-/area/blueshield
+// Blueshield area
+/area/station/command/heads_quarters/blueshield
name = "Blueshield's Office"
icon = 'modular_skyrat/modules/mapping/icons/areas/areas_station.dmi'
icon_state = "blueshield"
diff --git a/modular_skyrat/modules/mapping/code/interdyne_mining.dm b/modular_skyrat/modules/mapping/code/interdyne_mining.dm
index dee18909635..860d17d104b 100644
--- a/modular_skyrat/modules/mapping/code/interdyne_mining.dm
+++ b/modular_skyrat/modules/mapping/code/interdyne_mining.dm
@@ -1,6 +1,6 @@
/obj/item/circuitboard/computer/order_console/mining/interdyne
name = "Interdyne Mining Equipment Vendor Console"
- build_path = /obj/machinery/computer/order_console/mining/golem
+ build_path = /obj/machinery/computer/order_console/mining/interdyne
// Interdyne/DS-2 mining equipment vendor that doesn't need a cargo shuttle to work
@@ -20,14 +20,14 @@
/obj/machinery/computer/order_console/mining/interdyne/redeem_voucher(obj/item/mining_voucher/voucher, mob/redeemer)
. = ..()
- for(var/mob/living/simple_animal/hostile/mining_drone/drone in drop_location())
+ for(var/mob/living/basic/mining_drone/drone in drop_location())
// There could already be an interdyne drone there
- if(!istype(drone, /mob/living/simple_animal/hostile/mining_drone/interdyne))
+ if(!istype(drone, /mob/living/basic/mining_drone/interdyne))
qdel(drone)
- new /mob/living/simple_animal/hostile/mining_drone/interdyne(drop_location())
+ new /mob/living/basic/mining_drone/interdyne(drop_location())
// Interdyne minebot
-/mob/living/simple_animal/hostile/mining_drone/interdyne
+/mob/living/basic/mining_drone/interdyne
name = "\improper Interdyne minebot"
faction = list(FACTION_NEUTRAL, ROLE_SYNDICATE)
diff --git a/modular_skyrat/modules/mapping/code/lavaland_ruin_code.dm b/modular_skyrat/modules/mapping/code/lavaland_ruin_code.dm
index b7e2e392e24..773afe71422 100644
--- a/modular_skyrat/modules/mapping/code/lavaland_ruin_code.dm
+++ b/modular_skyrat/modules/mapping/code/lavaland_ruin_code.dm
@@ -23,6 +23,7 @@
/datum/outfit/lavaland_syndicate
name = "Interdyne Bioweapon Scientist"
uniform = /obj/item/clothing/under/rank/rnd/scientist/skyrat/utility/syndicate
+ suit = /obj/item/clothing/suit/toggle/labcoat/interdyne
ears = /obj/item/radio/headset/interdyne
/datum/outfit/lavaland_syndicate/post_equip(mob/living/carbon/human/syndicate, visualsOnly = FALSE)
diff --git a/modular_skyrat/modules/mapping/code/wardrobes.dm b/modular_skyrat/modules/mapping/code/wardrobes.dm
index 81a1d86f681..bfb7e2621d3 100644
--- a/modular_skyrat/modules/mapping/code/wardrobes.dm
+++ b/modular_skyrat/modules/mapping/code/wardrobes.dm
@@ -37,12 +37,17 @@
/obj/item/clothing/under/syndicate/skyrat/maid = 5,
/obj/item/clothing/gloves/combat/maid = 5,
/obj/item/clothing/head/costume/maidheadband/syndicate = 5,
- /obj/item/storage/box/nif_ghost_box = 10,
+ /obj/item/storage/box/nif_ghost_box/ghost_role = 10,
)
refill_canister = /obj/item/vending_refill/wardrobe/syndie_wardrobe
light_color = COLOR_MOSTLY_PURE_RED
+/obj/machinery/vending/wardrobe/syndie_wardrobe/ghost_cafe
+ excluded_products = list(
+ /obj/item/storage/box/nif_ghost_box/ghost_role,
+ )
+
/obj/item/vending_refill/wardrobe/syndie_wardrobe
machine_name = "SynDrobe"
diff --git a/modular_skyrat/modules/marines/code/smartgun.dm b/modular_skyrat/modules/marines/code/smartgun.dm
index a31cf1a6bc0..1927413f51b 100644
--- a/modular_skyrat/modules/marines/code/smartgun.dm
+++ b/modular_skyrat/modules/marines/code/smartgun.dm
@@ -118,7 +118,6 @@
/obj/item/ammo_casing/smart
firing_effect_type = null
- is_cased_ammo = FALSE
/obj/item/ammo_casing/smart/Initialize(mapload)
. = ..()
diff --git a/modular_skyrat/modules/medical/code/bodypart.dm b/modular_skyrat/modules/medical/code/bodypart.dm
deleted file mode 100644
index 60a695f59ef..00000000000
--- a/modular_skyrat/modules/medical/code/bodypart.dm
+++ /dev/null
@@ -1,11 +0,0 @@
-/obj/item/bodypart/proc/apply_gauze(obj/item/stack/medical/gauze/new_gauze)
- if(!istype(new_gauze) || current_gauze)
- return
- current_gauze = new new_gauze.gauze_type(src)
- new_gauze.use(1)
-
-/obj/item/bodypart/proc/apply_splint(obj/item/stack/medical/gauze/new_splint)
- if(!istype(new_splint) || current_splint)
- return
- current_splint = new new_splint.splint_type(src)
- new_splint.use(1)
diff --git a/modular_skyrat/modules/medical/code/bodypart_aid.dm b/modular_skyrat/modules/medical/code/bodypart_aid.dm
deleted file mode 100644
index e5b3b13ceaa..00000000000
--- a/modular_skyrat/modules/medical/code/bodypart_aid.dm
+++ /dev/null
@@ -1,227 +0,0 @@
-#define SELF_AID_REMOVE_DELAY (5 SECONDS)
-#define OTHER_AID_REMOVE_DELAY (2 SECONDS)
-
-/datum/bodypart_aid
- var/name
- /// Keeping track of how damaged our aid is from external things, such as hits, it will break when it reaches 0
- var/integrity = 2
- /// To which bodypart we're attached to
- var/obj/item/bodypart/bodypart
- /// Which item do we get when we rip this off, while its in pristine condition
- var/stack_to_drop
- /// Suffix for our used overlay. The suffix is the bodypart zone, and "_digitigrade" for some legs. If this is null then it wont make an overlay. Gauzes are rendered before splints
- var/overlay_prefix
- /// Bodypart is [this_prefix] with get_description()
- var/desc_prefix
-
-/datum/bodypart_aid/Topic(href, href_list)
- . = ..()
- if(href_list["remove"])
- if(!bodypart.owner)
- return
- if(!iscarbon(usr))
- return
- if(!in_range(usr, bodypart.owner))
- return
- var/mob/living/carbon/C = usr
- var/self = (C == bodypart.owner)
- C.visible_message(span_notice("[C] begins removing [name] from [self ? "[bodypart.owner.p_Their()]" : "[bodypart.owner]'s" ] [bodypart.name]..."), span_notice("You begin to remove [name] from [self ? "your" : "[bodypart.owner]'s"] [bodypart.name]..."))
- if(!do_after(C, (self ? SELF_AID_REMOVE_DELAY : OTHER_AID_REMOVE_DELAY), target=bodypart.owner))
- return
- if(QDELETED(src))
- return
- C.visible_message(span_notice("[C] removes [name] from [self ? "[bodypart.owner.p_Their()]" : "[bodypart.owner]'s" ] [bodypart.name]."), span_notice("You remove [name] from [self ? "your" : "[bodypart.owner]'s" ] [bodypart.name]."))
- var/obj/item/gotten = rip_off()
- if(gotten && !C.put_in_hands(gotten))
- gotten.forceMove(get_turf(C))
-
-/datum/bodypart_aid/New(obj/item/bodypart/BP)
- //'bodypart == BP' is set in subtypes to ensure some proper signals and behaviours
- if(overlay_prefix && bodypart.owner)
- bodypart.owner.update_bandage_overlays()
-
-/datum/bodypart_aid/Destroy()
- if(overlay_prefix && bodypart.owner)
- bodypart.owner.update_bandage_overlays()
- bodypart = null
- ..()
-
-/**
- * take_damage() called when the bandage gets damaged
- *
- * This proc will subtract integrity and delete the bandage with a to_chat message to whoever was bandaged
- *
- */
-
-/datum/bodypart_aid/proc/take_damage()
- integrity--
- if(integrity <= 0)
- if(bodypart.owner)
- to_chat(bodypart.owner, span_warning("The [name] on your [bodypart.name] tears and falls off!"))
- qdel(src)
-
-/**
- * rip_off() called when someone rips it off
- *
- * It will return the bandage if it's considered pristine
- *
- */
-
-/datum/bodypart_aid/proc/rip_off()
- if(is_pristine())
- . = new stack_to_drop(null, 1)
- qdel(src)
-
-/**
- * get_description() called by examine procs
- *
- * It will returns a description of the bandage
- *
- */
-
-/datum/bodypart_aid/proc/get_description()
- return "[name]"
-
-/**
- * is_pristine() called by rip_off()
- *
- * Used to determine whether the bandage can be re-used and won't qdel itself
- *
- */
-
-/datum/bodypart_aid/proc/is_pristine()
- return (integrity == initial(integrity))
-
-/datum/bodypart_aid/splint
- name = "splint"
- overlay_prefix = "splint"
- desc_prefix = "fastened"
- stack_to_drop = /obj/item/stack/medical/gauze
- /// How effective are we in keeping the bodypart rigid
- var/splint_factor = 0.3
- /// Whether the splint prevents the limb from being disabled, with a ruptured tendon or a shattered bone
- var/helps_disabled = TRUE
- /// Total condition of our splint, the more we use it the more it gets looser
- var/sling_condition = 5
-
-/datum/bodypart_aid/splint/get_description()
- var/desc
- switch(sling_condition)
- if(0 to 1.25)
- desc = "barely holding"
- if(1.25 to 2.75)
- desc = "loose"
- if(2.75 to 4)
- desc = "rigid"
- if(4 to INFINITY)
- desc = "tight"
- desc += " [name]"
- return desc
-
-/datum/bodypart_aid/splint/Destroy()
- SEND_SIGNAL(bodypart, COMSIG_BODYPART_SPLINT_DESTROYED)
- bodypart.current_splint = null
- return ..()
-
-/datum/bodypart_aid/splint/New(obj/item/bodypart/BP)
- bodypart = BP
- BP.current_splint = src
- SEND_SIGNAL(BP, COMSIG_BODYPART_SPLINTED, src)
- ..()
-
-/datum/bodypart_aid/splint/improvised
- name = "improvised splint"
- splint_factor = 0.6
- helps_disabled= FALSE
- stack_to_drop = /obj/item/stack/medical/gauze/improvised
- overlay_prefix = "splint_improv"
-
-/datum/bodypart_aid/gauze
- name = "gauze"
- stack_to_drop = /obj/item/stack/medical/gauze
- overlay_prefix = "gauze"
- desc_prefix = "bandaged"
- /// How much more can we absorb
- var/absorption_capacity = 5
- /// How fast do we absorb
- var/absorption_rate = 0.12
- /// How much does the gauze help with keeping infections clean
- var/sanitisation_factor = 0.4
- /// How much sanitisation we've got after we become fairly stained and worn
- var/sanitisation_factor_stained = 0.8
- /// Is it blood stained? For description
- var/blood_stained = FALSE
- /// Is it pus stained? For description
- var/pus_stained = FALSE
-
-/datum/bodypart_aid/gauze/get_description()
- var/desc
- switch(absorption_capacity)
- if(-INFINITY to 0)
- desc = "unusable"
- if(0 to 1.25)
- desc = "nearly ruined"
- if(1.25 to 2.75)
- desc = "badly worn"
- if(2.75 to 4)
- desc = "slightly used"
- if(4 to INFINITY)
- desc = "clean"
- if(blood_stained)
- desc += ", bloodied"
- if(pus_stained)
- desc += ", pus stained"
- desc += " [name]"
- return desc
-
-/datum/bodypart_aid/gauze/New(obj/item/bodypart/BP)
- bodypart = BP
- BP.current_gauze = src
- SEND_SIGNAL(BP, COMSIG_BODYPART_GAUZED, src)
- ..()
-
-/datum/bodypart_aid/gauze/Destroy()
- SEND_SIGNAL(bodypart, COMSIG_BODYPART_GAUZE_DESTROYED)
- bodypart.current_gauze = null
- return ..()
-
-/datum/bodypart_aid/gauze/is_pristine()
- . = ..()
- if(.)
- return (absorption_capacity == initial(absorption_capacity))
-
-/**
- * seep_gauze() is for when a gauze wrapping absorbs blood or pus from wounds, lowering its absorption capacity.
- *
- * The passed amount of seepage is deducted from the bandage's absorption capacity, and if we reach a negative absorption capacity, the bandage won't help our wounds.
- * When the bandage is left with a low amount of absorption, it'll notify user and act worse as a sanitiser for infections
- * Returns TRUE if the bandage absorbed anything, FALSE if it's fully stained.
- *
- * Arguments:
- * * seep_amt - How much absorption capacity we're removing from our current bandages (think, how much blood or pus are we soaking up this tick?)
- * * type - Is it blood or pus we're being stained with? GAUZE_STAIN_BLOOD, GAUZE_STAIN_PUS defines from wounds.dm
- */
-
-/datum/bodypart_aid/gauze/proc/seep_gauze(amount, type)
- if(absorption_capacity > 0)
- . = TRUE
- absorption_capacity -= amount
- else
- return FALSE
- //If our remaining absorption capacity is low, make so blood and pus stains show
- if(absorption_capacity < 2)
- sanitisation_factor = sanitisation_factor_stained
- if(type == GAUZE_STAIN_BLOOD && !blood_stained)
- blood_stained = TRUE
- if(bodypart.owner)
- to_chat(bodypart.owner, span_warning("The [name] on your [bodypart.name] [pick(list("pools", "trickles", "seeps"))] with blood."))
- else if(type == GAUZE_STAIN_PUS && !pus_stained)
- pus_stained = TRUE
- if(bodypart.owner)
- to_chat(bodypart.owner, span_warning("The [name] on your [bodypart.name] [pick(list("pools", "trickles", "seeps"))] with pus."))
-
-/datum/bodypart_aid/gauze/improvised
- name = "improvised gauze"
- stack_to_drop = /obj/item/stack/medical/gauze/improvised
- absorption_rate = 0.09
- absorption_capacity = 3
diff --git a/modular_skyrat/modules/medical/code/carbon_examine.dm b/modular_skyrat/modules/medical/code/carbon_examine.dm
index aab30138184..e86ed9f9267 100644
--- a/modular_skyrat/modules/medical/code/carbon_examine.dm
+++ b/modular_skyrat/modules/medical/code/carbon_examine.dm
@@ -49,11 +49,7 @@
if(WOUND_SEVERITY_CRITICAL)
msg += "\t[t_His] [LB.name] is suffering [W.a_or_from] [W.get_topic_name(user)]!!"
if(LB.current_gauze)
- var/datum/bodypart_aid/current_gauze = LB.current_gauze
- msg += "\t[t_His] [LB.name] is [current_gauze.desc_prefix] with [current_gauze.get_description()]."
- if(LB.current_splint)
- var/datum/bodypart_aid/current_splint = LB.current_splint
- msg += "\t[t_His] [LB.name] is [current_splint.desc_prefix] with a [current_splint.get_description()]."
+ msg += "\t[t_His] [LB.name] is [LB.current_gauze.get_gauze_usage_prefix()] with [LB.current_gauze.get_gauze_description()]."
if(!any_bodypart_damage)
msg += "\t[t_He] [t_Has] no significantly damaged bodyparts."
diff --git a/modular_skyrat/modules/medical/code/carbon_update_icons.dm b/modular_skyrat/modules/medical/code/carbon_update_icons.dm
index 76167bbf6ea..0c3b4bb4f47 100644
--- a/modular_skyrat/modules/medical/code/carbon_update_icons.dm
+++ b/modular_skyrat/modules/medical/code/carbon_update_icons.dm
@@ -6,15 +6,9 @@
for(var/b in bodyparts)
var/obj/item/bodypart/BP = b
- if(BP.current_gauze && BP.current_gauze.overlay_prefix)
- var/bp_suffix = BP.body_zone
- if(BP.bodytype & BODYTYPE_DIGITIGRADE)
- bp_suffix += "_digitigrade"
- overlays.add_overlay("[BP.current_gauze.overlay_prefix]_[bp_suffix]")
- if(BP.current_splint && BP.current_splint.overlay_prefix)
- var/bp_suffix = BP.body_zone
- if(BP.bodytype & BODYTYPE_DIGITIGRADE)
- bp_suffix += "_digitigrade"
- overlays.add_overlay("[BP.current_splint.overlay_prefix]_[bp_suffix]")
+ var/obj/item/stack/medical/gauze/our_gauze = BP.current_gauze
+ if (!our_gauze)
+ continue
+ overlays.add_overlay(our_gauze.get_overlay_prefix())
apply_overlay(BANDAGE_LAYER)
diff --git a/modular_skyrat/modules/medical/code/carbon_defense.dm b/modular_skyrat/modules/medical/code/grasp.dm
similarity index 94%
rename from modular_skyrat/modules/medical/code/carbon_defense.dm
rename to modular_skyrat/modules/medical/code/grasp.dm
index 8fbc3c407be..808732c5572 100644
--- a/modular_skyrat/modules/medical/code/carbon_defense.dm
+++ b/modular_skyrat/modules/medical/code/grasp.dm
@@ -1,5 +1,5 @@
/mob/living/carbon/proc/self_grasp_bleeding_limb(obj/item/bodypart/grasped_part, supress_message = FALSE)
- if(!grasped_part?.get_modified_bleed_rate())
+ if(!grasped_part?.can_be_grasped())
return
var/starting_hand_index = active_hand_index
if(starting_hand_index == grasped_part.held_index)
diff --git a/modular_skyrat/modules/medical/code/health_analyzer.dm b/modular_skyrat/modules/medical/code/health_analyzer.dm
new file mode 100644
index 00000000000..1d7eba6198f
--- /dev/null
+++ b/modular_skyrat/modules/medical/code/health_analyzer.dm
@@ -0,0 +1,11 @@
+/// If TRUE, this analyzer can be used for medibot construction. If FALSE, it cannot. Returns TRUE by default.
+/obj/item/healthanalyzer/proc/can_be_used_in_medibot()
+ return TRUE
+
+/obj/item/healthanalyzer/no_medibot
+ name = "surplus health analyzer"
+ desc = "A hand-held body scanner capable of distinguishing vital signs of the subject. Has a side button to scan for chemicals, and can be toggled to scan wounds. \
+ This one seems to lack the mounting braces usually found on medibot-compatable analyzers..."
+
+/obj/item/healthanalyzer/no_medibot/can_be_used_in_medibot()
+ return FALSE
diff --git a/modular_skyrat/modules/medical/code/medical_stacks.dm b/modular_skyrat/modules/medical/code/medical_stacks.dm
deleted file mode 100644
index 35b2ff1b1f9..00000000000
--- a/modular_skyrat/modules/medical/code/medical_stacks.dm
+++ /dev/null
@@ -1,65 +0,0 @@
-/obj/item/stack/medical/gauze
- var/gauze_type = /datum/bodypart_aid/gauze
- var/splint_type = /datum/bodypart_aid/splint
-
-/obj/item/stack/medical/gauze/improvised
- gauze_type = /datum/bodypart_aid/gauze/improvised
- splint_type = /datum/bodypart_aid/splint/improvised
-
-// gauze is only relevant for wounds, which are handled in the wounds themselves
-/obj/item/stack/medical/gauze/try_heal(mob/living/patient, mob/user, silent)
-
- var/treatment_delay = (user == patient ? self_delay : other_delay)
-
- var/obj/item/bodypart/limb = patient.get_bodypart(check_zone(user.zone_selected))
- if(!limb)
- patient.balloon_alert(user, "missing limb!")
- return
- if(!LAZYLEN(limb.wounds))
- patient.balloon_alert(user, "no wounds!") // good problem to have imo
- return
-
- var/gauzeable_wound = FALSE
- var/splintable_wound = FALSE
- var/datum/wound/woundies
- for(var/i in limb.wounds)
- woundies = i
- if(woundies.wound_flags & (ACCEPTS_GAUZE | ACCEPTS_SPLINT))
- if(woundies.wound_flags & ACCEPTS_GAUZE)
- gauzeable_wound = TRUE
- continue
- if(woundies.wound_flags & ACCEPTS_SPLINT)
- splintable_wound = TRUE
- continue
- if(!gauzeable_wound && !splintable_wound)
- patient.balloon_alert(user, "can't heal those!")
- return
-
- if(limb.current_gauze && gauzeable_wound)
- gauzeable_wound = FALSE
- if(limb.current_splint && splintable_wound)
- splintable_wound = FALSE
- if(!gauzeable_wound && !splintable_wound)
- balloon_alert(user, "already bandaged!")
- return
-
- if(HAS_TRAIT(woundies, TRAIT_WOUND_SCANNED))
- treatment_delay *= 0.5
- if(user == patient)
- user.visible_message(span_warning("[user] begins expertly [gauzeable_wound ? "wrapping the wounds on their [limb.plaintext_zone]" : "splinting their [limb.plaintext_zone]"] with [src]..."), span_notice("You keep in mind the indications from the holo-image about your injury, and expertly begin [gauzeable_wound ? "wrapping your wounds" : "splinting your [limb.plaintext_zone]"] with [src]."))
- else
- user.visible_message(span_warning("[user] begins expertly [gauzeable_wound ? "wrapping the wounds on [patient]'s [limb.plaintext_zone]" : "splinting [patient]'s [limb.plaintext_zone]"] with [src]..."), span_warning("You begin quickly [gauzeable_wound ? "wrapping the wounds on [patient]'s [limb.plaintext_zone]" : "splinting [patient]'s [limb.plaintext_zone]"] with [src], keeping the holo-image indications in mind..."))
- else
- user.visible_message(span_warning("[user] begins [gauzeable_wound ? "wrapping the wounds on [patient]'s [limb.plaintext_zone]" : "splinting [patient]'s [limb.plaintext_zone]"] with [src]..."), span_warning("You begin [gauzeable_wound ? "wrapping the wounds on" : "splinting"] [user == patient ? "your" : "[patient]'s"] [limb.plaintext_zone] with [src]..."))
-
- if(!do_after(user, treatment_delay, target = patient))
- return
-
- user.visible_message("[user] [gauzeable_wound ? "wraps the wounds on" : "splints"] [user == patient ? "[user.p_their()]" : "[patient]'s"] [limb.plaintext_zone] with [src].", "You [gauzeable_wound ? "wrap the wounds on" : "splint"] [user == patient ? "your" : "[patient]'s"] [limb.plaintext_zone].")
- if(gauzeable_wound)
- limb.apply_gauze(src)
- return
- if(splintable_wound)
- limb.apply_splint(src)
- return
-
diff --git a/modular_skyrat/modules/medical/code/smartdarts.dm b/modular_skyrat/modules/medical/code/smartdarts.dm
index c36caa3f1eb..ed649300e93 100644
--- a/modular_skyrat/modules/medical/code/smartdarts.dm
+++ b/modular_skyrat/modules/medical/code/smartdarts.dm
@@ -34,7 +34,7 @@
to_chat(user, span_warning("You cannot directly remove reagents from [target]!"))
return SECONDARY_ATTACK_CONTINUE_CHAIN
- var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this, transfered_by = user) // transfer from, transfer to - who cares?
+ var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this, transferred_by = user) // transfer from, transfer to - who cares?
to_chat(user, span_notice("You fill [src] with [trans] units of the solution. It now contains [reagents.total_volume] units."))
return SECONDARY_ATTACK_CONTINUE_CHAIN
diff --git a/modular_skyrat/modules/medical/code/wounds/bleed.dm b/modular_skyrat/modules/medical/code/wounds/bleed.dm
new file mode 100644
index 00000000000..75d80d3b384
--- /dev/null
+++ b/modular_skyrat/modules/medical/code/wounds/bleed.dm
@@ -0,0 +1,19 @@
+/datum/wound/slash/flesh/show_wound_topic(mob/user)
+ return (user == victim && blood_flow)
+
+/datum/wound/slash/flesh/Topic(href, href_list)
+ . = ..()
+ if(href_list["wound_topic"])
+ if(!usr == victim)
+ return
+ victim.self_grasp_bleeding_limb(limb)
+
+/datum/wound/pierce/bleed/show_wound_topic(mob/user)
+ return (user == victim && blood_flow)
+
+/datum/wound/slash/bleed/Topic(href, href_list)
+ . = ..()
+ if(href_list["wound_topic"])
+ if(!usr == victim)
+ return
+ victim.self_grasp_bleeding_limb(limb)
diff --git a/modular_skyrat/modules/medical/code/wounds/bones.dm b/modular_skyrat/modules/medical/code/wounds/bones.dm
deleted file mode 100644
index 089e289e3d8..00000000000
--- a/modular_skyrat/modules/medical/code/wounds/bones.dm
+++ /dev/null
@@ -1,455 +0,0 @@
-
-/*
- Blunt/Bone wounds
-*/
-// TODO: well, a lot really, but i'd kill to get overlays and a bonebreaking effect like Blitz: The League, similar to electric shock skeletons
-
-/datum/wound/blunt
- name = "Blunt (Bone) Wound"
- sound_effect = 'sound/effects/wounds/crack1.ogg'
- wound_type = WOUND_BLUNT
- wound_flags = (BONE_WOUND | ACCEPTS_SPLINT)
-
- /// Have we been taped?
- var/taped
- /// Have we been bone gel'd?
- var/gelled
- /// If we did the gel + surgical tape healing method for fractures, how many ticks does it take to heal by default
- var/regen_ticks_needed
- /// Our current counter for gel + surgical tape regeneration
- var/regen_ticks_current
- /// If we suffer severe head booboos, we can get brain traumas tied to them
- var/datum/brain_trauma/active_trauma
- /// What brain trauma group, if any, we can draw from for head wounds
- var/brain_trauma_group
- /// If we deal brain traumas, when is the next one due?
- var/next_trauma_cycle
- /// How long do we wait +/- 20% for the next trauma?
- var/trauma_cycle_cooldown
- /// If this is a chest wound and this is set, we have this chance to cough up blood when hit in the chest
- var/internal_bleeding_chance = 0
-
-/*
- Overwriting of base procs
-*/
-/datum/wound/blunt/wound_injury(datum/wound/old_wound = null, attack_direction)
- // hook into gaining/losing gauze so crit bone wounds can re-enable/disable depending if they're slung or not
- RegisterSignals(limb, list(COMSIG_BODYPART_SPLINTED, COMSIG_BODYPART_SPLINT_DESTROYED), PROC_REF(update_inefficiencies))
-
- if(limb.body_zone == BODY_ZONE_HEAD && brain_trauma_group)
- processes = TRUE
- active_trauma = victim.gain_trauma_type(brain_trauma_group, TRAUMA_RESILIENCE_WOUND)
- next_trauma_cycle = world.time + (rand(100-WOUND_BONE_HEAD_TIME_VARIANCE, 100+WOUND_BONE_HEAD_TIME_VARIANCE) * 0.01 * trauma_cycle_cooldown)
-
- RegisterSignal(victim, COMSIG_HUMAN_EARLY_UNARMED_ATTACK, PROC_REF(attack_with_hurt_hand))
- if(limb.held_index && victim.get_item_for_held_index(limb.held_index) && (disabling || prob(30 * severity)))
- var/obj/item/held_item = victim.get_item_for_held_index(limb.held_index)
- if(istype(held_item, /obj/item/offhand))
- held_item = victim.get_inactive_held_item()
-
- if(held_item && victim.dropItemToGround(held_item))
- victim.visible_message(span_danger("[victim] drops [held_item] in shock!"), span_warning("The force on your [parse_zone(limb.body_zone)] causes you to drop [held_item]!"), vision_distance=COMBAT_MESSAGE_RANGE)
-
- update_inefficiencies()
-
-/datum/wound/blunt/remove_wound(ignore_limb, replaced)
- limp_slowdown = 0
- QDEL_NULL(active_trauma)
- if(limb)
- UnregisterSignal(limb, list(COMSIG_BODYPART_GAUZED, COMSIG_BODYPART_GAUZE_DESTROYED))
- if(victim)
- UnregisterSignal(victim, COMSIG_HUMAN_EARLY_UNARMED_ATTACK)
- return ..()
-
-/datum/wound/blunt/handle_process()
- . = ..()
- if(limb.body_zone == BODY_ZONE_HEAD && brain_trauma_group && world.time > next_trauma_cycle)
- if(active_trauma)
- QDEL_NULL(active_trauma)
- else
- active_trauma = victim.gain_trauma_type(brain_trauma_group, TRAUMA_RESILIENCE_WOUND)
- next_trauma_cycle = world.time + (rand(100-WOUND_BONE_HEAD_TIME_VARIANCE, 100+WOUND_BONE_HEAD_TIME_VARIANCE) * 0.01 * trauma_cycle_cooldown)
-
- if(!gelled || !taped)
- return
-
- regen_ticks_current++
- if(victim.body_position == LYING_DOWN)
- if(prob(50))
- regen_ticks_current += 0.5
- if(victim.IsSleeping() && prob(50))
- regen_ticks_current += 0.5
-
- if(prob(severity * 3))
- victim.take_bodypart_damage(rand(1, severity * 2), wound_bonus = CANT_WOUND)
- victim.adjustStaminaLoss(rand(2, severity * 2.5))
- if(prob(33))
- to_chat(victim, span_danger("You feel a sharp pain in your body as your bones are reforming!"))
-
- if(regen_ticks_current > regen_ticks_needed)
- if(!victim || !limb)
- qdel(src)
- return
- to_chat(victim, span_green("Your [parse_zone(limb.body_zone)] has recovered from your fracture!"))
- remove_wound()
-
-/// If we're a human who's punching something with a broken arm, we might hurt ourselves doing so
-/datum/wound/blunt/proc/attack_with_hurt_hand(mob/M, atom/target, proximity)
- SIGNAL_HANDLER
-
- if(victim.get_active_hand() != limb || !victim.combat_mode || !ismob(target) || severity <= WOUND_SEVERITY_MODERATE)
- return
-
- // With a severe or critical wound, you have a 15% or 30% chance to proc pain on hit
- if(prob((severity - 1) * 15))
- // And you have a 70% or 50% chance to actually land the blow, respectively
- if(prob(70 - 20 * (severity - 1)))
- to_chat(victim, span_userdanger("The fracture in your [parse_zone(limb.body_zone)] shoots with pain as you strike [target]!"))
- limb.receive_damage(brute=rand(1,5))
- else
- victim.visible_message(span_danger("[victim] weakly strikes [target] with [victim.p_their()] broken [parse_zone(limb.body_zone)], recoiling from pain!"), \
- span_userdanger("You fail to strike [target] as the fracture in your [parse_zone(limb.body_zone)] lights up in unbearable pain!"), vision_distance=COMBAT_MESSAGE_RANGE)
- INVOKE_ASYNC(victim, TYPE_PROC_REF(/mob, emote), "scream")
- victim.Stun(0.5 SECONDS)
- limb.receive_damage(brute=rand(3,7))
- return COMPONENT_CANCEL_ATTACK_CHAIN
-
-
-/datum/wound/blunt/receive_damage(wounding_type, wounding_dmg, wound_bonus)
- if(!victim || wounding_dmg < WOUND_MINIMUM_DAMAGE)
- return
- if(ishuman(victim))
- var/mob/living/carbon/human/human_victim = victim
- if(HAS_TRAIT(human_victim, TRAIT_NOBLOOD))
- return
-
- if(limb.body_zone == BODY_ZONE_CHEST && victim.blood_volume && prob(internal_bleeding_chance + wounding_dmg))
- var/blood_bled = rand(1, wounding_dmg * (severity == WOUND_SEVERITY_CRITICAL ? 2 : 1.5)) // 12 brute toolbox can cause up to 18/24 bleeding with a severe/critical chest wound
- switch(blood_bled)
- if(1 to 6)
- victim.bleed(blood_bled, TRUE)
- if(7 to 13)
- victim.visible_message(span_smalldanger("A thin stream of blood drips from [victim]'s mouth from the blow to [victim.p_their()] chest."), span_danger("You cough up a bit of blood from the blow to your chest."), vision_distance=COMBAT_MESSAGE_RANGE)
- victim.bleed(blood_bled, TRUE)
- if(14 to 19)
- victim.visible_message(span_smalldanger("Blood spews out of [victim]'s mouth from the blow to [victim.p_their()] chest!"), span_danger("You spit out a string of blood from the blow to your chest!"), vision_distance=COMBAT_MESSAGE_RANGE)
- new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir)
- victim.bleed(blood_bled)
- if(20 to INFINITY)
- victim.visible_message(span_danger("Blood spurts out of [victim]'s mouth from the blow to [victim.p_their()] chest!"), span_danger("You choke up on a spray of blood from the blow to your chest!"), vision_distance=COMBAT_MESSAGE_RANGE)
- victim.bleed(blood_bled)
- new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir)
- victim.add_splatter_floor(get_step(victim.loc, victim.dir))
-
-
-/datum/wound/blunt/get_examine_description(mob/user)
- if(!limb.current_splint && !gelled && !taped)
- return ..()
-
- var/list/msg = list()
- if(!limb.current_splint)
- msg += "[victim.p_their(TRUE)] [parse_zone(limb.body_zone)] [examine_desc]"
- else
- var/sling_condition = ""
- // how much life we have left in these bandages
- switch(limb.current_splint.sling_condition)
- if(0 to 1.25)
- sling_condition = "just barely"
- if(1.25 to 2.75)
- sling_condition = "loosely"
- if(2.75 to 4)
- sling_condition = "mostly"
- if(4 to INFINITY)
- sling_condition = "tightly"
-
- msg += "[victim.p_their(TRUE)] [parse_zone(limb.body_zone)] is [sling_condition] fastened with a [limb.current_splint.name]"
-
- if(taped)
- msg += ", and appears to be reforming itself under some surgical tape!"
- else if(gelled)
- msg += ", with fizzing flecks of blue bone gel sparking off the bone!"
- else
- msg += "!"
- return "[msg.Join()]"
-
-/*
- New common procs for /datum/wound/blunt/
-*/
-
-/datum/wound/blunt/proc/update_inefficiencies()
- SIGNAL_HANDLER
- if(limb.body_zone in list(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
- if(limb.current_splint)
- limp_slowdown = initial(limp_slowdown) * limb.current_splint.splint_factor
- else
- limp_slowdown = initial(limp_slowdown)
- victim.apply_status_effect(/datum/status_effect/limp)
- else if(limb.body_zone in list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM))
- if(limb.current_splint)
- interaction_efficiency_penalty = 1 + ((interaction_efficiency_penalty - 1) * limb.current_splint.splint_factor)
- else
- interaction_efficiency_penalty = interaction_efficiency_penalty
-
- if(initial(disabling))
- set_disabling(!(limb.current_splint && limb.current_splint.helps_disabled))
-
- limb.update_wounds()
-
-/// Joint Dislocation (Moderate Blunt)
-/datum/wound/blunt/moderate
- name = "Joint Dislocation"
- desc = "Patient's bone has been unset from socket, causing pain and reduced motor function."
- treat_text = "Recommended application of bonesetter to affected limb, though manual relocation by applying an aggressive grab to the patient and helpfully interacting with afflicted limb may suffice."
- examine_desc = "is awkwardly jammed out of place"
- occur_text = "jerks violently and becomes unseated"
- severity = WOUND_SEVERITY_MODERATE
- viable_zones = list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
- interaction_efficiency_penalty = 1.5
- limp_slowdown = 3
- threshold_minimum = 35
- threshold_penalty = 15
- treatable_tool = TOOL_BONESET
- wound_flags = (BONE_WOUND)
- status_effect_type = /datum/status_effect/wound/blunt/moderate
- scar_keyword = "bluntmoderate"
-
-/datum/wound/blunt/moderate/Destroy()
- if(victim)
- UnregisterSignal(victim, COMSIG_LIVING_DOORCRUSHED)
- return ..()
-
-/datum/wound/blunt/moderate/wound_injury(datum/wound/old_wound, attack_direction)
- . = ..()
- RegisterSignal(victim, COMSIG_LIVING_DOORCRUSHED, PROC_REF(door_crush))
-
-/// Getting smushed in an airlock/firelock is a last-ditch attempt to try relocating your limb
-/datum/wound/blunt/moderate/proc/door_crush()
- SIGNAL_HANDLER
- if(prob(33))
- victim.visible_message(span_danger("[victim]'s dislocated [parse_zone(limb.body_zone)] pops back into place!"), span_userdanger("Your dislocated [parse_zone(limb.body_zone)] pops back into place! Ow!"))
- remove_wound()
-
-/datum/wound/blunt/moderate/try_handling(mob/living/carbon/human/user)
- if(user.pulling != victim || user.zone_selected != limb.body_zone)
- return FALSE
-
- if(user.grab_state == GRAB_PASSIVE)
- to_chat(user, span_warning("You must have [victim] in an aggressive grab to manipulate [victim.p_their()] [lowertext(name)]!"))
- return TRUE
-
- if(user.grab_state >= GRAB_AGGRESSIVE)
- user.visible_message(span_danger("[user] begins twisting and straining [victim]'s dislocated [parse_zone(limb.body_zone)]!"), span_notice("You begin twisting and straining [victim]'s dislocated [parse_zone(limb.body_zone)]..."), ignored_mobs=victim)
- to_chat(victim, span_userdanger("[user] begins twisting and straining your dislocated [parse_zone(limb.body_zone)]!"))
- if(!user.combat_mode)
- chiropractice(user)
- else
- malpractice(user)
- return TRUE
-
-/// If someone is snapping our dislocated joint back into place by hand with an aggro grab and help intent
-/datum/wound/blunt/moderate/proc/chiropractice(mob/living/carbon/human/user)
- var/time = base_treat_time
-
- if(!do_after(user, time, target=victim, extra_checks = CALLBACK(src, PROC_REF(still_exists))))
- return
-
- if(prob(65))
- user.visible_message(span_danger("[user] snaps [victim]'s dislocated [parse_zone(limb.body_zone)] back into place!"), span_notice("You snap [victim]'s dislocated [parse_zone(limb.body_zone)] back into place!"), ignored_mobs=victim)
- to_chat(victim, span_userdanger("[user] snaps your dislocated [parse_zone(limb.body_zone)] back into place!"))
- victim.emote("scream")
- limb.receive_damage(brute=20, wound_bonus=CANT_WOUND)
- qdel(src)
- else
- user.visible_message(span_danger("[user] wrenches [victim]'s dislocated [parse_zone(limb.body_zone)] around painfully!"), span_danger("You wrench [victim]'s dislocated [parse_zone(limb.body_zone)] around painfully!"), ignored_mobs=victim)
- to_chat(victim, span_userdanger("[user] wrenches your dislocated [parse_zone(limb.body_zone)] around painfully!"))
- limb.receive_damage(brute=10, wound_bonus=CANT_WOUND)
- chiropractice(user)
-
-/// If someone is snapping our dislocated joint into a fracture by hand with an aggro grab and harm or disarm intent
-/datum/wound/blunt/moderate/proc/malpractice(mob/living/carbon/human/user)
- var/time = base_treat_time
-
- if(!do_after(user, time, target=victim, extra_checks = CALLBACK(src, PROC_REF(still_exists))))
- return
-
- if(prob(65))
- user.visible_message(span_danger("[user] snaps [victim]'s dislocated [parse_zone(limb.body_zone)] with a sickening crack!"), span_danger("You snap [victim]'s dislocated [parse_zone(limb.body_zone)] with a sickening crack!"), ignored_mobs=victim)
- to_chat(victim, span_userdanger("[user] snaps your dislocated [parse_zone(limb.body_zone)] with a sickening crack!"))
- victim.emote("scream")
- limb.receive_damage(brute=25, wound_bonus=30)
- else
- user.visible_message(span_danger("[user] wrenches [victim]'s dislocated [parse_zone(limb.body_zone)] around painfully!"), span_danger("You wrench [victim]'s dislocated [parse_zone(limb.body_zone)] around painfully!"), ignored_mobs=victim)
- to_chat(victim, span_userdanger("[user] wrenches your dislocated [parse_zone(limb.body_zone)] around painfully!"))
- limb.receive_damage(brute=10, wound_bonus=CANT_WOUND)
- malpractice(user)
-
-
-/datum/wound/blunt/moderate/treat(obj/item/I, mob/user)
- if(victim == user)
- victim.visible_message(span_danger("[user] begins resetting [victim.p_their()] [parse_zone(limb.body_zone)] with [I]."), span_warning("You begin resetting your [parse_zone(limb.body_zone)] with [I]..."))
- else
- user.visible_message(span_danger("[user] begins resetting [victim]'s [parse_zone(limb.body_zone)] with [I]."), span_notice("You begin resetting [victim]'s [parse_zone(limb.body_zone)] with [I]..."))
-
- if(!do_after(user, base_treat_time * (user == victim ? 1.5 : 1), target = victim, extra_checks=CALLBACK(src, PROC_REF(still_exists))))
- return
-
- if(victim == user)
- limb.receive_damage(brute=15, wound_bonus=CANT_WOUND)
- victim.visible_message(span_danger("[user] finishes resetting [victim.p_their()] [parse_zone(limb.body_zone)]!"), span_userdanger("You reset your [parse_zone(limb.body_zone)]!"))
- else
- limb.receive_damage(brute=10, wound_bonus=CANT_WOUND)
- user.visible_message(span_danger("[user] finishes resetting [victim]'s [parse_zone(limb.body_zone)]!"), span_nicegreen("You finish resetting [victim]'s [parse_zone(limb.body_zone)]!"), victim)
- to_chat(victim, span_userdanger("[user] resets your [parse_zone(limb.body_zone)]!"))
-
- victim.emote("scream")
- qdel(src)
-
-/*
- Severe (Hairline Fracture)
-*/
-
-/datum/wound/blunt/severe
- name = "Hairline Fracture"
- desc = "Patient's bone has suffered a crack in the foundation, causing serious pain and reduced limb functionality."
- treat_text = "Recommended light surgical application of bone gel, though a sling of medical gauze will prevent worsening situation."
- examine_desc = "appears grotesquely swollen, its attachment weakened"
- occur_text = "sprays chips of bone and develops a nasty looking bruise"
-
- severity = WOUND_SEVERITY_SEVERE
- interaction_efficiency_penalty = 2
- limp_slowdown = 6
- threshold_minimum = 60
- threshold_penalty = 30
- treatable_by = list(/obj/item/stack/sticky_tape/surgical, /obj/item/stack/medical/bone_gel)
- status_effect_type = /datum/status_effect/wound/blunt/severe
- scar_keyword = "bluntsevere"
- brain_trauma_group = BRAIN_TRAUMA_MILD
- trauma_cycle_cooldown = 1.5 MINUTES
- internal_bleeding_chance = 40
- wound_flags = (BONE_WOUND | ACCEPTS_SPLINT | MANGLES_BONE)
- regen_ticks_needed = 120 // ticks every 2 seconds, 240 seconds, so roughly 4 minutes default
-
-/// Compound Fracture (Critical Blunt)
-/datum/wound/blunt/critical
- name = "Compound Fracture"
- desc = "Patient's bones have suffered multiple gruesome fractures, causing significant pain and near uselessness of limb."
- treat_text = "Immediate binding of affected limb, followed by surgical intervention ASAP."
- examine_desc = "is mangled and pulped, seemingly held together by tissue alone"
- occur_text = "cracks apart, exposing broken bones to open air"
-
- severity = WOUND_SEVERITY_CRITICAL
- interaction_efficiency_penalty = 4
- limp_slowdown = 9
- sound_effect = 'sound/effects/wounds/crack2.ogg'
- threshold_minimum = 115
- threshold_penalty = 50
- disabling = TRUE
- treatable_by = list(/obj/item/stack/sticky_tape/surgical, /obj/item/stack/medical/bone_gel)
- status_effect_type = /datum/status_effect/wound/blunt/critical
- scar_keyword = "bluntcritical"
- brain_trauma_group = BRAIN_TRAUMA_SEVERE
- trauma_cycle_cooldown = 2.5 MINUTES
- internal_bleeding_chance = 60
- wound_flags = (BONE_WOUND | ACCEPTS_SPLINT | MANGLES_BONE)
- regen_ticks_needed = 240 // ticks every 2 seconds, 480 seconds, so roughly 8 minutes default
-
-// doesn't make much sense for "a" bone to stick out of your head
-/datum/wound/blunt/critical/apply_wound(obj/item/bodypart/L, silent = FALSE, datum/wound/old_wound = null, smited = FALSE, attack_direction = null, wound_source = "Unknown")
- if(L.body_zone == BODY_ZONE_HEAD)
- occur_text = "splits open, exposing a bare, cracked skull through the flesh and blood"
- examine_desc = "has an unsettling indent, with bits of skull poking out"
- . = ..()
-
-/// if someone is using bone gel on our wound
-/datum/wound/blunt/proc/gel(obj/item/stack/medical/bone_gel/gel, mob/user)
- if(gelled)
- to_chat(user, span_warning("[user == victim ? "Your" : "[victim]'s"] [parse_zone(limb.body_zone)] is already coated with bone gel!"))
- return
-
- user.visible_message(span_danger("[user] begins hastily applying [gel] to [victim]'s' [parse_zone(limb.body_zone)]..."), span_warning("You begin hastily applying [gel] to [user == victim ? "your" : "[victim]'s"] [parse_zone(limb.body_zone)], disregarding the warning label..."))
-
- if(!do_after(user, base_treat_time * 1.5 * (user == victim ? 1.5 : 1), target = victim, extra_checks=CALLBACK(src, PROC_REF(still_exists))))
- return
-
- gel.use(1)
- victim.emote("scream")
- if(user != victim)
- user.visible_message(span_notice("[user] finishes applying [gel] to [victim]'s [parse_zone(limb.body_zone)], emitting a fizzing noise!"), span_notice("You finish applying [gel] to [victim]'s [parse_zone(limb.body_zone)]!"), ignored_mobs=victim)
- to_chat(victim, span_userdanger("[user] finishes applying [gel] to your [parse_zone(limb.body_zone)], and you can feel the bones exploding with pain as they begin melting and reforming!"))
- else
- var/painkiller_bonus = 0
- if(victim.get_drunk_amount() > 10)
- painkiller_bonus += 10
- if(victim.reagents.has_reagent(/datum/reagent/medicine/morphine))
- painkiller_bonus += 20
- if(victim.reagents.has_reagent(/datum/reagent/determination))
- painkiller_bonus += 10
- if(victim.reagents.has_reagent(/datum/reagent/consumable/ethanol/painkiller))
- painkiller_bonus += 5
- if(victim.reagents.has_reagent(/datum/reagent/medicine/mine_salve))
- painkiller_bonus += 20
-
- if(prob(25 + (20 * (severity - 2)) - painkiller_bonus)) // 25%/45% chance to fail self-applying with severe and critical wounds, modded by painkillers
- victim.visible_message(span_danger("[victim] fails to finish applying [gel] to [victim.p_their()] [parse_zone(limb.body_zone)], passing out from the pain!"), span_notice("You pass out from the pain of applying [gel] to your [parse_zone(limb.body_zone)] before you can finish!"))
- victim.AdjustUnconscious(5 SECONDS)
- return
- victim.visible_message(span_notice("[victim] finishes applying [gel] to [victim.p_their()] [parse_zone(limb.body_zone)], grimacing from the pain!"), span_notice("You finish applying [gel] to your [parse_zone(limb.body_zone)], and your bones explode in pain!"))
-
- limb.receive_damage(25, wound_bonus=CANT_WOUND)
- victim.adjustStaminaLoss(100)
- if(!gelled)
- gelled = TRUE
-
-/// if someone is using surgical tape on our wound
-/datum/wound/blunt/proc/tape(obj/item/stack/sticky_tape/surgical/tape, mob/user)
- if(!gelled)
- to_chat(user, span_warning("[user == victim ? "Your" : "[victim]'s"] [parse_zone(limb.body_zone)] must be coated with bone gel to perform this emergency operation!"))
- return
- if(taped)
- to_chat(user, span_warning("[user == victim ? "Your" : "[victim]'s"] [parse_zone(limb.body_zone)] is already wrapped in [tape.name] and reforming!"))
- return
-
- user.visible_message(span_danger("[user] begins applying [tape] to [victim]'s' [parse_zone(limb.body_zone)]..."), span_warning("You begin applying [tape] to [user == victim ? "your" : "[victim]'s"] [parse_zone(limb.body_zone)]..."))
-
- if(!do_after(user, base_treat_time * (user == victim ? 1.5 : 1), target = victim, extra_checks=CALLBACK(src, PROC_REF(still_exists))))
- return
-
- if(victim == user)
- regen_ticks_needed *= 1.5
-
- tape.use(1)
- if(user != victim)
- user.visible_message(span_notice("[user] finishes applying [tape] to [victim]'s [parse_zone(limb.body_zone)], emitting a fizzing noise!"), span_notice("You finish applying [tape] to [victim]'s [parse_zone(limb.body_zone)]!"), ignored_mobs=victim)
- to_chat(victim, span_green("[user] finishes applying [tape] to your [parse_zone(limb.body_zone)], you immediately begin to feel your bones start to reform!"))
- else
- victim.visible_message(span_notice("[victim] finishes applying [tape] to [victim.p_their()] [parse_zone(limb.body_zone)], !"), span_green("You finish applying [tape] to your [parse_zone(limb.body_zone)], and you immediately begin to feel your bones start to reform!"))
-
- taped = TRUE
- processes = TRUE
-
-/datum/wound/blunt/treat(obj/item/used_item, mob/user)
- if(istype(used_item, /obj/item/stack/medical/bone_gel))
- gel(used_item, user)
- else if(istype(used_item, /obj/item/stack/sticky_tape/surgical))
- tape(used_item, user)
-
-/datum/wound/blunt/get_scanner_description(mob/user)
- . = ..()
-
- . += "
"
-
- if(!gelled)
- . += "Alternative Treatment: Apply bone gel directly to injured limb, then apply surgical tape to begin bone regeneration. This is both excruciatingly painful and slow, and only recommended in dire circumstances.\n"
- else if(!taped)
- . += span_notice("Continue Alternative Treatment: Apply surgical tape directly to injured limb to begin bone regeneration. Note, this is both excruciatingly painful and slow, though sleep or laying down will speed recovery.\n")
- else
- . += span_notice("Note: Bone regeneration in effect. Bone is [round(regen_ticks_current*100/regen_ticks_needed)]% regenerated.\n")
-
- if(limb.body_zone == BODY_ZONE_HEAD)
- . += "Cranial Trauma Detected: Patient will suffer random bouts of [severity == WOUND_SEVERITY_SEVERE ? "mild" : "severe"] brain traumas until bone is repaired."
- else if(limb.body_zone == BODY_ZONE_CHEST && victim.blood_volume)
- . += "Ribcage Trauma Detected: Further trauma to chest is likely to worsen internal bleeding until bone is repaired."
- . += "
"
-
-/datum/wound/blunt/get_limb_examine_description()
- return span_warning("The bones in this limb appear badly cracked.")
diff --git a/modular_skyrat/modules/medical/code/wounds/burns.dm b/modular_skyrat/modules/medical/code/wounds/burns.dm
deleted file mode 100644
index 45eb0f2b7dc..00000000000
--- a/modular_skyrat/modules/medical/code/wounds/burns.dm
+++ /dev/null
@@ -1,311 +0,0 @@
-
-/*
- Burn wounds
-*/
-
-// TODO: well, a lot really, but specifically I want to add potential fusing of clothing/equipment on the affected area, and limb infections, though those may go in body part code
-/datum/wound/burn
- name = "Burn Wound"
- a_or_from = "from"
- wound_type = WOUND_BURN
- processes = TRUE
- sound_effect = 'sound/effects/wounds/sizzle1.ogg'
- wound_flags = (FLESH_WOUND | ACCEPTS_GAUZE)
-
- treatable_by = list(/obj/item/stack/medical/ointment, /obj/item/stack/medical/mesh) // sterilizer and alcohol will require reagent treatments, coming soon
-
- // Flesh damage vars
- /// How much damage to our flesh we currently have. Once both this and infestation reach 0, the wound is considered healed
- var/flesh_damage = 5
- /// Our current counter for how much flesh regeneration we have stacked from regenerative mesh/synthflesh/whatever, decrements each tick and lowers flesh_damage
- var/flesh_healing = 0
-
- // Infestation vars (only for severe and critical)
- /// How quickly infection breeds on this burn if we don't have disinfectant
- var/infestation_rate = 0
- /// Our current level of infection
- var/infestation = 0
- /// Our current level of sanitization/anti-infection, from disinfectants/alcohol/UV lights. While positive, totally pauses and slowly reverses infestation effects each tick
- var/sanitization = 0
-
- /// Once we reach infestation beyond WOUND_INFESTATION_SEPSIS, we get this many warnings before the limb is completely paralyzed (you'd have to ignore a really bad burn for a really long time for this to happen)
- var/strikes_to_lose_limb = 3
-
-
-/datum/wound/burn/handle_process()
- . = ..()
- if(strikes_to_lose_limb == 0) // we've already hit sepsis, nothing more to do
- victim.adjustToxLoss(0.5)
- if(prob(1))
- victim.visible_message(span_danger("The infection on the remnants of [victim]'s [parse_zone(limb.body_zone)] shift and bubble nauseatingly!"), span_warning("You can feel the infection on the remnants of your [parse_zone(limb.body_zone)] coursing through your veins!"), vision_distance = COMBAT_MESSAGE_RANGE)
- return
-
- if(victim.reagents)
- if(victim.reagents.has_reagent(/datum/reagent/medicine/spaceacillin))
- sanitization += 0.9
- if(victim.reagents.has_reagent(/datum/reagent/space_cleaner/sterilizine))
- sanitization += 0.9
- if(victim.reagents.has_reagent(/datum/reagent/medicine/mine_salve))
- sanitization += 0.3
- flesh_healing += 0.5
-
- var/bandage_factor = 1 // good bandages multiply the length of flesh healing
- if(limb.current_gauze && limb.current_gauze.seep_gauze(WOUND_BURN_SANITIZATION_RATE, GAUZE_STAIN_PUS))
- bandage_factor = limb.current_gauze.sanitisation_factor
-
-
- // if we have little/no infection, the limb doesn't have much burn damage, and our nutrition is good, heal some flesh
- if(infestation <= WOUND_INFECTION_MODERATE && (limb.burn_dam < 5) && (victim.nutrition >= NUTRITION_LEVEL_FED))
- flesh_healing += 0.2
-
- if(flesh_healing > 0)
- flesh_damage = max(0, flesh_damage - 0.5)
- flesh_healing = max(0, flesh_healing - (0.5 * bandage_factor)) // good bandages multiply the length of flesh healing
-
- // here's the check to see if we're cleared up
- if((flesh_damage <= 0) && (infestation <= 1))
- to_chat(victim, span_green("The burns on your [parse_zone(limb.body_zone)] have cleared up!"))
- qdel(src)
- return
-
- // sanitization is checked after the clearing check but before the actual ill-effects, because we freeze the effects of infection while we have sanitization
- if(sanitization > 0)
- infestation = max(0, infestation - WOUND_BURN_SANITIZATION_RATE)
- sanitization = max(0, sanitization - (WOUND_BURN_SANITIZATION_RATE * bandage_factor))
- return
-
- infestation += infestation_rate
-
- switch(infestation)
- if(0 to WOUND_INFECTION_MODERATE)
- if(WOUND_INFECTION_MODERATE to WOUND_INFECTION_SEVERE)
- if(prob(30))
- victim.adjustToxLoss(0.2)
- if(prob(6))
- to_chat(victim, span_warning("The blisters on your [parse_zone(limb.body_zone)] ooze a strange pus..."))
- if(WOUND_INFECTION_SEVERE to WOUND_INFECTION_CRITICAL)
- if(!disabling && prob(2))
- to_chat(victim, span_warning("Your [parse_zone(limb.body_zone)] completely locks up, as you struggle for control against the infection!"))
- set_disabling(TRUE)
- else if(disabling && prob(8))
- to_chat(victim, span_notice("You regain sensation in your [parse_zone(limb.body_zone)], but it's still in terrible shape!"))
- set_disabling(FALSE)
- else if(prob(20))
- victim.adjustToxLoss(0.5)
- if(WOUND_INFECTION_CRITICAL to WOUND_INFECTION_SEPTIC)
- if(!disabling && prob(3))
- to_chat(victim, span_warning("You suddenly lose all sensation of the festering infection in your [parse_zone(limb.body_zone)]!"))
- set_disabling(TRUE)
- else if(disabling && prob(3))
- to_chat(victim, span_notice("You can barely feel your [parse_zone(limb.body_zone)] again, and you have to strain to retain motor control!"))
- set_disabling(FALSE)
- else if(prob(1))
- to_chat(victim, span_warning("You contemplate life without your [parse_zone(limb.body_zone)]..."))
- victim.adjustToxLoss(0.75)
- else if(prob(4))
- victim.adjustToxLoss(1)
- if(WOUND_INFECTION_SEPTIC to INFINITY)
- if(prob(infestation))
- switch(strikes_to_lose_limb)
- if(3 to INFINITY)
- to_chat(victim, span_deadsay("The skin on your [parse_zone(limb.body_zone)] is literally dripping off, you feel awful!"))
- if(2)
- to_chat(victim, span_deadsay("The infection in your [parse_zone(limb.body_zone)] is literally dripping off, you feel horrible!"))
- if(1)
- to_chat(victim, span_deadsay("Infection has just about completely claimed your [parse_zone(limb.body_zone)]!"))
- if(0)
- to_chat(victim, span_deadsay("The last of the nerve endings in your [parse_zone(limb.body_zone)] wither away, as the infection completely paralyzes your joint connector."))
- threshold_penalty = 120 // piss easy to destroy
- var/datum/brain_trauma/severe/paralysis/sepsis = new (limb.body_zone)
- victim.gain_trauma(sepsis)
- strikes_to_lose_limb--
-
-/datum/wound/burn/get_examine_description(mob/user)
- if(strikes_to_lose_limb <= 0)
- return span_deadsay("[victim.p_Their()] [parse_zone(limb.body_zone)] has locked up completely and is non-functional. Amputate or augment limb immediately, or place the patient in a cryotube.")
-
- var/list/condition = list("[victim.p_Their()] [parse_zone(limb.body_zone)] [examine_desc]")
- if(limb.current_gauze)
- var/bandage_condition
- switch(limb.current_gauze.absorption_capacity)
- if(0 to 1.25)
- bandage_condition = "nearly ruined"
- if(1.25 to 2.75)
- bandage_condition = "badly worn"
- if(2.75 to 4)
- bandage_condition = "slightly pus-stained"
- if(4 to INFINITY)
- bandage_condition = "clean"
-
- condition += " underneath a dressing of [bandage_condition] [limb.current_gauze.name]"
- else
- switch(infestation)
- if(WOUND_INFECTION_MODERATE to WOUND_INFECTION_SEVERE)
- condition += ", with small spots of discoloration along the nearby veins!"
- if(WOUND_INFECTION_SEVERE to WOUND_INFECTION_CRITICAL)
- condition += ", with growing clouds of infection."
- if(WOUND_INFECTION_CRITICAL to WOUND_INFECTION_SEPTIC)
- condition += ", with streaks of rotten, pulsating infection!"
- if(WOUND_INFECTION_SEPTIC to INFINITY)
- return span_deadsay("[victim.p_Their()] [parse_zone(limb.body_zone)] is a mess of charred skin and infected rot!")
- else
- condition += "!"
-
- return "[condition.Join()]"
-
-/datum/wound/burn/get_scanner_description(mob/user)
- if(strikes_to_lose_limb == 0)
- var/oopsie = "Type: [name]\nSeverity: [severity_text()]"
- oopsie += "
Infection Level: The bodypart has suffered complete sepsis and must be removed. Amputate or augment limb immediately.
"
- return oopsie
-
- . = ..()
- . += "
"
-
- if(infestation <= sanitization && flesh_damage <= flesh_healing)
- . += "No further treatment required: Burns will heal shortly."
- else
- switch(infestation)
- if(WOUND_INFECTION_MODERATE to WOUND_INFECTION_SEVERE)
- . += "Infection Level: Moderate\n"
- if(WOUND_INFECTION_SEVERE to WOUND_INFECTION_CRITICAL)
- . += "Infection Level: Severe\n"
- if(WOUND_INFECTION_CRITICAL to WOUND_INFECTION_SEPTIC)
- . += "Infection Level: CRITICAL\n"
- if(WOUND_INFECTION_SEPTIC to INFINITY)
- . += "Infection Level: LOSS IMMINENT\n"
- if(infestation > sanitization)
- . += "\tSurgical debridement, antibiotics/sterilizers, or regenerative mesh will rid infection. Paramedic UV penlights are also effective.\n"
-
- if(flesh_damage > 0)
- . += "Flesh damage detected: Application of ointment, regenerative mesh, Synthflesh, or ingestion of \"Miner's Salve\" will repair damaged flesh. Good nutrition, rest, and keeping the wound clean can also slowly repair flesh.\n"
- . += "
"
-
-/datum/wound/burn/get_limb_examine_description()
- return span_warning("The flesh on this limb appears badly cooked.")
-
-/*
- new burn common procs
-*/
-
-/// if someone is using ointment or mesh on our burns
-/datum/wound/burn/proc/ointmentmesh(obj/item/stack/medical/treatment_item, mob/user)
- user.visible_message(span_notice("[user] begins applying [treatment_item] to [victim]'s [parse_zone(limb.body_zone)]..."), span_notice("You begin applying [treatment_item] to [user == victim ? "your" : "[victim]'s"] [parse_zone(limb.body_zone)]..."))
- if(!do_after(user, (user == victim ? treatment_item.self_delay : treatment_item.other_delay), extra_checks = CALLBACK(src, PROC_REF(still_exists))))
- return
-
- limb.heal_damage(treatment_item.heal_brute, treatment_item.heal_burn)
- user.visible_message(span_green("[user] applies [treatment_item] to [victim]."), span_green("You apply [treatment_item] to [user == victim ? "your" : "[victim]'s"] [parse_zone(limb.body_zone)]."))
- treatment_item.use(1)
- sanitization += treatment_item.sanitization
- flesh_healing += treatment_item.flesh_regeneration
-
- if((infestation <= 0 || sanitization >= infestation) && (flesh_damage <= 0 || flesh_healing > flesh_damage))
- to_chat(user, span_notice("You've done all you can with [treatment_item], now you must wait for the flesh on [victim]'s [parse_zone(limb.body_zone)] to recover."))
- else
- try_treating(treatment_item, user)
-
-/// Paramedic UV penlights
-/datum/wound/burn/proc/uv(obj/item/flashlight/pen/paramedic/penlight_used, mob/user)
- if(!COOLDOWN_FINISHED(penlight_used, uv_cooldown))
- to_chat(user, span_notice("[penlight_used] is still recharging!"))
- return
- if(infestation <= 0 || infestation < sanitization)
- to_chat(user, span_notice("There's no infection to treat on [victim]'s [parse_zone(limb.body_zone)]!"))
- return
-
- user.visible_message(span_notice("[user] flashes the burns on [victim]'s [limb] with [penlight_used]."), span_notice("You flash the burns on [user == victim ? "your" : "[victim]'s"] [parse_zone(limb.body_zone)] with [penlight_used]."), vision_distance=COMBAT_MESSAGE_RANGE)
- sanitization += penlight_used.uv_power
- COOLDOWN_START(penlight_used, uv_cooldown, penlight_used.uv_cooldown_length)
-
-/datum/wound/burn/treat(obj/item/treatment_item, mob/user)
- if(istype(treatment_item, /obj/item/stack/medical/ointment))
- ointmentmesh(treatment_item, user)
- else if(istype(treatment_item, /obj/item/stack/medical/mesh))
- var/obj/item/stack/medical/mesh/mesh_check = treatment_item
- if(!mesh_check.is_open)
- to_chat(user, span_warning("You need to open [mesh_check] first."))
- return
- ointmentmesh(mesh_check, user)
- else if(istype(treatment_item, /obj/item/flashlight/pen/paramedic))
- uv(treatment_item, user)
-
-// people complained about burns not healing on stasis beds, so in addition to checking if it's cured, they also get the special ability to very slowly heal on stasis beds if they have the healing effects stored
-/datum/wound/burn/on_stasis()
- . = ..()
- if(flesh_healing > 0)
- flesh_damage = max(0, flesh_damage - 0.2)
- if((flesh_damage <= 0) && (infestation <= WOUND_INFECTION_MODERATE))
- to_chat(victim, span_green("The burns on your [parse_zone(limb.body_zone)] have cleared up!"))
- qdel(src)
- return
- if(sanitization > 0)
- infestation = max(0, infestation - WOUND_BURN_SANITIZATION_RATE * 0.2)
-
-/datum/wound/burn/on_synthflesh(amount)
- flesh_healing += amount * 0.5 // 20u patch will heal 10 flesh standard
-
-// we don't even care about first degree burns, straight to second
-/datum/wound/burn/moderate
- name = "Second Degree Burns"
- desc = "Patient is suffering considerable burns with mild skin penetration, weakening limb integrity and increased burning sensations."
- treat_text = "Recommended application of topical ointment or regenerative mesh to affected region."
- examine_desc = "is badly burned and breaking out in blisters"
- occur_text = "breaks out with violent red burns"
- severity = WOUND_SEVERITY_MODERATE
- damage_mulitplier_penalty = 1.1
- threshold_minimum = 40
- threshold_penalty = 30 // burns cause significant decrease in limb integrity compared to other wounds
- status_effect_type = /datum/status_effect/wound/burn/moderate
- flesh_damage = 5
- scar_keyword = "burnmoderate"
-
-/datum/wound/burn/severe
- name = "Third Degree Burns"
- desc = "Patient is suffering extreme burns with full skin penetration, creating serious risk of infection and greatly reduced limb integrity."
- treat_text = "Recommended immediate disinfection and excision of any infected skin, followed by bandaging and ointment. If the limb has locked up, it must be amputated, augmented or treated with cryogenics."
- examine_desc = "appears seriously charred, with aggressive red splotches"
- occur_text = "chars rapidly, exposing ruined tissue and spreading angry red burns"
- severity = WOUND_SEVERITY_SEVERE
- damage_mulitplier_penalty = 1.2
- threshold_minimum = 80
- threshold_penalty = 40
- status_effect_type = /datum/status_effect/wound/burn/severe
- treatable_by = list(/obj/item/flashlight/pen/paramedic, /obj/item/stack/medical/ointment, /obj/item/stack/medical/mesh)
- infestation_rate = 0.05 // appx 13 minutes to reach sepsis without any treatment
- flesh_damage = 12.5
- scar_keyword = "burnsevere"
-
-/datum/wound/burn/critical
- name = "Catastrophic Burns"
- desc = "Patient is suffering near complete loss of tissue and significantly charred muscle and bone, creating life-threatening risk of infection and negligible limb integrity."
- treat_text = "Immediate surgical debriding of any infected skin, followed by potent tissue regeneration formula and bandaging. If the limb has locked up, it must be amputated, augmented or treated with cryogenics."
- examine_desc = "is a ruined mess of blanched bone, melted fat, and charred tissue"
- occur_text = "vaporizes as flesh, bone, and fat melt together in a horrifying mess"
- severity = WOUND_SEVERITY_CRITICAL
- damage_mulitplier_penalty = 1.3
- sound_effect = 'sound/effects/wounds/sizzle2.ogg'
- threshold_minimum = 140
- threshold_penalty = 80
- status_effect_type = /datum/status_effect/wound/burn/critical
- treatable_by = list(/obj/item/flashlight/pen/paramedic, /obj/item/stack/medical/ointment, /obj/item/stack/medical/mesh)
- infestation_rate = 0.15 // appx 4.33 minutes to reach sepsis without any treatment
- flesh_damage = 20
- scar_keyword = "burncritical"
-
-///special severe wound caused by sparring interference or other god related punishments.
-/datum/wound/burn/severe/brand
- name = "Holy Brand"
- desc = "Patient is suffering extreme burns from a strange brand marking, creating serious risk of infection and greatly reduced limb integrity."
- examine_desc = "appears to have holy symbols painfully branded into their flesh, leaving severe burns."
- occur_text = "chars rapidly into a strange pattern of holy symbols, burned into the flesh."
-
-/// special severe wound caused by the cursed slot machine.
-/datum/wound/burn/severe/cursed_brand
- name = "Ancient Brand"
- desc = "Patient is suffering extreme burns with oddly ornate brand markings, creating serious risk of infection and greatly reduced limb integrity."
- examine_desc = "appears to have ornate symbols painfully branded into their flesh, leaving severe burns"
- occur_text = "chars rapidly into a pattern that can only be described as an agglomeration of several financial symbols, burned into the flesh"
-
-/datum/wound/burn/severe/cursed_brand/get_limb_examine_description()
- return span_warning("The flesh on this limb has several ornate symbols burned into it, with pitting throughout.")
diff --git a/modular_skyrat/modules/medical/code/wounds/medical.dm b/modular_skyrat/modules/medical/code/wounds/medical.dm
new file mode 100644
index 00000000000..80662956e5f
--- /dev/null
+++ b/modular_skyrat/modules/medical/code/wounds/medical.dm
@@ -0,0 +1,147 @@
+#define SELF_AID_REMOVE_DELAY 5 SECONDS
+#define OTHER_AID_REMOVE_DELAY 2 SECONDS
+
+/obj/item/stack/medical/gauze
+ /// The amount of direct hits our limb can take before we fall off.
+ var/integrity = 2
+ /// The bodypart we are attached to. Nullable if we aren't applied to anything.
+ var/obj/item/bodypart/bodypart
+ /// If we are splinting a limb, this is the overlay prefix we will use.
+ var/splint_prefix = "splint"
+ /// If we are bandaging a limb, this is the overlay prefix we will use.
+ var/gauze_prefix = "gauze"
+ /// If it is at all possible for us to splint a limb.
+ var/can_splint = TRUE
+
+/obj/item/bodypart/apply_gauze(obj/item/stack/gauze)
+ RegisterSignal(src, COMSIG_BODYPART_GAUZED, PROC_REF(got_gauzed))
+
+ . = ..()
+
+ UnregisterSignal(src, COMSIG_BODYPART_GAUZED)
+
+/// Signal handler that allows us to modularly detect if we were applied to a limb or not.
+/obj/item/bodypart/proc/got_gauzed(datum/signal_source, obj/item/stack/medical/gauze/new_gauze)
+ SIGNAL_HANDLER
+
+ if (istype(current_gauze, /obj/item/stack/medical/gauze))
+ var/obj/item/stack/medical/gauze/applied_gauze = current_gauze
+ applied_gauze.set_limb(src) // new_gauze isnt actually the gauze that was applied weirdly
+
+/obj/item/stack/medical/gauze/Destroy()
+ bodypart?.current_gauze = null
+ bodypart?.owner?.update_bandage_overlays()
+ set_limb(null)
+ return ..()
+
+/**
+ * rip_off() called when someone rips it off
+ *
+ * It will return the bandage if it's considered pristine
+ *
+ */
+/obj/item/stack/medical/gauze/proc/rip_off()
+ if (is_pristine())
+ . = new src.type(null, 1)
+ bodypart?.owner?.update_bandage_overlays()
+ qdel(src)
+
+/// Returns either [splint_prefix] or [gauze_prefix] depending on if we are splinting or not. Suffixes it with a digitigrade flag if applicable for the limb.
+/obj/item/stack/medical/gauze/proc/get_overlay_prefix()
+ var/splinting = is_splinting()
+
+ var/prefix
+ if (splinting)
+ prefix = splint_prefix
+ else
+ prefix = gauze_prefix
+
+ var/suffix = bodypart.body_zone
+ if(bodypart.bodytype & BODYTYPE_DIGITIGRADE)
+ suffix += "_digitigrade"
+
+ return "[prefix]_[suffix]"
+
+/// Returns if we can splint, and if any wound on our bodypart gives a splint overlay.
+/obj/item/stack/medical/gauze/proc/is_splinting()
+ SHOULD_BE_PURE(TRUE)
+
+ if (!can_splint)
+ return FALSE
+
+ for (var/datum/wound/iterated_wound as anything in bodypart.wounds)
+ if (iterated_wound.wound_flags & SPLINT_OVERLAY)
+ return TRUE
+
+ return FALSE
+
+/**
+ * is_pristine() called by rip_off()
+ *
+ * Used to determine whether the bandage can be re-used and won't qdel itself
+ *
+ */
+
+/obj/item/stack/medical/gauze/proc/is_pristine()
+ return (integrity == initial(integrity))
+
+/**
+ * get_hit() called when the bandage gets damaged
+ *
+ * This proc will subtract integrity and delete the bandage with a to_chat message to whoever was bandaged
+ *
+ */
+
+/obj/item/stack/medical/gauze/proc/get_hit()
+ integrity--
+ if(integrity <= 0)
+ if(bodypart.owner)
+ to_chat(bodypart.owner, span_warning("The [name] on your [bodypart.name] tears and falls off!"))
+ qdel(src)
+
+/obj/item/stack/medical/gauze/Topic(href, href_list)
+ . = ..()
+ if(href_list["remove"])
+ if(!bodypart.owner)
+ return
+ if(!iscarbon(usr))
+ return
+ if(!in_range(usr, bodypart.owner))
+ return
+ var/mob/living/carbon/C = usr
+ var/self = (C == bodypart.owner)
+ C.visible_message(span_notice("[C] begins removing [name] from [self ? "[bodypart.owner.p_Their()]" : "[bodypart.owner]'s" ] [bodypart.name]..."), span_notice("You begin to remove [name] from [self ? "your" : "[bodypart.owner]'s"] [bodypart.name]..."))
+ if(!do_after(C, (self ? SELF_AID_REMOVE_DELAY : OTHER_AID_REMOVE_DELAY), target=bodypart.owner))
+ return
+ if(QDELETED(src))
+ return
+ C.visible_message(span_notice("[C] removes [name] from [self ? "[bodypart.owner.p_Their()]" : "[bodypart.owner]'s" ] [bodypart.name]."), span_notice("You remove [name] from [self ? "your" : "[bodypart.owner]'s" ] [bodypart.name]."))
+ var/obj/item/gotten = rip_off()
+ if(gotten && !C.put_in_hands(gotten))
+ gotten.forceMove(get_turf(C))
+
+/// Sets bodypart to limb, and then updates owner's bandage overlays. Limb is nullable.
+/obj/item/stack/medical/gauze/proc/set_limb(limb)
+ bodypart = limb
+ bodypart?.owner?.update_bandage_overlays()
+
+/// Returns the name of ourself when used in a "owner is [usage_prefix] by [name]" examine_more situation/
+/obj/item/stack/proc/get_gauze_description()
+ return "[name]"
+
+/// Returns the usage prefix of ourself when used in a "owner is [usage_prefix] by [name]" examine_more situation/
+/obj/item/stack/proc/get_gauze_usage_prefix()
+ return "bandaged"
+
+/obj/item/stack/medical/gauze/get_gauze_usage_prefix()
+ if (is_splinting())
+ return "fastened"
+ else
+ return ..()
+
+/// Returns TRUE if we can generate an overlay, false otherwise.
+/obj/item/stack/medical/gauze/proc/has_overlay()
+ return (!isnull(gauze_prefix) && !isnull(splint_prefix))
+
+/obj/item/stack/medical/gauze/improvised
+ splint_prefix = "splint_improv"
diff --git a/modular_skyrat/modules/medical/code/wounds/muscle.dm b/modular_skyrat/modules/medical/code/wounds/muscle.dm
index 2090da83bb8..c1f9c3fc4c3 100644
--- a/modular_skyrat/modules/medical/code/wounds/muscle.dm
+++ b/modular_skyrat/modules/medical/code/wounds/muscle.dm
@@ -6,23 +6,33 @@
/datum/wound/muscle
name = "Muscle Wound"
sound_effect = 'sound/effects/wounds/blood1.ogg'
- wound_type = WOUND_MUSCLE
- wound_flags = (FLESH_WOUND | ACCEPTS_SPLINT)
- viable_zones = list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
+ wound_flags = (ACCEPTS_GAUZE | SPLINT_OVERLAY)
+
processes = TRUE
/// How much do we need to regen. Will regen faster if we're splinted and or laying down
var/regen_ticks_needed
/// Our current counter for healing
var/regen_ticks_current = 0
+ can_scar = FALSE
+
+/datum/wound_pregen_data/muscle
+ abstract = TRUE
+
+ viable_zones = list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
+ required_limb_biostate = BIO_FLESH
+
+ required_wounding_types = list(WOUND_BLUNT, WOUND_SLASH, WOUND_PIERCE)
+ match_all_wounding_types = FALSE
+
+ wound_series = WOUND_SERIES_MUSCLE_DAMAGE
+
+ weight = 3 // very low chance to replace a normal wound. this is about 4.5%
+
/*
Overwriting of base procs
*/
/datum/wound/muscle/wound_injury(datum/wound/old_wound = null, attack_direction)
- // hook into gaining/losing gauze so crit muscle wounds can re-enable/disable depending if they're slung or not
- RegisterSignals(limb, list(COMSIG_BODYPART_SPLINTED, COMSIG_BODYPART_SPLINT_DESTROYED), PROC_REF(update_inefficiencies))
-
- RegisterSignal(victim, COMSIG_HUMAN_EARLY_UNARMED_ATTACK, PROC_REF(attack_with_hurt_hand))
if(limb.held_index && victim.get_item_for_held_index(limb.held_index) && (disabling || prob(30 * severity)))
var/obj/item/I = victim.get_item_for_held_index(limb.held_index)
if(istype(I, /obj/item/offhand))
@@ -31,14 +41,19 @@
if(I && victim.dropItemToGround(I))
victim.visible_message(span_danger("[victim] drops [I] in shock!"), span_warning("The force on your [parse_zone(limb.body_zone)] causes you to drop [I]!"), vision_distance=COMBAT_MESSAGE_RANGE)
- update_inefficiencies()
+ return ..()
+
+/datum/wound/muscle/set_victim(new_victim)
+ if (victim)
+ UnregisterSignal(victim, COMSIG_HUMAN_EARLY_UNARMED_ATTACK)
+
+ if (new_victim)
+ RegisterSignal(new_victim, COMSIG_HUMAN_EARLY_UNARMED_ATTACK, PROC_REF(attack_with_hurt_hand))
+
+ return ..()
/datum/wound/muscle/remove_wound(ignore_limb, replaced)
limp_slowdown = 0
- if(limb)
- UnregisterSignal(limb, list(COMSIG_BODYPART_GAUZED, COMSIG_BODYPART_GAUZE_DESTROYED))
- if(victim)
- UnregisterSignal(victim, COMSIG_HUMAN_EARLY_UNARMED_ATTACK)
return ..()
/datum/wound/muscle/handle_process()
@@ -51,8 +66,8 @@
if(victim.IsSleeping())
regen_ticks_current += 0.5
- if(limb.current_splint)
- regen_ticks_current += (1-limb.current_splint.splint_factor)
+ if(limb.current_gauze)
+ regen_ticks_current += (1-limb.current_gauze.splint_factor)
if(regen_ticks_current > regen_ticks_needed)
if(!victim || !limb)
@@ -83,70 +98,50 @@
return COMPONENT_CANCEL_ATTACK_CHAIN
/datum/wound/muscle/get_examine_description(mob/user)
- if(!limb.current_splint)
+ if(!limb.current_gauze)
return ..()
var/list/msg = list()
- if(!limb.current_splint)
+ if(!limb.current_gauze)
msg += "[victim.p_Their()] [parse_zone(limb.body_zone)] [examine_desc]"
else
- var/sling_condition = ""
+ var/absorption_capacity = ""
// how much life we have left in these bandages
- switch(limb.current_splint.sling_condition)
+ switch(limb.current_gauze.absorption_capacity)
if(0 to 1.25)
- sling_condition = "just barely"
+ absorption_capacity = "just barely"
if(1.25 to 2.75)
- sling_condition = "loosely"
+ absorption_capacity = "loosely"
if(2.75 to 4)
- sling_condition = "mostly"
+ absorption_capacity = "mostly"
if(4 to INFINITY)
- sling_condition = "tightly"
+ absorption_capacity = "tightly"
- msg += "[victim.p_Their()] [parse_zone(limb.body_zone)] is [sling_condition] fastened with a [limb.current_splint.name]!"
+ msg += "[victim.p_Their()] [parse_zone(limb.body_zone)] is [absorption_capacity] fastened with a [limb.current_gauze.name]!"
return "[msg.Join()]"
-/*
- Common procs mostly copied from bone wounds, as their behaviour is very similar
-*/
-
-/datum/wound/muscle/proc/update_inefficiencies()
- SIGNAL_HANDLER
- if(limb.body_zone in list(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
- if(limb.current_splint)
- limp_slowdown = initial(limp_slowdown) * limb.current_splint.splint_factor
- else
- limp_slowdown = initial(limp_slowdown)
- victim.apply_status_effect(/datum/status_effect/limp)
- else if(limb.body_zone in list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM))
- if(limb.current_splint)
- interaction_efficiency_penalty = 1 + ((interaction_efficiency_penalty - 1) * limb.current_splint.splint_factor)
- else
- interaction_efficiency_penalty = interaction_efficiency_penalty
-
- if(initial(disabling))
- if(limb.current_splint && limb.current_splint.helps_disabled)
- set_disabling(FALSE)
- else
- set_disabling(TRUE)
-
- limb.update_wounds()
-
/// Moderate (Muscle Tear)
/datum/wound/muscle/moderate
name = "Muscle Tear"
desc = "Patient's muscle has torn, causing serious pain and reduced limb functionality."
- treat_text = "Recommended rest and sleep, or splinting the limb."
+ treat_text = "A tight splint on the affected limb, as well as plenty of rest and sleep."
examine_desc = "appears unnaturallly red and swollen"
occur_text = "swells up, it's skin turning red"
severity = WOUND_SEVERITY_MODERATE
interaction_efficiency_penalty = 1.5
limp_slowdown = 2
- threshold_minimum = 35
+ limp_chance = 30
threshold_penalty = 15
status_effect_type = /datum/status_effect/wound/muscle/moderate
regen_ticks_needed = 90
+/datum/wound_pregen_data/muscle/tear
+ abstract = FALSE
+
+ wound_path_to_generate = /datum/wound/muscle/moderate
+ threshold_minimum = 35
+
/*
Severe (Ruptured Tendon)
*/
@@ -155,53 +150,26 @@
name = "Ruptured Tendon"
sound_effect = 'sound/effects/wounds/blood2.ogg'
desc = "Patient's tendon has been severed, causing significant pain and near uselessness of limb."
- treat_text = "Recommended rest and sleep aswell as splinting the limb."
+ treat_text = "A tight splint on the affected limb, as well as plenty of rest and sleep."
examine_desc = "is limp and awkwardly twitching, skin swollen and red"
occur_text = "twists in pain and goes limp, it's tendon ruptured"
severity = WOUND_SEVERITY_SEVERE
interaction_efficiency_penalty = 2
limp_slowdown = 5
- threshold_minimum = 80
+ limp_chance = 40
threshold_penalty = 35
disabling = TRUE
status_effect_type = /datum/status_effect/wound/muscle/severe
regen_ticks_needed = 150
-/datum/status_effect/wound/muscle
+/datum/wound_pregen_data/muscle/tendon
+ abstract = FALSE
-/datum/status_effect/wound/muscle/on_apply()
- . = ..()
- RegisterSignal(owner, COMSIG_MOB_SWAP_HANDS, PROC_REF(on_swap_hands))
- on_swap_hands()
-
-/datum/status_effect/wound/muscle/on_remove()
- . = ..()
- UnregisterSignal(owner, COMSIG_MOB_SWAP_HANDS)
- var/mob/living/carbon/wound_owner = owner
- wound_owner.remove_actionspeed_modifier(/datum/actionspeed_modifier/muscle_wound)
-
-/datum/status_effect/wound/muscle/proc/on_swap_hands()
- SIGNAL_HANDLER
-
- var/mob/living/carbon/wound_owner = owner
- if(wound_owner.get_active_hand() == linked_limb)
- wound_owner.add_actionspeed_modifier(/datum/actionspeed_modifier/muscle_wound, (linked_wound.interaction_efficiency_penalty - 1))
- else
- wound_owner.remove_actionspeed_modifier(/datum/actionspeed_modifier/muscle_wound)
-
-/datum/status_effect/wound/muscle/nextmove_modifier()
- var/mob/living/carbon/C = owner
-
- if(C.get_active_hand() == linked_limb)
- return linked_wound.interaction_efficiency_penalty
-
- return 1
+ wound_path_to_generate = /datum/wound/muscle/severe
+ threshold_minimum = 80
// muscle
/datum/status_effect/wound/muscle/moderate
id = "torn muscle"
/datum/status_effect/wound/muscle/severe
id = "ruptured tendon"
-
-/datum/actionspeed_modifier/muscle_wound
- variable = TRUE
diff --git a/modular_skyrat/modules/medical/code/wounds/pierce.dm b/modular_skyrat/modules/medical/code/wounds/pierce.dm
deleted file mode 100644
index c41855402d0..00000000000
--- a/modular_skyrat/modules/medical/code/wounds/pierce.dm
+++ /dev/null
@@ -1,198 +0,0 @@
-
-/*
- Piercing wounds
-*/
-
-/datum/wound/pierce
- name = "Piercing Wound"
- sound_effect = 'sound/weapons/slice.ogg'
- processes = TRUE
- wound_type = WOUND_PIERCE
- treatable_by = list(/obj/item/stack/medical/suture)
- treatable_tool = TOOL_CAUTERY
- base_treat_time = 3 SECONDS
- wound_flags = (FLESH_WOUND | ACCEPTS_GAUZE)
-
- /// How much blood we start losing when this wound is first applied
- var/initial_flow
- /// If gauzed, what percent of the internal bleeding actually clots of the total absorption rate
- var/gauzed_clot_rate
-
- /// When hit on this bodypart, we have this chance of losing some blood + the incoming damage
- var/internal_bleeding_chance
- /// If we let off blood when hit, the max blood lost is this * the incoming damage
- var/internal_bleeding_coefficient
-
-/datum/wound/slash/show_wound_topic(mob/user)
- return (user == victim && blood_flow)
-
-/datum/wound/slash/Topic(href, href_list)
- . = ..()
- if(href_list["wound_topic"])
- if(!usr == victim)
- return
- victim.self_grasp_bleeding_limb(limb)
-
-/datum/wound/pierce/wound_injury(datum/wound/old_wound, attack_direction)
- set_blood_flow(initial_flow)
-
-/datum/wound/pierce/receive_damage(wounding_type, wounding_dmg, wound_bonus)
- if(victim.stat == DEAD || wounding_dmg < 5)
- return
- if(victim.blood_volume && prob(internal_bleeding_chance + wounding_dmg))
- if(limb.current_splint && limb.current_splint.splint_factor)
- wounding_dmg *= (1 - limb.current_splint.splint_factor)
- var/blood_bled = rand(1, wounding_dmg * internal_bleeding_coefficient) // 12 brute toolbox can cause up to 15/18/21 bloodloss on mod/sev/crit
- switch(blood_bled)
- if(1 to 6)
- victim.bleed(blood_bled, TRUE)
- if(7 to 13)
- victim.visible_message(span_smalldanger("Blood droplets fly from the hole in [victim]'s [parse_zone(limb.body_zone)]."), span_danger("You cough up a bit of blood from the blow to your [parse_zone(limb.body_zone)]."), vision_distance=COMBAT_MESSAGE_RANGE)
- victim.bleed(blood_bled, TRUE)
- if(14 to 19)
- victim.visible_message(span_smalldanger("A small stream of blood spurts from the hole in [victim]'s [parse_zone(limb.body_zone)]!"), span_danger("You spit out a string of blood from the blow to your [parse_zone(limb.body_zone)]!"), vision_distance=COMBAT_MESSAGE_RANGE)
- new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir)
- victim.bleed(blood_bled)
- if(20 to INFINITY)
- victim.visible_message(span_danger("A spray of blood streams from the gash in [victim]'s [parse_zone(limb.body_zone)]!"), span_danger("You choke up on a spray of blood from the blow to your [parse_zone(limb.body_zone)]!"), vision_distance=COMBAT_MESSAGE_RANGE)
- victim.bleed(blood_bled)
- new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir)
- victim.add_splatter_floor(get_step(victim.loc, victim.dir))
-
-/datum/wound/pierce/get_bleed_rate_of_change()
- if(HAS_TRAIT(victim, TRAIT_BLOODY_MESS))
- return BLOOD_FLOW_INCREASING
- if(limb.current_gauze)
- return BLOOD_FLOW_DECREASING
- return BLOOD_FLOW_STEADY
-
-/datum/wound/pierce/handle_process()
- set_blood_flow(min(blood_flow, WOUND_SLASH_MAX_BLOODFLOW))
-
- if(victim.bodytemperature < (BODYTEMP_NORMAL - 10))
- adjust_blood_flow(-0.2)
- if(prob(5))
- to_chat(victim, span_notice("You feel the [lowertext(name)] in your [parse_zone(limb.body_zone)] firming up from the cold!"))
-
- if(HAS_TRAIT(victim, TRAIT_BLOODY_MESS))
- adjust_blood_flow(0.5) // old heparin used to just add +2 bleed stacks per tick, this adds 0.5 bleed flow to all open cuts which is probably even stronger as long as you can cut them first
-
- if(limb.current_gauze && limb.current_gauze.seep_gauze(limb.current_gauze.absorption_rate, GAUZE_STAIN_BLOOD))
- adjust_blood_flow(-(limb.current_gauze.absorption_rate * gauzed_clot_rate))
-
- if(blood_flow <= 0)
- qdel(src)
-
-/datum/wound/pierce/on_stasis()
- . = ..()
- if(blood_flow <= 0)
- qdel(src)
-
-/datum/wound/pierce/check_grab_treatments(obj/item/I, mob/user)
- if(I.get_temperature()) // if we're using something hot but not a cautery, we need to be aggro grabbing them first, so we don't try treating someone we're eswording
- return TRUE
-
-/datum/wound/pierce/treat(obj/item/treatment_item, mob/user)
- if(istype(treatment_item, /obj/item/stack/medical/suture))
- suture(treatment_item, user)
- else if(treatment_item.tool_behaviour == TOOL_CAUTERY || treatment_item.get_temperature())
- tool_cauterize(treatment_item, user)
-
-/datum/wound/pierce/on_xadone(power)
- . = ..()
- adjust_blood_flow(-(0.03 * power)) // i think it's like a minimum of 3 power, so .09 blood_flow reduction per tick is pretty good for 0 effort
-
-/datum/wound/pierce/on_synthflesh(power)
- . = ..()
- adjust_blood_flow(-(0.05 * power)) // 20u * 0.05 = -1 blood flow, less than with slashes but still good considering smaller bleed rates
-
-/// If someone is using a suture to close this puncture
-/datum/wound/pierce/proc/suture(obj/item/stack/medical/suture/used_suture, mob/user)
- var/self_penalty_mult = (user == victim ? 1.4 : 1)
- user.visible_message(span_notice("[user] begins stitching [victim]'s [parse_zone(limb.body_zone)] with [used_suture]..."), span_notice("You begin stitching [user == victim ? "your" : "[victim]'s"] [parse_zone(limb.body_zone)] with [used_suture]..."))
- if(!do_after(user, base_treat_time * self_penalty_mult, target=victim, extra_checks = CALLBACK(src, PROC_REF(still_exists))))
- return
- user.visible_message(span_green("[user] stitches up some of the bleeding on [victim]."), span_green("You stitch up some of the bleeding on [user == victim ? "yourself" : "[victim]"]."))
- var/blood_sutured = used_suture.stop_bleeding / self_penalty_mult
- adjust_blood_flow(-blood_sutured)
- limb.heal_damage(used_suture.heal_brute, used_suture.heal_burn)
- used_suture.use(1)
-
- if(blood_flow > 0)
- try_treating(used_suture, user)
- else
- to_chat(user, span_green("You successfully close the hole in [user == victim ? "your" : "[victim]'s"] [parse_zone(limb.body_zone)]."))
-
-/// If someone is using either a cautery tool or something with heat to cauterize this pierce
-/datum/wound/pierce/proc/tool_cauterize(obj/item/used_cautery, mob/user)
- var/improv_penalty_mult = (used_cautery.tool_behaviour == TOOL_CAUTERY ? 1 : 1.25) // 25% longer and less effective if you don't use a real cautery
- var/self_penalty_mult = (user == victim ? 1.5 : 1) // 50% longer and less effective if you do it to yourself
-
- user.visible_message(span_danger("[user] begins cauterizing [victim]'s [parse_zone(limb.body_zone)] with [used_cautery]..."), span_warning("You begin cauterizing [user == victim ? "your" : "[victim]'s"] [parse_zone(limb.body_zone)] with [used_cautery]..."))
- if(!do_after(user, base_treat_time * self_penalty_mult * improv_penalty_mult, target=victim, extra_checks = CALLBACK(src, PROC_REF(still_exists))))
- return
-
- user.visible_message(span_green("[user] cauterizes some of the bleeding on [victim]."), span_green("You cauterize some of the bleeding on [victim]."))
- limb.receive_damage(burn = 2 + severity, wound_bonus = CANT_WOUND)
- if(prob(30))
- victim.emote("scream")
- var/blood_cauterized = (0.6 / (self_penalty_mult * improv_penalty_mult))
- adjust_blood_flow(-blood_cauterized)
-
- if(blood_flow > 0)
- try_treating(used_cautery, user)
-
-/datum/wound/pierce/moderate
- name = "Minor Breakage"
- desc = "Patient's skin has been broken open, causing severe bruising and minor internal bleeding in affected area."
- treat_text = "Treat affected site with bandaging or exposure to extreme cold. In dire cases, brief exposure to vacuum may suffice." // space is cold in ss13, so it's like an ice pack!
- examine_desc = "has a small, circular hole, gently bleeding"
- occur_text = "spurts out a thin stream of blood"
- sound_effect = 'sound/effects/wounds/pierce1.ogg'
- severity = WOUND_SEVERITY_MODERATE
- initial_flow = 1.5
- gauzed_clot_rate = 0.8
- internal_bleeding_chance = 30
- internal_bleeding_coefficient = 1.25
- threshold_minimum = 30
- threshold_penalty = 20
- status_effect_type = /datum/status_effect/wound/pierce/moderate
- scar_keyword = "piercemoderate"
-
-/datum/wound/pierce/severe
- name = "Open Puncture"
- desc = "Patient's internal tissue is penetrated, causing sizeable internal bleeding and reduced limb stability."
- treat_text = "Repair punctures in skin by suture or cautery, extreme cold may also work."
- examine_desc = "is pierced clear through, with bits of tissue obscuring the open hole"
- occur_text = "looses a violent spray of blood, revealing a pierced wound"
- sound_effect = 'sound/effects/wounds/pierce2.ogg'
- severity = WOUND_SEVERITY_SEVERE
- initial_flow = 2.25
- gauzed_clot_rate = 0.6
- internal_bleeding_chance = 60
- internal_bleeding_coefficient = 1.5
- threshold_minimum = 50
- threshold_penalty = 35
- status_effect_type = /datum/status_effect/wound/pierce/severe
- scar_keyword = "piercesevere"
-
-/datum/wound/pierce/critical
- name = "Ruptured Cavity"
- desc = "Patient's internal tissue and circulatory system is shredded, causing significant internal bleeding and damage to internal organs."
- treat_text = "Surgical repair of puncture wound, followed by supervised resanguination."
- examine_desc = "is ripped clear through, barely held together by exposed bone"
- occur_text = "blasts apart, sending chunks of viscera flying in all directions"
- sound_effect = 'sound/effects/wounds/pierce3.ogg'
- severity = WOUND_SEVERITY_CRITICAL
- initial_flow = 3
- gauzed_clot_rate = 0.4
- internal_bleeding_chance = 80
- internal_bleeding_coefficient = 1.75
- threshold_minimum = 100
- threshold_penalty = 50
- status_effect_type = /datum/status_effect/wound/pierce/critical
- scar_keyword = "piercecritical"
- wound_flags = (FLESH_WOUND | ACCEPTS_GAUZE | MANGLES_FLESH)
-
-/datum/wound/pierce/get_limb_examine_description()
- return span_warning("The flesh on this limb appears badly perforated.")
diff --git a/modular_skyrat/modules/medical/code/wounds/slash.dm b/modular_skyrat/modules/medical/code/wounds/slash.dm
deleted file mode 100644
index 345381ac503..00000000000
--- a/modular_skyrat/modules/medical/code/wounds/slash.dm
+++ /dev/null
@@ -1,324 +0,0 @@
-
-/*
- Slashing wounds
-*/
-
-/datum/wound/slash
- name = "Slashing (Cut) Wound"
- sound_effect = 'sound/weapons/slice.ogg'
- processes = TRUE
- wound_type = WOUND_SLASH
- treatable_by = list(/obj/item/stack/medical/suture)
- treatable_by_grabbed = list(/obj/item/gun/energy/laser)
- treatable_tool = TOOL_CAUTERY
- base_treat_time = 3 SECONDS
- wound_flags = (FLESH_WOUND | ACCEPTS_GAUZE)
-
- /// How much blood we start losing when this wound is first applied
- var/initial_flow
- /// When we have less than this amount of flow, either from treatment or clotting, we demote to a lower cut or are healed of the wound
- var/minimum_flow
- /// How much our blood_flow will naturally decrease per second, not only do larger cuts bleed more blood faster, they clot slower (higher number = clot quicker, negative = opening up)
- var/clot_rate
-
- /// Once the blood flow drops below minimum_flow, we demote it to this type of wound. If there's none, we're all better
- var/demotes_to
-
- /// The maximum flow we've had so far
- var/highest_flow
-
- /// A bad system I'm using to track the worst scar we earned (since we can demote, we want the biggest our wound has been, not what it was when it was cured (probably moderate))
- var/datum/scar/highest_scar
-
-/datum/wound/slash/show_wound_topic(mob/user)
- return (user == victim && blood_flow)
-
-/datum/wound/slash/Topic(href, href_list)
- . = ..()
- if(href_list["wound_topic"])
- if(!usr == victim)
- return
- victim.self_grasp_bleeding_limb(limb)
-
-/datum/wound/slash/wound_injury(datum/wound/slash/old_wound = null, attack_direction)
- if(old_wound)
- set_blood_flow(max(old_wound.blood_flow, initial_flow))
- if(old_wound.severity > severity && old_wound.highest_scar)
- highest_scar = old_wound.highest_scar
- old_wound.highest_scar = null
- else
- set_blood_flow(initial_flow)
- if(attack_direction && victim.blood_volume > BLOOD_VOLUME_OKAY)
- victim.spray_blood(attack_direction, severity)
-
- if(!highest_scar)
- highest_scar = new
- highest_scar.generate(limb, src, add_to_scars=FALSE)
-
-/datum/wound/slash/remove_wound(ignore_limb, replaced)
- if(!replaced && highest_scar)
- already_scarred = TRUE
- highest_scar.lazy_attach(limb)
- return ..()
-
-/datum/wound/slash/get_examine_description(mob/user)
- if(!limb.current_gauze)
- return ..()
-
- var/list/msg = list("The cuts on [victim.p_their()] [parse_zone(limb.body_zone)] are wrapped with ")
- // how much life we have left in these bandages
- switch(limb.current_gauze.absorption_capacity)
- if(0 to 1.25)
- msg += "nearly ruined"
- if(1.25 to 2.75)
- msg += "badly worn"
- if(2.75 to 4)
- msg += "slightly bloodied"
- if(4 to INFINITY)
- msg += "clean"
- msg += " [limb.current_gauze.name]!"
-
- return "[msg.Join()]"
-
-/datum/wound/slash/receive_damage(wounding_type, wounding_dmg, wound_bonus)
- if(victim.stat != DEAD && wound_bonus != CANT_WOUND && wounding_type == WOUND_SLASH) // can't stab dead bodies to make it bleed faster this way
- adjust_blood_flow(WOUND_SLASH_DAMAGE_FLOW_COEFF * wounding_dmg)
-
-/datum/wound/slash/drag_bleed_amount()
- // say we have 3 severe cuts with 3 blood flow each, pretty reasonable
- // compare with being at 100 brute damage before, where you bled (brute/100 * 2), = 2 blood per tile
- var/bleed_amt = min(blood_flow * 0.1, 1) // 3 * 3 * 0.1 = 0.9 blood total, less than before! the share here is .3 blood of course.
-
- if(limb.current_gauze && limb.current_gauze.seep_gauze(bleed_amt * 0.33, GAUZE_STAIN_BLOOD)) // gauze stops all bleeding from dragging on this limb, but wears the gauze out quicker
- return 0
-
- return bleed_amt
-
-/datum/wound/slash/get_bleed_rate_of_change()
- if(HAS_TRAIT(victim, TRAIT_BLOODY_MESS))
- return BLOOD_FLOW_INCREASING
- if(limb.current_gauze || clot_rate > 0)
- return BLOOD_FLOW_DECREASING
- if(clot_rate < 0)
- return BLOOD_FLOW_INCREASING
-
-/datum/wound/slash/handle_process()
- set_blood_flow(min(blood_flow, WOUND_SLASH_MAX_BLOODFLOW))
-
- if(HAS_TRAIT(victim, TRAIT_BLOODY_MESS))
- adjust_blood_flow(0.5) // old heparin used to just add +2 bleed stacks per tick, this adds 0.5 bleed flow to all open cuts which is probably even stronger as long as you can cut them first
-
- if(limb.current_gauze)
- if(clot_rate > 0)
- adjust_blood_flow(-clot_rate)
- if(limb.current_gauze && limb.current_gauze.seep_gauze(limb.current_gauze.absorption_rate, GAUZE_STAIN_BLOOD))
- adjust_blood_flow(-limb.current_gauze.absorption_rate)
- else
- adjust_blood_flow(-clot_rate)
-
- if(blood_flow > highest_flow)
- highest_flow = blood_flow
-
- if(blood_flow < minimum_flow)
- if(demotes_to)
- replace_wound(demotes_to)
- else
- to_chat(victim, span_green("The cut on your [parse_zone(limb.body_zone)] has stopped bleeding!"))
- qdel(src)
-
-
-/datum/wound/slash/on_stasis()
- if(blood_flow >= minimum_flow)
- return
- if(demotes_to)
- replace_wound(demotes_to)
- return
- qdel(src)
-
-/* BEWARE, THE BELOW NONSENSE IS MADNESS. bones.dm looks more like what I have in mind and is sufficiently clean, don't pay attention to this messiness */
-
-/datum/wound/slash/check_grab_treatments(obj/item/treatment_item, mob/user)
- if(istype(treatment_item, /obj/item/gun/energy/laser))
- return TRUE
- if(treatment_item.get_temperature()) // if we're using something hot but not a cautery, we need to be aggro grabbing them first, so we don't try treating someone we're eswording
- return TRUE
-
-/datum/wound/slash/treat(obj/item/treatment_item, mob/user)
- if(istype(treatment_item, /obj/item/gun/energy/laser))
- las_cauterize(treatment_item, user)
- else if(treatment_item.tool_behaviour == TOOL_CAUTERY || treatment_item.get_temperature())
- tool_cauterize(treatment_item, user)
- else if(istype(treatment_item, /obj/item/stack/medical/suture))
- suture(treatment_item, user)
-
-/datum/wound/slash/try_handling(mob/living/carbon/human/user)
- if(user.pulling != victim || user.zone_selected != limb.body_zone || !user.combat_mode || !isfelinid(user) || !victim.can_inject(user, TRUE))
- return FALSE
- if(DOING_INTERACTION_WITH_TARGET(user, victim))
- to_chat(user, span_warning("You're already interacting with [victim]!"))
- return
- if(user.is_mouth_covered())
- to_chat(user, span_warning("Your mouth is covered, you can't lick [victim]'s wounds!"))
- return
- if(!user.get_organ_slot(ORGAN_SLOT_TONGUE))
- to_chat(user, span_warning("You can't lick wounds without a tongue!")) // f in chat
- return
-
- lick_wounds(user)
- return TRUE
-
-/// if a felinid is licking this cut to reduce bleeding
-/datum/wound/slash/proc/lick_wounds(mob/living/carbon/human/user)
- // transmission is one way patient -> felinid since google said cat saliva is antiseptic or whatever, and also because felinids are already risking getting beaten for this even without people suspecting they're spreading a deathvirus
- for(var/i in victim.diseases)
- var/datum/disease/iter_disease = i
- if(iter_disease.spread_flags & (DISEASE_SPREAD_SPECIAL | DISEASE_SPREAD_NON_CONTAGIOUS))
- continue
- user.ForceContractDisease(iter_disease)
-
- user.visible_message(span_notice("[user] begins licking the wounds on [victim]'s [parse_zone(limb.body_zone)]."), span_notice("You begin licking the wounds on [victim]'s [parse_zone(limb.body_zone)]..."), ignored_mobs=victim)
- to_chat(victim, span_notice("[user] begins to lick the wounds on your [parse_zone(limb.body_zone)]."))
- if(!do_after(user, base_treat_time, target=victim, extra_checks = CALLBACK(src, PROC_REF(still_exists))))
- return
-
- user.visible_message(span_notice("[user] licks the wounds on [victim]'s [parse_zone(limb.body_zone)]."), span_notice("You lick some of the wounds on [victim]'s [parse_zone(limb.body_zone)]"), ignored_mobs=victim)
- to_chat(victim, span_green("[user] licks the wounds on your [parse_zone(limb.body_zone)]!"))
- adjust_blood_flow(-0.5)
-
- if(blood_flow > minimum_flow)
- try_handling(user)
- else if(demotes_to)
- to_chat(user, span_green("You successfully lower the severity of [victim]'s cuts."))
-
-/datum/wound/slash/on_xadone(power)
- . = ..()
- adjust_blood_flow(-(0.03 * power)) // i think it's like a minimum of 3 power, so .09 blood_flow reduction per tick is pretty good for 0 effort
-
-/datum/wound/slash/on_synthflesh(power)
- . = ..()
- adjust_blood_flow(-(0.075 * power)) // 20u * 0.075 = -1.5 blood flow, pretty good for how little effort it is
-
-/// If someone's putting a laser gun up to our cut to cauterize it
-/datum/wound/slash/proc/las_cauterize(obj/item/gun/energy/laser/lasgun, mob/user)
- var/self_penalty_mult = (user == victim ? 1.25 : 1)
- user.visible_message(span_warning("[user] begins aiming [lasgun] directly at [victim]'s [parse_zone(limb.body_zone)]..."), span_userdanger("You begin aiming [lasgun] directly at [user == victim ? "your" : "[victim]'s"] [parse_zone(limb.body_zone)]..."))
- if(!do_after(user, base_treat_time * self_penalty_mult, target=victim, extra_checks = CALLBACK(src, PROC_REF(still_exists))))
- return
- var/damage = lasgun.chambered.loaded_projectile.damage
- lasgun.chambered.loaded_projectile.wound_bonus -= 30
- lasgun.chambered.loaded_projectile.damage *= self_penalty_mult
- if(!lasgun.process_fire(victim, victim, TRUE, null, limb.body_zone))
- return
- victim.emote("scream")
- adjust_blood_flow(-1 * (damage / (5 * self_penalty_mult))) // 20 / 5 = 4 bloodflow removed, p good
- victim.visible_message(span_warning("The cuts on [victim]'s [parse_zone(limb.body_zone)] scar over!"))
-
-/// If someone is using either a cautery tool or something with heat to cauterize this cut
-/datum/wound/slash/proc/tool_cauterize(obj/item/used_cautery, mob/user)
- var/improv_penalty_mult = (used_cautery.tool_behaviour == TOOL_CAUTERY ? 1 : 1.25) // 25% longer and less effective if you don't use a real cautery
- var/self_penalty_mult = (user == victim ? 1.5 : 1) // 50% longer and less effective if you do it to yourself
-
- user.visible_message(span_danger("[user] begins cauterizing [victim]'s [parse_zone(limb.body_zone)] with [used_cautery]..."), span_warning("You begin cauterizing [user == victim ? "your" : "[victim]'s"] [parse_zone(limb.body_zone)] with [used_cautery]..."))
- if(!do_after(user, base_treat_time * self_penalty_mult * improv_penalty_mult, target=victim, extra_checks = CALLBACK(src, PROC_REF(still_exists))))
- return
-
- user.visible_message(span_green("[user] cauterizes some of the bleeding on [victim]."), span_green("You cauterize some of the bleeding on [victim]."))
- limb.receive_damage(burn = 2 + severity, wound_bonus = CANT_WOUND)
- if(prob(30))
- victim.emote("scream")
- var/blood_cauterized = (0.6 / (self_penalty_mult * improv_penalty_mult))
- adjust_blood_flow(-blood_cauterized)
-
- if(blood_flow > minimum_flow)
- try_treating(used_cautery, user)
- else if(demotes_to)
- to_chat(user, span_green("You successfully lower the severity of [user == victim ? "your" : "[victim]'s"] cuts."))
-
-/// If someone is using a suture to close this cut
-/datum/wound/slash/proc/suture(obj/item/stack/medical/suture/used_suture, mob/user)
- var/self_penalty_mult = (user == victim ? 1.4 : 1)
- user.visible_message(span_notice("[user] begins stitching [victim]'s [parse_zone(limb.body_zone)] with [used_suture]..."), span_notice("You begin stitching [user == victim ? "your" : "[victim]'s"] [parse_zone(limb.body_zone)] with [used_suture]..."))
-
- if(!do_after(user, base_treat_time * self_penalty_mult, target=victim, extra_checks = CALLBACK(src, PROC_REF(still_exists))))
- return
- user.visible_message(span_green("[user] stitches up some of the bleeding on [victim]."), span_green("You stitch up some of the bleeding on [user == victim ? "yourself" : "[victim]"]."))
- var/blood_sutured = used_suture.stop_bleeding / self_penalty_mult
- adjust_blood_flow(-blood_sutured)
- limb.heal_damage(used_suture.heal_brute, used_suture.heal_burn)
- used_suture.use(1)
-
- if(blood_flow > minimum_flow)
- try_treating(used_suture, user)
- else if(demotes_to)
- to_chat(user, span_green("You successfully lower the severity of [user == victim ? "your" : "[victim]'s"] cuts."))
-
-
-/datum/wound/slash/moderate
- name = "Rough Abrasion"
- desc = "Patient's skin has been badly scraped, generating moderate blood loss."
- treat_text = "Application of clean bandages or first-aid grade sutures, followed by food and rest."
- examine_desc = "has an open cut"
- occur_text = "is cut open, slowly leaking blood"
- sound_effect = 'sound/effects/wounds/blood1.ogg'
- severity = WOUND_SEVERITY_MODERATE
- initial_flow = 2
- minimum_flow = 0.5
- clot_rate = 0.05
- threshold_minimum = 20
- threshold_penalty = 10
- status_effect_type = /datum/status_effect/wound/slash/moderate
- scar_keyword = "slashmoderate"
-
-/datum/wound/slash/severe
- name = "Open Laceration"
- desc = "Patient's skin is ripped clean open, allowing significant blood loss."
- treat_text = "Speedy application of first-aid grade sutures and clean bandages, followed by vitals monitoring to ensure recovery."
- examine_desc = "has a severe cut"
- occur_text = "is ripped open, veins spurting blood"
- sound_effect = 'sound/effects/wounds/blood2.ogg'
- severity = WOUND_SEVERITY_SEVERE
- initial_flow = 3.25
- minimum_flow = 2.75
- clot_rate = 0.03
- threshold_minimum = 50
- threshold_penalty = 25
- demotes_to = /datum/wound/slash/moderate
- status_effect_type = /datum/status_effect/wound/slash/severe
- scar_keyword = "slashsevere"
-
-/datum/wound/slash/critical
- name = "Weeping Avulsion"
- desc = "Patient's skin is completely torn open, along with significant loss of tissue. Extreme blood loss will lead to quick death without intervention."
- treat_text = "Immediate bandaging and either suturing or cauterization, followed by supervised resanguination."
- examine_desc = "is carved down to the bone, spraying blood wildly"
- occur_text = "is torn open, spraying blood wildly"
- sound_effect = 'sound/effects/wounds/blood3.ogg'
- severity = WOUND_SEVERITY_CRITICAL
- initial_flow = 4
- minimum_flow = 3.85
- clot_rate = -0.015 // critical cuts actively get worse instead of better
- threshold_minimum = 80
- threshold_penalty = 40
- demotes_to = /datum/wound/slash/severe
- status_effect_type = /datum/status_effect/wound/slash/critical
- scar_keyword = "slashcritical"
- wound_flags = (FLESH_WOUND | ACCEPTS_GAUZE | MANGLES_FLESH)
-
-/datum/wound/slash/moderate/many_cuts
- name = "Numerous Small Slashes"
- desc = "Patient's skin has numerous small slashes and cuts, generating moderate blood loss."
- examine_desc = "has a ton of small cuts"
- occur_text = "is cut numerous times, leaving many small slashes."
-
-// Subtype for cleave (heretic spell)
-/datum/wound/slash/critical/cleave
- name = "Burning Avulsion"
- examine_desc = "is ruptured, spraying blood wildly"
- clot_rate = 0.01
-
-/datum/wound/slash/critical/cleave/update_descriptions()
- if(no_bleeding)
- occur_text = "is ruptured"
-
-/datum/wound/slash/get_limb_examine_description()
- return span_warning("The flesh on this limb appears badly lacerated.")
diff --git a/modular_skyrat/modules/mentor/code/client_procs.dm b/modular_skyrat/modules/mentor/code/client_procs.dm
index af6ecae38e4..8c83b8c615e 100644
--- a/modular_skyrat/modules/mentor/code/client_procs.dm
+++ b/modular_skyrat/modules/mentor/code/client_procs.dm
@@ -44,6 +44,13 @@
cmd_mentor_dementor()
-/client/proc/is_mentor() // admins are mentors too.
- if(mentor_datum || check_rights_for(src, R_ADMIN))
+/**
+ * Returns whether or not the user is qualified as a mentor.
+ *
+ * Arguments:
+ * * admin_bypass - Whether or not admins can succeed this check, even if they
+ * do not actually possess the role. Defaults to `TRUE`.
+ */
+/client/proc/is_mentor(admin_bypass = TRUE)
+ if(mentor_datum || (admin_bypass && check_rights_for(src, R_ADMIN)))
return TRUE
diff --git a/modular_skyrat/modules/microfusion/code/projectiles.dm b/modular_skyrat/modules/microfusion/code/projectiles.dm
index c1f0a5f908e..6e90ebfda46 100644
--- a/modular_skyrat/modules/microfusion/code/projectiles.dm
+++ b/modular_skyrat/modules/microfusion/code/projectiles.dm
@@ -16,7 +16,7 @@
/obj/projectile/beam/laser/microfusion
name = "microfusion laser"
icon = 'modular_skyrat/modules/microfusion/icons/projectiles.dmi'
- damage = 20
+ damage = 25
/obj/projectile/beam/microfusion_disabler
name = "microfusion disabler laser"
@@ -36,7 +36,7 @@
/obj/projectile/beam/laser/microfusion/superheated
name = "superheated microfusion laser"
icon_state = "laser_greyscale"
- damage = 15 //Trading damage for fire stacks
+ damage = 20 //Trading damage for fire stacks
color = LIGHT_COLOR_FIRE
light_color = LIGHT_COLOR_FIRE
@@ -51,7 +51,7 @@
name = "hellfire microfusion laser"
icon_state = "laser_greyscale"
wound_bonus = 0
- damage = 15 // You are trading damage for a significant wound bonus and speed increase
+ damage = 20 // You are trading damage for a significant wound bonus and speed increase
speed = 0.6
color = LIGHT_COLOR_FLARE
light_color = LIGHT_COLOR_FLARE
@@ -63,16 +63,16 @@
name = "scatter microfusion laser"
/obj/projectile/beam/laser/microfusion/repeater
- damage = 10
+ damage = 12.5
/obj/projectile/beam/laser/microfusion/penetrator
name = "focused microfusion laser"
- damage = 15
+ damage = 20
armour_penetration = 50
/obj/projectile/beam/laser/microfusion/lance
name = "lance microfusion laser"
- damage = 40 // We're turning the gun into a heavylaser
+ damage = 50 // We're turning the gun into a heavylaser
tracer_type = /obj/effect/projectile/tracer/heavy_laser
muzzle_type = /obj/effect/projectile/muzzle/heavy_laser
impact_type = /obj/effect/projectile/impact/heavy_laser
@@ -91,7 +91,7 @@
color = COLOR_VIVID_YELLOW
light_color = COLOR_VIVID_YELLOW
damage_type = STAMINA
- damage = 20
+ damage = 25
armor_flag = ENERGY
hitsound = 'sound/misc/slip.ogg'
impact_type = /obj/effect/projectile/impact/disabler
diff --git a/modular_skyrat/modules/modular_ert/code/trauma_team/trauma_team_outfit.dm b/modular_skyrat/modules/modular_ert/code/trauma_team/trauma_team_outfit.dm
index 604d28eb5c1..23b65976985 100644
--- a/modular_skyrat/modules/modular_ert/code/trauma_team/trauma_team_outfit.dm
+++ b/modular_skyrat/modules/modular_ert/code/trauma_team/trauma_team_outfit.dm
@@ -29,7 +29,7 @@
/obj/item/reagent_containers/hypospray/combat,\
/obj/item/gun/medbeam,\
/obj/item/storage/medkit/tactical/ntrauma,\
- /obj/item/roller,\
+ /obj/item/emergency_bed,\
)
/*
diff --git a/modular_skyrat/modules/modular_implants/code/misc_devices.dm b/modular_skyrat/modules/modular_implants/code/misc_devices.dm
index 9907c41dffe..2582d06a959 100644
--- a/modular_skyrat/modules/modular_implants/code/misc_devices.dm
+++ b/modular_skyrat/modules/modular_implants/code/misc_devices.dm
@@ -121,6 +121,12 @@
/obj/item/clothing/glasses/thin,
/obj/item/clothing/glasses/biker,
/obj/item/clothing/glasses/sunglasses/gar,
+ /obj/item/clothing/glasses/hypno,
+ /obj/item/clothing/glasses/heat,
+ /obj/item/clothing/glasses/cold,
+ /obj/item/clothing/glasses/orange,
+ /obj/item/clothing/glasses/red,
+ /obj/item/clothing/glasses/psych,
)
/obj/item/nif_hud_adapter/examine(mob/user)
diff --git a/modular_skyrat/modules/modular_implants/code/nif_research.dm b/modular_skyrat/modules/modular_implants/code/nif_research.dm
index 149f6ded250..7e8e1ca94f8 100644
--- a/modular_skyrat/modules/modular_implants/code/nif_research.dm
+++ b/modular_skyrat/modules/modular_implants/code/nif_research.dm
@@ -26,7 +26,7 @@
build_path = /obj/item/handheld_soulcatcher
materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 3, /datum/material/silver = SHEET_MATERIAL_AMOUNT, /datum/material/bluespace = SHEET_MATERIAL_AMOUNT)
category = list(RND_CATEGORY_TOOLS + RND_SUBCATEGORY_EQUIPMENT_MEDICAL) // look, the anesthetic machine's there too
- departmental_flags = DEPARTMENT_BITFLAG_MEDICAL
+ departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SCIENCE
/datum/design/nifsoft_hud
build_type = PROTOLATHE | AWAY_LATHE
@@ -68,6 +68,13 @@
build_path = /obj/item/disk/nifsoft_uploader/sci_hud
departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_SERVICE | DEPARTMENT_BITFLAG_MEDICAL
+/datum/design/nifsoft_hud/meson
+ name = "Meson HUD NIFSoft"
+ desc = "A NIFSoft datadisk containing the Meson HUD NIFsoft."
+ id = "nifsoft_hud_meson"
+ build_path = /obj/item/disk/nifsoft_uploader/meson_hud
+ departmental_flags = DEPARTMENT_BITFLAG_CARGO | DEPARTMENT_BITFLAG_ENGINEERING
+
/datum/design/nif_hud_kit
name = "NIF HUD Retrofitter"
desc = "A kit that modifies select glasses to display HUDs for NIFs."
diff --git a/modular_skyrat/modules/modular_implants/code/nifs.dm b/modular_skyrat/modules/modular_implants/code/nifs.dm
index 18944df55f7..69c0a581c35 100644
--- a/modular_skyrat/modules/modular_implants/code/nifs.dm
+++ b/modular_skyrat/modules/modular_implants/code/nifs.dm
@@ -497,13 +497,16 @@
/obj/item/storage/box/nif_ghost_box/PopulateContents()
new /obj/item/autosurgeon/organ/nif/ghost_role(src)
- new /obj/item/disk/nifsoft_uploader/hivemind(src)
new /obj/item/disk/nifsoft_uploader/shapeshifter(src)
new /obj/item/disk/nifsoft_uploader/summoner(src)
new /obj/item/disk/nifsoft_uploader/money_sense(src)
new /obj/item/disk/nifsoft_uploader/dorms(src)
new /obj/item/disk/nifsoft_uploader/soulcatcher(src)
+/obj/item/storage/box/nif_ghost_box/ghost_role/PopulateContents()
+ . = ..()
+ new /obj/item/disk/nifsoft_uploader/hivemind(src)
+
#undef NIF_CALIBRATION_STAGE_1
#undef NIF_CALIBRATION_STAGE_1_END
#undef NIF_CALIBRATION_STAGE_2
diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts/huds.dm b/modular_skyrat/modules/modular_implants/code/nifsofts/huds.dm
index c850e1e7d58..77353910752 100644
--- a/modular_skyrat/modules/modular_implants/code/nifsofts/huds.dm
+++ b/modular_skyrat/modules/modular_implants/code/nifsofts/huds.dm
@@ -26,6 +26,8 @@
for(var/trait as anything in added_eyewear_traits)
ADD_TRAIT(linked_mob, trait, NIFSOFT_TRAIT)
+ linked_mob.update_sight()
+
/// Attempts to remove the HUDs given to the user by the NIFSoft
/datum/nifsoft/hud/proc/remove_huds()
if(hud_type)
@@ -38,6 +40,7 @@
for(var/trait in added_eyewear_traits)
REMOVE_TRAIT(linked_mob, trait, NIFSOFT_TRAIT)
+ linked_mob.update_sight()
return TRUE
/datum/nifsoft/hud/activate()
@@ -121,6 +124,11 @@
ui_icon = "flask"
added_eyewear_traits = list(TRAIT_REAGENT_SCANNER, TRAIT_RESEARCH_SCANNER)
+/datum/nifsoft/hud/job/meson
+ name = "Meson Scrying Lens"
+ ui_icon = "radiation"
+ added_eyewear_traits = list(TRAIT_MADNESS_IMMUNE, TRAIT_MESON_VISION)
+
//
// UPLOADER DISKS
//
@@ -145,6 +153,9 @@
name = "Science Scrying Lens"
loaded_nifsoft = /datum/nifsoft/hud/job/science
+/obj/item/disk/nifsoft_uploader/meson_hud
+ name = "Meson Scrying Lens"
+ loaded_nifsoft = /datum/nifsoft/hud/job/meson
//
// NIFSOFT HUD GLASSES
diff --git a/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm b/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm
index 6fb548eb4ff..97158ba5d91 100644
--- a/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm
+++ b/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm
@@ -249,7 +249,7 @@ GLOBAL_LIST_EMPTY(soulcatchers)
current_souls -= target_soul
target_room.current_souls += target_soul
- to_chat(target_soul, span_cyan("you've been transfered to [target_room]!"))
+ to_chat(target_soul, span_cyan("you've been transferred to [target_room]!"))
to_chat(target_soul, span_notice(target_room.room_description))
return TRUE
diff --git a/modular_skyrat/modules/modular_items/code/pastries.dm b/modular_skyrat/modules/modular_items/code/pastries.dm
index d99e4d1da27..8ae5939bb09 100644
--- a/modular_skyrat/modules/modular_items/code/pastries.dm
+++ b/modular_skyrat/modules/modular_items/code/pastries.dm
@@ -9,6 +9,7 @@
foodtypes = GRAIN | SUGAR | FRUIT
food_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/nutriment/vitamin = 2)
tastes = list("fruit" = 1, "raisins" = 1, "christmas spirit" = 1)
+ crafting_complexity = FOOD_COMPLEXITY_3
/obj/item/food/mimce_pie
name = "mimce pie"
@@ -20,6 +21,7 @@
foodtypes = GRAIN | SUGAR | FRUIT
food_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/nutriment/vitamin = 2)
tastes = list("nothing" = 1, "christmas spirit" = 1)
+ crafting_complexity = FOOD_COMPLEXITY_3
// RECIPE
diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_chemistry/reagents/_aphrodisiac.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_chemistry/reagents/_aphrodisiac.dm
index f5eb135346a..34d27290e00 100644
--- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_chemistry/reagents/_aphrodisiac.dm
+++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_chemistry/reagents/_aphrodisiac.dm
@@ -2,6 +2,7 @@
/datum/reagent/drug/aphrodisiac
name = "liquid ERP"
description = "ERP in its liquified form. Complain to a coder."
+ chemical_flags = REAGENT_NO_RANDOM_RECIPE
/// What preference you need enabled for effects on life
var/life_pref_datum = /datum/preference/toggle/erp
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 5227584084a..81cd35398b0 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
@@ -170,17 +170,25 @@
// Open the valve when press the button
/datum/action/item_action/mask_inhale/Trigger(trigger_flags)
- if(istype(target, /obj/item/clothing/mask/gas/bdsm_mask))
- var/obj/item/clothing/mask/gas/bdsm_mask/mask = target
- if(mask.breath_status == FALSE)
- mask.time_to_choke_left = mask.time_to_choke
- mask.breath_status = TRUE
- var/mob/living/carbon/affected_mob = usr
- affected_mob.try_lewd_autoemote("inhale")
- var/obj/item/reagent_containers/cup/lewd_filter/filter = mask.contents[1]
- filter.reagent_consumption(affected_mob, filter.amount_per_transfer_from_this)
- return
- return ..()
+ var/obj/item/clothing/mask/gas/bdsm_mask/mask = target
+ if(!istype(mask))
+ return ..()
+
+ if(mask.breath_status)
+ return FALSE
+
+ mask.time_to_choke_left = mask.time_to_choke
+ mask.breath_status = TRUE
+
+ var/mob/living/carbon/affected_mob = usr
+ if(!istype(affected_mob))
+ return FALSE
+
+ affected_mob.try_lewd_autoemote("inhale")
+ var/obj/item/reagent_containers/cup/lewd_filter/filter = mask.contents[1]
+ filter.reagent_consumption(affected_mob, filter.amount_per_transfer_from_this)
+
+ return TRUE
// Adding breath_manually on equip
/obj/item/clothing/mask/gas/bdsm_mask/equipped(/mob/user, slot)
@@ -232,6 +240,8 @@
/obj/item/clothing/mask/gas/bdsm_mask/process(seconds_per_tick)
var/mob/living/affected_mob = loc
var/mob/living/carbon/affected_carbon = affected_mob
+ if(!istype(affected_carbon))
+ return FALSE
if(time_to_choke_left < time_to_choke/2 && breath_status == TRUE)
if(temp_check == FALSE && affected_mob.stat == CONSCIOUS) // If user passed out while wearing this we should continue when he wakes up
@@ -239,15 +249,14 @@
time_to_choke_left = time_to_choke
temp_check = TRUE
- if(ispath(affected_carbon))
- if(affected_mob.stat == CONSCIOUS)
- affected_carbon.try_lewd_autoemote("exhale")
- breath_status = FALSE
- if(rand(0, 3) == 0)
- affected_carbon.try_lewd_autoemote("moan")
- else
- breath_status = TRUE
- temp_check = FALSE
+ if(affected_mob.stat == CONSCIOUS)
+ affected_carbon.try_lewd_autoemote("exhale")
+ breath_status = FALSE
+ if(rand(0, 3) == 0)
+ affected_carbon.try_lewd_autoemote("moan")
+ else
+ breath_status = TRUE
+ temp_check = FALSE
if(time_to_choke_left <= 0)
if(tt <= 0)
diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_helpers/human.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_helpers/human.dm
index ce6aa14dfb2..c861b924d6f 100644
--- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_helpers/human.dm
+++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_helpers/human.dm
@@ -209,6 +209,21 @@
else
return TRUE
+/// Returns true if the human has accessible tail for the parameter. Accepts any of the `REQUIRE_GENITAL_` defines.
+/mob/living/carbon/human/proc/has_tail(required_state = REQUIRE_GENITAL_ANY)
+ var/obj/item/organ/genital = get_organ_slot(ORGAN_SLOT_TAIL)
+ if(!genital)
+ return FALSE
+
+ switch(required_state)
+ if(REQUIRE_GENITAL_ANY)
+ return TRUE
+ if(REQUIRE_GENITAL_EXPOSED)
+ return !get_item_by_slot(ORGAN_SLOT_TAIL)
+ if(REQUIRE_GENITAL_UNEXPOSED)
+ return get_item_by_slot(ORGAN_SLOT_TAIL)
+ else
+ return TRUE
/*
* This code needed for changing character's gender by chems
@@ -363,3 +378,7 @@
if(wear_suit && istype(wear_suit, /obj/item/clothing/suit/straight_jacket/kinky_sleepbag))
return FALSE
..()
+
+/// Checks if the tail is exposed.
+/obj/item/organ/external/tail/proc/is_exposed()
+ return TRUE // your tail is always exposed, dummy! why are you checking this
diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/dildo.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/dildo.dm
index 95416eb183a..a94c833cc9b 100644
--- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/dildo.dm
+++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/dildo.dm
@@ -136,7 +136,7 @@
user.adjust_pleasure(8)
if(BODY_ZONE_HEAD, BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_PRECISE_EYES) //Mouth only. Sorry, perverts. No eye/ear penetration for you today.
- if(!target.is_mouth_covered())
+ if(target.is_mouth_covered())
to_chat(user, span_danger("Looks like [target]'s mouth is covered!"))
return FALSE
@@ -227,6 +227,11 @@ GLOBAL_LIST_INIT(dildo_colors, list(//mostly neon colors
color_changed = TRUE
return TRUE
+/obj/item/clothing/sextoy/dildo/custom_dildo/Initialize(mapload)
+ . = ..()
+ if(!length(dildo_sizes))
+ populate_dildo_designs()
+
/// Choose a color and transparency level for the toy
/obj/item/clothing/sextoy/dildo/custom_dildo/proc/customize(mob/living/user)
if(!src || !user || user.incapacitated() || !in_range(user, src))
diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_structures/pillow.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_structures/pillow.dm
index 284d6161d58..0ac4d57fafb 100644
--- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_structures/pillow.dm
+++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_structures/pillow.dm
@@ -172,7 +172,7 @@
var/color_changed = FALSE
var/form_changed = FALSE
- buildstacktype = /obj/item/stack/sheet/cloth
+ build_stack_type = /obj/item/stack/sheet/cloth
/obj/structure/bed/pillow_tiny/Initialize(mapload)
.=..()
@@ -398,7 +398,7 @@
var/pillow2_form_changed = FALSE
var/pillow3_form_changed = FALSE
- buildstacktype = /obj/item/stack/sheet/cloth
+ build_stack_type = /obj/item/stack/sheet/cloth
/obj/structure/bed/pillow_large/Initialize(mapload)
update_icon()
diff --git a/modular_skyrat/modules/modular_vending/code/wardrobes.dm b/modular_skyrat/modules/modular_vending/code/wardrobes.dm
index 8cf3fb0f6da..e5f3e0210e7 100644
--- a/modular_skyrat/modules/modular_vending/code/wardrobes.dm
+++ b/modular_skyrat/modules/modular_vending/code/wardrobes.dm
@@ -43,7 +43,6 @@
/obj/item/clothing/under/rank/cargo/tech/skyrat/turtleneck/skirt = 3,
/obj/item/clothing/under/rank/cargo/tech/skyrat/utility = 3,
/obj/item/clothing/under/rank/cargo/tech/skyrat/casualman = 3,
- /obj/item/clothing/suit/gorka/supply = 3,
/obj/item/clothing/suit/toggle/jacket/supply = 3,
/obj/item/clothing/glasses/hud/gun_permit = 5, //from company imports module
/obj/item/storage/backpack/messenger = 3,
@@ -62,6 +61,9 @@
/obj/item/clothing/mask/breath = 2,
/obj/item/reagent_containers/cup/bottle/morphine = 2,
/obj/item/reagent_containers/syringe = 2,
+ /obj/item/bonesetter = 2, // for dislocations
+ /obj/item/stack/medical/gauze = 4, // for ALL wounds
+ /obj/item/healthanalyzer/no_medibot = 2, // disallows medibot use so its not wasted immediately on medibots
/obj/item/storage/backpack/science/robo = 2,
/obj/item/storage/backpack/satchel/science/robo = 2,
/obj/item/storage/backpack/duffelbag/science/robo = 2,
diff --git a/modular_skyrat/modules/modular_weapons/code/energy.dm b/modular_skyrat/modules/modular_weapons/code/energy.dm
index 247a9a82ba5..550af2c130e 100644
--- a/modular_skyrat/modules/modular_weapons/code/energy.dm
+++ b/modular_skyrat/modules/modular_weapons/code/energy.dm
@@ -219,7 +219,7 @@
icon = 'modular_skyrat/modules/modular_weapons/icons/obj/ammo.dmi'
icon_state = "plasma_shell"
worn_icon_state = "shell"
- caliber = "Beam Shell"
+ caliber = CALIBER_LASER
custom_materials = list(/datum/material/iron=SHEET_MATERIAL_AMOUNT * 2,/datum/material/plasma=HALF_SHEET_MATERIAL_AMOUNT)
projectile_type = /obj/projectile/beam/laser/single
@@ -228,7 +228,6 @@
desc = "A chemical mixture that once triggered, creates a deadly projectile, melting it's own casing in the process."
icon_state = "plasma_shell2"
worn_icon_state = "shell"
- caliber = "Beam Shell"
custom_materials = list(/datum/material/iron=SHEET_MATERIAL_AMOUNT * 2,/datum/material/plasma=HALF_SHEET_MATERIAL_AMOUNT)
projectile_type = /obj/projectile/beam/laser/double
@@ -237,7 +236,6 @@
desc = "A chemical mixture that once triggered, creates a deadly bouncing projectile, melting it's own casing in the process."
icon_state = "bounce_shell"
worn_icon_state = "shell"
- caliber = "Beam Shell"
custom_materials = list(/datum/material/iron=SHEET_MATERIAL_AMOUNT * 2,/datum/material/plasma=HALF_SHEET_MATERIAL_AMOUNT)
projectile_type = /obj/projectile/beam/laser/bounce
diff --git a/modular_skyrat/modules/modular_weapons/code/melee.dm b/modular_skyrat/modules/modular_weapons/code/melee.dm
index e2b633a9c1e..8165a798a6f 100644
--- a/modular_skyrat/modules/modular_weapons/code/melee.dm
+++ b/modular_skyrat/modules/modular_weapons/code/melee.dm
@@ -1,4 +1,5 @@
-// Cargo Sabres
+// Sabres, including the cargo variety
+
/obj/item/storage/belt/sabre/cargo
name = "authentic shamshir leather sheath"
desc = "A good-looking sheath that is advertised as being made of real Venusian black leather. It feels rather plastic-like to the touch, and it looks like it's made to fit a British cavalry sabre."
@@ -9,6 +10,11 @@
new /obj/item/melee/sabre/cargo(src)
update_appearance()
+/obj/item/melee/sabre
+ force = 20 // Original: 15
+ wound_bonus = 5 // Original: 10
+ bare_wound_bonus = 20 // Original: 25 Both down slightly, to make up for the damage buff, since it'd get a bit wacky ontop of the armor pen.
+
/obj/item/melee/sabre/cargo
name = "authentic shamshir sabre"
desc = "An expertly crafted historical human sword once used by the Persians which has recently gained traction due to Venusian historal recreation sports. One small flaw, the Taj-based company who produces these has mistaken them for British cavalry sabres akin to those used by high ranking Nanotrasen officials. Atleast it cuts the same way!"
@@ -18,6 +24,7 @@
block_chance = 20
armour_penetration = 25
+
// This is here so that people can't buy the Sabres and craft them into powercrepes
/datum/crafting_recipe/food/powercrepe
blacklist = list(/obj/item/melee/sabre/cargo)
diff --git a/modular_skyrat/modules/mold/code/mold_controller.dm b/modular_skyrat/modules/mold/code/mold_controller.dm
index e6771cc4874..8a9ed323827 100644
--- a/modular_skyrat/modules/mold/code/mold_controller.dm
+++ b/modular_skyrat/modules/mold/code/mold_controller.dm
@@ -102,6 +102,8 @@
spawn_resin(iterated_turf)
if(iterated_turf == our_turf)
continue
+ if(isopenspaceturf(iterated_turf))
+ continue
if(hatcheries_to_spawn && prob(40))
hatcheries_to_spawn--
@@ -174,7 +176,8 @@
CALCULATE_ADJACENT_TURFS(T, NORMAL_TURF)
else
- possible_locs += T
+ if(!isopenspaceturf(T)) // no spawning in openspace turfs
+ possible_locs += T
for(var/T in possible_locs)
var/turf/iterated_turf = T
diff --git a/modular_skyrat/modules/mold/code/mold_disease.dm b/modular_skyrat/modules/mold/code/mold_disease.dm
index 4e008aa3a54..8778e469bec 100644
--- a/modular_skyrat/modules/mold/code/mold_disease.dm
+++ b/modular_skyrat/modules/mold/code/mold_disease.dm
@@ -63,7 +63,7 @@
to_chat(affected_mob, span_danger("[pick("You feel uncomfortably hot...", "You feel like unzipping your jumpsuit", "You feel like taking off some clothes...")]"))
affected_mob.adjust_bodytemperature(30)
if(SPT_PROB(5, seconds_per_tick))
- affected_mob.vomit(20)
+ affected_mob.vomit(vomit_flags = VOMIT_CATEGORY_DEFAULT, lost_nutrition = 20)
/datum/reagent/cryptococcus_spores
name = "Cryptococcus gattii microbes"
diff --git a/modular_skyrat/modules/mold/code/mold_event.dm b/modular_skyrat/modules/mold/code/mold_event.dm
index 2b71b708546..da6dee42b3f 100644
--- a/modular_skyrat/modules/mold/code/mold_event.dm
+++ b/modular_skyrat/modules/mold/code/mold_event.dm
@@ -50,6 +50,9 @@
continue
for(var/turf/open/floor in checked_area.get_contained_turfs())
+ if(isopenspaceturf(floor))
+ continue
+
if(!floor.Enter(test_resin))
continue
diff --git a/modular_skyrat/modules/mold/code/mold_structures.dm b/modular_skyrat/modules/mold/code/mold_structures.dm
index 98e4fd262d0..30aa9f4e40c 100644
--- a/modular_skyrat/modules/mold/code/mold_structures.dm
+++ b/modular_skyrat/modules/mold/code/mold_structures.dm
@@ -132,7 +132,7 @@
icon_state = "blob_floor"
density = FALSE
plane = FLOOR_PLANE
- layer = ABOVE_NORMAL_TURF_LAYER
+ layer = LOW_SIGIL_LAYER
max_integrity = 50
var/blooming = FALSE
/// Are we a floor resin? If not then we're a wall resin
@@ -193,7 +193,7 @@
pixel_x = -32
icon_state = "blob_wall"
plane = GAME_PLANE
- layer = ABOVE_NORMAL_TURF_LAYER
+ layer = LOW_SIGIL_LAYER
if(prob(7))
blooming = TRUE
@@ -331,7 +331,7 @@
icon = 'modular_skyrat/modules/mold/icons/blob_spawner.dmi'
icon_state = "blob_vent"
density = FALSE
- layer = LOW_OBJ_LAYER
+ layer = SIGIL_LAYER
max_integrity = 150
/// The mold atmosphere conditioner will spawn the mold's preferred atmosphere every so often.
var/happy_atmos = null
@@ -370,7 +370,7 @@
icon = 'modular_skyrat/modules/mold/icons/blob_spawner.dmi'
icon_state = "blob_spawner"
density = FALSE
- layer = LOW_OBJ_LAYER
+ layer = SIGIL_LAYER
max_integrity = 150
/obj/structure/mold/structure/spawner/Destroy()
diff --git a/modular_skyrat/modules/morenarcotics/code/cocaine_item.dm b/modular_skyrat/modules/morenarcotics/code/cocaine_item.dm
index 10fde9ab06e..2a4da011635 100644
--- a/modular_skyrat/modules/morenarcotics/code/cocaine_item.dm
+++ b/modular_skyrat/modules/morenarcotics/code/cocaine_item.dm
@@ -52,11 +52,11 @@
if(covered)
to_chat(user, span_warning("You have to remove your [covered] first!"))
return
- user.visible_message(span_notice("'[user] starts snorting the [src]."))
+ user.visible_message(span_notice("[user] starts snorting the [src]."))
if(do_after(user, 30))
to_chat(user, span_notice("You finish snorting the [src]."))
if(reagents.total_volume)
- reagents.trans_to(user, reagents.total_volume, transfered_by = user, methods = INGEST)
+ reagents.trans_to(user, reagents.total_volume, transferred_by = user, methods = INGEST)
qdel(src)
/obj/item/reagent_containers/cocaine/attack(mob/target, mob/user)
diff --git a/modular_skyrat/modules/morenarcotics/code/crackpipe.dm b/modular_skyrat/modules/morenarcotics/code/crackpipe.dm
index 42d09c707ba..e17bf805a37 100644
--- a/modular_skyrat/modules/morenarcotics/code/crackpipe.dm
+++ b/modular_skyrat/modules/morenarcotics/code/crackpipe.dm
@@ -33,7 +33,7 @@
smoketime = 2 * 60
name = "[used_item.name]-packed [initial(name)]"
if(used_item.reagents)
- used_item.reagents.trans_to(src, used_item.reagents.total_volume, transfered_by = user)
+ used_item.reagents.trans_to(src, used_item.reagents.total_volume, transferred_by = user)
qdel(used_item)
else
var/lighting_text = used_item.ignition_effect(src,user)
diff --git a/modular_skyrat/modules/morenarcotics/code/opium.dm b/modular_skyrat/modules/morenarcotics/code/opium.dm
index 20436d38c8c..7c49c67ca5d 100644
--- a/modular_skyrat/modules/morenarcotics/code/opium.dm
+++ b/modular_skyrat/modules/morenarcotics/code/opium.dm
@@ -46,7 +46,7 @@
if(do_after(user, 30))
to_chat(user, span_notice("You finish snorting the [src]."))
if(reagents.total_volume)
- reagents.trans_to(user, reagents.total_volume, transfered_by = user, methods = INGEST)
+ reagents.trans_to(user, reagents.total_volume, transferred_by = user, methods = INGEST)
qdel(src)
/obj/item/reagent_containers/heroin/attack(mob/target, mob/user)
diff --git a/modular_skyrat/modules/morenarcotics/code/vapecarts.dm b/modular_skyrat/modules/morenarcotics/code/vapecarts.dm
index 19d65924945..8e9d242484e 100644
--- a/modular_skyrat/modules/morenarcotics/code/vapecarts.dm
+++ b/modular_skyrat/modules/morenarcotics/code/vapecarts.dm
@@ -17,7 +17,7 @@
if(istype(target, /obj/item/clothing/mask/vape))
var/obj/item/clothing/mask/vape/target_vape = target
if(target_vape.screw == TRUE && !target_vape.reagents.total_volume)
- src.reagents.trans_to(target_vape, src.volume, transfered_by = user)
+ src.reagents.trans_to(target_vape, src.volume, transferred_by = user)
qdel(src)
to_chat(user, span_notice("You plug the [src.name] into the vape."))
else if(!target_vape.screw)
diff --git a/modular_skyrat/modules/moretraitoritems/code/mafioso.dm b/modular_skyrat/modules/moretraitoritems/code/mafioso.dm
index bc58e789153..e07039ded74 100644
--- a/modular_skyrat/modules/moretraitoritems/code/mafioso.dm
+++ b/modular_skyrat/modules/moretraitoritems/code/mafioso.dm
@@ -13,10 +13,10 @@
acid = 30
wound = 20
-/obj/item/clothing/under/suit/blacktwopiece/armoured
- armor_type = /datum/armor/clothing_under/blacktwopiece_armoured
+/obj/item/clothing/under/suit/black/armoured
+ armor_type = /datum/armor/clothing_under/black_armoured
-/datum/armor/clothing_under/blacktwopiece_armoured
+/datum/armor/clothing_under/black_armoured
melee = 10
bullet = 10
laser = 10
diff --git a/modular_skyrat/modules/moretraitoritems/code/syndicate_loadout.dm b/modular_skyrat/modules/moretraitoritems/code/syndicate_loadout.dm
index 8a49d1b6cf5..2df1919fbbf 100644
--- a/modular_skyrat/modules/moretraitoritems/code/syndicate_loadout.dm
+++ b/modular_skyrat/modules/moretraitoritems/code/syndicate_loadout.dm
@@ -188,7 +188,7 @@
new /obj/item/gun/ballistic/automatic/tommygun(src)
new /obj/item/ammo_box/magazine/tommygunm45(src)
new /obj/item/clothing/suit/jacket/det_suit/noir/mafioso(src)
- new /obj/item/clothing/under/suit/blacktwopiece/armoured(src)
+ new /obj/item/clothing/under/suit/black/armoured(src)
new /obj/item/clothing/mask/fakemoustache/italian(src)
new /obj/item/switchblade(src)
new /obj/item/clothing/shoes/laceup(src)
diff --git a/modular_skyrat/modules/mutants/code/mutant_component.dm b/modular_skyrat/modules/mutants/code/mutant_component.dm
index 99233cb2656..4e78065eb37 100644
--- a/modular_skyrat/modules/mutants/code/mutant_component.dm
+++ b/modular_skyrat/modules/mutants/code/mutant_component.dm
@@ -100,7 +100,7 @@
if(SPT_PROB(10, seconds_per_tick))
var/obj/item/bodypart/wound_area = host.get_bodypart(BODY_ZONE_CHEST)
if(wound_area)
- var/datum/wound/slash/moderate/rotting_wound = new
+ var/datum/wound/slash/flesh/moderate/rotting_wound = new
rotting_wound.apply_wound(wound_area)
host.emote(pick(list("cough", "sneeze", "scream")))
if(timer_id)
diff --git a/modular_skyrat/modules/nanotrasen_rep/code/nanotrasen_consultant.dm b/modular_skyrat/modules/nanotrasen_rep/code/nanotrasen_consultant.dm
index 12d2406d0b7..b9126f3a3a5 100644
--- a/modular_skyrat/modules/nanotrasen_rep/code/nanotrasen_consultant.dm
+++ b/modular_skyrat/modules/nanotrasen_rep/code/nanotrasen_consultant.dm
@@ -73,14 +73,14 @@
id_trim = /datum/id_trim/job/nanotrasen_consultant
/obj/item/radio/headset/heads/nanotrasen_consultant
- name = "\proper the nanotrasen consultant's headset"
+ name = "\proper the Nanotrasen consultant's headset"
desc = "An official Central Command headset."
icon_state = "cent_headset"
keyslot = new /obj/item/encryptionkey/headset_com
keyslot2 = new /obj/item/encryptionkey/headset_cent
/obj/item/radio/headset/heads/nanotrasen_consultant/alt
- name = "\proper the nanotrasen consultant's bowman headset"
+ name = "\proper the Nanotrasen consultant's bowman headset"
desc = "An official Central Command headset. Protects ears from flashbangs."
icon_state = "cent_headset_alt"
@@ -126,6 +126,27 @@
new /obj/item/ammo_box/magazine/m45a5(src)
new /obj/item/ammo_box/magazine/m45a5(src)
+/obj/item/storage/bag/garment/nanotrasen_consultant
+ name = "Nanotrasen consultant's garment bag"
+ desc = "A bag for storing extra clothes and shoes. This one belongs to the Nanotrasen consultant."
+
+/obj/item/storage/bag/garment/nanotrasen_consultant/PopulateContents()
+ new /obj/item/clothing/shoes/sneakers/brown(src)
+ new /obj/item/clothing/glasses/sunglasses/gar/giga(src)
+ new /obj/item/clothing/gloves/combat(src)
+ new /obj/item/clothing/gloves/combat/naval/nanotrasen_consultant(src)
+ new /obj/item/clothing/suit/hooded/wintercoat/centcom/nt_consultant(src)
+ new /obj/item/clothing/under/rank/nanotrasen_consultant(src)
+ new /obj/item/clothing/under/rank/nanotrasen_consultant/skirt(src)
+ new /obj/item/clothing/under/rank/centcom/officer(src)
+ new /obj/item/clothing/under/rank/centcom/officer_skirt(src)
+ new /obj/item/clothing/head/nanotrasen_consultant(src)
+ new /obj/item/clothing/head/nanotrasen_consultant/beret(src)
+ new /obj/item/clothing/head/beret/centcom_formal/nt_consultant(src)
+ new /obj/item/clothing/head/hats/centhat(src)
+ new /obj/item/clothing/suit/armor/centcom_formal/nt_consultant(src)
+ new /obj/item/clothing/under/rank/centcom/intern(src)
+ new /obj/item/clothing/head/hats/intern(src)
/obj/structure/closet/secure_closet/nanotrasen_consultant/station
name = "\proper nanotrasen consultant's locker"
@@ -139,14 +160,10 @@
new /obj/item/storage/backpack/satchel/leather(src)
new /obj/item/clothing/neck/petcollar(src)
new /obj/item/pet_carrier(src)
- new /obj/item/clothing/shoes/sneakers/brown(src)
new /obj/item/clothing/suit/armor/vest(src)
new /obj/item/computer_disk/command/captain(src)
new /obj/item/radio/headset/heads/nanotrasen_consultant/alt(src)
new /obj/item/radio/headset/heads/nanotrasen_consultant(src)
- new /obj/item/clothing/glasses/sunglasses/gar/giga(src)
- new /obj/item/clothing/gloves/combat(src)
- new /obj/item/clothing/gloves/combat/naval/nanotrasen_consultant(src)
new /obj/item/storage/photo_album/personal(src)
new /obj/item/bedsheet/centcom(src)
- new /obj/item/clothing/suit/hooded/wintercoat/centcom/nt_consultant(src)
+ new /obj/item/storage/bag/garment/nanotrasen_consultant(src)
diff --git a/modular_skyrat/modules/novaya_ert/code/ert.dm b/modular_skyrat/modules/novaya_ert/code/ert.dm
index 6e0a23f50a0..f9c0fbbfa3b 100644
--- a/modular_skyrat/modules/novaya_ert/code/ert.dm
+++ b/modular_skyrat/modules/novaya_ert/code/ert.dm
@@ -1,5 +1,5 @@
/datum/ert/nri
- roles = list(/datum/antagonist/ert/nri, /datum/antagonist/ert/nri/medic, /datum/antagonist/ert/nri/engineer, /datum/antagonist/ert/nri/heavy)
+ roles = list(/datum/antagonist/ert/nri, /datum/antagonist/ert/nri/medic, /datum/antagonist/ert/nri/engineer)
leader_role = /datum/antagonist/ert/nri/commander
rename_team = "NRI border patrol"
code = "Red"
@@ -55,10 +55,6 @@
role = "Commander"
outfit = /datum/outfit/centcom/ert/nri/commander
-/datum/antagonist/ert/nri/heavy
- role = "Heavy Soldier"
- outfit = /datum/outfit/centcom/ert/nri/heavy
-
/datum/antagonist/ert/nri/medic
role = "Corpsman"
outfit = /datum/outfit/centcom/ert/nri/medic
diff --git a/modular_skyrat/modules/novaya_ert/code/head.dm b/modular_skyrat/modules/novaya_ert/code/head.dm
index b0c88b5c8dd..7b9b95166ad 100644
--- a/modular_skyrat/modules/novaya_ert/code/head.dm
+++ b/modular_skyrat/modules/novaya_ert/code/head.dm
@@ -1,23 +1,3 @@
-/obj/item/clothing/head/helmet/rus_helmet/nri
- name = "\improper M-42 helmet"
- desc = "A lightweight M-42 helmet, previously used by the NRI military. This helmet performed well in the Border War against SolFed, but NRI required significant design changes due to the enemy's new and improved weaponry. These models were recently phased out and then quickly found their way onto the black market, now commonly seen in the hands (or on the heads) of insurgents."
- icon = 'modular_skyrat/master_files/icons/obj/clothing/head/helmet.dmi'
- worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/head/helmet.dmi'
- worn_icon_teshari = 'modular_skyrat/master_files/icons/mob/clothing/species/teshari/head.dmi'
- icon_state = "russian_green_helmet"
- armor_type = /datum/armor/rus_helmet_nri
- supports_variations_flags = CLOTHING_SNOUTED_VARIATION_NO_NEW_ICON
-
-/datum/armor/rus_helmet_nri
- melee = 30
- bullet = 40
- laser = 20
- energy = 30
- bomb = 35
- fire = 50
- acid = 50
- wound = 15
-
/obj/item/clothing/head/beret/sec/nri
name = "commander's beret"
desc = "Za rodinu!!"
@@ -33,69 +13,6 @@
acid = 50
wound = 20
-/obj/item/clothing/head/helmet/nri_heavy
- name = "\improper Cordun-M helmet"
- desc = "A heavy Russian combat helmet with a strong ballistic visor. Alt+click to adjust."
- icon_state = "russian_heavy_helmet"
- icon = 'modular_skyrat/master_files/icons/obj/clothing/head/helmet.dmi'
- worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/head/helmet.dmi'
- armor_type = /datum/armor/helmet_nri_heavy
- flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH
- resistance_flags = FIRE_PROOF|UNACIDABLE|ACID_PROOF|FREEZE_PROOF
- clothing_flags = STOPSPRESSUREDAMAGE|SNUG_FIT|BLOCK_GAS_SMOKE_EFFECT|THICKMATERIAL
- /// What position the helmet is in, TRUE = DOWN, FALSE = UP
- var/helmet_position = TRUE
-
-/datum/armor/helmet_nri_heavy
- melee = 60
- bullet = 60
- laser = 50
- energy = 50
- bomb = 100
- bio = 100
- fire = 70
- acid = 70
- wound = 35
-
-/obj/item/clothing/head/helmet/nri_heavy/AltClick(mob/user)
- . = ..()
- helmet_position = !helmet_position
- to_chat(user, span_notice("You flip [src] [helmet_position ? "down" : "up"] with a heavy clunk!"))
- update_appearance()
-
-/obj/item/clothing/head/helmet/nri_heavy/update_icon_state()
- . = ..()
- var/state = "[initial(icon_state)]"
- if(helmet_position)
- state += "-down"
- else
- state += "-up"
- icon_state = state
-
-/obj/item/clothing/head/helmet/nri_heavy/mob_can_equip(mob/living/M, slot, disable_warning, bypass_equip_delay_self, ignore_equipped, indirect_action)
- if(is_species(M, /datum/species/teshari))
- to_chat(M, span_warning("[src] is far too big for you!"))
- return FALSE
- return ..()
-
-/obj/item/clothing/head/helmet/nri_heavy/old
- name = "\improper REDUT helmet"
- desc = "A heavy Russian combat helmet with a strong ballistic visor. Alt+click to adjust."
- armor_type = /datum/armor/nri_heavy_old
- resistance_flags = FIRE_PROOF|ACID_PROOF|FREEZE_PROOF
- clothing_flags = SNUG_FIT|THICKMATERIAL
-
-/datum/armor/nri_heavy_old
- melee = 50
- bullet = 50
- laser = 40
- energy = 50
- bomb = 75
- bio = 60
- fire = 45
- acid = 45
- wound = 20
-
/obj/item/clothing/head/helmet/space/hev_suit/nri
name = "\improper VOSKHOD powered combat armor helmet"
desc = "A composite graphene-plasteel helmet with a ballistic nylon inner padding, complete with a deployable airtight polycarbonate visor and respirator system. 'ÐРИ - ÐžÐ±Ð¾Ñ€Ð¾Ð½Ð½Ð°Ñ ÐšÐ¾Ð»Ð»ÐµÐ³Ð¸Ñ' is imprinted on the back."
diff --git a/modular_skyrat/modules/novaya_ert/code/mod_suit.dm b/modular_skyrat/modules/novaya_ert/code/mod_suit.dm
index adcae3fa3c7..d9c5adb7f71 100644
--- a/modular_skyrat/modules/novaya_ert/code/mod_suit.dm
+++ b/modular_skyrat/modules/novaya_ert/code/mod_suit.dm
@@ -178,6 +178,7 @@
and even useful information such as their overall health and wellness. The vitals monitor also comes with a speaker, loud enough \
to alert anyone nearby that someone has, in fact, died. This specific unit has a clock and operational ID readout."
display_time = TRUE
+ death_sound = 'modular_skyrat/modules/novaya_ert/sound/flatline.ogg'
///Blatant copy of the adrenaline boost module.
/obj/item/mod/module/auto_doc
diff --git a/modular_skyrat/modules/novaya_ert/code/outfit.dm b/modular_skyrat/modules/novaya_ert/code/outfit.dm
index e9331538f24..a88805933af 100644
--- a/modular_skyrat/modules/novaya_ert/code/outfit.dm
+++ b/modular_skyrat/modules/novaya_ert/code/outfit.dm
@@ -26,26 +26,6 @@
id = /obj/item/card/id/advanced/centcom/ert/nri
id_trim = /datum/id_trim/nri
-/datum/outfit/centcom/ert/nri/heavy
- name = "Novaya Rossiyskaya Imperiya Heavy Soldier"
- head = /obj/item/clothing/head/helmet/nri_heavy
- suit = /obj/item/clothing/suit/armor/heavy/nri
- glasses = /obj/item/clothing/glasses/hud/security/night
- mask = /obj/item/clothing/mask/gas/hecu2
- belt = /obj/item/storage/belt/military/nri/heavy
- suit_store = null
- back = /obj/item/storage/backpack/duffelbag/syndie/nri
- backpack_contents = list(/obj/item/storage/box/nri_survival_pack,
- /obj/item/storage/medkit/emergency,
- /obj/item/advanced_choice_beacon/nri/heavy,
- /obj/item/beamout_tool,
- /obj/item/crucifix)
- l_pocket = /obj/item/wrench/combat
-
- l_hand = /obj/item/gun/ballistic/automatic/pistol/aps
-
- id_trim = /datum/id_trim/nri/heavy
-
/datum/outfit/centcom/ert/nri/commander
name = "Novaya Rossiyskaya Imperiya Platoon Commander"
head = null
diff --git a/modular_skyrat/modules/novaya_ert/code/suit.dm b/modular_skyrat/modules/novaya_ert/code/suit.dm
index b363c2f212a..4466bd26da4 100644
--- a/modular_skyrat/modules/novaya_ert/code/suit.dm
+++ b/modular_skyrat/modules/novaya_ert/code/suit.dm
@@ -8,84 +8,6 @@
#define NRI_HEAL_AMOUNT 10
#define NRI_BLOOD_REPLENISHMENT 20
-/obj/item/clothing/suit/armor/vest/russian/nri
- name = "\improper B42M combined armor vest"
- desc = "A B42M combined body armor designed to protect the torso from bullets, shrapnel and blunt force. This vest performed well in the Border War against SolFed, but NRI required significant design changes due to the enemy's new and improved weaponry. These models were recently phased out and then quickly found their way onto the black market, now commonly seen in the hands (or on the bodies) of insurgents."
- icon = 'modular_skyrat/master_files/icons/obj/clothing/suits/armor.dmi'
- worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/suits/armor.dmi'
- worn_icon_teshari = 'modular_skyrat/master_files/icons/mob/clothing/species/teshari/suit.dmi'
- icon_state = "russian_green_armor"
- armor_type = /datum/armor/russian_nri
- supports_variations_flags = CLOTHING_NO_VARIATION
- inhand_icon_state = "armor"
- uses_advanced_reskins = TRUE
- unique_reskin = list(
- "Basic" = list(
- RESKIN_ICON_STATE = "russian_green_armor",
- RESKIN_WORN_ICON_STATE = "russian_green_armor"
- ),
- "Corpsman" = list(
- RESKIN_ICON_STATE = "russian_medic_armor",
- RESKIN_WORN_ICON_STATE = "russian_medic_armor"
- ),
- )
-
-/datum/armor/russian_nri
- melee = 30
- bullet = 40
- laser = 20
- energy = 30
- bomb = 35
- fire = 50
- acid = 50
- wound = 15
-
-/obj/item/clothing/suit/armor/heavy/nri
- name = "\improper Cordun-M armor system"
- desc = "A robust set of full-body armor designed for the harshest of environments. A modern set of heavy armor recently implemented by NRI Defense Collegium to accomodate with modern specifications. While a combination of lighter materials and a passive internal exoskeleton might assist the user's movement, you'll still be as slow as a snail."
- icon = 'modular_skyrat/master_files/icons/obj/clothing/suits/armor.dmi'
- worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/suits/armor.dmi'
- worn_icon_teshari = 'modular_skyrat/master_files/icons/mob/clothing/species/teshari/suit.dmi'
- icon_state = "russian_heavy_armor"
- armor_type = /datum/armor/heavy_nri
- resistance_flags = FIRE_PROOF|UNACIDABLE|ACID_PROOF|FREEZE_PROOF
- clothing_flags = STOPSPRESSUREDAMAGE|SNUG_FIT|BLOCK_GAS_SMOKE_EFFECT|THICKMATERIAL
- slowdown = 1.5
- equip_delay_self = 5 SECONDS
- supports_variations_flags = CLOTHING_DIGITIGRADE_VARIATION
-
-/datum/armor/heavy_nri
- melee = 60
- bullet = 60
- laser = 50
- energy = 50
- bomb = 100
- bio = 100
- fire = 70
- acid = 70
- wound = 35
-
-/obj/item/clothing/suit/armor/heavy/nri/old
- name = "\improper REDUT armor system"
- desc = "A strong set of full-body armor designed for harsh environments. After the NRI withdrew them, these models found their way onto the black market and have been rarely used by freelance mercenaries and planetary militias ever since, because of their relatively low cost."
- icon = 'modular_skyrat/master_files/icons/obj/clothing/suits/armor.dmi'
- worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/suits/armor.dmi'
- armor_type = /datum/armor/nri_old
- resistance_flags = FIRE_PROOF|ACID_PROOF|FREEZE_PROOF
- clothing_flags = SNUG_FIT|THICKMATERIAL
- slowdown = 2
-
-/datum/armor/nri_old
- melee = 50
- bullet = 50
- laser = 40
- energy = 40
- bomb = 75
- bio = 60
- fire = 45
- acid = 45
- wound = 20
-
/obj/item/clothing/suit/space/hev_suit/nri
name = "\improper VOSKHOD powered combat armor"
desc = "A hybrid set of space-resistant armor built on a modified mass-produced Nomex-Aerogel flight suit, polyurea coated durathread-lined light plasteel plates hinder mobility as little as possible while the onboard life support system aids the user in combat. The power cell is what makes the armor work without hassle, a sticker in the power supply unit warns anyone reading to responsibly manage battery levels."
diff --git a/modular_skyrat/modules/novaya_ert/sound/flatline.ogg b/modular_skyrat/modules/novaya_ert/sound/flatline.ogg
new file mode 100644
index 00000000000..93712b6da64
Binary files /dev/null and b/modular_skyrat/modules/novaya_ert/sound/flatline.ogg differ
diff --git a/modular_skyrat/modules/opposing_force/code/equipment/clothing.dm b/modular_skyrat/modules/opposing_force/code/equipment/clothing.dm
index 1154c5973b9..1756407a2b9 100644
--- a/modular_skyrat/modules/opposing_force/code/equipment/clothing.dm
+++ b/modular_skyrat/modules/opposing_force/code/equipment/clothing.dm
@@ -59,19 +59,6 @@
name = "NRI Commander Beret"
description = "An armored beret worn by high-ranking NRI officers"
-/datum/opposing_force_equipment/clothing/reduthelm
- item_type = /obj/item/clothing/head/helmet/nri_heavy/old
- description = "A specialized ultra-heavy composite ballistic helmet stolen from space russians. Purpose-built for heavy duty combat, \
- or murder with a frying pan."
- admin_note = "WARNING: This helmet is very well armored, equal to an elite nukie suits helmets with the armor deployed."
-
-/datum/opposing_force_equipment/clothing/nrivest
- item_type = /obj/item/clothing/suit/armor/vest/russian/nri
-
-/datum/opposing_force_equipment/clothing/redut
- item_type = /obj/item/clothing/suit/armor/heavy/nri/old
- admin_note = "WARNING: This is an extremely strong armor, with a decent slowdown, comparable to an elite nukie hardsuit with the armor deployed."
-
/datum/opposing_force_equipment/clothing/nrijumpsuit
item_type = /obj/item/clothing/under/costume/nri
diff --git a/modular_skyrat/modules/opposing_force/code/equipment/misc.dm b/modular_skyrat/modules/opposing_force/code/equipment/misc.dm
index b23096ab270..0b284e0987a 100644
--- a/modular_skyrat/modules/opposing_force/code/equipment/misc.dm
+++ b/modular_skyrat/modules/opposing_force/code/equipment/misc.dm
@@ -48,37 +48,3 @@
item_type = /obj/item/storage/box/syndie_kit/origami_bundle
description = "A box containing a guide on how to craft masterful works of origami, allowing you to transform normal pieces of paper into \
perfectly aerodynamic (and potentially lethal) paper airplanes."
-
-/datum/opposing_force_equipment/other/surplus
- name = "Surplus Crate"
- item_type = /obj/effect/gibspawner/generic
- description = "A dusty crate from the back of the Syndicate warehouse. Rumored to contain a valuable assortment of items, \
- but you never know. Contents are sorted to always be worth 50 TC."
- admin_note = "WARNING: Unless there is very-good reason, avoid giving this out, equals about 50tc worth of items and could be almost anything traitor related."
- var/telecrystal_count = 50
-
-/datum/opposing_force_equipment/other/surplus/on_issue(mob/living/target)
- var/list/uplink_items = list()
- var/obj/structure/closet/crate/holder_crate = new(get_turf(target))
- for(var/datum/uplink_item/item_path as anything in SStraitor.uplink_items_by_type)
- var/datum/uplink_item/item = SStraitor.uplink_items_by_type[item_path]
- if(item.purchasable_from & UPLINK_TRAITORS)
- uplink_items += item
-
- while(telecrystal_count)
- var/datum/uplink_item/uplink_item = pick(uplink_items)
- if(!uplink_item.surplus || prob(100 - uplink_item.surplus))
- continue
- if(telecrystal_count < uplink_item.cost)
- continue
- if(!uplink_item.item)
- continue
- telecrystal_count -= uplink_item.cost
- new uplink_item.item(holder_crate)
-
-/datum/opposing_force_equipment/other/surplus/super
- name = "Super Surplus Crate"
- description = "A dusty SUPER-SIZED crate from the back of the Syndicate warehouse. Rumored to contain a valuable assortment of items, \
- but you never know. Contents are sorted to always be worth 125 TC."
- telecrystal_count = 125
- admin_note = "WARNING: This should only be given out for events, absolutely no guarantee whatsoever of what will come out of this. Contents equal to 125 TC."
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 09409fdf811..beb05614011 100644
--- a/modular_skyrat/modules/player_ranks/code/subsystem/player_ranks.dm
+++ b/modular_skyrat/modules/player_ranks/code/subsystem/player_ranks.dm
@@ -46,15 +46,17 @@ SUBSYSTEM_DEF(player_ranks)
*
* Arguments:
* * user - The client to verify the donator status of.
+ * * admin_bypass - Whether or not admins can succeed this check, even if they
+ * do not actually possess the role. Defaults to `TRUE`.
*/
-/datum/controller/subsystem/player_ranks/proc/is_donator(client/user)
+/datum/controller/subsystem/player_ranks/proc/is_donator(client/user, admin_bypass = TRUE)
if(!istype(user))
CRASH("Invalid user type provided to is_donator(), expected 'client' and obtained '[user ? user.type : "null"]'.")
if(GLOB.donator_list[user.ckey])
return TRUE
- if(is_admin(user))
+ if(admin_bypass && is_admin(user))
return TRUE
return FALSE
@@ -66,12 +68,14 @@ SUBSYSTEM_DEF(player_ranks)
*
* Arguments:
* * user - The client to verify the mentor status of.
+ * * admin_bypass - Whether or not admins can succeed this check, even if they
+ * do not actually possess the role. Defaults to `TRUE`.
*/
-/datum/controller/subsystem/player_ranks/proc/is_mentor(client/user)
+/datum/controller/subsystem/player_ranks/proc/is_mentor(client/user, admin_bypass = TRUE)
if(!istype(user))
CRASH("Invalid user type provided to is_mentor(), expected 'client' and obtained '[user ? user.type : "null"]'.")
- return user.is_mentor()
+ return user.is_mentor(admin_bypass)
/**
@@ -79,8 +83,10 @@ SUBSYSTEM_DEF(player_ranks)
*
* Arguments:
* * user - The client to verify the veteran status of.
+ * * admin_bypass - Whether or not admins can succeed this check, even if they
+ * do not actually possess the role. Defaults to `TRUE`.
*/
-/datum/controller/subsystem/player_ranks/proc/is_veteran(client/user)
+/datum/controller/subsystem/player_ranks/proc/is_veteran(client/user, admin_bypass = TRUE)
// BUBBER EDIT REMOVAL - Down with sponsored metacliques and player elistism systems.
return TRUE
@@ -90,7 +96,7 @@ SUBSYSTEM_DEF(player_ranks)
if(GLOB.veteran_list[user.ckey])
return TRUE
- if(is_admin(user))
+ if(admin_bypass && is_admin(user))
return TRUE
return FALSE */
diff --git a/modular_skyrat/modules/poly_commands/parrot.dm b/modular_skyrat/modules/poly_commands/parrot.dm
index df8c73ef882..f522edf7da1 100644
--- a/modular_skyrat/modules/poly_commands/parrot.dm
+++ b/modular_skyrat/modules/poly_commands/parrot.dm
@@ -12,7 +12,7 @@
/mob/living/simple_animal/parrot/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans, list/message_mods = list(), message_range)
. = ..()
- if(check_command(message, speaker))
+ if(check_command(raw_message, speaker))
return
if(speaker != src && prob(50)) //Dont imitate ourselves
if(!radio_freq || prob(10))
@@ -20,7 +20,7 @@
speech_buffer -= pick(speech_buffer)
speech_buffer |= html_decode(raw_message)
if(speaker == src && !client) //If a parrot squawks in the woods and no one is around to hear it, does it make a sound? This code says yes!
- return message
+ return raw_message
/mob/living/simple_animal/parrot/proc/perch_on_human(mob/living/carbon/human/human_target)
if(!human_target)
@@ -61,30 +61,30 @@
/mob/living/simple_animal/parrot/poly/proc/command_perch(mob/living/carbon/human/human_target)
if (!buckled)
buckled_to_human = FALSE
- if(human_target.buckled_mobs?.len >= human_target.max_buckled_mobs)
+ if(LAZYLEN(human_target.buckled_mobs) >= human_target.max_buckled_mobs)
return
if(buckled_to_human)
- emote("me", EMOTE_VISIBLE, "gives [human_target] a confused look, squawking softly.")
+ manual_emote("gives [human_target] a confused look, squawking softly.")
return
if(get_dist(src, human_target) > 1 || buckled) // Only adjacent
- emote("me", EMOTE_VISIBLE, "tilts their head at [human_target], before bawking loudly and staying put.")
+ manual_emote("tilts their head at [human_target], before bawking loudly and staying put.")
return
- emote("me", EMOTE_VISIBLE, "obediently hops up onto [human_target]'s shoulder, spreading their wings for a moment before settling down.")
+ manual_emote("obediently hops up onto [human_target]'s shoulder, spreading their wings for a moment before settling down.")
perch_on_human(human_target)
/mob/living/simple_animal/parrot/poly/proc/command_hop_off(mob/living/carbon/human/human_target)
if (!buckled)
buckled_to_human = FALSE
if(!buckled_to_human || !buckled)
- emote("me", EMOTE_VISIBLE, "gives [human_target] a confused look, squawking softly.")
+ manual_emote("gives [human_target] a confused look, squawking softly.")
return
icon_state = icon_living
parrot_state = PARROT_WANDER
if(buckled)
- to_chat(src, span_notice("You are no longer sitting on [buckled]."))
+ to_chat(src, span_notice("You are no longer sitting on [human_target]."))
buckled.unbuckle_mob(src, TRUE)
- emote("me", EMOTE_VISIBLE, "squawks and hops off of [buckled], flying away.")
+ manual_emote("squawks and hops off of [human_target], flying away.")
buckled = null
buckled_to_human = FALSE
pixel_x = initial(pixel_x)
diff --git a/modular_skyrat/modules/primitive_cooking_additions/code/big_mortar.dm b/modular_skyrat/modules/primitive_cooking_additions/code/big_mortar.dm
index 23069d83941..3c2fc629a79 100644
--- a/modular_skyrat/modules/primitive_cooking_additions/code/big_mortar.dm
+++ b/modular_skyrat/modules/primitive_cooking_additions/code/big_mortar.dm
@@ -59,6 +59,28 @@
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
/obj/structure/large_mortar/attackby(obj/item/attacking_item, mob/living/carbon/human/user)
+ if(istype(attacking_item, /obj/item/storage/bag))
+ if(length(contents) >= maximum_contained_items)
+ balloon_alert(user, "already full")
+ return TRUE
+
+ if(!length(attacking_item.contents))
+ balloon_alert(user, "nothing to transfer!")
+ return TRUE
+
+ for(var/obj/item/target_item in attacking_item.contents)
+ if(length(contents) >= maximum_contained_items)
+ break
+
+ if(target_item.juice_typepath || target_item.grind_results)
+ target_item.forceMove(src)
+
+ if (length(contents) >= maximum_contained_items)
+ balloon_alert(user, "filled!")
+ else
+ balloon_alert(user, "transferred")
+ return TRUE
+
if(istype(attacking_item, /obj/item/pestle))
if(!anchored)
balloon_alert(user, "secure to ground first")
@@ -90,7 +112,7 @@
switch(picked_option)
if("Juice")
for(var/obj/item/target_item as anything in contents)
- if(target_item.juice_results)
+ if(target_item.juice_typepath)
juice_target_item(target_item, user)
else
grind_target_item(target_item, user)
@@ -103,7 +125,7 @@
juice_target_item(target_item, user)
return
- if(!attacking_item.juice_results && !attacking_item.grind_results)
+ if(!attacking_item.grind_results && !attacking_item.juice_typepath)
balloon_alert(user, "can't grind this")
return ..()
@@ -112,27 +134,20 @@
return
attacking_item.forceMove(src)
+ return ..()
///Juices the passed target item, and transfers any contained chems to the mortar as well
/obj/structure/large_mortar/proc/juice_target_item(obj/item/to_be_juiced, mob/living/carbon/human/user)
- to_be_juiced.on_juice()
- reagents.add_reagent_list(to_be_juiced.juice_results)
+ to_be_juiced.juice(src.reagents, user)
- if(to_be_juiced.reagents) //If juiced item has reagents within, transfer them to the mortar
- to_be_juiced.reagents.trans_to(src, to_be_juiced.reagents.total_volume, transfered_by = user)
-
- to_chat(user, span_notice("You juice [to_be_juiced] into a fine liquid."))
+ to_chat(user, span_notice("You juice [to_be_juiced] into a liquid."))
QDEL_NULL(to_be_juiced)
///Grinds the passed target item, and transfers any contained chems to the mortar as well
/obj/structure/large_mortar/proc/grind_target_item(obj/item/to_be_ground, mob/living/carbon/human/user)
- to_be_ground.on_grind()
- reagents.add_reagent_list(to_be_ground.grind_results)
+ to_be_ground.grind(src.reagents, user)
- if(to_be_ground.reagents) //If grinded item has reagents within, transfer them to the mortar
- to_be_ground.reagents.trans_to(src, to_be_ground.reagents.total_volume, transfered_by = user)
-
- to_chat(user, span_notice("You break [to_be_ground] into powder."))
+ to_chat(user, span_notice("You break [to_be_ground] into a fine powder."))
QDEL_NULL(to_be_ground)
#undef LARGE_MORTAR_STAMINA_MINIMUM
diff --git a/modular_skyrat/modules/primitive_cooking_additions/code/millstone.dm b/modular_skyrat/modules/primitive_cooking_additions/code/millstone.dm
index 92a43c8b45c..314390a7f54 100644
--- a/modular_skyrat/modules/primitive_cooking_additions/code/millstone.dm
+++ b/modular_skyrat/modules/primitive_cooking_additions/code/millstone.dm
@@ -66,6 +66,44 @@
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
/obj/structure/millstone/attackby(obj/item/attacking_item, mob/user)
+ if(istype(attacking_item, /obj/item/storage/bag))
+ if(length(contents) >= maximum_contained_items)
+ balloon_alert(user, "already full")
+ return TRUE
+
+ if(!length(attacking_item.contents))
+ balloon_alert(user, "nothing to transfer!")
+ return TRUE
+
+ for(var/obj/item/food/grown/target_item in attacking_item.contents)
+ if(length(contents) >= maximum_contained_items)
+ break
+
+ target_item.forceMove(src)
+
+ if (length(contents) >= maximum_contained_items)
+ balloon_alert(user, "filled!")
+ else
+ balloon_alert(user, "transferred")
+
+ return TRUE
+
+ if(attacking_item.tool_behaviour == TOOL_WRENCH)
+ attacking_item.play_tool_sound(src)
+ anchored = !anchored
+ balloon_alert(user, "[src] [anchored ? "anchored" : "unanchored"]")
+ return TRUE
+
+ if(attacking_item.tool_behaviour == TOOL_SCREWDRIVER)
+ attacking_item.play_tool_sound(src)
+
+ for(var/i in 1 to 6)
+ var/obj/item/stack/sheet/mineral/stone = new (get_turf(src))
+ transfer_fingerprints_to(stone)
+
+ qdel(src)
+ return TRUE
+
if(!((istype(attacking_item, /obj/item/food/grown/)) || (istype(attacking_item, /obj/item/grown))))
balloon_alert(user, "can only mill plants")
return ..()
@@ -75,6 +113,7 @@
return
attacking_item.forceMove(src)
+ return ..()
/// Takes the content's seeds and spits them out on the turf, as well as grinding whatever the contents may be
/obj/structure/millstone/proc/mill_it_up(mob/living/carbon/human/user)
diff --git a/modular_skyrat/modules/robohand/code/bodypart_autosurgeon.dm b/modular_skyrat/modules/robohand/code/bodypart_autosurgeon.dm
index 61f1e618a2e..46de28831c2 100644
--- a/modular_skyrat/modules/robohand/code/bodypart_autosurgeon.dm
+++ b/modular_skyrat/modules/robohand/code/bodypart_autosurgeon.dm
@@ -91,4 +91,3 @@
/obj/item/autosurgeon/bodypart/r_arm_robotic/Initialize(mapload)
. = ..()
storedbodypart.icon = 'modular_skyrat/master_files/icons/mob/augmentation/hi2ipc.dmi'
- storedbodypart.organic_render = FALSE
diff --git a/modular_skyrat/modules/sec_haul/code/misc/bullet_drive.dm b/modular_skyrat/modules/sec_haul/code/misc/bullet_drive.dm
index 747601cb1f1..7abf5585e08 100644
--- a/modular_skyrat/modules/sec_haul/code/misc/bullet_drive.dm
+++ b/modular_skyrat/modules/sec_haul/code/misc/bullet_drive.dm
@@ -6,7 +6,7 @@
density = TRUE
circuit = /obj/item/circuitboard/machine/dish_drive/bullet
collectable_items = list(/obj/item/ammo_casing)
- succrange = 10
+ suck_distance = 8
binrange = 10
/obj/item/circuitboard/machine/dish_drive/bullet
@@ -52,7 +52,7 @@
do_the_dishes()
if(!suction_enabled)
return
- for(var/obj/item/I in view(succrange, src))
+ for(var/obj/item/I in view(2 + suck_distance, src))
if(istype(I, /obj/machinery/dish_drive/bullet))
visible_message(span_userdanger("[src] has detected another bullet drive nearby, and is sad!"))
break
diff --git a/modular_skyrat/modules/sec_haul/code/misc/packs.dm b/modular_skyrat/modules/sec_haul/code/misc/packs.dm
index 9b69bd8afc9..4782e9ca6d6 100644
--- a/modular_skyrat/modules/sec_haul/code/misc/packs.dm
+++ b/modular_skyrat/modules/sec_haul/code/misc/packs.dm
@@ -1,4 +1,4 @@
-/datum/supply_pack/vending/sectech
+/datum/supply_pack/vending/sectech_skyrat
name = "Peacekeeper Equipment Supply Crate"
desc = "Armadyne branded Peacekeeper supply crate, filled with things you need to restock the equipment vendor."
cost = CARGO_CRATE_VALUE * 3
@@ -7,7 +7,7 @@
crate_name = "Peacekeeper equipment supply crate"
crate_type = /obj/structure/closet/crate/secure/gear
-/datum/supply_pack/vending/wardrobes/security
+/datum/supply_pack/vending/wardrobes/security_skyrat
name = "Peacekeeper Wardrobe Supply Crate"
desc = "This crate contains refills for the Peacekeeper Outfitting Station and LawDrobe."
cost = CARGO_CRATE_VALUE * 3
diff --git a/modular_skyrat/modules/sec_haul/readme.md b/modular_skyrat/modules/sec_haul/readme.md
index fd645b249c6..7133a179464 100644
--- a/modular_skyrat/modules/sec_haul/readme.md
+++ b/modular_skyrat/modules/sec_haul/readme.md
@@ -16,7 +16,8 @@ Completely overhauls security to something that will hopefully fit us.
### Master file additions
-- N/A
+- `modular_skyrat/master_files/code/modules/cargo/packs/vending_restock.dm`: `var/special`
+- `modular_skyrat/master_files/code/modules/cargo/packs/security.dm`: `var/special`, `var/cost`
### Included files that are not contained in this module:
diff --git a/modular_skyrat/modules/stone/code/stone.dm b/modular_skyrat/modules/stone/code/stone.dm
index fb7ecd3f43a..e41ac38f344 100644
--- a/modular_skyrat/modules/stone/code/stone.dm
+++ b/modular_skyrat/modules/stone/code/stone.dm
@@ -20,6 +20,7 @@
GLOBAL_LIST_INIT(stone_recipes, list ( \
new/datum/stack_recipe("stone brick wall", /turf/closed/wall/mineral/stone, 5, one_per_turf = 1, on_solid_ground = 1, applies_mats = TRUE, category = CAT_STRUCTURE), \
new/datum/stack_recipe("stone brick tile", /obj/item/stack/tile/mineral/stone, 1, 4, 20, check_density = FALSE, category = CAT_TILES),
+ new/datum/stack_recipe("millstone", /obj/structure/millstone, 6, one_per_turf = 1, on_solid_ground = 1, category = CAT_STRUCTURE),
))
/obj/item/stack/sheet/mineral/stone/get_main_recipes()
@@ -54,7 +55,7 @@ GLOBAL_LIST_INIT(stone_recipes, list ( \
. += span_notice("With a chisel or even a pickaxe of some kind, you could cut this into blocks.")
/obj/item/stack/stone/attackby(obj/item/attacking_item, mob/user, params)
- if((attacking_item.tool_behaviour != TOOL_MINING) || !(istype(attacking_item, /obj/item/chisel)))
+ if((attacking_item.tool_behaviour != TOOL_MINING) && !(istype(attacking_item, /obj/item/chisel)))
return ..()
playsound(src, 'sound/effects/picaxe1.ogg', 50, TRUE)
balloon_alert_to_viewers("cutting...")
@@ -127,3 +128,9 @@ GLOBAL_LIST_INIT(stone_recipes, list ( \
smoothing_flags = SMOOTH_BITMASK
smoothing_groups = SMOOTH_GROUP_STONE_WALLS + SMOOTH_GROUP_WALLS + SMOOTH_GROUP_CLOSED_TURFS
canSmoothWith = SMOOTH_GROUP_STONE_WALLS
+
+/turf/closed/mineral/gets_drilled(mob/user, give_exp = FALSE)
+ if(prob(5))
+ new /obj/item/stack/stone(src)
+
+ return ..()
diff --git a/modular_skyrat/modules/supermatter_surge/code/supermatter_surge.dm b/modular_skyrat/modules/supermatter_surge/code/supermatter_surge.dm
deleted file mode 100644
index 351903a3e49..00000000000
--- a/modular_skyrat/modules/supermatter_surge/code/supermatter_surge.dm
+++ /dev/null
@@ -1,70 +0,0 @@
-#define SUPERMATTER_SURGE_BULLET_ENERGY_FACTOR_UPPER 300
-#define SUPERMATTER_SURGE_BULLET_ENERGY_FACTOR_LOWER 100
-#define SUPERMATTER_SURGE_TIME_UPPER 360 * 0.5
-#define SUPERMATTER_SURGE_TIME_LOWER 180 * 0.5
-#define SUPERMATTER_SURGE_ANNOUNCE_THRESHOLD 25
-#define LOWER_SURGE_LIMIT 100 to 150
-#define MIDDLE_SURGE_LIMIT 151 to 200
-#define UPPER_SURGE_LIMIT 201 to 250
-/**
- * Supermatter Surge
- *
- * A very simple event designed to give engineering a challenge. It simply increases the supermatters power by a set amount, and announces it.
- *
- * This should be entirely fine for a powerful setup, but will require intervention on a lower power setup.
- */
-
-/datum/round_event_control/supermatter_surge
- name = "Supermatter Surge"
- typepath = /datum/round_event/supermatter_surge
- category = EVENT_CATEGORY_ENGINEERING
- max_occurrences = 4
- earliest_start = 30 MINUTES
- description = "The supermatter will increase in power by a random amount, and announce it."
-
-/datum/round_event/supermatter_surge
- announce_when = 1
- end_when = SUPERMATTER_SURGE_TIME_LOWER
- /// How powerful is the supermatter surge going to be? Set in setup.
- var/surge_power = SUPERMATTER_SURGE_BULLET_ENERGY_FACTOR_LOWER
- var/starting_surge_power = 0
- /// Typecasted reference to the supermatter chosen at the events start. Prevents the engine from going AWOL if it changes for some reason.
- var/obj/machinery/power/supermatter_crystal/our_main_engine
-
-/datum/round_event/supermatter_surge/setup()
- our_main_engine = GLOB.main_supermatter_engine
- surge_power = rand(SUPERMATTER_SURGE_BULLET_ENERGY_FACTOR_LOWER, SUPERMATTER_SURGE_BULLET_ENERGY_FACTOR_UPPER)
- starting_surge_power = our_main_engine.bullet_energy
- end_when = rand(SUPERMATTER_SURGE_TIME_LOWER, SUPERMATTER_SURGE_TIME_UPPER)
-
-/datum/round_event/supermatter_surge/announce()
- if(surge_power > SUPERMATTER_SURGE_ANNOUNCE_THRESHOLD || prob(round(surge_power)))
- priority_announce("Class [get_surge_level()] supermatter surge detected. Intervention may be required.", "Anomaly Alert", ANNOUNCER_KLAXON)
-
-/datum/round_event/supermatter_surge/proc/get_surge_level()
- switch(surge_power)
- if(LOWER_SURGE_LIMIT)
- return 4
- if(MIDDLE_SURGE_LIMIT)
- return 3
- if(UPPER_SURGE_LIMIT)
- return 2
- else
- return 1
-
-/datum/round_event/supermatter_surge/start()
- our_main_engine?.bullet_energy *= surge_power
-
-/datum/round_event/supermatter_surge/end()
- our_main_engine?.bullet_energy = starting_surge_power
- priority_announce("The supermatter surge has dissipated.", "Anomaly Cleared")
- our_main_engine = null
-
-#undef SUPERMATTER_SURGE_BULLET_ENERGY_FACTOR_UPPER
-#undef SUPERMATTER_SURGE_BULLET_ENERGY_FACTOR_LOWER
-#undef SUPERMATTER_SURGE_TIME_UPPER
-#undef SUPERMATTER_SURGE_TIME_LOWER
-#undef SUPERMATTER_SURGE_ANNOUNCE_THRESHOLD
-#undef LOWER_SURGE_LIMIT
-#undef MIDDLE_SURGE_LIMIT
-#undef UPPER_SURGE_LIMIT
diff --git a/modular_skyrat/modules/synths/code/reagents/reagents.dm b/modular_skyrat/modules/synths/code/reagents/reagents.dm
index b99291084f2..ef48f0bf947 100644
--- a/modular_skyrat/modules/synths/code/reagents/reagents.dm
+++ b/modular_skyrat/modules/synths/code/reagents/reagents.dm
@@ -78,7 +78,7 @@
return ..()
affected_mob.reagents.remove_reagent(type, NANITE_SLURRY_ORGANIC_PURGE_RATE) //gets removed from organics very fast
if(prob(NANITE_SLURRY_ORGANIC_VOMIT_CHANCE))
- affected_mob.vomit(vomit_type = VOMIT_NANITE)
+ affected_mob.vomit(vomit_flags = (MOB_VOMIT_MESSAGE | MOB_VOMIT_HARM), vomit_type = /obj/effect/decal/cleanable/vomit/nanites)
return TRUE
#undef NANITE_SLURRY_ORGANIC_PURGE_RATE
diff --git a/modular_skyrat/modules/tribal_extended/code/ammo/reusable/arrow.dm b/modular_skyrat/modules/tribal_extended/code/ammo/reusable/arrow.dm
index dbd807d16e5..0fdfb0967d1 100644
--- a/modular_skyrat/modules/tribal_extended/code/ammo/reusable/arrow.dm
+++ b/modular_skyrat/modules/tribal_extended/code/ammo/reusable/arrow.dm
@@ -5,8 +5,12 @@
/obj/projectile/bullet/arrow/prehit_pierce(mob/living/target, mob/living/carbon/human/user)
if(isnull(target))
return ..()
- if(target.type in nemesis_paths)
- damage += faction_bonus_force
+
+ // check if target is a matching type and apply damage bonus if applicable
+ for(var/nemesis_path in nemesis_paths)
+ if(istype(target, nemesis_path))
+ damage += faction_bonus_force
+ break
return ..()
diff --git a/modular_skyrat/modules/xenoarch/code/modules/hydroponics/amauri.dm b/modular_skyrat/modules/xenoarch/code/modules/hydroponics/amauri.dm
index af6c178a007..ed234b942e8 100644
--- a/modular_skyrat/modules/xenoarch/code/modules/hydroponics/amauri.dm
+++ b/modular_skyrat/modules/xenoarch/code/modules/hydroponics/amauri.dm
@@ -24,5 +24,5 @@
filling_color = "#FF4500"
bite_consumption_mod = 0.5
foodtypes = FRUIT
- juice_results = list(/datum/reagent/medicine/psicodine = 0)
+ juice_typepath = /datum/reagent/medicine/psicodine
tastes = list("shadow" = 1)
diff --git a/modular_skyrat/modules/xenoarch/code/modules/hydroponics/gelthi.dm b/modular_skyrat/modules/xenoarch/code/modules/hydroponics/gelthi.dm
index 63013a631dc..3ff46763f1e 100644
--- a/modular_skyrat/modules/xenoarch/code/modules/hydroponics/gelthi.dm
+++ b/modular_skyrat/modules/xenoarch/code/modules/hydroponics/gelthi.dm
@@ -24,5 +24,5 @@
filling_color = "#FF4500"
bite_consumption_mod = 0.5
foodtypes = FRUIT
- juice_results = list(/datum/reagent/gold = 0)
+ juice_typepath = /datum/reagent/gold
tastes = list("gold" = 1)
diff --git a/modular_skyrat/modules/xenoarch/code/modules/hydroponics/jurlmah.dm b/modular_skyrat/modules/xenoarch/code/modules/hydroponics/jurlmah.dm
index 95dda523b59..5351435276b 100644
--- a/modular_skyrat/modules/xenoarch/code/modules/hydroponics/jurlmah.dm
+++ b/modular_skyrat/modules/xenoarch/code/modules/hydroponics/jurlmah.dm
@@ -24,5 +24,5 @@
filling_color = "#FF4500"
bite_consumption_mod = 0.5
foodtypes = FRUIT
- juice_results = list(/datum/reagent/medicine/cryoxadone = 0)
+ juice_typepath = /datum/reagent/medicine/cryoxadone
tastes = list("cold" = 1)
diff --git a/modular_skyrat/modules/xenoarch/code/modules/hydroponics/nofruit.dm b/modular_skyrat/modules/xenoarch/code/modules/hydroponics/nofruit.dm
index 770259c1266..65d8625e5d8 100644
--- a/modular_skyrat/modules/xenoarch/code/modules/hydroponics/nofruit.dm
+++ b/modular_skyrat/modules/xenoarch/code/modules/hydroponics/nofruit.dm
@@ -24,5 +24,5 @@
filling_color = "#FF4500"
bite_consumption_mod = 0.5
foodtypes = FRUIT
- juice_results = list(/datum/reagent/consumable/nothing = 0)
+ juice_typepath = /datum/reagent/consumable/nothing
tastes = list("entertainment" = 1)
diff --git a/modular_skyrat/modules/xenoarch/code/modules/hydroponics/shand.dm b/modular_skyrat/modules/xenoarch/code/modules/hydroponics/shand.dm
index a898cd99ed9..c028b7b6082 100644
--- a/modular_skyrat/modules/xenoarch/code/modules/hydroponics/shand.dm
+++ b/modular_skyrat/modules/xenoarch/code/modules/hydroponics/shand.dm
@@ -24,5 +24,5 @@
filling_color = "#FF4500"
bite_consumption_mod = 0.5
foodtypes = FRUIT
- juice_results = list(/datum/reagent/pax = 0)
+ juice_typepath = /datum/reagent/pax
tastes = list("peace" = 1)
diff --git a/modular_skyrat/modules/xenoarch/code/modules/hydroponics/surik.dm b/modular_skyrat/modules/xenoarch/code/modules/hydroponics/surik.dm
index b055083e428..073274209dd 100644
--- a/modular_skyrat/modules/xenoarch/code/modules/hydroponics/surik.dm
+++ b/modular_skyrat/modules/xenoarch/code/modules/hydroponics/surik.dm
@@ -24,5 +24,5 @@
filling_color = "#FF4500"
bite_consumption_mod = 0.5
foodtypes = FRUIT
- juice_results = list(/datum/reagent/consumable/frostoil = 0)
+ juice_typepath = /datum/reagent/consumable/frostoil
tastes = list("snow" = 1)
diff --git a/modular_skyrat/modules/xenoarch/code/modules/hydroponics/telriis.dm b/modular_skyrat/modules/xenoarch/code/modules/hydroponics/telriis.dm
index 0193e4e140b..7783cbdac1b 100644
--- a/modular_skyrat/modules/xenoarch/code/modules/hydroponics/telriis.dm
+++ b/modular_skyrat/modules/xenoarch/code/modules/hydroponics/telriis.dm
@@ -25,5 +25,5 @@
filling_color = "#FF4500"
bite_consumption_mod = 0.5
foodtypes = FRUIT
- juice_results = list(/datum/reagent/medicine/higadrite = 0)
+ juice_typepath = /datum/reagent/medicine/higadrite
tastes = list("liver" = 1)
diff --git a/modular_skyrat/modules/xenoarch/code/modules/hydroponics/thaadra.dm b/modular_skyrat/modules/xenoarch/code/modules/hydroponics/thaadra.dm
index 0c6384ed79a..e9eeadb274e 100644
--- a/modular_skyrat/modules/xenoarch/code/modules/hydroponics/thaadra.dm
+++ b/modular_skyrat/modules/xenoarch/code/modules/hydroponics/thaadra.dm
@@ -24,5 +24,5 @@
filling_color = "#FF4500"
bite_consumption_mod = 0.5
foodtypes = FRUIT
- juice_results = list(/datum/reagent/silver = 0)
+ juice_typepath = /datum/reagent/silver
tastes = list("silver" = 1)
diff --git a/modular_skyrat/modules/xenoarch/code/modules/hydroponics/vale.dm b/modular_skyrat/modules/xenoarch/code/modules/hydroponics/vale.dm
index b3a78598dae..adf8654d6b6 100644
--- a/modular_skyrat/modules/xenoarch/code/modules/hydroponics/vale.dm
+++ b/modular_skyrat/modules/xenoarch/code/modules/hydroponics/vale.dm
@@ -24,5 +24,5 @@
filling_color = "#FF4500"
bite_consumption_mod = 0.5
foodtypes = FRUIT
- juice_results = list(/datum/reagent/medicine/neurine = 0)
+ juice_typepath = /datum/reagent/medicine/neurine
tastes = list("medicine" = 1)
diff --git a/modular_skyrat/modules/xenoarch/code/modules/hydroponics/vaporsac.dm b/modular_skyrat/modules/xenoarch/code/modules/hydroponics/vaporsac.dm
index fb3d6f72efc..1f467a66ab6 100644
--- a/modular_skyrat/modules/xenoarch/code/modules/hydroponics/vaporsac.dm
+++ b/modular_skyrat/modules/xenoarch/code/modules/hydroponics/vaporsac.dm
@@ -24,5 +24,5 @@
filling_color = "#FF4500"
bite_consumption_mod = 0.5
foodtypes = FRUIT
- juice_results = list(/datum/reagent/nitrous_oxide = 0)
+ juice_typepath = /datum/reagent/nitrous_oxide
tastes = list("sleep" = 1)
diff --git a/modular_zubbers/code/_globalvars/lists/maintenance_loot_common.dm b/modular_zubbers/code/_globalvars/lists/maintenance_loot_common.dm
index e23a5f9d0f7..b272924536b 100644
--- a/modular_zubbers/code/_globalvars/lists/maintenance_loot_common.dm
+++ b/modular_zubbers/code/_globalvars/lists/maintenance_loot_common.dm
@@ -866,7 +866,6 @@ GLOBAL_LIST_INIT(common_loot, list( //common: basic items
/obj/item/food/tatortot = 100,
/obj/item/food/tofu/prison = 200,
/obj/item/reagent_containers/condiment/mayonnaise = 100,
- /obj/item/reagent_containers/condiment/cooking_oil = 25,
/obj/item/reagent_containers/condiment/cornmeal = 25,
/obj/item/reagent_containers/condiment/cherryjelly = 10,
/obj/item/reagent_containers/condiment/peanut_butter = 10,
diff --git a/modular_zubbers/code/_globalvars/lists/maintenance_loot_uncommon.dm b/modular_zubbers/code/_globalvars/lists/maintenance_loot_uncommon.dm
index 7871263b595..2141740be5d 100644
--- a/modular_zubbers/code/_globalvars/lists/maintenance_loot_uncommon.dm
+++ b/modular_zubbers/code/_globalvars/lists/maintenance_loot_uncommon.dm
@@ -168,7 +168,6 @@ GLOBAL_LIST_INIT(uncommon_loot, list(//uncommon: useful items
/obj/item/reagent_containers/cup/beaker = 100,
/obj/item/reagent_containers/cup/beaker/large = 10,
/obj/item/retractor = 25,
- /obj/item/roller = 50,
/obj/item/scalpel = 50,
/obj/item/sensor_device = 1,
/obj/item/sequence_scanner = 25,
diff --git a/modular_zubbers/code/datums/bubber_quirks/neutral.dm b/modular_zubbers/code/datums/bubber_quirks/neutral.dm
new file mode 100644
index 00000000000..cad9c0a742e
--- /dev/null
+++ b/modular_zubbers/code/datums/bubber_quirks/neutral.dm
@@ -0,0 +1,10 @@
+/datum/quirk/item_quirk/colorist
+ name = "Colorist"
+ desc = "You like carrying around a hair dye spray to quickly apply color patterns to your hair."
+ icon = FA_ICON_FILL_DRIP
+ value = 0
+ medical_record_text = "Patient enjoys dyeing their hair with pretty colors."
+ mail_goodies = list(/obj/item/dyespray)
+
+/datum/quirk/item_quirk/colorist/add_unique(client/client_source)
+ give_item_to_holder(/obj/item/dyespray, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
diff --git a/sound/ambience/ambimaint6.ogg b/sound/ambience/ambimaint6.ogg
new file mode 100644
index 00000000000..f83e3ed1d6b
Binary files /dev/null and b/sound/ambience/ambimaint6.ogg differ
diff --git a/sound/ambience/ambimaint7.ogg b/sound/ambience/ambimaint7.ogg
new file mode 100644
index 00000000000..3db2f226a4a
Binary files /dev/null and b/sound/ambience/ambimaint7.ogg differ
diff --git a/sound/ambience/license.txt b/sound/ambience/license.txt
index 5e75b772d11..607dd6628e7 100644
--- a/sound/ambience/license.txt
+++ b/sound/ambience/license.txt
@@ -11,4 +11,7 @@ title3.ogg is Tintin On The Moon remixed by Cuboos https://tgstation13.org/phpBB
VoidsEmbrace.ogg is Chopin - Waltz in C Sharp Minor (Op. 64 No. 2). It is in public domain.
+ambispace4.ogg is Sipping Bird, by Capsandi. It has been licensed under CC-BY 3.0 license.
+ambimaint6.ogg and ambimaint7.ogg, created by Capsandi are licensed under CC-BY 3.0 license.
+
CC-BY 3.0: http://creativecommons.org/licenses/by/3.0/
diff --git a/sound/attributions.txt b/sound/attributions.txt
index baeb5f30851..09ac2bd5642 100644
--- a/sound/attributions.txt
+++ b/sound/attributions.txt
@@ -88,6 +88,14 @@ https://freesound.org/people/squareal/sounds/237375/
ding_short.ogg is from Natty23 (CC 4)
https://freesound.org/people/Natty23/sounds/411747/
-
jingle.ogg is from Zapsplat (https://www.zapsplat.com/license-type/standard-license/)
https://www.zapsplat.com/sound-effect-category/sleigh-bells/
+
+tada_fanfare.ogg is adapted from plasterbrain's "Tada Fanfare A", which is public domain (CC 0):
+https://freesound.org/people/plasterbrain/sounds/397355/
+
+glockenspiel_ping.ogg is adapted from FunWithSound's "Short Success Sound Glockenspiel Treasure Video Game", which is public domain (CC 0):
+https://freesound.org/people/FunWithSound/sounds/456965/
+
+beeps_jingle.ogg is adapted from Eponn's "Achievement happy Beeps Jingle", which is public domain (CC 0):
+https://freesound.org/people/Eponn/sounds/619838/
diff --git a/sound/effects/alert.ogg b/sound/effects/alert.ogg
index 69bc52bdb80..e68847321e2 100644
Binary files a/sound/effects/alert.ogg and b/sound/effects/alert.ogg differ
diff --git a/sound/effects/beeps_jingle.ogg b/sound/effects/beeps_jingle.ogg
new file mode 100644
index 00000000000..0d4b647f88d
Binary files /dev/null and b/sound/effects/beeps_jingle.ogg differ
diff --git a/sound/effects/glockenspiel_ping.ogg b/sound/effects/glockenspiel_ping.ogg
new file mode 100644
index 00000000000..f2530007129
Binary files /dev/null and b/sound/effects/glockenspiel_ping.ogg differ
diff --git a/sound/effects/license.txt b/sound/effects/license.txt
index 77351397fde..04bb7108d95 100644
--- a/sound/effects/license.txt
+++ b/sound/effects/license.txt
@@ -4,3 +4,6 @@
cartoon_pop.ogg by Tobiasz 'unfa' Karoń
(https://freesound.org/people/unfa/sounds/245645/)
It has been licensed under CC-BY 3.0, which can be found at http://creativecommons.org/licenses/by/3.0/
+
+alert.ogg by bbrocer. Extended, looped, and reverbed
+https://freesound.org/people/bbrocer/sounds/389511/
\ No newline at end of file
diff --git a/sound/effects/tada_fanfare.ogg b/sound/effects/tada_fanfare.ogg
new file mode 100644
index 00000000000..055635e9dec
Binary files /dev/null and b/sound/effects/tada_fanfare.ogg differ
diff --git a/sound/items/hypospray.ogg b/sound/items/hypospray.ogg
new file mode 100644
index 00000000000..e5c7bd8f92b
Binary files /dev/null and b/sound/items/hypospray.ogg differ
diff --git a/sound/lavaland/bdm_boss.ogg b/sound/lavaland/bdm_boss.ogg
new file mode 100644
index 00000000000..a5c14095416
Binary files /dev/null and b/sound/lavaland/bdm_boss.ogg differ
diff --git a/sound/machines/engine_alert3.ogg b/sound/machines/engine_alert3.ogg
new file mode 100644
index 00000000000..394bfed2a13
Binary files /dev/null and b/sound/machines/engine_alert3.ogg differ
diff --git a/sound/magic/hereticknock.ogg b/sound/magic/hereticknock.ogg
new file mode 100644
index 00000000000..87ca57302a2
Binary files /dev/null and b/sound/magic/hereticknock.ogg differ
diff --git a/sound/misc/airraid.ogg b/sound/misc/airraid.ogg
index 820eaccf91d..cc9913becdd 100644
Binary files a/sound/misc/airraid.ogg and b/sound/misc/airraid.ogg differ
diff --git a/sound/misc/announce_syndi.ogg b/sound/misc/announce_syndi.ogg
new file mode 100644
index 00000000000..49c255bd0e9
Binary files /dev/null and b/sound/misc/announce_syndi.ogg differ
diff --git a/sound/misc/bloblarm.ogg b/sound/misc/bloblarm.ogg
index 93bcdbcc49a..2c934e1bf18 100644
Binary files a/sound/misc/bloblarm.ogg and b/sound/misc/bloblarm.ogg differ
diff --git a/sound/misc/license.txt b/sound/misc/license.txt
index b92a4a279a9..69ef2992820 100644
--- a/sound/misc/license.txt
+++ b/sound/misc/license.txt
@@ -2,4 +2,7 @@ bloop.ogg by my man Tim Khan
(https://freesound.org/people/tim.kahn/sounds/130377/)
knuckles.ogg by CGEffex. Shortened and cut.
-https://freesound.org/people/CGEffex/sounds/93981/
\ No newline at end of file
+https://freesound.org/people/CGEffex/sounds/93981/
+
+airraid.ogg by Jwade722. Shortened and cut.
+https://freesound.org/people/Jwade722/sounds/534550/
\ No newline at end of file
diff --git a/sound/misc/notice3.ogg b/sound/misc/notice3.ogg
new file mode 100644
index 00000000000..e41a4361ca6
Binary files /dev/null and b/sound/misc/notice3.ogg differ
diff --git a/strings/tips.txt b/strings/tips.txt
index 514a9dada7a..12248bb4124 100644
--- a/strings/tips.txt
+++ b/strings/tips.txt
@@ -13,9 +13,9 @@ As a Botanist, you should look into increasing the potency of your plants. This
As a Cargo Technician, you can earn more cargo points by shipping back crates from maintenance, liquid containers, plasma sheets, rare seeds from hydroponics, and more!
As a Cargo Technician, you can hack MULEbots to make them faster, run over people in their way, and even let you ride them!
As a Cargo Technician, you can order contraband items from the supply shuttle console by de-constructing it and using a multitool on the circuit board, the re-assembling it.
+As a Changeling, taking on someone else's appearance will also give you all of their scars. You can use Fleshmend to get rid of all scars.
As a Changeling, the Extract DNA sting counts for your genome absorb objective, but does not let you respec your powers.
As a Changeling, you can absorb someone by strangling them and using the Absorb verb; this gives you the ability to rechoose your powers, the DNA of whoever you absorbed, the memory of the absorbed, and some samples of things the absorbed said.
-As a Changeling, your Regenerate Limbs power will quickly heal all of your wounds, but they'll still leave scars. Changelings can use Fleshmend to get rid of scars, or you can ingest Carpotoxin to get rid of them like a normal person.
As a Chemist, some chemicals can only be synthesized by heating up the contents with a chemical heater or manually with lighters and similar tools.
As a Chemist, there are dozens of chemicals that can heal, and even more that can cause harm. Experiment!
As a Chemist, Water and Potassium mixed together will create an explosion, with power scaling by amount used. Don't do it.
@@ -267,3 +267,4 @@ You can spray a fire extinguisher, throw items or fire a gun while floating thro
You can swap floor tiles by holding a crowbar in one hand and a stack of tiles in the other.
You can use a machine in the vault to deposit cash or rob Cargo's department funds.
You'll quickly lose your interest in the game if you play to win and kill. If you find yourself doing this, take a step back and talk to people - it's a much better experience!
+Some areas of the station use simple nautical directions to indicate their respective locations, like Fore (Front of the ship), Aft (Back), Port (Left side), Starboard (Right), Quarter and Bow (Either sides of Aft and Fore, respectively). You can review these terms on the Notepad App of your PDA.
\ No newline at end of file
diff --git a/strings/wounds/bone_scar_desc.json b/strings/wounds/bone_scar_desc.json
index b1eb84bb8b7..2a89f022002 100644
--- a/strings/wounds/bone_scar_desc.json
+++ b/strings/wounds/bone_scar_desc.json
@@ -1,6 +1,11 @@
{
"generic": ["general disfigurement"],
+ "dislocate": [
+ "the bone equivalent of a faded bruise",
+ "a series of tiny chip marks"
+ ],
+
"bluntmoderate": [
"the bone equivalent of a faded bruise",
"a series of tiny chip marks"
diff --git a/strings/wounds/flesh_scar_desc.json b/strings/wounds/flesh_scar_desc.json
index d8c253873cc..0fd78bec8e4 100644
--- a/strings/wounds/flesh_scar_desc.json
+++ b/strings/wounds/flesh_scar_desc.json
@@ -1,6 +1,12 @@
{
"generic": ["general disfigurement"],
+ "dislocate": [
+ "light discoloring",
+ "a slight blue tint",
+ "a slightly deadened tint"
+ ],
+
"bluntmoderate": [
"light discoloring",
"a slight blue tint",
diff --git a/tgstation.dme b/tgstation.dme
index 74c8a2e0b3a..cdb81c9a98f 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -104,6 +104,7 @@
#include "code\__DEFINES\ghost.dm"
#include "code\__DEFINES\gravity.dm"
#include "code\__DEFINES\guardian_defines.dm"
+#include "code\__DEFINES\holiday.dm"
#include "code\__DEFINES\holopads.dm"
#include "code\__DEFINES\hud.dm"
#include "code\__DEFINES\icon_smoothing.dm"
@@ -177,6 +178,7 @@
#include "code\__DEFINES\quirks.dm"
#include "code\__DEFINES\radiation.dm"
#include "code\__DEFINES\radio.dm"
+#include "code\__DEFINES\radioactive_nebula.dm"
#include "code\__DEFINES\reactions.dm"
#include "code\__DEFINES\reagents.dm"
#include "code\__DEFINES\reagents_specific_heat.dm"
@@ -300,6 +302,7 @@
#include "code\__DEFINES\dcs\signals\signals_janitor.dm"
#include "code\__DEFINES\dcs\signals\signals_key.dm"
#include "code\__DEFINES\dcs\signals\signals_ladder.dm"
+#include "code\__DEFINES\dcs\signals\signals_lazy_templates.dm"
#include "code\__DEFINES\dcs\signals\signals_leash.dm"
#include "code\__DEFINES\dcs\signals\signals_lift.dm"
#include "code\__DEFINES\dcs\signals\signals_light_eater.dm"
@@ -319,6 +322,7 @@
#include "code\__DEFINES\dcs\signals\signals_radiation.dm"
#include "code\__DEFINES\dcs\signals\signals_reagent.dm"
#include "code\__DEFINES\dcs\signals\signals_restaurant.dm"
+#include "code\__DEFINES\dcs\signals\signals_saboteur.dm"
#include "code\__DEFINES\dcs\signals\signals_scangate.dm"
#include "code\__DEFINES\dcs\signals\signals_screentips.dm"
#include "code\__DEFINES\dcs\signals\signals_spatial_grid.dm"
@@ -433,6 +437,7 @@
#include "code\__DEFINES\~skyrat_defines\turfs.dm"
#include "code\__DEFINES\~skyrat_defines\vox_defines.dm"
#include "code\__DEFINES\~skyrat_defines\vv.dm"
+#include "code\__DEFINES\~skyrat_defines\wounds.dm"
#include "code\__DEFINES\~skyrat_defines\_globalvars\bitfields.dm"
#include "code\__DEFINES\~skyrat_defines\_globalvars\logging.dm"
#include "code\__DEFINES\~skyrat_defines\_globalvars\lists\mapping.dm"
@@ -458,7 +463,6 @@
#include "code\__HELPERS\atoms.dm"
#include "code\__HELPERS\auxtools.dm"
#include "code\__HELPERS\bitflag_lists.dm"
-#include "code\__HELPERS\byond_status.dm"
#include "code\__HELPERS\cameras.dm"
#include "code\__HELPERS\chat.dm"
#include "code\__HELPERS\chat_filter.dm"
@@ -718,6 +722,7 @@
#include "code\controllers\subsystem\profiler.dm"
#include "code\controllers\subsystem\radiation.dm"
#include "code\controllers\subsystem\radio.dm"
+#include "code\controllers\subsystem\radioactive_nebula.dm"
#include "code\controllers\subsystem\research.dm"
#include "code\controllers\subsystem\restaurant.dm"
#include "code\controllers\subsystem\runechat.dm"
@@ -765,6 +770,7 @@
#include "code\controllers\subsystem\processing\digital_clock.dm"
#include "code\controllers\subsystem\processing\fastprocess.dm"
#include "code\controllers\subsystem\processing\fire_burning.dm"
+#include "code\controllers\subsystem\processing\fishing.dm"
#include "code\controllers\subsystem\processing\greyscale.dm"
#include "code\controllers\subsystem\processing\instruments.dm"
#include "code\controllers\subsystem\processing\obj.dm"
@@ -886,6 +892,7 @@
#include "code\datums\ai\basic_mobs\base_basic_controller.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"
#include "code\datums\ai\basic_mobs\basic_ai_behaviors\find_parent.dm"
#include "code\datums\ai\basic_mobs\basic_ai_behaviors\nearest_targetting.dm"
#include "code\datums\ai\basic_mobs\basic_ai_behaviors\pick_up_item.dm"
@@ -898,6 +905,7 @@
#include "code\datums\ai\basic_mobs\basic_ai_behaviors\travel_towards.dm"
#include "code\datums\ai\basic_mobs\basic_ai_behaviors\ventcrawling.dm"
#include "code\datums\ai\basic_mobs\basic_ai_behaviors\write_on_paper.dm"
+#include "code\datums\ai\basic_mobs\basic_subtrees\attack_adjacent_target.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\attack_obstacle_in_path.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\climb_tree.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\find_food.dm"
@@ -905,6 +913,7 @@
#include "code\datums\ai\basic_mobs\basic_subtrees\find_parent.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\flee_target.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\maintain_distance.dm"
+#include "code\datums\ai\basic_mobs\basic_subtrees\move_to_cardinal.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\opportunistic_ventcrawler.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\ranged_skirmish.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\simple_attack_target.dm"
@@ -1066,7 +1075,6 @@
#include "code\datums\components\force_move.dm"
#include "code\datums\components\fov_handler.dm"
#include "code\datums\components\fullauto.dm"
-#include "code\datums\components\gags_recolorable.dm"
#include "code\datums\components\gas_leaker.dm"
#include "code\datums\components\geiger_sound.dm"
#include "code\datums\components\ghost_direct_control.dm"
@@ -1094,6 +1102,7 @@
#include "code\datums\components\label.dm"
#include "code\datums\components\leash.dm"
#include "code\datums\components\light_eater.dm"
+#include "code\datums\components\ling_decoy_brain.dm"
#include "code\datums\components\lock_on_cursor.dm"
#include "code\datums\components\magnet.dm"
#include "code\datums\components\manual_blinking.dm"
@@ -1197,6 +1206,7 @@
#include "code\datums\components\uplink.dm"
#include "code\datums\components\usb_port.dm"
#include "code\datums\components\vacuum.dm"
+#include "code\datums\components\wall_mounted.dm"
#include "code\datums\components\wearertargeting.dm"
#include "code\datums\components\weatherannouncer.dm"
#include "code\datums\components\wet_floor.dm"
@@ -1228,6 +1238,7 @@
#include "code\datums\components\food\decomposition.dm"
#include "code\datums\components\food\edible.dm"
#include "code\datums\components\food\germ_sensitive.dm"
+#include "code\datums\components\food\ghost_edible.dm"
#include "code\datums\components\food\golem_food.dm"
#include "code\datums\components\food\ice_cream_holder.dm"
#include "code\datums\components\material\material_container.dm"
@@ -1329,6 +1340,7 @@
#include "code\datums\elements\bed_tucking.dm"
#include "code\datums\elements\befriend_petting.dm"
#include "code\datums\elements\blocks_explosives.dm"
+#include "code\datums\elements\bombable_turf.dm"
#include "code\datums\elements\bonus_damage.dm"
#include "code\datums\elements\bsa_blocker.dm"
#include "code\datums\elements\bugkiller_reagent.dm"
@@ -1374,6 +1386,7 @@
#include "code\datums\elements\footstep_override.dm"
#include "code\datums\elements\forced_gravity.dm"
#include "code\datums\elements\frozen.dm"
+#include "code\datums\elements\gags_recolorable.dm"
#include "code\datums\elements\give_turf_traits.dm"
#include "code\datums\elements\haunted.dm"
#include "code\datums\elements\high_fiver.dm"
@@ -1391,6 +1404,7 @@
#include "code\datums\elements\light_eater.dm"
#include "code\datums\elements\loomable.dm"
#include "code\datums\elements\mirage_border.dm"
+#include "code\datums\elements\mob_grabber.dm"
#include "code\datums\elements\mob_killed_tally.dm"
#include "code\datums\elements\movement_turf_changer.dm"
#include "code\datums\elements\movetype_handler.dm"
@@ -1547,6 +1561,7 @@
#include "code\datums\mood_events\dna_infuser_events.dm"
#include "code\datums\mood_events\drink_events.dm"
#include "code\datums\mood_events\drug_events.dm"
+#include "code\datums\mood_events\food_events.dm"
#include "code\datums\mood_events\generic_negative_events.dm"
#include "code\datums\mood_events\generic_positive_events.dm"
#include "code\datums\mood_events\morbid_events.dm"
@@ -1578,10 +1593,89 @@
#include "code\datums\proximity_monitor\fields\projectile_dampener.dm"
#include "code\datums\proximity_monitor\fields\timestop.dm"
#include "code\datums\quirks\_quirk.dm"
-#include "code\datums\quirks\negative_quirks\negative_quirks.dm"
-#include "code\datums\quirks\neutral_quirks\neutral_quirks.dm"
-#include "code\datums\quirks\positive_quirks\positive_quirks.dm"
+#include "code\datums\quirks\negative_quirks\allergic.dm"
+#include "code\datums\quirks\negative_quirks\bad_back.dm"
+#include "code\datums\quirks\negative_quirks\bad_touch.dm"
+#include "code\datums\quirks\negative_quirks\big_hands.dm"
+#include "code\datums\quirks\negative_quirks\blindness.dm"
+#include "code\datums\quirks\negative_quirks\blood_deficiency.dm"
+#include "code\datums\quirks\negative_quirks\body_purist.dm"
+#include "code\datums\quirks\negative_quirks\brain_problems.dm"
+#include "code\datums\quirks\negative_quirks\chronic_illness.dm"
+#include "code\datums\quirks\negative_quirks\claustrophobia.dm"
+#include "code\datums\quirks\negative_quirks\clumsy.dm"
+#include "code\datums\quirks\negative_quirks\cursed.dm"
+#include "code\datums\quirks\negative_quirks\deafness.dm"
+#include "code\datums\quirks\negative_quirks\depression.dm"
+#include "code\datums\quirks\negative_quirks\family_heirloom.dm"
+#include "code\datums\quirks\negative_quirks\frail.dm"
+#include "code\datums\quirks\negative_quirks\glass_jaw.dm"
+#include "code\datums\quirks\negative_quirks\heavy_sleeper.dm"
+#include "code\datums\quirks\negative_quirks\hemiplegic.dm"
+#include "code\datums\quirks\negative_quirks\hypersensitive.dm"
+#include "code\datums\quirks\negative_quirks\illiterate.dm"
+#include "code\datums\quirks\negative_quirks\indebted.dm"
+#include "code\datums\quirks\negative_quirks\insanity.dm"
+#include "code\datums\quirks\negative_quirks\junkie.dm"
+#include "code\datums\quirks\negative_quirks\light_drinker.dm"
+#include "code\datums\quirks\negative_quirks\mute.dm"
+#include "code\datums\quirks\negative_quirks\nearsighted.dm"
+#include "code\datums\quirks\negative_quirks\non_violent.dm"
+#include "code\datums\quirks\negative_quirks\numb.dm"
+#include "code\datums\quirks\negative_quirks\nyctophobia.dm"
+#include "code\datums\quirks\negative_quirks\paraplegic.dm"
+#include "code\datums\quirks\negative_quirks\photophobia.dm"
+#include "code\datums\quirks\negative_quirks\poor_aim.dm"
+#include "code\datums\quirks\negative_quirks\prosopagnosia.dm"
+#include "code\datums\quirks\negative_quirks\prosthetic_limb.dm"
+#include "code\datums\quirks\negative_quirks\prosthetic_organ.dm"
+#include "code\datums\quirks\negative_quirks\pushover.dm"
+#include "code\datums\quirks\negative_quirks\quadruple_amputee.dm"
+#include "code\datums\quirks\negative_quirks\social_anxiety.dm"
+#include "code\datums\quirks\negative_quirks\softspoken.dm"
+#include "code\datums\quirks\negative_quirks\tin_man.dm"
+#include "code\datums\quirks\negative_quirks\unstable.dm"
+#include "code\datums\quirks\neutral_quirks\bald.dm"
+#include "code\datums\quirks\neutral_quirks\colorist.dm"
+#include "code\datums\quirks\neutral_quirks\deviant_tastes.dm"
+#include "code\datums\quirks\neutral_quirks\extrovert.dm"
+#include "code\datums\quirks\neutral_quirks\foreigner.dm"
+#include "code\datums\quirks\neutral_quirks\gamer.dm"
+#include "code\datums\quirks\neutral_quirks\heretochromatic.dm"
+#include "code\datums\quirks\neutral_quirks\introvert.dm"
+#include "code\datums\quirks\neutral_quirks\monochromatic.dm"
+#include "code\datums\quirks\neutral_quirks\no_taste.dm"
+#include "code\datums\quirks\neutral_quirks\phobia.dm"
+#include "code\datums\quirks\neutral_quirks\photographer.dm"
+#include "code\datums\quirks\neutral_quirks\pineapple_hater.dm"
+#include "code\datums\quirks\neutral_quirks\pineapple_liker.dm"
+#include "code\datums\quirks\neutral_quirks\pride_pin.dm"
+#include "code\datums\quirks\neutral_quirks\shifty_eyes.dm"
+#include "code\datums\quirks\neutral_quirks\snob.dm"
+#include "code\datums\quirks\neutral_quirks\vegetarian.dm"
+#include "code\datums\quirks\positive_quirks\alcohol_tolerance.dm"
+#include "code\datums\quirks\positive_quirks\apathetic.dm"
+#include "code\datums\quirks\positive_quirks\bilingual.dm"
+#include "code\datums\quirks\positive_quirks\clown_enjoyer.dm"
+#include "code\datums\quirks\positive_quirks\drunk_healing.dm"
+#include "code\datums\quirks\positive_quirks\empath.dm"
+#include "code\datums\quirks\positive_quirks\freerunning.dm"
+#include "code\datums\quirks\positive_quirks\friendly.dm"
+#include "code\datums\quirks\positive_quirks\jolly.dm"
+#include "code\datums\quirks\positive_quirks\light_step.dm"
+#include "code\datums\quirks\positive_quirks\mime_fan.dm"
+#include "code\datums\quirks\positive_quirks\musician.dm"
+#include "code\datums\quirks\positive_quirks\night_vision.dm"
+#include "code\datums\quirks\positive_quirks\poster_boy.dm"
+#include "code\datums\quirks\positive_quirks\self_aware.dm"
+#include "code\datums\quirks\positive_quirks\settler.dm"
+#include "code\datums\quirks\positive_quirks\signer.dm"
+#include "code\datums\quirks\positive_quirks\skittish.dm"
#include "code\datums\quirks\positive_quirks\spacer.dm"
+#include "code\datums\quirks\positive_quirks\spiritual.dm"
+#include "code\datums\quirks\positive_quirks\tagger.dm"
+#include "code\datums\quirks\positive_quirks\throwing_arm.dm"
+#include "code\datums\quirks\positive_quirks\voracious.dm"
#include "code\datums\records\crime.dm"
#include "code\datums\records\data.dm"
#include "code\datums\records\manifest.dm"
@@ -1625,6 +1719,7 @@
#include "code\datums\status_effects\agent_pinpointer.dm"
#include "code\datums\status_effects\buffs.dm"
#include "code\datums\status_effects\drug_effects.dm"
+#include "code\datums\status_effects\food_effects.dm"
#include "code\datums\status_effects\gas.dm"
#include "code\datums\status_effects\grouped_effect.dm"
#include "code\datums\status_effects\limited_effect.dm"
@@ -1632,6 +1727,8 @@
#include "code\datums\status_effects\song_effects.dm"
#include "code\datums\status_effects\stacking_effect.dm"
#include "code\datums\status_effects\wound_effects.dm"
+#include "code\datums\status_effects\buffs\food_haste.dm"
+#include "code\datums\status_effects\buffs\food_traits.dm"
#include "code\datums\status_effects\buffs\stun_absorption.dm"
#include "code\datums\status_effects\debuffs\blindness.dm"
#include "code\datums\status_effects\debuffs\choke.dm"
@@ -1668,6 +1765,7 @@
#include "code\datums\storage\subtypes\organ_box.dm"
#include "code\datums\storage\subtypes\pockets.dm"
#include "code\datums\storage\subtypes\rped.dm"
+#include "code\datums\storage\subtypes\surgery_tray.dm"
#include "code\datums\storage\subtypes\trash.dm"
#include "code\datums\votes\_vote_datum.dm"
#include "code\datums\votes\custom_vote.dm"
@@ -1690,6 +1788,7 @@
#include "code\datums\wires\emitter.dm"
#include "code\datums\wires\explosive.dm"
#include "code\datums\wires\fax.dm"
+#include "code\datums\wires\mass_driver.dm"
#include "code\datums\wires\mecha.dm"
#include "code\datums\wires\microwave.dm"
#include "code\datums\wires\mod.dm"
@@ -1703,13 +1802,16 @@
#include "code\datums\wires\syndicatebomb.dm"
#include "code\datums\wires\tesla_coil.dm"
#include "code\datums\wires\vending.dm"
+#include "code\datums\wounds\_wound_static_data.dm"
#include "code\datums\wounds\_wounds.dm"
+#include "code\datums\wounds\blunt.dm"
#include "code\datums\wounds\bones.dm"
#include "code\datums\wounds\burns.dm"
#include "code\datums\wounds\loss.dm"
#include "code\datums\wounds\pierce.dm"
#include "code\datums\wounds\slash.dm"
#include "code\datums\wounds\scars\_scars.dm"
+#include "code\datums\wounds\scars\_static_scar_data.dm"
#include "code\game\alternate_appearance.dm"
#include "code\game\atom_defense.dm"
#include "code\game\atoms.dm"
@@ -2065,6 +2167,7 @@
#include "code\game\objects\items\choice_beacon.dm"
#include "code\game\objects\items\chromosome.dm"
#include "code\game\objects\items\cigs_lighters.dm"
+#include "code\game\objects\items\climbingrope.dm"
#include "code\game\objects\items\clown_items.dm"
#include "code\game\objects\items\control_wand.dm"
#include "code\game\objects\items\cosmetics.dm"
@@ -2130,6 +2233,7 @@
#include "code\game\objects\items\skub.dm"
#include "code\game\objects\items\spear.dm"
#include "code\game\objects\items\sticker.dm"
+#include "code\game\objects\items\surgery_tray.dm"
#include "code\game\objects\items\syndie_spraycan.dm"
#include "code\game\objects\items\tail_pin.dm"
#include "code\game\objects\items\taster.dm"
@@ -2252,6 +2356,7 @@
#include "code\game\objects\items\granters\magic\mindswap.dm"
#include "code\game\objects\items\granters\magic\sacred_flame.dm"
#include "code\game\objects\items\granters\magic\smoke.dm"
+#include "code\game\objects\items\granters\magic\summon_cheese.dm"
#include "code\game\objects\items\granters\magic\summon_item.dm"
#include "code\game\objects\items\granters\martial_arts\_martial_arts.dm"
#include "code\game\objects\items\granters\martial_arts\cqc.dm"
@@ -2517,6 +2622,7 @@
#include "code\game\turfs\change_turf.dm"
#include "code\game\turfs\turf.dm"
#include "code\game\turfs\closed\_closed.dm"
+#include "code\game\turfs\closed\indestructible.dm"
#include "code\game\turfs\closed\minerals.dm"
#include "code\game\turfs\closed\walls.dm"
#include "code\game\turfs\closed\wall\material_walls.dm"
@@ -2561,6 +2667,7 @@
#include "code\modules\actionspeed\modifiers\drugs.dm"
#include "code\modules\actionspeed\modifiers\mood.dm"
#include "code\modules\actionspeed\modifiers\status_effects.dm"
+#include "code\modules\actionspeed\modifiers\wound.dm"
#include "code\modules\admin\admin.dm"
#include "code\modules\admin\admin_fax_panel.dm"
#include "code\modules\admin\admin_investigate.dm"
@@ -2600,11 +2707,11 @@
#include "code\modules\admin\whitelist.dm"
#include "code\modules\admin\callproc\callproc.dm"
#include "code\modules\admin\smites\bad_luck.dm"
+#include "code\modules\admin\smites\become_object.dm"
#include "code\modules\admin\smites\berforate.dm"
#include "code\modules\admin\smites\bloodless.dm"
#include "code\modules\admin\smites\boneless.dm"
#include "code\modules\admin\smites\brain_damage.dm"
-#include "code\modules\admin\smites\bread.dm"
#include "code\modules\admin\smites\bsa.dm"
#include "code\modules\admin\smites\curse_of_babel.dm"
#include "code\modules\admin\smites\dock_pay.dm"
@@ -2789,6 +2896,7 @@
#include "code\modules\antagonists\changeling\powers\headcrab.dm"
#include "code\modules\antagonists\changeling\powers\lesserform.dm"
#include "code\modules\antagonists\changeling\powers\mimic_voice.dm"
+#include "code\modules\antagonists\changeling\powers\mmi_talk.dm"
#include "code\modules\antagonists\changeling\powers\mutations.dm"
#include "code\modules\antagonists\changeling\powers\panacea.dm"
#include "code\modules\antagonists\changeling\powers\pheromone_receptors.dm"
@@ -2846,17 +2954,21 @@
#include "code\modules\antagonists\heretic\items\heretic_blades.dm"
#include "code\modules\antagonists\heretic\items\heretic_necks.dm"
#include "code\modules\antagonists\heretic\items\hunter_rifle.dm"
+#include "code\modules\antagonists\heretic\items\keyring.dm"
+#include "code\modules\antagonists\heretic\items\lintel.dm"
#include "code\modules\antagonists\heretic\items\madness_mask.dm"
#include "code\modules\antagonists\heretic\knowledge\ash_lore.dm"
#include "code\modules\antagonists\heretic\knowledge\blade_lore.dm"
#include "code\modules\antagonists\heretic\knowledge\cosmic_lore.dm"
#include "code\modules\antagonists\heretic\knowledge\flesh_lore.dm"
#include "code\modules\antagonists\heretic\knowledge\general_side.dm"
+#include "code\modules\antagonists\heretic\knowledge\knock_lore.dm"
#include "code\modules\antagonists\heretic\knowledge\rust_lore.dm"
#include "code\modules\antagonists\heretic\knowledge\side_ash_flesh.dm"
#include "code\modules\antagonists\heretic\knowledge\side_blade_rust.dm"
#include "code\modules\antagonists\heretic\knowledge\side_cosmos_ash.dm"
#include "code\modules\antagonists\heretic\knowledge\side_flesh_void.dm"
+#include "code\modules\antagonists\heretic\knowledge\side_knock_flesh.dm"
#include "code\modules\antagonists\heretic\knowledge\side_rust_cosmos.dm"
#include "code\modules\antagonists\heretic\knowledge\side_void_blade.dm"
#include "code\modules\antagonists\heretic\knowledge\starting_lore.dm"
@@ -2866,10 +2978,14 @@
#include "code\modules\antagonists\heretic\knowledge\sacrifice_knowledge\sacrifice_map.dm"
#include "code\modules\antagonists\heretic\knowledge\sacrifice_knowledge\sacrifice_moodlets.dm"
#include "code\modules\antagonists\heretic\magic\aggressive_spread.dm"
+#include "code\modules\antagonists\heretic\magic\apetravulnera.dm"
+#include "code\modules\antagonists\heretic\magic\ascended_shapeshift.dm"
#include "code\modules\antagonists\heretic\magic\ash_ascension.dm"
#include "code\modules\antagonists\heretic\magic\ash_jaunt.dm"
#include "code\modules\antagonists\heretic\magic\blood_cleave.dm"
#include "code\modules\antagonists\heretic\magic\blood_siphon.dm"
+#include "code\modules\antagonists\heretic\magic\burglar_finesse.dm"
+#include "code\modules\antagonists\heretic\magic\caretaker.dm"
#include "code\modules\antagonists\heretic\magic\cosmic_expansion.dm"
#include "code\modules\antagonists\heretic\magic\cosmic_runes.dm"
#include "code\modules\antagonists\heretic\magic\eldritch_blind.dm"
@@ -2897,12 +3013,14 @@
#include "code\modules\antagonists\heretic\magic\void_cold_cone.dm"
#include "code\modules\antagonists\heretic\magic\void_phase.dm"
#include "code\modules\antagonists\heretic\magic\void_pull.dm"
+#include "code\modules\antagonists\heretic\magic\wave_of_desperation.dm"
#include "code\modules\antagonists\heretic\mobs\maid_in_mirror.dm"
#include "code\modules\antagonists\heretic\status_effects\buffs.dm"
#include "code\modules\antagonists\heretic\status_effects\debuffs.dm"
#include "code\modules\antagonists\heretic\status_effects\ghoul.dm"
#include "code\modules\antagonists\heretic\status_effects\mark_effects.dm"
#include "code\modules\antagonists\heretic\structures\carving_knife.dm"
+#include "code\modules\antagonists\heretic\structures\knock_final.dm"
#include "code\modules\antagonists\heretic\structures\mawed_crucible.dm"
#include "code\modules\antagonists\highlander\highlander.dm"
#include "code\modules\antagonists\hypnotized\hypnotized.dm"
@@ -3008,6 +3126,7 @@
#include "code\modules\antagonists\wizard\equipment\spellbook_entries\mobility.dm"
#include "code\modules\antagonists\wizard\equipment\spellbook_entries\offensive.dm"
#include "code\modules\antagonists\wizard\equipment\spellbook_entries\summons.dm"
+#include "code\modules\antagonists\wizard\grand_ritual\fluff.dm"
#include "code\modules\antagonists\wizard\grand_ritual\grand_ritual.dm"
#include "code\modules\antagonists\wizard\grand_ritual\grand_ritual_finale.dm"
#include "code\modules\antagonists\wizard\grand_ritual\grand_rune.dm"
@@ -3328,6 +3447,7 @@
#include "code\modules\client\preferences\multiz_performance.dm"
#include "code\modules\client\preferences\names.dm"
#include "code\modules\client\preferences\ooc.dm"
+#include "code\modules\client\preferences\operative_species.dm"
#include "code\modules\client\preferences\paint_color.dm"
#include "code\modules\client\preferences\parallax.dm"
#include "code\modules\client\preferences\pda.dm"
@@ -3587,6 +3707,7 @@
#include "code\modules\events\shuttle_insurance.dm"
#include "code\modules\events\spider_infestation.dm"
#include "code\modules\events\stray_cargo.dm"
+#include "code\modules\events\supermatter_surge.dm"
#include "code\modules\events\tram_malfunction.dm"
#include "code\modules\events\vent_clog.dm"
#include "code\modules\events\wisdomcow.dm"
@@ -3841,6 +3962,7 @@
#include "code\modules\hydroponics\grown\random.dm"
#include "code\modules\hydroponics\grown\replicapod.dm"
#include "code\modules\hydroponics\grown\root.dm"
+#include "code\modules\hydroponics\grown\seedling.dm"
#include "code\modules\hydroponics\grown\sugarcane.dm"
#include "code\modules\hydroponics\grown\tea_coffee.dm"
#include "code\modules\hydroponics\grown\tobacco.dm"
@@ -4113,7 +4235,6 @@
#include "code\modules\mapfluff\ruins\spaceruin_code\interdyne.dm"
#include "code\modules\mapfluff\ruins\spaceruin_code\listeningstation.dm"
#include "code\modules\mapfluff\ruins\spaceruin_code\meateor.dm"
-#include "code\modules\mapfluff\ruins\spaceruin_code\oldstation.dm"
#include "code\modules\mapfluff\ruins\spaceruin_code\originalcontent.dm"
#include "code\modules\mapfluff\ruins\spaceruin_code\spacehotel.dm"
#include "code\modules\mapfluff\ruins\spaceruin_code\the_Outlet.dm"
@@ -4121,6 +4242,11 @@
#include "code\modules\mapfluff\ruins\spaceruin_code\waystation.dm"
#include "code\modules\mapfluff\ruins\spaceruin_code\whiteship.dm"
#include "code\modules\mapfluff\ruins\spaceruin_code\whiteshipruin_box.dm"
+#include "code\modules\mapfluff\ruins\spaceruin_code\oldstation\oldstation_cytology.dm"
+#include "code\modules\mapfluff\ruins\spaceruin_code\oldstation\oldstation_fluff.dm"
+#include "code\modules\mapfluff\ruins\spaceruin_code\oldstation\oldstation_machines.dm"
+#include "code\modules\mapfluff\ruins\spaceruin_code\oldstation\oldstation_mod.dm"
+#include "code\modules\mapfluff\ruins\spaceruin_code\oldstation\oldstation_rnd.dm"
#include "code\modules\mapping\access_helpers.dm"
#include "code\modules\mapping\mail_sorting_helpers.dm"
#include "code\modules\mapping\map_template.dm"
@@ -4153,7 +4279,6 @@
#include "code\modules\mining\machine_stacking.dm"
#include "code\modules\mining\machine_unloading.dm"
#include "code\modules\mining\mine_items.dm"
-#include "code\modules\mining\minebot.dm"
#include "code\modules\mining\money_bag.dm"
#include "code\modules\mining\ores_coins.dm"
#include "code\modules\mining\satchel_ore_boxdm.dm"
@@ -4236,6 +4361,8 @@
#include "code\modules\mob\living\basic\festivus_pole.dm"
#include "code\modules\mob\living\basic\health_adjustment.dm"
#include "code\modules\mob\living\basic\tree.dm"
+#include "code\modules\mob\living\basic\clown\clown.dm"
+#include "code\modules\mob\living\basic\clown\clown_ai.dm"
#include "code\modules\mob\living\basic\farm_animals\deer.dm"
#include "code\modules\mob\living\basic\farm_animals\pig.dm"
#include "code\modules\mob\living\basic\farm_animals\pony.dm"
@@ -4259,6 +4386,9 @@
#include "code\modules\mob\living\basic\jungle\mega_arachnid\mega_arachnid.dm"
#include "code\modules\mob\living\basic\jungle\mega_arachnid\mega_arachnid_abilities.dm"
#include "code\modules\mob\living\basic\jungle\mega_arachnid\mega_arachnid_ai.dm"
+#include "code\modules\mob\living\basic\jungle\seedling\seedling.dm"
+#include "code\modules\mob\living\basic\jungle\seedling\seedling_ai.dm"
+#include "code\modules\mob\living\basic\jungle\seedling\seedling_projectiles.dm"
#include "code\modules\mob\living\basic\lavaland\mining.dm"
#include "code\modules\mob\living\basic\lavaland\basilisk\basilisk.dm"
#include "code\modules\mob\living\basic\lavaland\basilisk\basilisk_overheat.dm"
@@ -4268,6 +4398,10 @@
#include "code\modules\mob\living\basic\lavaland\bileworm\bileworm_instrument.dm"
#include "code\modules\mob\living\basic\lavaland\bileworm\bileworm_loot.dm"
#include "code\modules\mob\living\basic\lavaland\bileworm\bileworm_vileworm.dm"
+#include "code\modules\mob\living\basic\lavaland\brimdemon\brimbeam.dm"
+#include "code\modules\mob\living\basic\lavaland\brimdemon\brimdemon.dm"
+#include "code\modules\mob\living\basic\lavaland\brimdemon\brimdemon_ai.dm"
+#include "code\modules\mob\living\basic\lavaland\brimdemon\brimdemon_loot.dm"
#include "code\modules\mob\living\basic\lavaland\goldgrub\goldgrub.dm"
#include "code\modules\mob\living\basic\lavaland\goldgrub\goldgrub_abilities.dm"
#include "code\modules\mob\living\basic\lavaland\goldgrub\goldgrub_ai.dm"
@@ -4284,6 +4418,10 @@
#include "code\modules\mob\living\basic\lavaland\watcher\watcher_gaze.dm"
#include "code\modules\mob\living\basic\lavaland\watcher\watcher_overwatch.dm"
#include "code\modules\mob\living\basic\lavaland\watcher\watcher_projectiles.dm"
+#include "code\modules\mob\living\basic\minebots\minebot.dm"
+#include "code\modules\mob\living\basic\minebots\minebot_abilities.dm"
+#include "code\modules\mob\living\basic\minebots\minebot_ai.dm"
+#include "code\modules\mob\living\basic\minebots\minebot_upgrades.dm"
#include "code\modules\mob\living\basic\pets\fox.dm"
#include "code\modules\mob\living\basic\pets\penguin.dm"
#include "code\modules\mob\living\basic\pets\pet.dm"
@@ -4577,7 +4715,6 @@
#include "code\modules\mob\living\simple_animal\hostile\venus_human_trap.dm"
#include "code\modules\mob\living\simple_animal\hostile\wizard.dm"
#include "code\modules\mob\living\simple_animal\hostile\zombie.dm"
-#include "code\modules\mob\living\simple_animal\hostile\bosses\boss.dm"
#include "code\modules\mob\living\simple_animal\hostile\constructs\artificer.dm"
#include "code\modules\mob\living\simple_animal\hostile\constructs\constructs.dm"
#include "code\modules\mob\living\simple_animal\hostile\constructs\harvester.dm"
@@ -4589,7 +4726,6 @@
#include "code\modules\mob\living\simple_animal\hostile\jungle\_jungle_mobs.dm"
#include "code\modules\mob\living\simple_animal\hostile\jungle\leaper.dm"
#include "code\modules\mob\living\simple_animal\hostile\jungle\mook.dm"
-#include "code\modules\mob\living\simple_animal\hostile\jungle\seedling.dm"
#include "code\modules\mob\living\simple_animal\hostile\megafauna\_megafauna.dm"
#include "code\modules\mob\living\simple_animal\hostile\megafauna\blood_drunk_miner.dm"
#include "code\modules\mob\living\simple_animal\hostile\megafauna\bubblegum.dm"
@@ -4600,7 +4736,6 @@
#include "code\modules\mob\living\simple_animal\hostile\megafauna\hierophant.dm"
#include "code\modules\mob\living\simple_animal\hostile\megafauna\legion.dm"
#include "code\modules\mob\living\simple_animal\hostile\megafauna\wendigo.dm"
-#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\brimdemon.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"
@@ -4613,7 +4748,6 @@
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\elites\herald.dm"
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\elites\legionnaire.dm"
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\elites\pandora.dm"
-#include "code\modules\mob\living\simple_animal\hostile\retaliate\clown.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"
@@ -4667,7 +4801,6 @@
#include "code\modules\mod\modules\modules_supply.dm"
#include "code\modules\mod\modules\modules_timeline.dm"
#include "code\modules\mod\modules\modules_visor.dm"
-#include "code\modules\modular_computers\laptop_vendor.dm"
#include "code\modules\modular_computers\computers\item\computer.dm"
#include "code\modules\modular_computers\computers\item\computer_files.dm"
#include "code\modules\modular_computers\computers\item\computer_power.dm"
@@ -4977,6 +5110,7 @@
#include "code\modules\projectiles\projectile\special\floral.dm"
#include "code\modules\projectiles\projectile\special\gravity.dm"
#include "code\modules\projectiles\projectile\special\ion.dm"
+#include "code\modules\projectiles\projectile\special\lightbreaker.dm"
#include "code\modules\projectiles\projectile\special\meteor.dm"
#include "code\modules\projectiles\projectile\special\mindflayer.dm"
#include "code\modules\projectiles\projectile\special\neurotoxin.dm"
@@ -5216,6 +5350,7 @@
#include "code\modules\spells\spell_types\conjure\_conjure.dm"
#include "code\modules\spells\spell_types\conjure\bees.dm"
#include "code\modules\spells\spell_types\conjure\carp.dm"
+#include "code\modules\spells\spell_types\conjure\cheese.dm"
#include "code\modules\spells\spell_types\conjure\constructs.dm"
#include "code\modules\spells\spell_types\conjure\creatures.dm"
#include "code\modules\spells\spell_types\conjure\cult_turfs.dm"
@@ -5298,6 +5433,7 @@
#include "code\modules\surgery\coronary_bypass.dm"
#include "code\modules\surgery\dental_implant.dm"
#include "code\modules\surgery\ear_surgery.dm"
+#include "code\modules\surgery\experimental_dissection.dm"
#include "code\modules\surgery\eye_surgery.dm"
#include "code\modules\surgery\gastrectomy.dm"
#include "code\modules\surgery\healing.dm"
@@ -5746,11 +5882,13 @@
#include "modular_skyrat\master_files\code\game\objects\items\oxygen_candle.dm"
#include "modular_skyrat\master_files\code\game\objects\items\RCD.dm"
#include "modular_skyrat\master_files\code\game\objects\items\religion.dm"
+#include "modular_skyrat\master_files\code\game\objects\items\scratchingstone.dm"
#include "modular_skyrat\master_files\code\game\objects\items\devices\anomaly_neutralizer.dm"
#include "modular_skyrat\master_files\code\game\objects\items\stacks\sheets\sheet_types.dm"
#include "modular_skyrat\master_files\code\game\objects\items\storage\backpack.dm"
#include "modular_skyrat\master_files\code\game\objects\items\storage\boxes.dm"
#include "modular_skyrat\master_files\code\game\objects\items\tools\weldingtool.dm"
+#include "modular_skyrat\master_files\code\game\objects\structures\mannequin.dm"
#include "modular_skyrat\master_files\code\game\objects\structures\railings.dm"
#include "modular_skyrat\master_files\code\game\objects\structures\sauna_oven.dm"
#include "modular_skyrat\master_files\code\game\objects\structures\tables_racks.dm"
@@ -5774,8 +5912,16 @@
#include "modular_skyrat\master_files\code\modules\asset_cache\assets\plumbing.dm"
#include "modular_skyrat\master_files\code\modules\buildmode\bm_mode.dm"
#include "modular_skyrat\master_files\code\modules\buildmode\submodes\offercontrol.dm"
+#include "modular_skyrat\master_files\code\modules\cargo\goodies.dm"
+#include "modular_skyrat\master_files\code\modules\cargo\orderconsole.dm"
+#include "modular_skyrat\master_files\code\modules\cargo\bounties\medical.dm"
+#include "modular_skyrat\master_files\code\modules\cargo\exports\tools.dm"
#include "modular_skyrat\master_files\code\modules\cargo\exports\traitor.dm"
#include "modular_skyrat\master_files\code\modules\cargo\markets\market_items\weapons.dm"
+#include "modular_skyrat\master_files\code\modules\cargo\packs\general.dm"
+#include "modular_skyrat\master_files\code\modules\cargo\packs\security.dm"
+#include "modular_skyrat\master_files\code\modules\cargo\packs\service.dm"
+#include "modular_skyrat\master_files\code\modules\cargo\packs\vending_restock.dm"
#include "modular_skyrat\master_files\code\modules\client\playtime.dm"
#include "modular_skyrat\master_files\code\modules\client\preferences.dm"
#include "modular_skyrat\master_files\code\modules\client\preferences_savefile.dm"
@@ -5902,6 +6048,7 @@
#include "modular_skyrat\master_files\code\modules\logging\categories\log_category_game.dm"
#include "modular_skyrat\master_files\code\modules\logging\categories\log_category_uplink.dm"
#include "modular_skyrat\master_files\code\modules\mapfluff\ruins\objects_and_mobs\necropolis_gate.dm"
+#include "modular_skyrat\master_files\code\modules\mapfluff\ruins\spaceruin_code\oldstation\oldstation_cytology.dm"
#include "modular_skyrat\master_files\code\modules\mining\equipment\explorer_gear.dm"
#include "modular_skyrat\master_files\code\modules\mob\login.dm"
#include "modular_skyrat\master_files\code\modules\mob\dead\new_player\latejoin_menu.dm"
@@ -5972,6 +6119,7 @@
#include "modular_skyrat\master_files\code\modules\surgery\surgery.dm"
#include "modular_skyrat\master_files\code\modules\surgery\bodyparts\_bodyparts.dm"
#include "modular_skyrat\master_files\code\modules\surgery\organs\tongue.dm"
+#include "modular_skyrat\master_files\code\modules\surgery\organs\internal\appendix\_appendix.dm"
#include "modular_skyrat\master_files\code\modules\vehicles\sealed.dm"
#include "modular_skyrat\master_files\code\modules\vehicles\snowmobile.dm"
#include "modular_skyrat\modules\additional_circuit\code\_designs.dm"
@@ -6029,7 +6177,6 @@
#include "modular_skyrat\modules\aesthetics\plasticflaps\code\plasticflaps.dm"
#include "modular_skyrat\modules\aesthetics\posters\posters.dm"
#include "modular_skyrat\modules\aesthetics\rack\code\rack.dm"
-#include "modular_skyrat\modules\aesthetics\rollerbed\code\rollerbed.dm"
#include "modular_skyrat\modules\aesthetics\shieldgen\code\shieldgen.dm"
#include "modular_skyrat\modules\aesthetics\stationobjs\stationobjs.dm"
#include "modular_skyrat\modules\aesthetics\status_display\code\status_display.dm"
@@ -6239,7 +6386,6 @@
#include "modular_skyrat\modules\cargoborg\code\robot_items.dm"
#include "modular_skyrat\modules\cargoborg\code\robot_modules.dm"
#include "modular_skyrat\modules\cell_component\code\cell_component.dm"
-#include "modular_skyrat\modules\cell_component\code\flashlight.dm"
#include "modular_skyrat\modules\cellguns\code\cellgun_cells.dm"
#include "modular_skyrat\modules\cellguns\code\cellguns.dm"
#include "modular_skyrat\modules\cellguns\code\medigun_cells.dm"
@@ -6314,7 +6460,7 @@
#include "modular_skyrat\modules\command_vendor\code\vending.dm"
#include "modular_skyrat\modules\company_imports\code\armament_component.dm"
#include "modular_skyrat\modules\company_imports\code\company_datums.dm"
-#include "modular_skyrat\modules\company_imports\code\company_subsystem.dm"
+#include "modular_skyrat\modules\company_imports\code\armament_datums\_armament_basetype.dm"
#include "modular_skyrat\modules\company_imports\code\armament_datums\bolt_nanotrasen_firearms.dm"
#include "modular_skyrat\modules\company_imports\code\armament_datums\deforest_medical.dm"
#include "modular_skyrat\modules\company_imports\code\armament_datums\jarnsmiour.dm"
@@ -6323,7 +6469,6 @@
#include "modular_skyrat\modules\company_imports\code\armament_datums\nakamura_modsuits.dm"
#include "modular_skyrat\modules\company_imports\code\armament_datums\nakamura_tools.dm"
#include "modular_skyrat\modules\company_imports\code\armament_datums\nri_military_surplus.dm"
-#include "modular_skyrat\modules\company_imports\code\armament_datums\parent_armament.dm"
#include "modular_skyrat\modules\company_imports\code\armament_datums\put_a_donk_on_it.dm"
#include "modular_skyrat\modules\company_imports\code\armament_datums\vitezstvi_ammo.dm"
#include "modular_skyrat\modules\company_imports\code\datums\cargo_order.dm"
@@ -6355,6 +6500,7 @@
#include "modular_skyrat\modules\contractor\code\datums\contractor_tablet.dm"
#include "modular_skyrat\modules\contractor\code\datums\mind_datum.dm"
#include "modular_skyrat\modules\contractor\code\datums\objective.dm"
+#include "modular_skyrat\modules\contractor\code\datums\outfit.dm"
#include "modular_skyrat\modules\contractor\code\datums\midround\antag_datum.dm"
#include "modular_skyrat\modules\contractor\code\datums\midround\event.dm"
#include "modular_skyrat\modules\contractor\code\datums\midround\objective.dm"
@@ -6587,6 +6733,7 @@
#include "modular_skyrat\modules\customization\modules\reagents\chemistry\reagents\toxin_reagents.dm"
#include "modular_skyrat\modules\customization\modules\reagents\chemistry\recipes\medicine.dm"
#include "modular_skyrat\modules\customization\modules\surgery\bodyparts\_bodyparts.dm"
+#include "modular_skyrat\modules\customization\modules\surgery\bodyparts\parts.dm"
#include "modular_skyrat\modules\customization\modules\surgery\bodyparts\robot_bodyparts.dm"
#include "modular_skyrat\modules\customization\modules\surgery\organs\cap.dm"
#include "modular_skyrat\modules\customization\modules\surgery\organs\ears.dm"
@@ -6694,7 +6841,6 @@
#include "modular_skyrat\modules\gunhud\code\gun_hud_component.dm"
#include "modular_skyrat\modules\gunpoint\code\gunpoint.dm"
#include "modular_skyrat\modules\gunpoint\code\gunpoint_datum.dm"
-#include "modular_skyrat\modules\gunsgalore\code\projectile.dm"
#include "modular_skyrat\modules\gunsgalore\code\ammo\ammo.dm"
#include "modular_skyrat\modules\gunsgalore\code\guns\akm.dm"
#include "modular_skyrat\modules\gunsgalore\code\guns\ballistic_master.dm"
@@ -6738,6 +6884,7 @@
#include "modular_skyrat\modules\ices_events\code\ICES_tgui.dm"
#include "modular_skyrat\modules\ices_events\code\effects\ef_foam.dm"
#include "modular_skyrat\modules\ices_events\code\events\ev_meteors.dm"
+#include "modular_skyrat\modules\ices_events\code\events\ev_roleplay_check.dm"
#include "modular_skyrat\modules\ices_events\code\events\ev_scrubbers.dm"
#include "modular_skyrat\modules\icspawning\code\cards_ids.dm"
#include "modular_skyrat\modules\icspawning\code\observer.dm"
@@ -6875,19 +7022,15 @@
#include "modular_skyrat\modules\marines\code\modsuit_modules.dm"
#include "modular_skyrat\modules\marines\code\smartgun.dm"
#include "modular_skyrat\modules\medical\code\anesthetic_machine.dm"
-#include "modular_skyrat\modules\medical\code\bodypart.dm"
-#include "modular_skyrat\modules\medical\code\bodypart_aid.dm"
-#include "modular_skyrat\modules\medical\code\carbon_defense.dm"
#include "modular_skyrat\modules\medical\code\carbon_examine.dm"
#include "modular_skyrat\modules\medical\code\carbon_update_icons.dm"
-#include "modular_skyrat\modules\medical\code\medical_stacks.dm"
+#include "modular_skyrat\modules\medical\code\grasp.dm"
+#include "modular_skyrat\modules\medical\code\health_analyzer.dm"
#include "modular_skyrat\modules\medical\code\smartdarts.dm"
#include "modular_skyrat\modules\medical\code\wounds\_wounds.dm"
-#include "modular_skyrat\modules\medical\code\wounds\bones.dm"
-#include "modular_skyrat\modules\medical\code\wounds\burns.dm"
+#include "modular_skyrat\modules\medical\code\wounds\bleed.dm"
+#include "modular_skyrat\modules\medical\code\wounds\medical.dm"
#include "modular_skyrat\modules\medical\code\wounds\muscle.dm"
-#include "modular_skyrat\modules\medical\code\wounds\pierce.dm"
-#include "modular_skyrat\modules\medical\code\wounds\slash.dm"
#include "modular_skyrat\modules\medical_designs\medical_designs.dm"
#include "modular_skyrat\modules\medievalcrate_skyrat\code\vintageitems.dm"
#include "modular_skyrat\modules\mentor\code\_globalvars.dm"
@@ -7368,7 +7511,6 @@
#include "modular_skyrat\modules\subsystems\code\ticket_ping\adminhelp.dm"
#include "modular_skyrat\modules\subsystems\code\ticket_ping\preference.dm"
#include "modular_skyrat\modules\subsystems\code\ticket_ping\ticket_ss.dm"
-#include "modular_skyrat\modules\supermatter_surge\code\supermatter_surge.dm"
#include "modular_skyrat\modules\Syndie_edits\code\area.dm"
#include "modular_skyrat\modules\Syndie_edits\code\syndie_edits.dm"
#include "modular_skyrat\modules\synths\code\bodyparts\brain.dm"
@@ -7482,6 +7624,7 @@
#include "modular_zubbers\code\datums\ai_laws\laws_neutral.dm"
#include "modular_zubbers\code\datums\ai_laws\laws_station_sided.dm"
#include "modular_zubbers\code\datums\bubber_quirks\hydrophilic.dm"
+#include "modular_zubbers\code\datums\bubber_quirks\neutral.dm"
#include "modular_zubbers\code\datums\computer_datums\protolathe_modifications.dm"
#include "modular_zubbers\code\datums\diseases\advance\presets.dm"
#include "modular_zubbers\code\datums\id_trim\jobs.dm"
diff --git a/tgui/packages/tgui/interfaces/AntagInfoChangeling.tsx b/tgui/packages/tgui/interfaces/AntagInfoChangeling.tsx
index 82b3fe2ff53..f3eda78c661 100644
--- a/tgui/packages/tgui/interfaces/AntagInfoChangeling.tsx
+++ b/tgui/packages/tgui/interfaces/AntagInfoChangeling.tsx
@@ -1,8 +1,9 @@
+import { BooleanLike } from 'common/react';
import { multiline } from 'common/string';
import { useBackend, useSharedState } from '../backend';
import { Button, Dimmer, Dropdown, Section, Stack, NoticeBox } from '../components';
import { Window } from '../layouts';
-import { ObjectivePrintout, Objective } from './common/Objectives';
+import { ObjectivePrintout, Objective, ReplaceObjectivesButton } from './common/Objectives';
const hivestyle = {
fontWeight: 'bold',
@@ -50,17 +51,18 @@ type Info = {
stolen_antag_info: string;
memories: Memory[];
objectives: Objective[];
+ can_change_objective: BooleanLike;
};
export const AntagInfoChangeling = (props, context) => {
return (
-
+
-
+
@@ -115,7 +117,7 @@ const HivemindSection = (props, context) => {
const IntroductionSection = (props, context) => {
const { act, data } = useBackend(context);
- const { true_name, hive_name, objectives } = data;
+ const { true_name, hive_name, objectives, can_change_objective } = data;
return (
{
{hive_name}.
-
+
+ }
+ />
diff --git a/tgui/packages/tgui/interfaces/AntagInfoHeretic.tsx b/tgui/packages/tgui/interfaces/AntagInfoHeretic.tsx
index cc5f5fd63ee..ff14419473c 100644
--- a/tgui/packages/tgui/interfaces/AntagInfoHeretic.tsx
+++ b/tgui/packages/tgui/interfaces/AntagInfoHeretic.tsx
@@ -2,7 +2,7 @@ import { useBackend, useLocalState } from '../backend';
import { Section, Stack, Box, Tabs, Button, BlockQuote } from '../components';
import { Window } from '../layouts';
import { BooleanLike } from 'common/react';
-import { ObjectivePrintout, Objective } from './common/Objectives';
+import { ObjectivePrintout, Objective, ReplaceObjectivesButton } from './common/Objectives';
const hereticRed = {
color: '#e03c3c',
@@ -49,11 +49,12 @@ type Info = {
total_sacrifices: number;
ascended: BooleanLike;
objectives: Objective[];
+ can_change_objective: BooleanLike;
};
const IntroductionSection = (props, context) => {
- const { data } = useBackend(context); // SKYRAT EDIT BELOW - ORIGINAL: In order to ascend, you have these tasks to fulfill:
- const { objectives } = data;
+ const { data, act } = useBackend(context);
+ const { objectives, ascended, can_change_objective } = data;
return (
@@ -62,20 +63,34 @@ const IntroductionSection = (props, context) => {
-
-
-
-
-
+ {!ascended && (
+
+
+ }
+ />
+
+ )}
@@ -292,7 +307,7 @@ export const AntagInfoHeretic = (props, context) => {
const [currentTab, setTab] = useLocalState(context, 'currentTab', 0);
return (
-
+ {
const { act, data } = useBackend(context);
- const { intro, objectives } = data;
+ const { intro, objectives, can_change_objective } = data;
return (
@@ -46,6 +47,13 @@ const IntroductionSection = (props, context) => {
objectives={objectives}
titleMessage="Your prime objectives:"
objectivePrefix="≥-"
+ objectiveFollowup={
+
+ }
/>
diff --git a/tgui/packages/tgui/interfaces/AntagInfoNinja.tsx b/tgui/packages/tgui/interfaces/AntagInfoNinja.tsx
new file mode 100644
index 00000000000..a537888af75
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/AntagInfoNinja.tsx
@@ -0,0 +1,68 @@
+import { BooleanLike } from 'common/react';
+import { useBackend } from '../backend';
+import { Icon, Section, Stack } from '../components';
+import { Window } from '../layouts';
+import { ObjectivePrintout, Objective, ReplaceObjectivesButton } from './common/Objectives';
+
+const ninja_emphasis = {
+ color: 'red',
+};
+
+type NinjaInfo = {
+ objectives: Objective[];
+ can_change_objective: BooleanLike;
+};
+
+export const AntagInfoNinja = (props, context) => {
+ const { data } = useBackend(context);
+ const { objectives, can_change_objective } = data;
+ return (
+
+
+
+
+
+
+ I am an elite mercenary of the Spider Clan.
+ A SPACE NINJA!
+
+
+ Surprise is my weapon. Shadows are my armor. Without them, I am
+ nothing.
+
+
+
+ Your advanced ninja suit contains many powerful modules.
+ It can be recharged by right clicking on station APCs or
+ other power sources, in order to drain their battery.
+
+ Right clicking on some kinds of machines or items wearing your
+ suit will hack them, to varying effect. Experiment and find out
+ what you can do!
+
+
+
+
+ }
+ />
+
+
+
+
+
+ );
+};
diff --git a/tgui/packages/tgui/interfaces/AntagInfoWizard.tsx b/tgui/packages/tgui/interfaces/AntagInfoWizard.tsx
index 81e1e12994e..e5de257851a 100644
--- a/tgui/packages/tgui/interfaces/AntagInfoWizard.tsx
+++ b/tgui/packages/tgui/interfaces/AntagInfoWizard.tsx
@@ -1,7 +1,8 @@
+import { BooleanLike } from 'common/react';
import { useBackend } from '../backend';
import { Box, Section, Stack } from '../components';
import { Window } from '../layouts';
-import { ObjectivePrintout, Objective } from './common/Objectives';
+import { ObjectivePrintout, Objective, ReplaceObjectivesButton } from './common/Objectives';
const teleportstyle = {
color: 'yellow',
@@ -44,14 +45,15 @@ type GrandRitual = {
type Info = {
objectives: Objective[];
ritual: GrandRitual;
+ can_change_objective: BooleanLike;
};
export const AntagInfoWizard = (props, context) => {
- const { data } = useBackend(context);
- const { ritual, objectives } = data;
+ const { data, act } = useBackend(context);
+ const { ritual, objectives, can_change_objective } = data;
return (
-
+
@@ -64,9 +66,18 @@ export const AntagInfoWizard = (props, context) => {
}
+ objectiveFollowup={
+
+ }
/>
+
+
+
diff --git a/tgui/packages/tgui/interfaces/CameraConsole.js b/tgui/packages/tgui/interfaces/CameraConsole.js
deleted file mode 100644
index 57cc34e77e1..00000000000
--- a/tgui/packages/tgui/interfaces/CameraConsole.js
+++ /dev/null
@@ -1,137 +0,0 @@
-import { filter, sortBy } from 'common/collections';
-import { flow } from 'common/fp';
-import { classes } from 'common/react';
-import { createSearch } from 'common/string';
-import { useBackend, useLocalState } from '../backend';
-import { Button, ByondUi, Flex, Input, Section } from '../components';
-import { Window } from '../layouts';
-
-/**
- * Returns previous and next camera names relative to the currently
- * active camera.
- */
-export const prevNextCamera = (cameras, activeCamera) => {
- if (!activeCamera) {
- return [];
- }
- const index = cameras.findIndex(
- (camera) => camera.name === activeCamera.name
- );
- return [cameras[index - 1]?.name, cameras[index + 1]?.name];
-};
-
-/**
- * Camera selector.
- *
- * Filters cameras, applies search terms and sorts the alphabetically.
- */
-export const selectCameras = (cameras, searchText = '') => {
- const testSearch = createSearch(searchText, (camera) => camera.name);
- return flow([
- // Null camera filter
- filter((camera) => camera?.name),
- // Optional search term
- searchText && filter(testSearch),
- // Slightly expensive, but way better than sorting in BYOND
- sortBy((camera) => camera.name),
- ])(cameras);
-};
-
-export const CameraConsole = (props, context) => {
- const { act, data } = useBackend(context);
- const { mapRef, activeCamera } = data;
- const cameras = selectCameras(data.cameras);
- const [prevCameraName, nextCameraName] = prevNextCamera(
- cameras,
- activeCamera
- );
- return (
-
-
- act('confirm_order')}
- />
-
- );
-};
-
-const CfStep3 = (props, context) => {
- const { act, data } = useBackend(context);
- return (
-
-
- Your device is ready for fabrication...
-
-
- Please insert the required{' '}
-
- {data.totalprice} cr
-
-
-
- Current:
-
- = data.totalprice ? 'good' : 'bad'}>
- {data.credits} cr
-
- act('purchase')}
- />
-
- );
-};
-
-const CfStep4 = (props, context) => {
- return (
-
-
- Thank you for your purchase!
-
-
- If you experience any difficulties with your new device, please contact
- your local network administrator.
-
-
- );
-};
diff --git a/tgui/packages/tgui/interfaces/DelamProcedure.tsx b/tgui/packages/tgui/interfaces/DelamProcedure.tsx
new file mode 100644
index 00000000000..f51c910d672
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/DelamProcedure.tsx
@@ -0,0 +1,105 @@
+import { Section, BlockQuote, Box, NoticeBox } from '../components';
+import { Window } from '../layouts';
+
+export const DelamProcedure = (context) => {
+ return (
+
+
+
+
+
+ So you've found yourself in a bit of a pickle with a
+ delamination of a supermatter reactor.
+
+
+ Don't worry, saving the day is just a few steps away!
+
+
+
+ Locate the ever-elusive red emergency stop button. It's
+ probably hiding in plain sight, so take your time, have a laugh, and
+ enjoy the anticipation. Remember, it's like a treasure hunt,
+ only with the added bonus of preventing a nuclear disaster.
+
+
+ Once you've uncovered the button, muster all your courage and
+ push it like there's no tomorrow. Well, actually, you're
+ pushing it to ensure there is a tomorrow. But hey, who doesn't
+ love a little paradoxical button-pushing?
+
+
+ Prepare for the impending suppression of the supermatter engine
+ room, because things are about to get real quiet. Just make sure
+ everyone has evacuated, or else they'll be in for a surprise.
+ The system needs its space, and it's not known for being the
+ friendliest neighbour.
+
+
+ After the delamination is successfully suppressed, take a moment to
+ appreciate the delicate beauty of crystal-based electricity. Take a
+ look around and fix any damage to those fragile glass components.
+ Feel free to put on your finest overalls and channel your inner
+ engiborg while doing so.
+
+
+ Keep an eye out for fires and the infamous air mix. It's always
+ an adventure trying to strike the perfect balance between breathable
+ air and potential suffocation. Remember, oxygen plus a spark equals
+ fireworks - the kind you definitely don't want inside a
+ reactor.
+
+
+
+ Did you know freon catches fire at low temperatures?
+
+
+ It even forms hot ice between 120K and 160K!
+
+
+ Remember you can always turn the engine room air alarm to
+ contaminated to assist in removing harmful gases!
+
+
+
+ To avoid singeing your eyebrows off, consider enlisting the help of
+ a synth or a trusty borg. After all, nothing says "safety
+ first" like outsourcing your firefighting to non-living,
+ non-breathing assistants.
+
+
+ Clear out any lightly radioactive debris and/or hot ice (The cargo
+ department will probably love to dispose it for you.)
+
+
+ Finally, revel in the satisfaction of knowing that you've
+ single-handedly prevented a delamination. But, of course, don't
+ forget to feel guilty because SAFETY MOTH Knows. SAFETY MOTH knows
+ everything. It's always watching, judging, and probably taking
+ notes for its next safety briefing. So bask in the glory of your
+ heroism, but know that the all-knowing Moff is onto you.
+
+
+ Optional step, for the true daredevils out there
+
+
+ When it comes time for your second attempt at starting the SM: Take
+ this sign, give it a good toss towards the crystal, and watch it
+ soar through the air.
+
+ Nothing says "I'm dealing with a potentially catastrophic
+ situation" like engaging in some whimsical shenanigans.
+