diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 0355ff343fa7f..035e7dd999680 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -182,6 +182,10 @@
/code/modules/atmospherics/ @Pickle-Coding
/code/modules/power/ @Pickle-Coding
+# Sadboysuss
+
+/sound/ @Sadboysuss
+
# MULTIPLE OWNERS
/SQL/ @Jordie0608 @scriptis
diff --git a/.github/actions/restore_or_install_byond/action.yml b/.github/actions/restore_or_install_byond/action.yml
index a4b9ce9da6d8b..4b07a612558d4 100644
--- a/.github/actions/restore_or_install_byond/action.yml
+++ b/.github/actions/restore_or_install_byond/action.yml
@@ -1,4 +1,4 @@
-# This is a reusable workflow to restore BYOND from a cache, or to install it otherwise.
+# This action attempts to restore BYOND from a cache, or to install it otherwise.
name: Restore or Install BYOND
description: Attempts to restore a specified BYOND version from cache; if it can't, it installs it.
diff --git a/.github/actions/setup_node/action.yml b/.github/actions/setup_node/action.yml
new file mode 100644
index 0000000000000..120dbf4639ba7
--- /dev/null
+++ b/.github/actions/setup_node/action.yml
@@ -0,0 +1,26 @@
+# This action is a wrapper around `actions/setup-node`, to use the version specified in
+# `dependencies.sh`.
+name: Setup Node
+description: Install Node using the version specified in `dependencies.sh`; additionally, restores the Yarn cache if one exists
+
+inputs:
+ restore-yarn-cache:
+ description: 'If `true`, restores the Yarn cache alongside installing node.'
+ required: false
+ type: boolean
+ default: false
+
+runs:
+ using: composite
+ steps:
+ - name: Configure Node version
+ shell: bash
+ run: |
+ source dependencies.sh
+ echo "NODE_VERSION_REQUIRED=$NODE_VERSION_LTS" >> $GITHUB_ENV
+ - name: Install Node
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ env.NODE_VERSION_REQUIRED }}
+ cache: ${{ fromJSON(inputs.restore-yarn-cache) && 'yarn' || '' }}
+ cache-dependency-path: ${{ fromJSON(inputs.restore-yarn-cache) && 'tgui/yarn.lock' || '' }}
diff --git a/.github/workflows/ci_suite.yml b/.github/workflows/ci_suite.yml
index 786cfabead3e1..17cc92e65064d 100644
--- a/.github/workflows/ci_suite.yml
+++ b/.github/workflows/ci_suite.yml
@@ -48,20 +48,10 @@ jobs:
key: ${{ runner.os }}-spacemandmm-${{ hashFiles('dependencies.sh') }}
restore-keys: |
${{ runner.os }}-spacemandmm-
- - name: Restore Yarn cache
- uses: actions/cache@v4
- with:
- path: tgui/.yarn/cache
- key: ${{ runner.os }}-yarn-${{ hashFiles('tgui/yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-yarn-
- - name: Restore Node cache
- uses: actions/cache@v4
+ - name: Setup Node
+ uses: ./.github/actions/setup_node
with:
- path: ~/.nvm
- key: ${{ runner.os }}-node-${{ hashFiles('dependencies.sh') }}
- restore-keys: |
- ${{ runner.os }}-node-
+ restore-yarn-cache: true
- name: Restore Bootstrap cache
uses: actions/cache@v4
with:
@@ -95,7 +85,6 @@ jobs:
- name: Install Tools
run: |
pip3 install setuptools
- bash tools/ci/install_node.sh
bash tools/ci/install_spaceman_dmm.sh dreamchecker
bash tools/ci/install_ripgrep.sh
tools/bootstrap/python -c ''
@@ -156,6 +145,8 @@ jobs:
steps:
- uses: actions/checkout@v4
+ - name: Setup Node
+ uses: ./.github/actions/setup_node
- name: Restore BYOND from Cache
uses: ./.github/actions/restore_or_install_byond
- name: Compile All Maps
@@ -265,13 +256,10 @@ jobs:
steps:
- uses: actions/checkout@v4
- - name: Restore Yarn cache
- uses: actions/cache@v4
+ - name: Setup Node
+ uses: ./.github/actions/setup_node
with:
- path: tgui/.yarn/cache
- key: ${{ runner.os }}-yarn-${{ hashFiles('tgui/yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-yarn-
+ restore-yarn-cache: true
- name: Compile
run: pwsh tools/ci/build.ps1
env:
diff --git a/.github/workflows/run_integration_tests.yml b/.github/workflows/run_integration_tests.yml
index b9ffc6564d136..cb2bfc4b42ba1 100644
--- a/.github/workflows/run_integration_tests.yml
+++ b/.github/workflows/run_integration_tests.yml
@@ -50,6 +50,8 @@ jobs:
mysql -u root -proot tg_ci < SQL/tgstation_schema.sql
mysql -u root -proot -e 'CREATE DATABASE tg_ci_prefixed;'
mysql -u root -proot tg_ci_prefixed < SQL/tgstation_schema_prefixed.sql
+ - name: Setup Node
+ uses: ./.github/actions/setup_node
- name: Install rust-g
run: |
bash tools/ci/install_rust_g.sh
@@ -67,6 +69,7 @@ jobs:
source $HOME/BYOND/byond/bin/byondsetup
tools/build/build --ci dm -DCIBUILDING -DANSICOLORS -Werror -ITG0001 -I"loop_checks"
- name: Run Tests
+ id: run_tests
run: |
source $HOME/BYOND/byond/bin/byondsetup
bash tools/ci/run_server.sh ${{ inputs.map }}
@@ -77,6 +80,29 @@ jobs:
name: test_artifacts_${{ inputs.map }}_${{ inputs.major }}_${{ inputs.minor }}
path: data/screenshots_new/
retention-days: 1
+ - name: On test fail, write a step summary
+ if: always() && steps.run_tests.outcome == 'failure'
+ run: |
+ # Get a JSON array of failed unit tests
+ FAILED_UNIT_TESTS=$(jq 'to_entries | map(.value | select(.status == 1))' data/unit_tests.json)
+
+ FAIL_COUNT=$(echo $FAILED_UNIT_TESTS | jq 'length')
+
+ echo "# Test failures" >> $GITHUB_STEP_SUMMARY
+ echo "$FAIL_COUNT tests failed." >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ for i in $( seq $FAIL_COUNT ); do
+ CURRENT_FAIL=$(echo $FAILED_UNIT_TESTS | jq --arg i $i '.[($i | tonumber) - 1]')
+
+ TEST=$(echo $CURRENT_FAIL | jq --raw-output '.name')
+
+ echo "### $TEST" >> $GITHUB_STEP_SUMMARY
+ echo '```' >> $GITHUB_STEP_SUMMARY
+ echo $CURRENT_FAIL | jq --raw-output '.message' >> $GITHUB_STEP_SUMMARY
+ echo '```' >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ done
- name: Check client Compatibility
if: always() && steps.compile_tests.outcome == 'success'
uses: tgstation/byond-client-compatibility-check@v3
diff --git a/SQL/database_changelog.md b/SQL/database_changelog.md
index f8770e2868dbb..373d97bdf6c7b 100644
--- a/SQL/database_changelog.md
+++ b/SQL/database_changelog.md
@@ -5,15 +5,25 @@ Make sure to also update `DB_MAJOR_VERSION` and `DB_MINOR_VERSION`, which can be
The latest database version is 5.28; The query to update the schema revision table is:
```sql
-INSERT INTO `schema_revision` (`major`, `minor`) VALUES (5, 28);
+INSERT INTO `schema_revision` (`major`, `minor`) VALUES (5, 29);
```
or
```sql
-INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (5, 28);
+INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (5, 29);
```
In any query remember to add a prefix to the table names if you use one.
-----------------------------------------------------
+Version 5.29, 4 February 2024, by Tiviplus
+Fixed admin rank table flags being capped at 16 in the DB instead of 24 (byond max)
+
+```sql
+ALTER TABLE `admin_ranks`
+ MODIFY COLUMN `flags` mediumint(5) unsigned NOT NULL,
+ MODIFY COLUMN `exclude_flags` mediumint(5) unsigned NOT NULL,
+ MODIFY COLUMN `can_edit_flags` mediumint(5) unsigned NOT NULL;
+```
+-----------------------------------------------------
Version 5.28, 1 November 2024, by Ghommie
Added `fish_progress` as the first 'progress' subtype of 'datum/award/scores'
diff --git a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql
index ba3ff538f1c82..96933aa14e189 100644
--- a/SQL/tgstation_schema.sql
+++ b/SQL/tgstation_schema.sql
@@ -53,9 +53,9 @@ DROP TABLE IF EXISTS `admin_ranks`;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `admin_ranks` (
`rank` varchar(32) NOT NULL,
- `flags` smallint(5) unsigned NOT NULL,
- `exclude_flags` smallint(5) unsigned NOT NULL,
- `can_edit_flags` smallint(5) unsigned NOT NULL,
+ `flags` mediumint(5) unsigned NOT NULL,
+ `exclude_flags` mediumint(5) unsigned NOT NULL,
+ `can_edit_flags` mediumint(5) unsigned NOT NULL,
PRIMARY KEY (`rank`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
diff --git a/SQL/tgstation_schema_prefixed.sql b/SQL/tgstation_schema_prefixed.sql
index 525b1b0aa33e6..7b322d5a65275 100644
--- a/SQL/tgstation_schema_prefixed.sql
+++ b/SQL/tgstation_schema_prefixed.sql
@@ -53,9 +53,9 @@ DROP TABLE IF EXISTS `SS13_admin_ranks`;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `SS13_admin_ranks` (
`rank` varchar(32) NOT NULL,
- `flags` smallint(5) unsigned NOT NULL,
- `exclude_flags` smallint(5) unsigned NOT NULL,
- `can_edit_flags` smallint(5) unsigned NOT NULL,
+ `flags` mediumint(5) unsigned NOT NULL,
+ `exclude_flags` mediumint(5) unsigned NOT NULL,
+ `can_edit_flags` mediumint(5) unsigned NOT NULL,
PRIMARY KEY (`rank`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm
index b73cf11fda63e..6bdb976de4bbc 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm
@@ -667,6 +667,9 @@
/area/ruin/syndicate_lava_base/chemistry)
"fx" = (
/obj/structure/sign/warning/secure_area,
+/obj/machinery/porta_turret/syndicate{
+ dir = 9
+ },
/turf/closed/wall/mineral/plastitanium/nodiagonal,
/area/ruin/syndicate_lava_base/cargo)
"fA" = (
@@ -1593,6 +1596,7 @@
/obj/effect/decal/cleanable/dirt,
/obj/machinery/airalarm/directional/east,
/obj/effect/mapping_helpers/airalarm/syndicate_access,
+/obj/item/defibrillator/loaded,
/turf/open/floor/iron/white/side{
dir = 4
},
@@ -1866,6 +1870,9 @@
/area/ruin/syndicate_lava_base/arrivals)
"oF" = (
/obj/structure/sign/warning/secure_area,
+/obj/machinery/porta_turret/syndicate{
+ dir = 9
+ },
/turf/closed/wall/mineral/plastitanium/nodiagonal,
/area/ruin/syndicate_lava_base/arrivals)
"oH" = (
@@ -2163,6 +2170,10 @@
/obj/machinery/light/small/directional/east,
/turf/open/floor/iron/dark,
/area/ruin/syndicate_lava_base/cargo)
+"sB" = (
+/obj/structure/sign/warning/secure_area,
+/turf/closed/wall/mineral/plastitanium/nodiagonal,
+/area/ruin/syndicate_lava_base/cargo)
"sH" = (
/obj/machinery/door/airlock/virology/glass{
name = "Monkey Pen"
@@ -3316,7 +3327,6 @@
/obj/structure/table/wood,
/obj/item/ammo_box/magazine/m9mm,
/obj/machinery/airalarm/directional/north,
-/obj/item/crowbar/red,
/obj/effect/mapping_helpers/airalarm/syndicate_access,
/turf/open/floor/carpet/red,
/area/ruin/syndicate_lava_base/dormitories)
@@ -3648,6 +3658,10 @@
},
/turf/open/floor/iron,
/area/ruin/syndicate_lava_base/engineering)
+"Oj" = (
+/obj/structure/sign/warning/secure_area,
+/turf/closed/wall/mineral/plastitanium/nodiagonal,
+/area/ruin/syndicate_lava_base/arrivals)
"Oq" = (
/obj/effect/spawner/random/vending/colavend{
hacked = 1
@@ -4127,7 +4141,6 @@
/obj/item/ammo_box/magazine/m9mm,
/obj/item/ammo_box/magazine/sniper_rounds,
/obj/machinery/airalarm/directional/north,
-/obj/item/crowbar/red,
/obj/effect/mapping_helpers/airalarm/syndicate_access,
/turf/open/floor/carpet/red,
/area/ruin/syndicate_lava_base/dormitories)
@@ -4506,7 +4519,6 @@
/obj/structure/table/wood,
/obj/item/ammo_box/magazine/m9mm,
/obj/item/ammo_box/magazine/sniper_rounds,
-/obj/item/crowbar/red,
/turf/open/floor/carpet/red,
/area/ruin/syndicate_lava_base/dormitories)
"Zw" = (
@@ -5325,7 +5337,7 @@ Vb
mT
mT
mT
-oF
+Oj
ab
ab
ab
@@ -6648,7 +6660,7 @@ ab
ab
ab
ab
-fx
+sB
gh
fx
si
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1/commswilding_1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1/commswilding_1.dmm
index 92338633ecfb3..8ca5c0cd2b50e 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1/commswilding_1.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1/commswilding_1.dmm
@@ -135,6 +135,10 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/ruin/syndicate_lava_base/telecomms)
+"R" = (
+/obj/structure/filingcabinet/medical,
+/turf/open/floor/iron/dark,
+/area/ruin/syndicate_lava_base/telecomms)
"U" = (
/obj/machinery/light/small/directional/east,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
@@ -216,7 +220,7 @@ f
(6,1,1) = {"
a
e
-c
+R
Z
m
C
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1/commswilding_3.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1/commswilding_3.dmm
index dd00fa974852e..cd6670dfb21f1 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1/commswilding_3.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1/commswilding_3.dmm
@@ -41,6 +41,10 @@
/obj/item/paper_bin,
/obj/item/pen,
/obj/structure/closet/cardboard,
+/obj/item/modular_computer/pda/chameleon/broken{
+ pixel_x = 5;
+ pixel_y = 4
+ },
/turf/open/floor/iron,
/area/ruin/syndicate_lava_base/telecomms)
"m" = (
@@ -63,7 +67,7 @@
/turf/open/floor/iron,
/area/ruin/syndicate_lava_base/telecomms)
"q" = (
-/obj/structure/girder,
+/obj/effect/spawner/structure/window/reinforced/plasma/plastitanium,
/turf/open/floor/plating/lavaland_atmos,
/area/ruin/syndicate_lava_base/telecomms)
"r" = (
@@ -75,16 +79,12 @@
/area/ruin/syndicate_lava_base/telecomms)
"t" = (
/obj/structure/sign/poster/contraband/syndiemoth/directional/west,
-/obj/item/radio/intercom{
- freerange = 1;
- name = "Syndicate Radio Intercom";
- pixel_y = 5
- },
-/obj/structure/table/reinforced,
/obj/effect/decal/cleanable/cobweb,
-/obj/item/phone{
- pixel_x = -4;
- pixel_y = -4
+/obj/machinery/computer/message_monitor{
+ dir = 4
+ },
+/obj/item/paper/monitorkey{
+ pixel_x = 5
},
/turf/open/floor/iron/grimy,
/area/ruin/syndicate_lava_base/telecomms)
@@ -99,6 +99,7 @@
/obj/machinery/door/poddoor{
id = "lavalandsyndi_fredrickleft"
},
+/obj/structure/fans/tiny,
/turf/open/floor/plating,
/area/ruin/syndicate_lava_base/telecomms)
"y" = (
@@ -112,16 +113,21 @@
/turf/open/floor/iron/grimy,
/area/ruin/syndicate_lava_base/telecomms)
"z" = (
-/obj/item/modular_computer/pda/chameleon/broken{
- pixel_x = 5;
- pixel_y = 4
- },
/obj/structure/table/reinforced,
/obj/item/food/cherrycupcake{
pixel_x = -7;
pixel_y = 13
},
+/obj/item/radio/intercom{
+ freerange = 1;
+ name = "Syndicate Radio Intercom";
+ pixel_y = 5
+ },
/obj/effect/decal/cleanable/dirt,
+/obj/item/phone{
+ pixel_x = -4;
+ pixel_y = -4
+ },
/turf/open/floor/iron/grimy,
/area/ruin/syndicate_lava_base/telecomms)
"A" = (
@@ -189,6 +195,7 @@
/obj/effect/turf_decal/tile/red{
dir = 1
},
+/obj/structure/filingcabinet/security,
/turf/open/floor/iron,
/area/ruin/syndicate_lava_base/telecomms)
"K" = (
@@ -199,6 +206,7 @@
"O" = (
/obj/effect/mapping_helpers/airalarm/syndicate_access,
/obj/machinery/airalarm/directional/north,
+/obj/structure/filingcabinet/medical,
/turf/open/floor/iron,
/area/ruin/syndicate_lava_base/telecomms)
"P" = (
diff --git a/_maps/RandomRuins/SpaceRuins/infested_frigate.dmm b/_maps/RandomRuins/SpaceRuins/infested_frigate.dmm
index c925d017ad3a3..aa130e8ddcd1e 100644
--- a/_maps/RandomRuins/SpaceRuins/infested_frigate.dmm
+++ b/_maps/RandomRuins/SpaceRuins/infested_frigate.dmm
@@ -1044,8 +1044,8 @@
pixel_x = 28
},
/obj/item/storage/toolbox/syndicate,
-/obj/item/storage/toolbox/maint_kit,
-/obj/item/storage/toolbox/maint_kit,
+/obj/item/gun_maintenance_supplies,
+/obj/item/gun_maintenance_supplies,
/obj/item/storage/toolbox/electrical,
/obj/item/storage/box/lights/bulbs,
/obj/item/stack/sheet/glass{
diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm
index 758a5c877925e..1940705b466f4 100644
--- a/_maps/map_files/Birdshot/birdshot.dmm
+++ b/_maps/map_files/Birdshot/birdshot.dmm
@@ -533,14 +533,16 @@
"amK" = (
/obj/effect/turf_decal/weather/snow,
/obj/structure/disposalpipe/segment,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/turf_decal/weather/snow/corner{
dir = 9
},
/obj/structure/cable,
/obj/machinery/airalarm/directional/west,
-/turf/open/floor/iron/freezer,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/components/binary/pump/on,
+/obj/effect/mapping_helpers/airalarm/tlv_cold_room,
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"amX" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -3895,14 +3897,14 @@
/turf/open/floor/iron/white/small,
/area/station/security/warden)
"bvP" = (
-/obj/machinery/door/airlock{
- name = "Kitchen"
- },
/obj/effect/mapping_helpers/airlock/access/all/service/kitchen,
/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,
+/obj/machinery/atmospherics/pipe/layer_manifold/supply/hidden,
+/obj/machinery/door/airlock{
+ name = "Maintenance"
+ },
/turf/open/floor/plating,
/area/station/maintenance/central/greater)
"bwz" = (
@@ -3949,9 +3951,8 @@
/obj/effect/turf_decal/weather/snow/corner{
dir = 1
},
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/food_cart,
-/turf/open/floor/iron/freezer,
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"bxI" = (
/obj/structure/cable,
@@ -4719,10 +4720,10 @@
/obj/structure/disposalpipe/segment{
dir = 4
},
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
- dir = 1
+/obj/machinery/atmospherics/pipe/heat_exchanging/junction{
+ dir = 4
},
-/turf/open/floor/iron/freezer,
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"bMt" = (
/obj/structure/cable,
@@ -7465,11 +7466,11 @@
id = "kitchenshutters";
name = "Kitchen Shutter Control"
},
-/obj/machinery/disposal/bin,
-/obj/structure/disposalpipe/trunk{
- dir = 8
+/obj/machinery/smartfridge/drying,
+/obj/effect/turf_decal/siding/end{
+ dir = 4
},
-/turf/open/floor/iron/kitchen/small,
+/turf/open/floor/iron/dark/textured_large,
/area/station/service/kitchen)
"cMG" = (
/obj/machinery/door/poddoor/incinerator_atmos_aux,
@@ -8506,7 +8507,8 @@
/obj/structure/disposalpipe/segment{
dir = 10
},
-/turf/open/floor/iron/freezer,
+/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w,
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"ddK" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -9402,9 +9404,8 @@
/turf/open/floor/iron/white,
/area/station/science/robotics/augments)
"duj" = (
-/obj/structure/disposalpipe/segment{
- dir = 5
- },
+/obj/structure/disposalpipe/segment,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible,
/turf/open/floor/iron/kitchen/small,
/area/station/service/kitchen)
"dun" = (
@@ -23047,7 +23048,10 @@
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
},
-/turf/open/floor/iron/freezer,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 4
+ },
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"hWU" = (
/obj/machinery/door/airlock{
@@ -26234,7 +26238,10 @@
dir = 1
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron/freezer,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 4
+ },
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"iSb" = (
/obj/structure/frame/computer{
@@ -30565,7 +30572,11 @@
},
/obj/machinery/power/apc/auto_name/directional/west,
/obj/structure/cable,
-/turf/open/floor/iron/freezer,
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 1
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible,
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"kjO" = (
/obj/machinery/portable_atmospherics/canister/air,
@@ -33549,7 +33560,10 @@
/obj/machinery/light/small/directional/north,
/obj/machinery/icecream_vat,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron/freezer,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 6
+ },
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"lji" = (
/obj/structure/flora/tree/jungle/style_2,
@@ -36987,6 +37001,7 @@
/obj/effect/turf_decal/siding/end{
dir = 8
},
+/obj/effect/mapping_helpers/airalarm/tlv_kitchen,
/turf/open/floor/iron/dark/textured_large,
/area/station/service/kitchen)
"moj" = (
@@ -44319,6 +44334,11 @@
/obj/effect/turf_decal/siding{
dir = 8
},
+/obj/item/book/manual/chef_recipes,
+/obj/item/stack/package_wrap{
+ pixel_y = 2
+ },
+/obj/item/holosign_creator/robot_seat/restaurant,
/turf/open/floor/iron/dark/textured_large,
/area/station/service/kitchen)
"oTN" = (
@@ -46399,6 +46419,9 @@
name = "Freezer"
},
/obj/structure/disposalpipe/segment,
+/obj/machinery/atmospherics/pipe/heat_exchanging/junction{
+ dir = 1
+ },
/turf/open/floor/iron/freezer,
/area/station/service/kitchen)
"pFk" = (
@@ -52236,15 +52259,13 @@
/turf/open/floor/iron/smooth,
/area/station/hallway/secondary/command)
"rxZ" = (
-/obj/item/book/manual/chef_recipes,
-/obj/item/stack/package_wrap{
- pixel_y = 2
- },
-/obj/item/holosign_creator/robot_seat/restaurant,
/obj/effect/turf_decal/siding{
dir = 9
},
-/obj/structure/table,
+/obj/machinery/disposal/bin,
+/obj/structure/disposalpipe/trunk{
+ dir = 1
+ },
/turf/open/floor/iron/dark/textured_large,
/area/station/service/kitchen)
"rya" = (
@@ -54932,7 +54953,10 @@
dir = 5
},
/obj/effect/turf_decal/weather/snow,
-/turf/open/floor/iron/freezer,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 10
+ },
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"sta" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -63679,11 +63703,12 @@
/area/station/science/robotics/mechbay)
"vfI" = (
/obj/machinery/light_switch/directional/north,
-/obj/structure/disposalpipe/segment{
- dir = 4
+/obj/effect/turf_decal/siding/end{
+ dir = 8
+ },
+/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on/coldroom{
+ dir = 8
},
-/obj/effect/turf_decal/siding/end,
-/obj/machinery/smartfridge/drying,
/turf/open/floor/iron/dark/textured_large,
/area/station/service/kitchen)
"vfK" = (
@@ -65364,6 +65389,10 @@
},
/turf/open/floor/iron/dark,
/area/station/science/xenobiology)
+"vCu" = (
+/obj/structure/disposalpipe/segment,
+/turf/open/floor/iron/kitchen/small,
+/area/station/service/kitchen)
"vCO" = (
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/white,
@@ -67010,7 +67039,10 @@
/obj/effect/turf_decal/weather/snow/corner{
dir = 6
},
-/turf/open/floor/iron/freezer,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 9
+ },
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"wbd" = (
/obj/structure/cable,
@@ -100294,7 +100326,7 @@ ljg
ddF
pEU
duj
-aTg
+vCu
rxZ
fhp
oTM
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index e11938e405dca..afeceb69f4760 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -3158,7 +3158,7 @@
},
/obj/structure/window/reinforced/spawner/directional/east,
/obj/effect/turf_decal/delivery,
-/turf/open/floor/iron/freezer,
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"aMK" = (
/obj/structure/chair/pew/left,
@@ -8221,7 +8221,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 1
},
-/turf/open/floor/iron/freezer,
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"bWZ" = (
/obj/effect/landmark/start/hangover,
@@ -18636,7 +18636,7 @@
/obj/effect/decal/cleanable/dirt,
/obj/machinery/duct,
/mob/living/basic/goat/pete,
-/turf/open/floor/iron/freezer,
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"eFj" = (
/obj/structure/window/reinforced/spawner/directional/west,
@@ -23442,7 +23442,7 @@
/obj/effect/decal/cleanable/dirt,
/obj/machinery/airalarm/directional/north,
/obj/effect/mapping_helpers/airalarm/tlv_cold_room,
-/turf/open/floor/iron/freezer,
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"fOz" = (
/obj/structure/disposalpipe/segment{
@@ -27339,7 +27339,7 @@
/area/station/science/xenobiology)
"gIJ" = (
/obj/machinery/gibber,
-/turf/open/floor/iron/dark/textured,
+/turf/open/floor/iron/kitchen_coldroom/dark/textured,
/area/station/service/kitchen/coldroom)
"gIM" = (
/obj/machinery/atmospherics/components/unary/passive_vent{
@@ -27801,7 +27801,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 4
},
-/turf/open/floor/iron/freezer,
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"gPt" = (
/obj/effect/landmark/event_spawn,
@@ -30515,7 +30515,7 @@
"hBF" = (
/obj/structure/kitchenspike,
/obj/effect/turf_decal/bot/left,
-/turf/open/floor/iron/dark,
+/turf/open/floor/iron/kitchen_coldroom/dark,
/area/station/service/kitchen/coldroom)
"hBL" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -32126,6 +32126,7 @@
/obj/effect/decal/cleanable/dirt,
/obj/machinery/airalarm/directional/west,
/obj/machinery/duct,
+/obj/effect/mapping_helpers/airalarm/tlv_kitchen,
/turf/open/floor/iron/cafeteria,
/area/station/service/kitchen)
"hXx" = (
@@ -32726,7 +32727,7 @@
"idQ" = (
/obj/structure/kitchenspike,
/obj/effect/turf_decal/bot/right,
-/turf/open/floor/iron/dark,
+/turf/open/floor/iron/kitchen_coldroom/dark,
/area/station/service/kitchen/coldroom)
"idT" = (
/turf/closed/wall/r_wall,
@@ -36643,7 +36644,7 @@
dir = 1
},
/obj/effect/turf_decal/siding/white,
-/turf/open/floor/iron/freezer,
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"jeo" = (
/turf/open/floor/plating,
@@ -40161,7 +40162,7 @@
dir = 1
},
/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/freezer,
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"jUV" = (
/obj/effect/turf_decal/trimline/neutral/filled/line{
@@ -56826,7 +56827,7 @@
pixel_x = -3;
pixel_y = -3
},
-/turf/open/floor/iron/dark,
+/turf/open/floor/iron/kitchen_coldroom/dark,
/area/station/service/kitchen/coldroom)
"okJ" = (
/obj/effect/turf_decal/bot,
@@ -58680,7 +58681,7 @@
dir = 4
},
/obj/effect/turf_decal/stripes/line,
-/turf/open/floor/iron/freezer,
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"oLV" = (
/obj/effect/landmark/start/hangover,
@@ -59332,7 +59333,7 @@
},
/obj/machinery/light/small/directional/east,
/obj/item/radio/intercom/directional/east,
-/turf/open/floor/iron/freezer,
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"oTC" = (
/obj/effect/decal/cleanable/dirt,
@@ -71398,7 +71399,7 @@
dir = 4
},
/obj/effect/turf_decal/siding/white/corner,
-/turf/open/floor/iron/freezer,
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"rQZ" = (
/obj/machinery/modular_computer/preset/id{
@@ -73380,7 +73381,7 @@
/obj/effect/turf_decal/bot,
/obj/item/food/meat/slab/monkey,
/obj/item/food/meat/slab/monkey,
-/turf/open/floor/iron/dark,
+/turf/open/floor/iron/kitchen_coldroom/dark,
/area/station/service/kitchen/coldroom)
"sqT" = (
/obj/structure/cable,
@@ -76683,7 +76684,7 @@
dir = 8
},
/obj/effect/landmark/event_spawn,
-/turf/open/floor/iron/freezer,
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"thB" = (
/obj/structure/window/reinforced/spawner/directional/west,
@@ -89432,7 +89433,7 @@
/obj/effect/turf_decal/bot,
/obj/structure/closet/secure_closet/freezer/kitchen,
/obj/item/reagent_containers/condiment/flour,
-/turf/open/floor/iron/dark,
+/turf/open/floor/iron/kitchen_coldroom/dark,
/area/station/service/kitchen/coldroom)
"wqn" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -89585,7 +89586,7 @@
"wrP" = (
/obj/structure/reagent_dispensers/cooking_oil,
/obj/effect/turf_decal/delivery,
-/turf/open/floor/iron/dark,
+/turf/open/floor/iron/kitchen_coldroom/dark,
/area/station/service/kitchen/coldroom)
"wrZ" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -92228,7 +92229,7 @@
/obj/item/reagent_containers/condiment/milk,
/obj/item/reagent_containers/condiment/milk,
/obj/item/reagent_containers/condiment/soymilk,
-/turf/open/floor/iron/dark,
+/turf/open/floor/iron/kitchen_coldroom/dark,
/area/station/service/kitchen/coldroom)
"xcd" = (
/obj/item/stack/cable_coil,
@@ -94250,7 +94251,7 @@
},
/obj/structure/disposalpipe/segment,
/obj/machinery/duct,
-/turf/open/floor/iron/freezer,
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"xAu" = (
/obj/effect/turf_decal/trimline/neutral/warning{
@@ -95267,7 +95268,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 4
},
-/turf/open/floor/iron/freezer,
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"xNv" = (
/obj/item/kirbyplants/random,
@@ -95380,7 +95381,7 @@
dir = 10;
name = "service camera"
},
-/turf/open/floor/iron/freezer,
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"xOP" = (
/obj/structure/cable,
@@ -96035,7 +96036,7 @@
/obj/machinery/light/small/directional/west,
/obj/machinery/firealarm/directional/west,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
-/turf/open/floor/iron/freezer,
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"xYW" = (
/obj/effect/decal/cleanable/dirt,
@@ -96333,7 +96334,7 @@
dir = 8
},
/obj/effect/decal/cleanable/food/flour,
-/turf/open/floor/iron/freezer,
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"ydp" = (
/obj/structure/table,
diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
index d03e68a03371a..7e0d66282425c 100644
--- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm
+++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
@@ -833,6 +833,12 @@
/obj/structure/window/reinforced/tinted/spawner/directional/north,
/turf/open/floor/plating,
/area/station/security/prison/safe)
+"anW" = (
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 4
+ },
+/turf/open/floor/plating/snowed/coldroom,
+/area/station/service/kitchen/coldroom)
"anZ" = (
/obj/effect/spawner/structure/window/hollow/reinforced/middle{
dir = 4
@@ -1156,6 +1162,12 @@
},
/turf/open/floor/iron,
/area/station/command/bridge)
+"aqH" = (
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 10
+ },
+/turf/open/floor/plating/snowed/coldroom,
+/area/station/service/kitchen/coldroom)
"aqQ" = (
/obj/structure/table,
/obj/item/stack/package_wrap,
@@ -1271,6 +1283,12 @@
/obj/item/storage/crayons,
/turf/open/floor/iron,
/area/station/commons/dorms)
+"asf" = (
+/obj/machinery/atmospherics/components/binary/pump/on{
+ dir = 8
+ },
+/turf/open/floor/plating/snowed/coldroom,
+/area/station/service/kitchen/coldroom)
"asg" = (
/obj/structure/closet,
/obj/effect/spawner/random/maintenance/two,
@@ -4318,11 +4336,9 @@
name = "The Ice Box";
req_access = list("kitchen")
},
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
- dir = 1
- },
/obj/effect/turf_decal/siding/white,
/obj/item/radio/intercom/directional/east,
+/obj/machinery/atmospherics/pipe/layer_manifold/supply/hidden,
/turf/open/floor/iron/freezer,
/area/station/service/kitchen/coldroom)
"biE" = (
@@ -5195,6 +5211,7 @@
/obj/structure/railing{
dir = 1
},
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/freezer,
/area/station/service/kitchen/coldroom)
"bts" = (
@@ -5503,6 +5520,12 @@
},
/turf/open/floor/plating/snowed/smoothed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
+"bxb" = (
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 4
+ },
+/turf/open/floor/plating/snowed/smoothed/icemoon,
+/area/icemoon/underground/unexplored/rivers/deep/shoreline)
"bxe" = (
/turf/closed/wall/r_wall,
/area/station/maintenance/solars/starboard/fore)
@@ -7976,11 +7999,9 @@
/turf/open/floor/iron/dark,
/area/station/service/chapel/office)
"ceQ" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
/obj/structure/cable,
/obj/structure/minecart_rail/railbreak,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple,
/turf/open/floor/plating/snowed/coldroom,
/area/station/service/kitchen/coldroom)
"ceS" = (
@@ -9550,6 +9571,9 @@
},
/turf/open/floor/iron/dark,
/area/station/ai_monitored/turret_protected/ai_upload)
+"cBY" = (
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/underground/unexplored/rivers/deep/shoreline)
"cCb" = (
/obj/structure/flora/tree/pine/style_random,
/turf/open/misc/asteroid/snow/icemoon,
@@ -12616,6 +12640,12 @@
/obj/effect/turf_decal/siding/thinplating,
/turf/open/floor/plating/snowed/smoothed/icemoon,
/area/icemoon/underground/explored)
+"dvk" = (
+/obj/structure/fence/corner{
+ dir = 9
+ },
+/turf/open/floor/plating/snowed/smoothed/icemoon,
+/area/icemoon/underground/unexplored/rivers/deep/shoreline)
"dvl" = (
/obj/machinery/camera/motion/directional/north{
c_tag = "Armory - External"
@@ -13202,6 +13232,13 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/carpet,
/area/station/security/prison/rec)
+"dED" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/heat_exchanging/manifold,
+/turf/open/floor/plating/snowed/coldroom,
+/area/station/service/kitchen/coldroom)
"dEI" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -14813,6 +14850,9 @@
"ees" = (
/obj/structure/kitchenspike,
/obj/machinery/status_display/evac/directional/west,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 6
+ },
/turf/open/floor/plating/snowed/coldroom,
/area/station/service/kitchen/coldroom)
"eeD" = (
@@ -15797,6 +15837,14 @@
},
/turf/open/floor/iron/showroomfloor,
/area/station/security/processing)
+"esY" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/structure/disposalpipe/segment{
+ dir = 9
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/lesser)
"eta" = (
/obj/machinery/camera/directional/west{
c_tag = "Central Hallway East"
@@ -16103,6 +16151,7 @@
dir = 4
},
/obj/effect/spawner/structure/window/reinforced/tinted,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible,
/turf/open/floor/plating,
/area/station/maintenance/starboard/lesser)
"eyb" = (
@@ -18581,8 +18630,9 @@
/turf/open/floor/circuit/telecomms/mainframe,
/area/station/tcommsat/server)
"fja" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
+/obj/machinery/light/cold/directional/east,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 9
},
/turf/open/floor/plating/snowed/coldroom,
/area/station/service/kitchen/coldroom)
@@ -19116,6 +19166,7 @@
/obj/structure/disposalpipe/segment{
dir = 5
},
+/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible,
/turf/open/floor/catwalk_floor/iron_smooth,
/area/station/maintenance/starboard/lesser)
"frN" = (
@@ -20584,6 +20635,7 @@
dir = 6
},
/obj/effect/decal/cleanable/dirt/dust,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible,
/turf/open/floor/plating,
/area/station/maintenance/starboard/lesser)
"fOU" = (
@@ -20685,6 +20737,7 @@
/obj/machinery/camera/directional/south{
c_tag = "Service - Electrical Maintenace Lower"
},
+/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible,
/turf/open/floor/catwalk_floor/iron_smooth,
/area/station/maintenance/starboard/lesser)
"fQk" = (
@@ -24539,15 +24592,7 @@
/turf/open/floor/plating,
/area/station/maintenance/aft/greater)
"gWi" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/machinery/door/airlock/freezer{
- desc = "The freezer where the chef keeps all the stuff that needs to be kept cold. Ice cold.";
- name = "The Ice Box"
- },
-/obj/effect/mapping_helpers/airlock/access/all/service/kitchen,
-/turf/open/floor/plating,
+/turf/closed/wall,
/area/station/service/kitchen/coldroom)
"gWn" = (
/obj/machinery/atmospherics/components/trinary/filter/flipped{
@@ -28600,6 +28645,12 @@
/obj/effect/mapping_helpers/airlock/access/all/medical/morgue,
/turf/open/floor/iron/dark,
/area/station/medical/morgue)
+"ieb" = (
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 9
+ },
+/turf/open/floor/plating/snowed/smoothed/icemoon,
+/area/icemoon/underground/explored)
"iem" = (
/obj/structure/railing{
dir = 8
@@ -29998,15 +30049,15 @@
/turf/open/floor/iron/white,
/area/station/maintenance/port/fore)
"iBi" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
/obj/structure/table,
/obj/item/food/grown/carrot,
/obj/item/food/grown/carrot{
pixel_x = -2;
pixel_y = 4
},
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 4
+ },
/turf/open/floor/plating/snowed/coldroom,
/area/station/service/kitchen/coldroom)
"iBl" = (
@@ -33367,6 +33418,9 @@
/area/station/security/warden)
"jBB" = (
/obj/structure/kitchenspike,
+/obj/machinery/atmospherics/pipe/heat_exchanging/junction{
+ dir = 8
+ },
/turf/open/floor/plating/snowed/coldroom,
/area/station/service/kitchen/coldroom)
"jBR" = (
@@ -33480,6 +33534,10 @@
/obj/structure/flora/bush/flowers_br/style_random,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors/nospawn)
+"jDF" = (
+/obj/machinery/atmospherics/pipe/heat_exchanging/manifold,
+/turf/open/floor/plating/snowed/coldroom,
+/area/station/service/kitchen/coldroom)
"jDG" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -34686,14 +34744,14 @@
/turf/open/floor/iron/dark,
/area/station/science/server)
"jUb" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
/obj/structure/table,
/obj/item/stack/sheet/mineral/coal{
pixel_x = 6;
pixel_y = 3
},
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 6
+ },
/turf/open/floor/plating/snowed/coldroom,
/area/station/service/kitchen/coldroom)
"jUi" = (
@@ -40173,6 +40231,7 @@
/obj/structure/disposalpipe/trunk/multiz{
dir = 8
},
+/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible,
/turf/open/floor/plating,
/area/station/maintenance/starboard/lesser)
"lvG" = (
@@ -41441,6 +41500,9 @@
frequency = 1453;
name = "Kitchen Intercom"
},
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 6
+ },
/turf/open/floor/plating/snowed/coldroom,
/area/station/service/kitchen/coldroom)
"lOI" = (
@@ -42363,6 +42425,13 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/smooth_large,
/area/station/command/heads_quarters/hos)
+"mcI" = (
+/obj/structure/lattice/catwalk,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 4
+ },
+/turf/open/openspace/icemoon,
+/area/icemoon/underground/explored)
"mcW" = (
/turf/open/floor/iron/white,
/area/station/medical/medbay/central)
@@ -48930,10 +48999,10 @@
/turf/open/floor/iron/white,
/area/station/science/robotics/lab)
"nVJ" = (
+/obj/structure/cable,
/obj/structure/disposalpipe/segment{
- dir = 4
+ dir = 10
},
-/obj/structure/cable,
/turf/open/floor/plating/snowed/coldroom,
/area/station/service/kitchen/coldroom)
"nVR" = (
@@ -49972,6 +50041,7 @@
dir = 4
},
/obj/effect/spawner/random/engineering/flashlight,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible,
/turf/open/floor/iron/smooth,
/area/station/maintenance/starboard/lesser)
"olV" = (
@@ -52511,6 +52581,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible,
/turf/open/floor/catwalk_floor/iron_smooth,
/area/station/maintenance/starboard/lesser)
"oTA" = (
@@ -53411,6 +53482,15 @@
/obj/effect/decal/cleanable/blood/splatter,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/underground/explored)
+"pgR" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/heat_exchanging/junction{
+ dir = 8
+ },
+/turf/open/floor/plating/snowed/coldroom,
+/area/station/service/kitchen/coldroom)
"pgY" = (
/obj/machinery/cryo_cell,
/obj/effect/turf_decal/stripes/line{
@@ -54142,7 +54222,12 @@
/turf/open/floor/plating,
/area/station/science/xenobiology)
"prX" = (
-/obj/machinery/light/cold/directional/east,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/atmospherics/components/binary/valve/on{
+ dir = 4
+ },
/turf/open/floor/plating/snowed/coldroom,
/area/station/service/kitchen/coldroom)
"psb" = (
@@ -56227,9 +56312,8 @@
/turf/open/genturf,
/area/icemoon/surface/outdoors/unexplored/rivers/no_monsters)
"pWE" = (
-/obj/structure/disposalpipe/segment{
- dir = 9
- },
+/obj/structure/disposalpipe/segment,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible,
/turf/open/floor/plating,
/area/station/maintenance/starboard/lesser)
"pWJ" = (
@@ -59166,6 +59250,12 @@
/obj/effect/mapping_helpers/airlock/access/all/engineering/general,
/turf/open/floor/plating,
/area/station/engineering/storage_shared)
+"qNe" = (
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 10
+ },
+/turf/open/floor/plating/snowed/smoothed/icemoon,
+/area/icemoon/underground/explored)
"qNf" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -60346,6 +60436,15 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/command/gateway)
+"rcR" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 4
+ },
+/turf/open/floor/plating/snowed/coldroom,
+/area/station/service/kitchen/coldroom)
"rcS" = (
/obj/effect/turf_decal/weather/snow/corner{
dir = 9
@@ -60371,6 +60470,13 @@
},
/turf/open/floor/iron/dark,
/area/station/command/heads_quarters/captain)
+"rdg" = (
+/obj/structure/fence/corner{
+ dir = 5
+ },
+/obj/structure/sign/warning/secure_area,
+/turf/open/floor/plating/snowed/smoothed/icemoon,
+/area/icemoon/underground/explored)
"rdn" = (
/obj/item/radio/intercom/directional/north,
/turf/open/floor/iron,
@@ -63028,6 +63134,12 @@
/obj/structure/minecart_rail{
dir = 1
},
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 5
+ },
/turf/open/floor/plating/snowed/coldroom,
/area/station/service/kitchen/coldroom)
"rSe" = (
@@ -63861,9 +63973,6 @@
/turf/open/floor/wood,
/area/station/security/prison/rec)
"sdF" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
/obj/structure/table,
/obj/item/grown/log/tree,
/obj/item/grown/log/tree{
@@ -64536,6 +64645,13 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/starboard)
+"snJ" = (
+/obj/structure/fence/corner{
+ dir = 2
+ },
+/obj/structure/sign/warning/secure_area,
+/turf/open/floor/plating/snowed/smoothed/icemoon,
+/area/icemoon/underground/unexplored/rivers/deep/shoreline)
"snL" = (
/obj/item/pickaxe{
desc = "Someone left their pickaxe out here, must not have known about the boulder processing machines inside.";
@@ -67440,6 +67556,9 @@
/obj/structure/railing{
dir = 1
},
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 4
+ },
/turf/open/floor/iron/freezer,
/area/station/service/kitchen/coldroom)
"tei" = (
@@ -68152,6 +68271,18 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/wood,
/area/station/maintenance/fore)
+"tnR" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/door/airlock/freezer{
+ desc = "The freezer where the chef keeps all the stuff that needs to be kept cold. Ice cold.";
+ name = "The Ice Box"
+ },
+/obj/effect/mapping_helpers/airlock/access/all/service/kitchen,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/lesser)
"tnY" = (
/obj/structure/sign/nanotrasen{
pixel_x = -32
@@ -74418,6 +74549,7 @@
/obj/machinery/processor{
pixel_y = 6
},
+/obj/effect/mapping_helpers/airalarm/tlv_kitchen,
/turf/open/floor/iron/white/smooth_large,
/area/station/service/kitchen)
"vjJ" = (
@@ -77054,6 +77186,12 @@
},
/turf/open/floor/iron/large,
/area/station/engineering/lobby)
+"vYU" = (
+/obj/structure/fence{
+ dir = 4
+ },
+/turf/open/floor/plating/snowed/smoothed/icemoon,
+/area/icemoon/underground/unexplored/rivers/deep/shoreline)
"vZa" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
@@ -78322,6 +78460,10 @@
},
/turf/open/floor/iron/dark,
/area/station/service/hydroponics/garden)
+"wtv" = (
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple,
+/turf/open/floor/plating/snowed/smoothed/icemoon,
+/area/icemoon/underground/explored)
"wtM" = (
/obj/machinery/door/airlock/external{
dir = 4;
@@ -80515,6 +80657,15 @@
/obj/item/toy/figure/botanist,
/turf/open/floor/iron/dark,
/area/station/service/hydroponics)
+"wZZ" = (
+/obj/effect/spawner/structure/window/hollow/reinforced/middle{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/heat_exchanging/junction{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/lesser)
"xad" = (
/obj/effect/spawner/structure/window/hollow/reinforced/middle,
/obj/structure/cable,
@@ -83396,6 +83547,9 @@
/area/mine/mechbay)
"xOc" = (
/obj/machinery/light/cold/directional/west,
+/obj/structure/disposalpipe/segment{
+ dir = 5
+ },
/turf/open/floor/plating/snowed/coldroom,
/area/station/service/kitchen/coldroom)
"xOk" = (
@@ -84135,6 +84289,7 @@
/area/icemoon/surface/outdoors/nospawn)
"xZv" = (
/obj/machinery/status_display/ai/directional/east,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply,
/turf/open/floor/plating/snowed/coldroom,
/area/station/service/kitchen/coldroom)
"xZy" = (
@@ -84265,6 +84420,12 @@
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/turf/open/floor/iron/showroomfloor,
/area/station/security/prison/mess)
+"yba" = (
+/obj/structure/fence/corner{
+ dir = 2
+ },
+/turf/open/floor/plating/snowed/smoothed/icemoon,
+/area/icemoon/underground/unexplored/rivers/deep/shoreline)
"ybb" = (
/obj/effect/turf_decal/trimline/green/filled/line{
dir = 1
@@ -104068,7 +104229,7 @@ thA
iDt
psb
rxz
-gFX
+wDU
wDU
aNw
qmt
@@ -189107,9 +189268,9 @@ tVF
kUo
iKd
ees
-mQk
+jDF
sdF
-mQk
+rcR
fwB
fwB
fwB
@@ -189364,9 +189525,9 @@ sRz
tec
vcD
jBB
-mQk
+anW
jUb
-mQk
+dED
mQk
fwB
nNg
@@ -189620,10 +189781,10 @@ jre
tAT
btq
nRn
-mQk
-mQk
+asf
+anW
iBi
-mQk
+pgR
mbM
oje
gYq
@@ -189878,7 +190039,7 @@ dLA
pnw
biu
xZv
-mQk
+aqH
fja
prX
eud
@@ -190137,7 +190298,7 @@ jre
jre
jre
gWi
-jre
+tnR
jre
jre
jre
@@ -190394,7 +190555,7 @@ wSs
oXE
fOS
pWE
-oXE
+esY
wSs
tpc
jre
@@ -191675,9 +191836,9 @@ xMq
jre
jre
jre
+wZZ
jre
-jre
-jre
+wZZ
jre
aZj
aCo
@@ -191932,9 +192093,9 @@ iDt
iDt
xMq
lvt
+mcI
lvt
-xMq
-xMq
+mcI
jre
jre
jre
@@ -192187,13 +192348,13 @@ scw
iDt
iDt
iDt
-rcY
+qau
lvt
+mcI
lvt
-xMq
-thA
-thA
-thA
+bxb
+cBY
+vYU
thA
thA
thA
@@ -192444,13 +192605,13 @@ scw
scw
iDt
cCb
-syw
-pJm
-pJm
-pCG
-iDt
-thA
-thA
+gsd
+xvp
+qNe
+wtv
+ieb
+dvk
+yba
thA
thA
thA
@@ -192702,11 +192863,11 @@ iDt
scw
iDt
iDt
-iDt
-iDt
-iDt
-iDt
-thA
+rdg
+pJm
+nvB
+pJm
+snJ
thA
thA
thA
@@ -267257,7 +267418,7 @@ ooL
ooL
ooL
ooL
-nXb
+omh
buU
omh
skW
@@ -267514,7 +267675,7 @@ bln
bln
lSu
lSu
-nXb
+omh
omh
omh
xTy
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 4a78966445fff..6d5d3a4400498 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -2179,6 +2179,7 @@
/obj/effect/turf_decal/tile/neutral/opposingcorners{
dir = 1
},
+/obj/effect/mapping_helpers/airalarm/tlv_kitchen,
/turf/open/floor/iron/cafeteria,
/area/station/service/kitchen)
"aNQ" = (
@@ -31313,12 +31314,12 @@
/obj/structure/cable,
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/pipe/layer_manifold/supply/hidden,
-/obj/machinery/door/airlock{
- name = "Kitchen Cold Room"
- },
/obj/machinery/duct,
/obj/structure/disposalpipe/segment,
/obj/effect/mapping_helpers/airlock/access/all/service/kitchen,
+/obj/machinery/door/airlock/freezer{
+ name = "Freezer"
+ },
/turf/open/floor/iron/cafeteria,
/area/station/service/kitchen/coldroom)
"lbh" = (
diff --git a/_maps/map_files/NebulaStation/NebulaStation.dmm b/_maps/map_files/NebulaStation/NebulaStation.dmm
index a386fe33b1a97..d0497c1988f8e 100644
--- a/_maps/map_files/NebulaStation/NebulaStation.dmm
+++ b/_maps/map_files/NebulaStation/NebulaStation.dmm
@@ -9598,6 +9598,9 @@
dir = 4
},
/obj/machinery/duct,
+/obj/machinery/atmospherics/pipe/heat_exchanging/manifold{
+ dir = 1
+ },
/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"byG" = (
@@ -12914,6 +12917,9 @@
dir = 4
},
/obj/machinery/duct,
+/obj/machinery/atmospherics/pipe/heat_exchanging/junction{
+ dir = 8
+ },
/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"bVR" = (
@@ -13265,10 +13271,6 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/service/kitchen)
-"bYy" = (
-/obj/structure/disposalpipe/segment,
-/turf/closed/wall,
-/area/station/maintenance/fore/greater)
"bYA" = (
/obj/effect/turf_decal/siding/wideplating_new/dark{
dir = 8
@@ -25169,9 +25171,6 @@
/turf/open/floor/iron/dark,
/area/station/service/chapel)
"dMb" = (
-/obj/machinery/door/airlock{
- name = "Kitchen Cold Room"
- },
/obj/effect/mapping_helpers/airlock/access/all/service/kitchen,
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -25184,6 +25183,9 @@
dir = 4
},
/obj/machinery/duct,
+/obj/machinery/door/airlock/freezer{
+ name = "Freezer"
+ },
/turf/open/floor/iron/dark,
/area/station/service/kitchen/coldroom)
"dMg" = (
@@ -33526,6 +33528,7 @@
/obj/effect/turf_decal/trimline/brown/corner{
dir = 4
},
+/obj/effect/mapping_helpers/airalarm/tlv_kitchen,
/turf/open/floor/iron/white/small,
/area/station/service/kitchen)
"eXC" = (
@@ -41346,8 +41349,10 @@
/obj/structure/disposalpipe/segment{
dir = 4
},
-/obj/machinery/atmospherics/pipe/heat_exchanging/simple,
/obj/machinery/duct,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 5
+ },
/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"ggh" = (
@@ -57574,12 +57579,14 @@
/obj/machinery/door/airlock/maintenance,
/obj/effect/mapping_helpers/airlock/access/all/service/kitchen,
/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/duct,
+/obj/machinery/atmospherics/pipe/layer_manifold/supply/hidden{
+ dir = 4
+ },
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
"iAX" = (
@@ -69075,14 +69082,14 @@
/turf/open/floor/iron/dark/textured_large,
/area/station/cargo/lobby)
"kla" = (
-/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
- dir = 9
- },
/obj/effect/turf_decal/weather/snow/corner,
/obj/effect/turf_decal/weather/snow,
/obj/effect/turf_decal/weather/snow/corner{
dir = 1
},
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 4
+ },
/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"kle" = (
@@ -105408,6 +105415,9 @@
dir = 4
},
/obj/machinery/duct,
+/obj/machinery/atmospherics/components/binary/pump/on{
+ dir = 8
+ },
/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"pCo" = (
@@ -108939,6 +108949,10 @@
},
/turf/open/floor/iron/dark/textured,
/area/station/commons/fitness/recreation/lasertag)
+"qfe" = (
+/obj/structure/disposalpipe/segment,
+/turf/closed/wall,
+/area/station/maintenance/fore/greater)
"qfk" = (
/obj/effect/turf_decal/siding{
dir = 10
@@ -141776,6 +141790,9 @@
/obj/structure/railing{
dir = 8
},
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 9
+ },
/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"vcM" = (
@@ -264684,7 +264701,7 @@ oDZ
aHU
rNJ
eIp
-bYy
+qfe
cDg
vOl
dAJ
@@ -266232,7 +266249,7 @@ bzt
jkE
nLg
cij
-bYy
+qfe
loK
kCi
nKp
@@ -266489,7 +266506,7 @@ giL
pPi
qIG
jDn
-ybp
+qfe
pKk
wtb
iWl
@@ -266746,7 +266763,7 @@ tNK
wNx
nJU
vBf
-bYy
+qfe
rqn
wik
jyw
diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm
index 22a3adce038d4..ca9cc19b6e31d 100644
--- a/_maps/map_files/tramstation/tramstation.dmm
+++ b/_maps/map_files/tramstation/tramstation.dmm
@@ -1314,6 +1314,9 @@
/turf/open/floor/plating/airless,
/area/station/asteroid)
"aeo" = (
+/obj/machinery/atmospherics/pipe/heat_exchanging/junction{
+ dir = 1
+ },
/turf/open/misc/asteroid/snow/coldroom,
/area/station/service/kitchen/coldroom)
"aeq" = (
@@ -1321,6 +1324,9 @@
/obj/effect/turf_decal/weather/snow/corner,
/obj/effect/turf_decal/weather/snow,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 4
+ },
/turf/open/floor/iron/kitchen_coldroom,
/area/station/service/kitchen/coldroom)
"aer" = (
@@ -1330,6 +1336,9 @@
/obj/effect/turf_decal/weather/snow,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 4
+ },
/turf/open/floor/iron/kitchen_coldroom,
/area/station/service/kitchen/coldroom)
"aes" = (
@@ -1395,6 +1404,14 @@
"aeF" = (
/obj/machinery/power/apc/auto_name/directional/south,
/obj/structure/cable,
+/obj/effect/spawner/random/structure{
+ name = "random snowman spawner";
+ loot = list(/obj/structure/statue/snow/snowman);
+ spawn_loot_chance = 10
+ },
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 5
+ },
/turf/open/misc/asteroid/snow/coldroom,
/area/station/service/kitchen/coldroom)
"aeG" = (
@@ -1435,13 +1452,13 @@
/turf/open/floor/plating/airless,
/area/station/asteroid)
"aeN" = (
-/obj/machinery/door/airlock{
- name = "Kitchen Access"
- },
/obj/effect/mapping_helpers/airlock/access/all/service/kitchen,
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/door/airlock/freezer{
+ name = "Freezer"
+ },
/turf/open/floor/catwalk_floor,
/area/station/service/kitchen/coldroom)
"aeO" = (
@@ -2931,7 +2948,9 @@
/obj/effect/turf_decal/weather/snow/corner{
dir = 4
},
-/obj/structure/kitchenspike,
+/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on/coldroom{
+ dir = 4
+ },
/turf/open/floor/iron/kitchen_coldroom,
/area/station/service/kitchen/coldroom)
"apr" = (
@@ -2940,6 +2959,12 @@
},
/turf/open/floor/iron,
/area/station/engineering/atmos/pumproom)
+"apA" = (
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 10
+ },
+/turf/open/misc/asteroid/snow/coldroom,
+/area/station/service/kitchen/coldroom)
"apC" = (
/turf/closed/wall,
/area/station/maintenance/department/crew_quarters/dorms)
@@ -6514,12 +6539,10 @@
/turf/open/floor/iron/white,
/area/station/security/medical)
"bje" = (
-/obj/effect/spawner/random/structure{
- name = "random snowman spawner";
- loot = list(/obj/structure/statue/snow/snowman);
- spawn_loot_chance = 10
- },
/obj/machinery/light_switch/directional/south,
+/obj/machinery/atmospherics/components/binary/pump/on{
+ dir = 8
+ },
/turf/open/misc/asteroid/snow/coldroom,
/area/station/service/kitchen/coldroom)
"bjK" = (
@@ -6938,6 +6961,7 @@
"btg" = (
/obj/effect/mapping_helpers/airalarm/tlv_cold_room,
/obj/machinery/airalarm/directional/south,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible,
/turf/open/misc/asteroid/snow/coldroom,
/area/station/service/kitchen/coldroom)
"btC" = (
@@ -8942,6 +8966,9 @@
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 4
},
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 5
+ },
/turf/open/floor/iron/kitchen_coldroom,
/area/station/service/kitchen/coldroom)
"caN" = (
@@ -10558,6 +10585,9 @@
/obj/effect/turf_decal/weather/snow,
/obj/effect/turf_decal/weather/snow/corner,
/obj/machinery/icecream_vat,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 4
+ },
/turf/open/floor/iron/kitchen_coldroom,
/area/station/service/kitchen/coldroom)
"cDK" = (
@@ -11386,6 +11416,9 @@
/obj/machinery/camera/directional/north{
c_tag = "Civilian - Kitchen Freezer"
},
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 4
+ },
/turf/open/floor/iron/kitchen_coldroom,
/area/station/service/kitchen/coldroom)
"cRf" = (
@@ -11635,6 +11668,9 @@
/obj/effect/turf_decal/weather/snow/corner{
dir = 8
},
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 9
+ },
/turf/open/floor/iron/kitchen_coldroom,
/area/station/service/kitchen/coldroom)
"cVw" = (
@@ -17591,6 +17627,9 @@
/obj/effect/turf_decal/weather/snow/corner,
/obj/item/radio/intercom/directional/north,
/obj/machinery/food_cart,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 6
+ },
/turf/open/floor/iron/kitchen_coldroom,
/area/station/service/kitchen/coldroom)
"fhc" = (
@@ -21140,6 +21179,9 @@
"gvC" = (
/obj/structure/closet/secure_closet/freezer/meat,
/obj/effect/turf_decal/weather/snow,
+/obj/machinery/atmospherics/pipe/heat_exchanging/manifold{
+ dir = 1
+ },
/turf/open/floor/iron/kitchen_coldroom,
/area/station/service/kitchen/coldroom)
"gvI" = (
@@ -43818,6 +43860,7 @@
/obj/effect/turf_decal/weather/snow/corner{
dir = 8
},
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple,
/turf/open/floor/iron/kitchen_coldroom,
/area/station/service/kitchen/coldroom)
"owm" = (
@@ -61540,6 +61583,7 @@
/obj/structure/closet/secure_closet/freezer/fridge,
/obj/effect/turf_decal/bot_white,
/obj/machinery/airalarm/directional/north,
+/obj/effect/mapping_helpers/airalarm/tlv_kitchen,
/turf/open/floor/iron/white/side,
/area/station/service/kitchen)
"uEE" = (
@@ -64912,9 +64956,12 @@
/turf/open/floor/iron/white,
/area/station/medical/medbay/central)
"vLB" = (
-/obj/structure/reagent_dispensers/cooking_oil,
/obj/effect/turf_decal/weather/snow,
/obj/machinery/light/cold/directional/north,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 4
+ },
+/obj/structure/reagent_dispensers/cooking_oil,
/turf/open/floor/iron/kitchen_coldroom,
/area/station/service/kitchen/coldroom)
"vLL" = (
@@ -67877,6 +67924,9 @@
"wQr" = (
/obj/effect/turf_decal/weather/snow,
/obj/machinery/vending/wardrobe/chef_wardrobe,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 10
+ },
/turf/open/floor/iron/kitchen_coldroom,
/area/station/service/kitchen/coldroom)
"wQN" = (
@@ -69768,6 +69818,9 @@
"xCR" = (
/obj/structure/ladder,
/obj/structure/extinguisher_cabinet/directional/south,
+/obj/machinery/atmospherics/pipe/layer_manifold/supply/hidden{
+ dir = 4
+ },
/turf/open/misc/asteroid/snow/coldroom,
/area/station/service/kitchen/coldroom)
"xDJ" = (
@@ -104061,7 +104114,7 @@ voF
jFC
nUP
cDD
-aeo
+apA
aeF
iRL
quF
diff --git a/_maps/map_files/wawastation/wawastation.dmm b/_maps/map_files/wawastation/wawastation.dmm
index feae642f8b108..a6812f5a3a0b8 100644
--- a/_maps/map_files/wawastation/wawastation.dmm
+++ b/_maps/map_files/wawastation/wawastation.dmm
@@ -1633,6 +1633,9 @@
"aAg" = (
/obj/effect/landmark/event_spawn,
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
+/obj/machinery/atmospherics/pipe/heat_exchanging/junction{
+ dir = 8
+ },
/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"aAk" = (
@@ -2137,6 +2140,9 @@
"aJv" = (
/obj/structure/reagent_dispensers/cooking_oil,
/obj/machinery/camera/autoname/directional/south,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 4
+ },
/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"aJz" = (
@@ -4187,6 +4193,9 @@
/area/station/command/bridge)
"byb" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
+/obj/machinery/atmospherics/pipe/heat_exchanging/manifold{
+ dir = 1
+ },
/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"byf" = (
@@ -8231,6 +8240,7 @@
/obj/machinery/airalarm/directional/south,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/mapping_helpers/airalarm/tlv_kitchen,
/turf/open/floor/iron/kitchen,
/area/station/service/kitchen)
"cXP" = (
@@ -8285,6 +8295,9 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/mob/living/basic/goat/pete,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 4
+ },
/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"cYP" = (
@@ -10063,6 +10076,9 @@
/area/station/engineering/main)
"dCh" = (
/obj/machinery/gibber,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 9
+ },
/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"dCi" = (
@@ -11612,9 +11628,13 @@
/turf/open/floor/iron,
/area/station/engineering/atmos)
"edv" = (
-/obj/machinery/computer/order_console/cook,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/service)
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/components/binary/pump/on{
+ dir = 8
+ },
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
+/area/station/service/kitchen/coldroom)
"edH" = (
/obj/effect/turf_decal/tile/red/half/contrasted{
dir = 8
@@ -15588,6 +15608,14 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron,
/area/station/hallway/primary/central)
+"fBA" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/heat_exchanging/manifold{
+ dir = 8
+ },
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
+/area/station/service/kitchen/coldroom)
"fBD" = (
/obj/effect/spawner/random/structure/grille,
/turf/open/floor/plating,
@@ -37663,7 +37691,9 @@
/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/west,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 5
+ },
/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"nlI" = (
@@ -40526,9 +40556,9 @@
/area/station/science/explab)
"otA" = (
/obj/structure/cable/multilayer/multiz,
-/obj/item/assembly/mousetrap/armed,
-/obj/machinery/light/directional/north,
-/turf/open/floor/plating,
+/obj/machinery/computer/order_console/cook,
+/obj/effect/turf_decal/tile/dark_green/opposingcorners,
+/turf/open/floor/iron,
/area/station/hallway/secondary/service)
"otH" = (
/obj/structure/closet/crate/cardboard,
@@ -41103,8 +41133,9 @@
/turf/closed/wall/r_wall,
/area/station/engineering/supermatter)
"oEo" = (
-/obj/effect/turf_decal/tile/dark_green/opposingcorners,
-/turf/closed/wall,
+/obj/machinery/light/directional/north,
+/obj/item/assembly/mousetrap/armed,
+/turf/open/floor/plating,
/area/station/hallway/secondary/service)
"oEp" = (
/obj/effect/spawner/structure/window,
@@ -44521,6 +44552,13 @@
dir = 1
},
/area/station/service/chapel)
+"pMV" = (
+/obj/machinery/power/apc/auto_name/directional/west,
+/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on/coldroom{
+ dir = 1
+ },
+/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
+/area/station/service/kitchen/coldroom)
"pNa" = (
/obj/machinery/door/window/left/directional/east,
/turf/open/floor/grass,
@@ -44870,6 +44908,9 @@
"pTn" = (
/obj/structure/kitchenspike,
/obj/machinery/light/directional/west,
+/obj/machinery/atmospherics/pipe/heat_exchanging/junction{
+ dir = 1
+ },
/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"pTt" = (
@@ -48057,13 +48098,13 @@
/turf/open/floor/iron/white,
/area/station/ai_monitored/turret_protected/ai_upload_foyer)
"rbt" = (
-/obj/machinery/door/airlock{
- name = "Kitchen Cold Room"
- },
/obj/effect/mapping_helpers/airlock/access/all/service/kitchen,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/cable,
+/obj/machinery/door/airlock/freezer{
+ name = "Freezer"
+ },
/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"rbw" = (
@@ -50352,6 +50393,9 @@
"rNs" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 10
+ },
/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"rNJ" = (
@@ -53842,12 +53886,14 @@
/turf/open/floor/catwalk_floor,
/area/station/maintenance/central/lesser)
"sUI" = (
-/obj/machinery/door/airlock{
- name = "Kitchen Cold Room"
- },
/obj/effect/mapping_helpers/airlock/access/all/service/kitchen,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/layer_manifold/supply/hidden{
+ dir = 4
+ },
+/obj/machinery/door/airlock/freezer{
+ name = "Freezer"
+ },
/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"sUM" = (
@@ -55367,6 +55413,9 @@
"twW" = (
/obj/structure/kitchenspike,
/obj/item/radio/intercom/directional/west,
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
+ dir = 6
+ },
/turf/open/floor/iron/kitchen_coldroom/freezerfloor,
/area/station/service/kitchen/coldroom)
"txo" = (
@@ -93468,7 +93517,7 @@ mMT
mMT
mMT
mMT
-edv
+mMT
eBb
hRB
cXe
@@ -93724,7 +93773,7 @@ mMT
mMT
twW
pTn
-mMT
+pMV
mMT
hwk
hRB
@@ -93980,7 +94029,7 @@ fDN
mMT
uZg
byb
-rNs
+fBA
nlz
rbt
cXL
@@ -94493,7 +94542,7 @@ atX
mUW
mMT
fNy
-rNs
+edv
rNs
dCh
mMT
diff --git a/_maps/virtual_domains/meta_central.dmm b/_maps/virtual_domains/meta_central.dmm
index 3fc4ed7f21e1f..76f90e2c88bb6 100644
--- a/_maps/virtual_domains/meta_central.dmm
+++ b/_maps/virtual_domains/meta_central.dmm
@@ -1339,13 +1339,6 @@
/obj/item/pickaxe/rusted,
/turf/open/floor/iron,
/area/virtual_domain)
-"lx" = (
-/obj/structure/barricade/sandbags,
-/obj/machinery/deployable_turret{
- dir = 1
- },
-/turf/open/floor/plating,
-/area/virtual_domain)
"lC" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/public/glass{
@@ -7784,7 +7777,7 @@ LG
uS
hd
Ol
-lx
+wN
vU
hp
lu
diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm
index 3569b9af1e61d..b687ef5ace2a2 100644
--- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm
+++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm
@@ -43,7 +43,7 @@
#define COMSIG_LIVING_REVIVE "living_revive"
///from base of mob/living/set_buckled(): (new_buckled)
#define COMSIG_LIVING_SET_BUCKLED "living_set_buckled"
-///from base of mob/living/set_body_position()
+///from base of mob/living/set_body_position(): (new_position, old_position)
#define COMSIG_LIVING_SET_BODY_POSITION "living_set_body_position"
/// Sent to a mob being injected with a syringe when the do_after initiates
#define COMSIG_LIVING_TRY_SYRINGE_INJECT "living_try_syringe_inject"
diff --git a/code/__DEFINES/obj_flags.dm b/code/__DEFINES/obj_flags.dm
index b6da277775666..97fbbdc8733fa 100644
--- a/code/__DEFINES/obj_flags.dm
+++ b/code/__DEFINES/obj_flags.dm
@@ -35,17 +35,16 @@
#define SURGICAL_TOOL (1<<12) //Tool commonly used for surgery: won't attack targets in an active surgical operation on help intent (in case of mistakes)
#define CRUEL_IMPLEMENT (1<<13) //This object, when used for surgery, is a lot worse at the job if the target is alive rather than dead
#define HAND_ITEM (1<<14) // If an item is just your hand (circled hand, slapper) and shouldn't block things like riding
-#define EXAMINE_SKIP (1<<15) // Makes the Examine proc not read out this item.
-#define XENOMORPH_HOLDABLE (1<<16) // A Xenomorph can hold this item.
-#define NO_PIXEL_RANDOM_DROP (1<<17) //if dropped, it wont have a randomized pixel_x/pixel_y
+#define XENOMORPH_HOLDABLE (1<<15) // A Xenomorph can hold this item.
+#define NO_PIXEL_RANDOM_DROP (1<<16) //if dropped, it wont have a randomized pixel_x/pixel_y
///Can be equipped on digitigrade legs.
-#define IGNORE_DIGITIGRADE (1<<18)
+#define IGNORE_DIGITIGRADE (1<<17)
/// Has contextual screentips when HOVERING OVER OTHER objects
-#define ITEM_HAS_CONTEXTUAL_SCREENTIPS (1 << 19)
+#define ITEM_HAS_CONTEXTUAL_SCREENTIPS (1 << 18)
/// No blood overlay is allowed to appear on this item, and it cannot gain blood DNA forensics
-#define NO_BLOOD_ON_ITEM (1 << 20)
+#define NO_BLOOD_ON_ITEM (1 << 19)
/// Whether this item should skip the /datum/component/fantasy applied on spawn on the RPG event. Used on things like stacks
-#define SKIP_FANTASY_ON_SPAWN (1<<21)
+#define SKIP_FANTASY_ON_SPAWN (1<<20)
// Flags for the clothing_flags var on /obj/item/clothing
diff --git a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm
index ed195f1c1da07..5660c7d87d0d4 100644
--- a/code/__DEFINES/sound.dm
+++ b/code/__DEFINES/sound.dm
@@ -256,6 +256,8 @@ GLOBAL_LIST_INIT(announcer_keys, list(
#define SFX_SEATBELT_UNBUCKLE "unbuckle"
#define SFX_HEADSET_EQUIP "headset_equip"
#define SFX_HEADSET_PICKUP "headset_pickup"
+#define SFX_BANDAGE_BEGIN "bandage_begin"
+#define SFX_BANDAGE_END "bandage_end"
// Standard is 44.1khz
#define MIN_EMOTE_PITCH 40000
diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm
index 464e8c9b5e355..5883233803910 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -20,7 +20,7 @@
*
* make sure you add an update to the schema_version stable in the db changelog
*/
-#define DB_MINOR_VERSION 28
+#define DB_MINOR_VERSION 29
//! ## Timing subsystem
diff --git a/code/__DEFINES/traits/_traits.dm b/code/__DEFINES/traits/_traits.dm
index 7ebf1ad659046..0b1231c081fa6 100644
--- a/code/__DEFINES/traits/_traits.dm
+++ b/code/__DEFINES/traits/_traits.dm
@@ -74,7 +74,9 @@
var/list/_S = sources; \
if (_L) { \
for (var/_T in _L) { \
- _L[_T] &= _S;\
+ if (_L[_T]) { \
+ _L[_T] &= _S; \
+ }; \
if (!length(_L[_T])) { \
_L -= _T; \
SEND_SIGNAL(target, SIGNAL_REMOVETRAIT(_T), _T); \
@@ -97,7 +99,9 @@
}; \
if (_L) { \
for (var/_T in _L) { \
- _L[_T] -= _S;\
+ if (_L[_T]) { \
+ _L[_T] -= _S; \
+ }; \
if (!length(_L[_T])) { \
_L -= _T; \
SEND_SIGNAL(target, SIGNAL_REMOVETRAIT(_T)); \
diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm
index 434927ac78adc..6a66031fc2503 100644
--- a/code/__DEFINES/traits/declarations.dm
+++ b/code/__DEFINES/traits/declarations.dm
@@ -379,8 +379,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// for something granting you a diagnostic hud
#define TRAIT_DIAGNOSTIC_HUD "diag_hud"
#define TRAIT_BOT_PATH_HUD "bot_path_hud"
-/// Is a medbot healing you
-#define TRAIT_MEDIBOTCOMINGTHROUGH "medbot"
#define TRAIT_PASSTABLE "passtable"
/// Lets you fly through windows
#define TRAIT_PASSWINDOW "passwindow"
@@ -618,7 +616,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_DISPLAY_JOB_IN_BINARY "display job in binary"
/// Trait that determines vulnerability to being stunned from a shove
-#define TRAIT_STUN_ON_NEXT_SHOVE "stun on next shove"
+#define TRAIT_DAZED "dazed"
/// Trait that determines whether our mob gains more strength from drinking during a fist fight
#define TRAIT_DRUNKEN_BRAWLER "drunken brawler"
@@ -872,6 +870,10 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_CONTRABAND_BLOCKER "contraband_blocker"
/// For edible items that cannot be composted inside hydro trays
#define TRAIT_UNCOMPOSTABLE "uncompostable"
+/// Items with this trait will not have their worn icon overlayed.
+#define TRAIT_NO_WORN_ICON "no_worn_icon"
+/// Items with this trait will not appear when examined.
+#define TRAIT_EXAMINE_SKIP "examine_skip"
//quirk traits
#define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance"
@@ -1427,4 +1429,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// Trait applied when the wire bundle component is added to an [/obj/item/integrated_circuit]
#define TRAIT_COMPONENT_WIRE_BUNDLE "component_wire_bundle"
+/// Trait that is added to fishes that someone already caught, be it in-game or just theoretically, such as when they're bought
+/// Prevents fishing achievement from being granted by catching one of these
+#define TRAIT_NO_FISHING_ACHIEVEMENT "no_fishing_achievement"
+
// END TRAIT DEFINES
diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm
index 1ce2d5d46cb9c..7fa8f49cb7938 100644
--- a/code/__DEFINES/vv.dm
+++ b/code/__DEFINES/vv.dm
@@ -39,8 +39,8 @@
#define IS_VALID_ASSOC_KEY(V) (!isnum(V)) //hhmmm..
//General helpers
-#define VV_HREF_TARGET_INTERNAL(target, href_key) "?_src_=vars;[HrefToken()];[href_key]=TRUE;[VV_HK_TARGET]=[REF(target)]"
-#define VV_HREF_TARGETREF_INTERNAL(targetref, href_key) "?_src_=vars;[HrefToken()];[href_key]=TRUE;[VV_HK_TARGET]=[targetref]"
+#define VV_HREF_TARGET_INTERNAL(target, href_key) "byond://?_src_=vars;[HrefToken()];[href_key]=TRUE;[VV_HK_TARGET]=[REF(target)]"
+#define VV_HREF_TARGETREF_INTERNAL(targetref, href_key) "byond://?_src_=vars;[HrefToken()];[href_key]=TRUE;[VV_HK_TARGET]=[targetref]"
#define VV_HREF_TARGET(target, href_key, text) "[text]"
#define VV_HREF_TARGETREF(targetref, href_key, text) "[text]"
#define VV_HREF_TARGET_1V(target, href_key, text, varname) "[text]" //for stuff like basic varedits, one variable
diff --git a/code/__DEFINES/wiremod.dm b/code/__DEFINES/wiremod.dm
index 421650e3bf1e7..b606f938869a1 100644
--- a/code/__DEFINES/wiremod.dm
+++ b/code/__DEFINES/wiremod.dm
@@ -123,6 +123,8 @@
#define CIRCUIT_FLAG_REFUSE_MODULE (1<<5)
/// This circuit component cannot be inserted into the same circuit multiple times. Only use this for major headaches.
#define CIRCUIT_NO_DUPLICATES (1<<6)
+/// This circuit component is currently disabled via configs
+#define CIRCUIT_FLAG_DISABLED (1<<7)
// Datatype flags
/// The datatype supports manual inputs
diff --git a/code/__HELPERS/_dreamluau.dm b/code/__HELPERS/_dreamluau.dm
index d8bb784c217a2..9436b95c55196 100644
--- a/code/__HELPERS/_dreamluau.dm
+++ b/code/__HELPERS/_dreamluau.dm
@@ -1,3 +1,4 @@
+#ifndef DISABLE_DREAMLUAU
/* This comment bypasses grep checks */ /var/__dreamluau
/* This comment also bypasses grep checks */ /var/__dreamluau_exists
@@ -299,3 +300,4 @@
*/
#define DREAMLUAU_CLEAR_REF_USERDATA(object) DREAMLUAU_CALL(clear_ref_userdata)((object))
+#endif
diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm
index 583db80877305..9d9afc57bcb63 100644
--- a/code/__HELPERS/icons.dm
+++ b/code/__HELPERS/icons.dm
@@ -1184,28 +1184,37 @@ GLOBAL_LIST_EMPTY(transformation_animation_objects)
animate(pixel_x = initialpixelx + rand(-pixelshiftx,pixelshiftx), pixel_y = initialpixely + rand(-pixelshifty,pixelshifty), time = shake_interval)
animate(pixel_x = initialpixelx, pixel_y = initialpixely, time = shake_interval)
-///Checks if the given iconstate exists in the given file, caching the result. Setting scream to TRUE will print a stack trace ONCE.
-/proc/icon_exists(file, state, scream)
+/// Checks whether a given icon state exists in a given icon file. If `file` and `state` both exist,
+/// this will return `TRUE` - otherwise, it will return `FALSE`.
+///
+/// If you want a stack trace to be output when the given state/file doesn't exist, use
+/// `/proc/icon_exists_or_scream()`.
+/proc/icon_exists(file, state)
var/static/list/icon_states_cache = list()
- if(icon_states_cache[file]?[state])
- return TRUE
-
- if(icon_states_cache[file]?[state] == FALSE)
- return FALSE
-
- var/list/states = icon_states(file)
+ if(isnull(file) || isnull(state))
+ return FALSE //This is common enough that it shouldn't panic, imo.
- if(!icon_states_cache[file])
+ if(isnull(icon_states_cache[file]))
icon_states_cache[file] = list()
+ for(var/istate in icon_states(file))
+ icon_states_cache[file][istate] = TRUE
+
+ return !isnull(icon_states_cache[file][state])
- if(state in states)
- icon_states_cache[file][state] = TRUE
+/// Functions the same as `/proc/icon_exists()`, but with the addition of a stack trace if the
+/// specified file or state doesn't exist.
+///
+/// Stack traces will only be output once for each file.
+/proc/icon_exists_or_scream(file, state)
+ if(icon_exists(file, state))
return TRUE
- else
- icon_states_cache[file][state] = FALSE
- if(scream)
- stack_trace("Icon Lookup for state: [state] in file [file] failed.")
- return FALSE
+
+ var/static/list/screams = list()
+ if(!isnull(screams[file]))
+ screams[file] = TRUE
+ stack_trace("State [state] in file [file] does not exist.")
+
+ return FALSE
/**
* Returns the size of the sprite in tiles.
diff --git a/code/__HELPERS/lighting.dm b/code/__HELPERS/lighting.dm
index 96087ba173770..da6f4d1cee2e5 100644
--- a/code/__HELPERS/lighting.dm
+++ b/code/__HELPERS/lighting.dm
@@ -9,7 +9,7 @@
//Test to make sure emissives with broken or missing icon states are created
if(PERFORM_ALL_TESTS(focus_only/invalid_emissives))
- if(icon_state && !icon_exists(icon, icon_state, scream = FALSE)) //Scream set to False so we can have a custom stack_trace
+ if(icon_state && !icon_exists(icon, icon_state))
stack_trace("An emissive appearance was added with non-existant icon_state \"[icon_state]\" in [icon]!")
return appearance
diff --git a/code/_compile_options.dm b/code/_compile_options.dm
index e0a2683f5c79d..b78808f1ff3ea 100644
--- a/code/_compile_options.dm
+++ b/code/_compile_options.dm
@@ -106,6 +106,16 @@
/// If this is uncommented, will profile mapload atom initializations
// #define PROFILE_MAPLOAD_INIT_ATOM
+/// If uncommented, Dreamluau will be fully disabled.
+// #define DISABLE_DREAMLUAU
+
+// OpenDream currently doesn't support byondapi, so automatically disable it on OD,
+// unless CIBUILDING is defined - we still want to lint dreamluau-related code.
+// Get rid of this whenever it does have support.
+#if defined(OPENDREAM) && !defined(SPACEMAN_DMM) && !defined(CIBUILDING)
+#define DISABLE_DREAMLUAU
+#endif
+
/// If this is uncommented, force our verb processing into just the 2% of a tick
/// We normally reserve for it
/// NEVER run this on live, it's for simulating highpop only
diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index 97df688b0d255..3de97d38129ac 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -176,7 +176,6 @@ DEFINE_BITFIELD(item_flags, list(
"ABSTRACT" = ABSTRACT,
"BEING_REMOVED" = BEING_REMOVED,
"DROPDEL" = DROPDEL,
- "EXAMINE_SKIP" = EXAMINE_SKIP,
"FORCE_STRING_OVERRIDE" = FORCE_STRING_OVERRIDE,
"HAND_ITEM" = HAND_ITEM,
"IGNORE_DIGITIGRADE" = IGNORE_DIGITIGRADE,
diff --git a/code/_globalvars/lists/canisters.dm b/code/_globalvars/lists/canisters.dm
index f8ec95f602051..746a8456d71c3 100644
--- a/code/_globalvars/lists/canisters.dm
+++ b/code/_globalvars/lists/canisters.dm
@@ -25,5 +25,5 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
GAS_ZAUKER = /obj/machinery/portable_atmospherics/canister/zauker,
GAS_HELIUM = /obj/machinery/portable_atmospherics/canister/helium,
GAS_ANTINOBLIUM = /obj/machinery/portable_atmospherics/canister/antinoblium,
- GAS_HALON = /obj/machinery/portable_atmospherics/canister/halon
+ GAS_HALON = /obj/machinery/portable_atmospherics/canister/halon,
))
diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm
index a244e1493bb04..451e1d993c7e1 100644
--- a/code/_globalvars/traits/_traits.dm
+++ b/code/_globalvars/traits/_traits.dm
@@ -205,6 +205,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_CRITICAL_CONDITION" = TRAIT_CRITICAL_CONDITION,
"TRAIT_CULT_HALO" = TRAIT_CULT_HALO,
"TRAIT_CURSED" = TRAIT_CURSED,
+ "TRAIT_DAZED" = TRAIT_DAZED,
"TRAIT_DEAF" = TRAIT_DEAF,
"TRAIT_DEATHCOMA" = TRAIT_DEATHCOMA,
"TRAIT_DEFIB_BLACKLISTED" = TRAIT_DEFIB_BLACKLISTED,
@@ -335,7 +336,6 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_MAGICALLY_PHASED" = TRAIT_MAGICALLY_PHASED,
"TRAIT_MARTIAL_ARTS_IMMUNE" = TRAIT_MARTIAL_ARTS_IMMUNE,
"TRAIT_MANSUS_TOUCHED" = TRAIT_MANSUS_TOUCHED,
- "TRAIT_MEDIBOTCOMINGTHROUGH" = TRAIT_MEDIBOTCOMINGTHROUGH,
"TRAIT_MEDICAL_HUD" = TRAIT_MEDICAL_HUD,
"TRAIT_MESON_VISION" = TRAIT_MESON_VISION,
"TRAIT_MIME_FAN" = TRAIT_MIME_FAN,
@@ -512,7 +512,6 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_STRONG_STOMACH" = TRAIT_STRONG_STOMACH,
"TRAIT_STUBBY_BODY" = TRAIT_STUBBY_BODY,
"TRAIT_STUNIMMUNE" = TRAIT_STUNIMMUNE,
- "TRAIT_STUN_ON_NEXT_SHOVE" = TRAIT_STUN_ON_NEXT_SHOVE,
"TRAIT_STURDY_FRAME" = TRAIT_STURDY_FRAME,
"TRAIT_SUCCUMB_OVERRIDE" = TRAIT_SUCCUMB_OVERRIDE,
"TRAIT_SUICIDED" = TRAIT_SUICIDED,
@@ -601,6 +600,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_CONTRABAND_BLOCKER" = TRAIT_CONTRABAND_BLOCKER,
"TRAIT_CUSTOM_TAP_SOUND" = TRAIT_CUSTOM_TAP_SOUND,
"TRAIT_DANGEROUS_OBJECT" = TRAIT_DANGEROUS_OBJECT,
+ "TRAIT_EXAMINE_SKIP" = TRAIT_EXAMINE_SKIP,
"TRAIT_FIREDOOR_OPENER" = TRAIT_FIREDOOR_OPENER,
"TRAIT_FISHING_BAIT" = TRAIT_FISHING_BAIT,
"TRAIT_FOOD_BBQ_GRILLED" = TRAIT_FOOD_BBQ_GRILLED,
@@ -618,6 +618,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_NO_TELEPORT" = TRAIT_NO_TELEPORT,
"TRAIT_NO_SIDE_KICK" = TRAIT_NO_SIDE_KICK,
"TRAIT_NODROP" = TRAIT_NODROP,
+ "TRAIT_NO_WORN_ICON" = TRAIT_NO_WORN_ICON,
"TRAIT_OMNI_BAIT" = TRAIT_OMNI_BAIT,
"TRAIT_PLANT_WILDMUTATE" = TRAIT_PLANT_WILDMUTATE,
"TRAIT_POISONOUS_BAIT" = TRAIT_POISONOUS_BAIT,
@@ -675,6 +676,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_RESIST_PSYCHIC" = TRAIT_RESIST_PSYCHIC,
"TRAIT_FISH_WELL_COOKED" = TRAIT_FISH_WELL_COOKED,
"TRAIT_YUCKY_FISH" = TRAIT_YUCKY_FISH,
+ "TRAIT_NO_FISHING_ACHIEVEMENT" = TRAIT_NO_FISHING_ACHIEVEMENT,
),
/obj/item/fishing_rod = list(
"TRAIT_ROD_ATTRACT_SHINY_LOVERS" = TRAIT_ROD_ATTRACT_SHINY_LOVERS,
diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm
index 1a7fa55e21e66..093ed55b5c8c1 100644
--- a/code/_globalvars/traits/admin_tooling.dm
+++ b/code/_globalvars/traits/admin_tooling.dm
@@ -75,6 +75,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list(
"TRAIT_CORPSELOCKED" = TRAIT_CORPSELOCKED,
"TRAIT_CRITICAL_CONDITION" = TRAIT_CRITICAL_CONDITION,
"TRAIT_CULT_HALO" = TRAIT_CULT_HALO,
+ "TRAIT_DAZED" = TRAIT_DAZED,
"TRAIT_DEAF" = TRAIT_DEAF,
"TRAIT_DEATHCOMA" = TRAIT_DEATHCOMA,
"TRAIT_DEFIB_BLACKLISTED" = TRAIT_DEFIB_BLACKLISTED,
@@ -298,7 +299,6 @@ GLOBAL_LIST_INIT(admin_visible_traits, list(
"TRAIT_TOO_TALL" = TRAIT_TOO_TALL,
"TRAIT_TOXIMMUNE" = TRAIT_TOXIMMUNE,
"TRAIT_TOXINLOVER" = TRAIT_TOXINLOVER,
- "TRAIT_MEDIBOTCOMINGTHROUGH" = TRAIT_MEDIBOTCOMINGTHROUGH,
"TRAIT_TUMOR_SUPPRESSION" = TRAIT_TUMOR_SUPPRESSED,
"TRAIT_UI_BLOCKED" = TRAIT_UI_BLOCKED,
"TRAIT_UNCONVERTABLE" = TRAIT_UNCONVERTABLE,
diff --git a/code/_onclick/hud/rendering/plane_master_group.dm b/code/_onclick/hud/rendering/plane_master_group.dm
index 52d56cfad63b9..27efc2a995e3d 100644
--- a/code/_onclick/hud/rendering/plane_master_group.dm
+++ b/code/_onclick/hud/rendering/plane_master_group.dm
@@ -196,19 +196,16 @@
/// If you wanna try someday feel free, but I can't manage it
/datum/plane_master_group/popup
-/// This is janky as hell but since something changed with CENTER positioning after build 1614 we have to switch to the bandaid LEFT,TOP positioning
-/// using LEFT,TOP *at* or *before* 1614 will result in another broken offset for cameras
-#define MAX_CLIENT_BUILD_WITH_WORKING_SECONDARY_MAPS 1614
-
+/// Note do not use return ..() because it will cause client crush when screen gets deleted
+/// TOOD: Remove this entirely when 516 is stable
/datum/plane_master_group/popup/attach_to(datum/hud/viewing_hud)
- // If we're about to display this group to a mob who's client is more recent than the last known version with working CENTER, then we need to remake the relays
- // with the correct screen_loc using the relay override
- if(viewing_hud.mymob?.client?.byond_build > MAX_CLIENT_BUILD_WITH_WORKING_SECONDARY_MAPS)
- relay_loc = "LEFT,TOP"
- rebuild_plane_masters()
- return ..()
-
-#undef MAX_CLIENT_BUILD_WITH_WORKING_SECONDARY_MAPS
+ if(viewing_hud.master_groups[key])
+ stack_trace("[key] is already in use by a plane master group on the passed in hud, belonging to [viewing_hud.mymob]!")
+ return
+ relay_loc = "1,1"
+ rebuild_plane_masters()
+ set_hud(viewing_hud)
+ show_hud()
/datum/plane_master_group/popup/build_planes_offset(datum/hud/source, new_offset, use_scale = TRUE)
return ..(source, new_offset, FALSE)
diff --git a/code/controllers/admin.dm b/code/controllers/admin.dm
index 5056e3804ef11..d96b362847c51 100644
--- a/code/controllers/admin.dm
+++ b/code/controllers/admin.dm
@@ -59,11 +59,12 @@ ADMIN_VERB(debug_controller, R_DEBUG, "Debug Controller", "Debug the various per
var/list/controllers = list()
var/list/controller_choices = list()
- for (var/datum/controller/controller in world)
- if (istype(controller, /datum/controller/subsystem))
+ for (var/var_key in global.vars)
+ var/datum/controller/controller = global.vars[var_key]
+ if(!istype(controller) || istype(controller, /datum/controller/subsystem))
continue
- controllers["[controller] (controller.type)"] = controller //we use an associated list to ensure clients can't hold references to controllers
- controller_choices += "[controller] (controller.type)"
+ controllers[controller.name] = controller //we use an associated list to ensure clients can't hold references to controllers
+ controller_choices += controller.name
var/datum/controller/controller_string = input("Select controller to debug", "Debug Controller") as null|anything in controller_choices
var/datum/controller/controller = controllers[controller_string]
diff --git a/code/controllers/subsystem/explosions.dm b/code/controllers/subsystem/explosions.dm
index 2b61cabb86074..36dbba09eae01 100644
--- a/code/controllers/subsystem/explosions.dm
+++ b/code/controllers/subsystem/explosions.dm
@@ -635,23 +635,27 @@ ADMIN_VERB(check_bomb_impacts, R_DEBUG, "Check Bomb Impact", "See what the effec
// top left to one before top right
if(highest_y <= max_y)
candidates += block(
- locate(max(lowest_x, 1), highest_y, our_z),
- locate(min(highest_x - 1, max_x), highest_y, our_z))
+ lowest_x, highest_y, our_z,
+ highest_x - 1, highest_y, our_z
+ )
// top right to one before bottom right
if(highest_x <= max_x)
candidates += block(
- locate(highest_x, min(highest_y, max_y), our_z),
- locate(highest_x, max(lowest_y + 1, 1), our_z))
+ highest_x, highest_y, our_z,
+ highest_x, lowest_y + 1, our_z
+ )
// bottom right to one before bottom left
if(lowest_y >= 1)
candidates += block(
- locate(min(highest_x, max_x), lowest_y, our_z),
- locate(max(lowest_x + 1, 1), lowest_y, our_z))
+ highest_x, lowest_y, our_z,
+ lowest_x + 1, lowest_y, our_z
+ )
// bottom left to one before top left
if(lowest_x >= 1)
candidates += block(
- locate(lowest_x, max(lowest_y, 1), our_z),
- locate(lowest_x, min(highest_y - 1, max_y), our_z))
+ lowest_x, lowest_y, our_z,
+ lowest_x, highest_y - 1, our_z
+ )
if(!do_directional)
outlist += candidates
diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm
index ad1b9e4132fed..b9c8a08ca751e 100644
--- a/code/controllers/subsystem/garbage.dm
+++ b/code/controllers/subsystem/garbage.dm
@@ -346,7 +346,9 @@ SUBSYSTEM_DEF(garbage)
/// Datums passed to this will be given a chance to clean up references to allow the GC to collect them.
/proc/qdel(datum/to_delete, force = FALSE)
if(!istype(to_delete))
+#ifndef DISABLE_DREAMLUAU
DREAMLUAU_CLEAR_REF_USERDATA(to_delete)
+#endif
del(to_delete)
return
diff --git a/code/controllers/subsystem/lua.dm b/code/controllers/subsystem/lua.dm
index 99df8cf335490..2d199ccd3dcc3 100644
--- a/code/controllers/subsystem/lua.dm
+++ b/code/controllers/subsystem/lua.dm
@@ -1,3 +1,4 @@
+#ifndef DISABLE_DREAMLUAU
SUBSYSTEM_DEF(lua)
name = "Lua Scripting"
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
@@ -156,3 +157,4 @@ SUBSYSTEM_DEF(lua)
continue
state.log_result(json_data)
return
+#endif
diff --git a/code/controllers/subsystem/map_vote.dm b/code/controllers/subsystem/map_vote.dm
index f57d73d773e63..d8a05cb9a817c 100644
--- a/code/controllers/subsystem/map_vote.dm
+++ b/code/controllers/subsystem/map_vote.dm
@@ -53,7 +53,7 @@ SUBSYSTEM_DEF(map_vote)
last_message_at = world.time
var/list/messages = args.Copy()
- to_chat(world, span_purple(boxed_message("Map Vote\n
[messages.Join("\n")]")))
+ to_chat(world, span_purple(boxed_message("Map Vote [jointext(messages, " ")]")))
/datum/controller/subsystem/map_vote/proc/finalize_map_vote(datum/vote/map_vote/map_vote)
if(already_voted)
@@ -170,4 +170,7 @@ SUBSYSTEM_DEF(map_vote)
for(var/map_id in map_vote_cache)
var/datum/map_config/map = config.maplist[map_id]
data += "[map.map_name] - [map_vote_cache[map_id]]"
- tally_printout = boxed_message("Current Tallies\n[data.Join("\n")]")
+ var/tally_msg = span_tooltip("A map's tallies are reset after it wins a vote. \
+ Otherwise, they are carried over and added onto from the next vote on the next round, \
+ until it eventually wins and is reset.", "Current Tallies")
+ tally_printout = boxed_message("[tally_msg] [jointext(data, " ")]")
diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm
index 31a30e6984f7a..d3a5083072637 100644
--- a/code/controllers/subsystem/mapping.dm
+++ b/code/controllers/subsystem/mapping.dm
@@ -653,10 +653,11 @@ ADMIN_VERB(load_away_mission, R_FUN, "Load Away Mission", "Load a specific away
if(!level_trait(z,ZTRAIT_RESERVED))
clearing_reserved_turfs = FALSE
CRASH("Invalid z level prepared for reservations.")
- var/turf/A = get_turf(locate(SHUTTLE_TRANSIT_BORDER,SHUTTLE_TRANSIT_BORDER,z))
- var/turf/B = get_turf(locate(world.maxx - SHUTTLE_TRANSIT_BORDER,world.maxy - SHUTTLE_TRANSIT_BORDER,z))
- var/block = block(A, B)
- for(var/turf/T as anything in block)
+ var/list/reserved_block = block(
+ SHUTTLE_TRANSIT_BORDER, SHUTTLE_TRANSIT_BORDER, z,
+ world.maxx - SHUTTLE_TRANSIT_BORDER, world.maxy - SHUTTLE_TRANSIT_BORDER, z
+ )
+ for(var/turf/T as anything in reserved_block)
// No need to empty() these, because they just got created and are already /turf/open/space/basic.
T.turf_flags = UNUSED_RESERVATION_TURF
T.blocks_air = TRUE
@@ -666,7 +667,7 @@ ADMIN_VERB(load_away_mission, R_FUN, "Load Away Mission", "Load a specific away
if(SSatoms.initialized)
SSatoms.InitializeAtoms(Z_TURFS(z))
- unused_turfs["[z]"] = block
+ unused_turfs["[z]"] = reserved_block
reservation_ready["[z]"] = TRUE
clearing_reserved_turfs = FALSE
diff --git a/code/controllers/subsystem/overlays.dm b/code/controllers/subsystem/overlays.dm
index fda892be7a432..96041edd4237a 100644
--- a/code/controllers/subsystem/overlays.dm
+++ b/code/controllers/subsystem/overlays.dm
@@ -47,8 +47,7 @@ SUBSYSTEM_DEF(overlays)
if (istext(overlay))
// This is too expensive to run normally but running it during CI is a good test
if (PERFORM_ALL_TESTS(focus_only/invalid_overlays))
- var/list/icon_states_available = icon_states(icon)
- if(!(overlay in icon_states_available))
+ if(!icon_exists(icon, overlay))
var/icon_file = "[icon]" || "Unknown Generated Icon"
stack_trace("Invalid overlay: Icon object '[icon_file]' [REF(icon)] used in '[src]' [type] is missing icon state [overlay].")
continue
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/ventcrawling.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/ventcrawling.dm
index aca89d832814a..06fcfa1472623 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/ventcrawling.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/ventcrawling.dm
@@ -82,7 +82,8 @@
if(!HAS_TRAIT(living_pawn, TRAIT_MOVE_VENTCRAWLING) && isturf(get_turf(living_pawn))) // we're out of the vents, so no need to do an exit
// assume that we got yeeted out somehow and return this so we can halt the suicide pill timer.
- return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
+ finish_action(controller, TRUE, target_key)
+ return
living_pawn.forceMove(exit_vent)
if(!living_pawn.can_enter_vent(exit_vent, provide_feedback = FALSE))
@@ -90,7 +91,8 @@
emergency_vent = calculate_exit_vent(controller)
if(isnull(emergency_vent))
// it's joever. we cooked too hard.
- return suicide_pill(controller) | AI_BEHAVIOR_DELAY
+ suicide_pill(controller)
+ return
controller.set_blackboard_key(BB_EXIT_VENT_TARGET, emergency_vent) // assign and go again
addtimer(CALLBACK(src, PROC_REF(exit_the_vents), controller), (rand(controller.blackboard[BB_LOWER_VENT_TIME_LIMIT], controller.blackboard[BB_UPPER_VENT_TIME_LIMIT]) / 2)) // we're in danger mode, so scurry out at half the time it would normally take.
@@ -99,9 +101,11 @@
living_pawn.handle_ventcrawl(exit_vent)
if(HAS_TRAIT(living_pawn, TRAIT_MOVE_VENTCRAWLING)) // how'd we fail? what the fuck
stack_trace("We failed to exit the vents, even though we should have been fine? This is very weird.")
- return suicide_pill(controller) | AI_BEHAVIOR_DELAY // all of the prior checks say we should have definitely made it through, but we didn't. dammit.
+ suicide_pill(controller)
+ return
- return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED // we did it! we went into the vents and out of the vents. poggers.
+ finish_action(controller, TRUE, target_key)
+ return
/// Incredibly stripped down version of the overarching `can_enter_vent` proc on `/mob, just meant for rapid rechecking of a vent. Will be TRUE if not blocked, FALSE otherwise.
/datum/ai_behavior/crawl_through_vents/proc/is_vent_valid(obj/machinery/atmospherics/components/unary/vent_pump/checkable)
diff --git a/code/datums/brain_damage/phobia.dm b/code/datums/brain_damage/phobia.dm
index e9733293cff13..132bf835396b7 100644
--- a/code/datums/brain_damage/phobia.dm
+++ b/code/datums/brain_damage/phobia.dm
@@ -90,7 +90,7 @@
if (!isitem(checked))
return TRUE
var/obj/item/checked_item = checked
- return !(checked_item.item_flags & EXAMINE_SKIP)
+ return !HAS_TRAIT(checked_item, TRAIT_EXAMINE_SKIP)
/datum/brain_trauma/mild/phobia/handle_hearing(datum/source, list/hearing_args)
if(!owner.can_hear() || owner == hearing_args[HEARING_SPEAKER] || !owner.has_language(hearing_args[HEARING_LANGUAGE])) //words can't trigger you if you can't hear them *taps head*
diff --git a/code/datums/components/crafting/ranged_weapon.dm b/code/datums/components/crafting/ranged_weapon.dm
index f5deb979cb50e..22735bcc5a362 100644
--- a/code/datums/components/crafting/ranged_weapon.dm
+++ b/code/datums/components/crafting/ranged_weapon.dm
@@ -43,6 +43,19 @@
time = 5 SECONDS
category = CAT_WEAPON_RANGED
+/datum/crafting_recipe/riflestock
+ name = "Makeshift Gun Maintenance Kit"
+ tool_behaviors = list(TOOL_WRENCH, TOOL_WELDER, TOOL_SCREWDRIVER)
+ result = /obj/item/gun_maintenance_supplies/makeshift
+ reqs = list(
+ /obj/item/stack/sheet/iron = 5,
+ /obj/item/stack/sticky_tape = 1,
+ /obj/item/pipe = 1,
+ /obj/item/stack/sheet/cloth = 2,
+ )
+ time = 5 SECONDS
+ category = CAT_WEAPON_RANGED
+
/datum/crafting_recipe/advancedegun
name = "Advanced Energy Gun"
result = /obj/item/gun/energy/e_gun/nuclear
diff --git a/code/datums/components/fantasy/prefixes.dm b/code/datums/components/fantasy/prefixes.dm
index cd80a1143130a..711844ea8be20 100644
--- a/code/datums/components/fantasy/prefixes.dm
+++ b/code/datums/components/fantasy/prefixes.dm
@@ -161,3 +161,26 @@
var/obj/item/master = comp.parent
comp.appliedComponents += master.AddComponent(/datum/component/soul_stealer)
return "soul-[pick("stealing", "hungering", "devouring")] [newName]"
+
+// On hitting a mob chain lightning will jump to another mob within 2 tiles of the original target
+/datum/fantasy_affix/thunderfury
+ name = "Thunderfury"
+ placement = AFFIX_PREFIX
+ alignment = AFFIX_GOOD
+ weight = 3
+
+/datum/fantasy_affix/thunderfury/apply(datum/component/fantasy/comp, newName)
+ comp.parent.AddElement(/datum/element/chain_lightning_attack, get_damage(comp), get_range(comp), get_limit(comp))
+ return "Thunderfury, Blessed [newName]"
+
+/datum/fantasy_affix/thunderfury/remove(datum/component/fantasy/comp)
+ comp.parent.RemoveElement(/datum/element/chain_lightning_attack, get_damage(comp), get_range(comp), get_limit(comp))
+
+/datum/fantasy_affix/thunderfury/proc/get_damage(datum/component/fantasy/comp)
+ return min(round(comp.quality, 2), 20)
+
+/datum/fantasy_affix/thunderfury/proc/get_range(datum/component/fantasy/comp)
+ return min(round(sqrt(comp.quality), 1), 3)
+
+/datum/fantasy_affix/thunderfury/proc/get_limit(datum/component/fantasy/comp)
+ return min(round(sqrt(comp.quality), 1), 3)
diff --git a/code/datums/components/fantasy/suffixes.dm b/code/datums/components/fantasy/suffixes.dm
index 997c9564592b3..cd9ca79ec0067 100644
--- a/code/datums/components/fantasy/suffixes.dm
+++ b/code/datums/components/fantasy/suffixes.dm
@@ -290,3 +290,20 @@
/datum/fantasy_affix/doot/remove(datum/component/fantasy/comp)
comp.parent.RemoveElement(/datum/element/spooky, too_spooky = comp.quality > 17, stam_damage_mult = comp.quality * 0.15)
+
+// On hitting a mob their click cd is slowed marginally
+/datum/fantasy_affix/windseeker
+ name = "of the Windseeker"
+ placement = AFFIX_SUFFIX
+ alignment = AFFIX_GOOD
+ weight = 3
+
+/datum/fantasy_affix/windseeker/apply(datum/component/fantasy/comp, newName)
+ comp.parent.AddElement(/datum/element/slow_target_click_cd_attack, get_cd_penalty(comp))
+ return "[newName] of the Windseeker"
+
+/datum/fantasy_affix/windseeker/remove(datum/component/fantasy/comp)
+ comp.parent.RemoveElement(/datum/element/slow_target_click_cd_attack, get_cd_penalty(comp))
+
+/datum/fantasy_affix/windseeker/proc/get_cd_penalty(datum/component/fantasy/comp)
+ return min(round(sqrt(comp.quality) * 0.1, 0.1), 0.4) // this gives you a small number, like 0.2 seconds
diff --git a/code/datums/components/riding/riding_mob.dm b/code/datums/components/riding/riding_mob.dm
index 809237542ebfd..9d3d202259e22 100644
--- a/code/datums/components/riding/riding_mob.dm
+++ b/code/datums/components/riding/riding_mob.dm
@@ -108,7 +108,6 @@
return COMPONENT_DRIVER_BLOCK_MOVE
var/mob/living/living_parent = parent
step(living_parent, direction)
- var/modified_move_cooldown = vehicle_move_cooldown
var/modified_move_delay = modified_move_delay(vehicle_move_delay)
if(ishuman(user) && HAS_TRAIT(user, TRAIT_ROUGHRIDER)) // YEEHAW!
var/mob/living/carbon/human/rough_rider = user
@@ -119,21 +118,16 @@
ride_benefit = rough_rider.mob_mood.sanity_level
switch(ride_benefit)
if(SANITY_LEVEL_GREAT)
- modified_move_cooldown *= 0.8
modified_move_delay *= 0.8
if(SANITY_LEVEL_NEUTRAL)
- modified_move_cooldown *= 0.9
modified_move_delay *= 0.9
if(SANITY_LEVEL_DISTURBED)
- modified_move_cooldown *= 1
modified_move_delay *= 1
if(SANITY_LEVEL_CRAZY)
- modified_move_cooldown *= 1.1
modified_move_delay *= 1.1
if(SANITY_LEVEL_INSANE)
- modified_move_cooldown *= 1.2
modified_move_delay *= 1.2
- COOLDOWN_START(src, vehicle_move_cooldown = modified_move_cooldown, modified_move_delay)
+ COOLDOWN_START(src, vehicle_move_cooldown, modified_move_delay)
return ..()
/// Yeets the rider off, used for animals and cyborgs, redefined for humans who shove their piggyback rider off
diff --git a/code/datums/components/slippery.dm b/code/datums/components/slippery.dm
index 8d2dbda379eda..370b3406ff9ff 100644
--- a/code/datums/components/slippery.dm
+++ b/code/datums/components/slippery.dm
@@ -23,6 +23,8 @@
var/knockdown_time = 0
/// How long the slip paralyzes (prevents the crossing mob doing anything) for.
var/paralyze_time = 0
+ /// How long the slip dazes (makes the crossing mob vulnerable to shove stuns) for.
+ var/daze_time = 3 SECONDS
/// Flags for how slippery the parent is. See [__DEFINES/mobs.dm]
var/lube_flags
/// Optional callback allowing you to define custom conditions for slipping
@@ -53,6 +55,7 @@
* * lube_flags - Controls the slip behaviour, they are listed starting [here][SLIDE]
* * datum/callback/on_slip_callback - Callback to define further custom controls on when slipping is applied
* * paralyze - length of time to paralyze the crossing mob for (Deciseconds)
+ * * daze - length of time to daze the crossing mob for (Deciseconds), default 3 seconds
* * force_drop - should the crossing mob drop items in its hands or not
* * slot_whitelist - flags controlling where on a mob this item can be equipped to make the parent mob slippery full list [here][ITEM_SLOT_OCLOTHING]
* * datum/callback/on_slip_callback - Callback to add custom behaviours as the crossing mob is slipped
@@ -62,12 +65,14 @@
lube_flags = NONE,
datum/callback/on_slip_callback,
paralyze,
+ daze = 3 SECONDS,
force_drop = FALSE,
slot_whitelist,
datum/callback/can_slip_callback,
)
src.knockdown_time = max(knockdown, 0)
src.paralyze_time = max(paralyze, 0)
+ src.daze_time = max(daze, 0)
src.force_drop_items = force_drop
src.lube_flags = lube_flags
src.can_slip_callback = can_slip_callback
@@ -126,6 +131,7 @@
lube_flags = NONE,
datum/callback/on_slip_callback,
paralyze,
+ daze,
force_drop = FALSE,
slot_whitelist,
datum/callback/can_slip_callback,
@@ -136,11 +142,13 @@
on_slip_callback = component.on_slip_callback
can_slip_callback = component.on_slip_callback
paralyze = component.paralyze_time
+ daze = component.daze_time
force_drop = component.force_drop_items
slot_whitelist = component.slot_whitelist
src.knockdown_time = max(knockdown, 0)
src.paralyze_time = max(paralyze, 0)
+ src.daze_time = max(daze, 0)
src.force_drop_items = force_drop
src.lube_flags = lube_flags
src.on_slip_callback = on_slip_callback
@@ -167,7 +175,7 @@
return
if(can_slip_callback && !can_slip_callback.Invoke(holder, victim))
return
- if(victim.slip(knockdown_time, parent, lube_flags, paralyze_time, force_drop_items))
+ if(victim.slip(knockdown_time, parent, lube_flags, paralyze_time, daze_time, force_drop_items))
on_slip_callback?.Invoke(victim)
/**
diff --git a/code/datums/components/temporary_body.dm b/code/datums/components/temporary_body.dm
index 28a7000a4951d..deadf90e6f99d 100644
--- a/code/datums/components/temporary_body.dm
+++ b/code/datums/components/temporary_body.dm
@@ -14,11 +14,12 @@
var/delete_on_death = FALSE
/datum/component/temporary_body/Initialize(datum/mind/old_mind, mob/living/old_body, delete_on_death = FALSE)
- if(!isliving(parent) || !isliving(old_body))
+ if(!isliving(parent))
return COMPONENT_INCOMPATIBLE
- ADD_TRAIT(old_body, TRAIT_MIND_TEMPORARILY_GONE, REF(src))
src.old_mind_ref = WEAKREF(old_mind)
- src.old_body_ref = WEAKREF(old_body)
+ if(istype(old_body))
+ ADD_TRAIT(old_body, TRAIT_MIND_TEMPORARILY_GONE, REF(src))
+ src.old_body_ref = WEAKREF(old_body)
src.delete_on_death = delete_on_death
/datum/component/temporary_body/RegisterWithParent()
@@ -38,9 +39,9 @@
/datum/component/temporary_body/proc/on_parent_destroy()
SIGNAL_HANDLER
var/datum/mind/old_mind = old_mind_ref?.resolve()
- var/mob/living/old_body = old_body_ref?.resolve()
+ var/mob/living/old_body = old_body_ref?.resolve() || old_mind.current
- if(!old_mind || !old_body)
+ if(!old_mind)
return
var/mob/living/living_parent = parent
@@ -50,12 +51,13 @@
if(!ghost)
CRASH("[src] belonging to [parent] was completely unable to find a ghost to put back into a body!")
ghost.mind = old_mind
- if(old_body.stat != DEAD)
+ if(old_body?.stat != DEAD)
old_mind.transfer_to(old_body, force_key_move = TRUE)
else
old_mind.set_current(old_body)
- REMOVE_TRAIT(old_body, TRAIT_MIND_TEMPORARILY_GONE, REF(src))
+ if(old_body)
+ REMOVE_TRAIT(old_body, TRAIT_MIND_TEMPORARILY_GONE, REF(src))
old_mind = null
old_body = null
diff --git a/code/datums/datum.dm b/code/datums/datum.dm
index 8337dac113178..c3c800bd85c93 100644
--- a/code/datums/datum.dm
+++ b/code/datums/datum.dm
@@ -142,9 +142,11 @@
_clear_signal_refs()
//END: ECS SHIT
+#ifndef DISABLE_DREAMLUAU
if(!(datum_flags & DF_STATIC_OBJECT))
DREAMLUAU_CLEAR_REF_USERDATA(vars) // vars ceases existing when src does, so we need to clear any lua refs to it that exist.
DREAMLUAU_CLEAR_REF_USERDATA(src)
+#endif
return QDEL_HINT_QUEUE
diff --git a/code/datums/elements/chain_lightning_attack.dm b/code/datums/elements/chain_lightning_attack.dm
new file mode 100644
index 0000000000000..dc4d48c15f50a
--- /dev/null
+++ b/code/datums/elements/chain_lightning_attack.dm
@@ -0,0 +1,46 @@
+/// Applied to an item: Causes the item to deal shock damage to a target and jump to other targets
+/datum/element/chain_lightning_attack
+ element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH_ON_HOST_DESTROY
+ argument_hash_start_idx = 2
+ /// Damage dealt by the shock of the chain lightning
+ var/shock_damage
+ /// Range the shock will jump to another target
+ var/shock_range
+ /// Maximum number of jumps the chain lightning can make
+ var/chain_limit
+
+/datum/element/chain_lightning_attack/Attach(datum/target, shock_damage = 10, shock_range = 2, chain_limit = 3)
+ . = ..()
+ if(!isitem(target))
+ return ELEMENT_INCOMPATIBLE
+
+ src.shock_damage = shock_damage
+ src.shock_range = shock_range
+ src.chain_limit = chain_limit
+ RegisterSignal(target, COMSIG_ITEM_AFTERATTACK, PROC_REF(try_chain))
+
+/datum/element/chain_lightning_attack/Detach(datum/source, ...)
+ . = ..()
+ UnregisterSignal(source, COMSIG_ITEM_AFTERATTACK)
+
+/datum/element/chain_lightning_attack/proc/try_chain(obj/item/source, atom/hit, mob/user)
+ SIGNAL_HANDLER
+
+ if(!isliving(hit))
+ return
+ do_chain(source, hit, user, list(user))
+
+/datum/element/chain_lightning_attack/proc/do_chain(obj/item/source, mob/living/next_target, atom/last_target, list/dont_hit = list())
+ if(!next_target.electrocute_act(shock_damage, source, flags = SHOCK_NOGLOVES|SHOCK_NOSTUN))
+ return
+ if(last_target != next_target)
+ last_target.Beam(next_target, icon_state = "lightning[rand(1, 12)]", time = 0.5 SECONDS)
+ dont_hit += next_target
+ if(length(dont_hit) >= chain_limit + 1)
+ return
+
+ for(var/mob/living/other_victim in view(next_target, shock_range))
+ if(other_victim in dont_hit)
+ continue
+ do_chain(source, other_victim, next_target, dont_hit)
+ break
diff --git a/code/datums/elements/dextrous.dm b/code/datums/elements/dextrous.dm
index 240cfc88494d3..a73d58e18788a 100644
--- a/code/datums/elements/dextrous.dm
+++ b/code/datums/elements/dextrous.dm
@@ -67,7 +67,7 @@
/datum/element/dextrous/proc/on_examined(mob/living/examined, mob/user, list/examine_list)
SIGNAL_HANDLER
for(var/obj/item/held_item in examined.held_items)
- if(held_item.item_flags & (ABSTRACT|EXAMINE_SKIP|HAND_ITEM))
+ if((held_item.item_flags & (ABSTRACT|HAND_ITEM)) || HAS_TRAIT(held_item, TRAIT_EXAMINE_SKIP))
continue
examine_list += span_info("[examined.p_They()] [examined.p_have()] [held_item.examine_title(user)] in [examined.p_their()] \
[examined.get_held_index_name(examined.get_held_index_of_item(held_item))].")
diff --git a/code/datums/elements/mirage_border.dm b/code/datums/elements/mirage_border.dm
index ca7c422dd1127..b7af7ee91f605 100644
--- a/code/datums/elements/mirage_border.dm
+++ b/code/datums/elements/mirage_border.dm
@@ -20,9 +20,10 @@
var/x = target_turf.x
var/y = target_turf.y
var/z = clamp(target_turf.z, 1, world.maxz)
- var/turf/southwest = locate(clamp(x - (direction & WEST ? range : 0), 1, world.maxx), clamp(y - (direction & SOUTH ? range : 0), 1, world.maxy), z)
- var/turf/northeast = locate(clamp(x + (direction & EAST ? range : 0), 1, world.maxx), clamp(y + (direction & NORTH ? range : 0), 1, world.maxy), z)
- holder.vis_contents += block(southwest, northeast)
+ holder.vis_contents += block(
+ x - (direction & WEST ? range : 0), y - (direction & SOUTH ? range : 0), z,
+ x + (direction & EAST ? range : 0), y + (direction & NORTH ? range : 0), z
+ )
if(direction & SOUTH)
holder.pixel_y -= ICON_SIZE_Y * range
if(direction & WEST)
diff --git a/code/datums/elements/slow_target_click_cd_attack.dm b/code/datums/elements/slow_target_click_cd_attack.dm
new file mode 100644
index 0000000000000..93403501a34b3
--- /dev/null
+++ b/code/datums/elements/slow_target_click_cd_attack.dm
@@ -0,0 +1,54 @@
+/// Applied to items: Applies a status effect to the target that slows their click CD
+/datum/element/slow_target_click_cd_attack
+ element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH_ON_HOST_DESTROY
+ argument_hash_start_idx = 2
+ /// How much click CD to add to the target's clicks
+ var/reduction
+
+/datum/element/slow_target_click_cd_attack/Attach(datum/target, reduction = 0.2 SECONDS)
+ . = ..()
+ if(!isitem(target))
+ return ELEMENT_INCOMPATIBLE
+
+ src.reduction = reduction
+ RegisterSignal(target, COMSIG_ITEM_AFTERATTACK, PROC_REF(try_slow))
+
+/datum/element/slow_target_click_cd_attack/Detach(datum/source, ...)
+ . = ..()
+ UnregisterSignal(source, COMSIG_ITEM_AFTERATTACK)
+
+/datum/element/slow_target_click_cd_attack/proc/try_slow(obj/item/source, atom/hit, mob/user)
+ SIGNAL_HANDLER
+
+ if(!isliving(hit))
+ return
+ var/mob/living/target = hit
+ target.apply_status_effect(/datum/status_effect/cd_slow, reduction, REF(src))
+
+/// Applied by [/datum/element/slow_target_click_cd_attack] to slow the target's click CD
+/datum/status_effect/cd_slow
+ id = "cd_slow"
+ duration = 4 SECONDS
+ status_type = STATUS_EFFECT_MULTIPLE
+ alert_type = null
+ tick_interval = STATUS_EFFECT_NO_TICK
+ /// How much click CD to add to the target's clicks
+ var/reduction
+ /// The source of the slow, they don't stack
+ var/source
+
+/datum/status_effect/cd_slow/on_creation(mob/living/new_owner, reduction, source)
+ src.reduction = reduction
+ src.source = source
+ return ..()
+
+/datum/status_effect/cd_slow/on_apply()
+ for(var/datum/status_effect/cd_slow/slow in owner)
+ if(slow.source == src.source)
+ slow.reduction = max(slow.reduction, src.reduction)
+ return FALSE
+
+ return TRUE
+
+/datum/status_effect/cd_slow/nextmove_adjust()
+ return reduction
diff --git a/code/datums/elements/strippable.dm b/code/datums/elements/strippable.dm
index e62f1847aa74a..002998a829cad 100644
--- a/code/datums/elements/strippable.dm
+++ b/code/datums/elements/strippable.dm
@@ -362,7 +362,7 @@
continue
var/obj/item/item = item_data.get_item(owner)
- if (isnull(item) || (HAS_TRAIT(item, TRAIT_NO_STRIP) || (item.item_flags & EXAMINE_SKIP)))
+ if (isnull(item) || (HAS_TRAIT(item, TRAIT_NO_STRIP) || HAS_TRAIT(item, TRAIT_EXAMINE_SKIP)))
items[strippable_key] = result
continue
diff --git a/code/datums/greyscale/layer.dm b/code/datums/greyscale/layer.dm
index f12fb1992c9db..6512a6c3d5619 100644
--- a/code/datums/greyscale/layer.dm
+++ b/code/datums/greyscale/layer.dm
@@ -92,8 +92,7 @@
/datum/greyscale_layer/icon_state/Initialize(icon_file)
. = ..()
- var/list/icon_states = icon_states(icon_file)
- if(!(icon_state in icon_states))
+ if(!icon_exists(icon_file, icon_state))
CRASH("Configured icon state \[[icon_state]\] was not found in [icon_file]. Double check your json configuration.")
icon = new(icon_file, icon_state)
diff --git a/code/datums/martial/boxing.dm b/code/datums/martial/boxing.dm
index 6aa3a6204bd4d..ecdab8e404998 100644
--- a/code/datums/martial/boxing.dm
+++ b/code/datums/martial/boxing.dm
@@ -111,7 +111,7 @@
if(istype(potential_spine))
strength_bonus *= potential_spine.strength_bonus
- damage += round(athletics_skill * check_streak(attacker, defender) + strength_bonus)
+ damage += round(athletics_skill * check_streak(attacker, defender) + strength_bonus, 1)
grant_experience = TRUE
var/current_atk_verb = atk_verb
@@ -149,7 +149,7 @@
to_chat(attacker, span_danger("Вы нанесли [current_atk_verbed] по [defender.declent_ru(DATIVE)]!"))
// Determines the total amount of experience earned per punch
- var/experience_earned = round(damage * 0.25, 0.1)
+ var/experience_earned = round(damage/4, 1)
defender.apply_damage(damage, damage_type, affecting, armor_block)
@@ -168,7 +168,7 @@
var/defender_athletics_skill = clamp(defender.mind?.get_skill_modifier(/datum/skill/athletics, SKILL_RANDS_MODIFIER), 0, 100)
//Determine our final probability, using a clamp to stop any prob() weirdness.
- var/final_knockout_probability = clamp(round(attacker_athletics_skill - defender_athletics_skill), 0 , 100)
+ var/final_knockout_probability = clamp(round(attacker_athletics_skill - defender_athletics_skill, 1), 0 , 100)
if(!prob(final_knockout_probability))
return TRUE
@@ -222,10 +222,10 @@
/// Handles our instances of experience gain while boxing. It also applies the exercised status effect.
/datum/martial_art/boxing/proc/skill_experience_adjustment(mob/living/boxer, experience_value)
//Boxing in heavier gravity gives you more experience
- var/gravity_modifier = boxer.has_gravity() > STANDARD_GRAVITY ? 1 : 0.5
+ var/gravity_modifier = boxer.has_gravity() > STANDARD_GRAVITY ? 1 : 2
//You gotta sleep before you get any experience!
- boxer.mind?.adjust_experience(/datum/skill/athletics, round(experience_value * gravity_modifier, 0.1))
+ boxer.mind?.adjust_experience(/datum/skill/athletics, round(experience_value / gravity_modifier, 1))
boxer.apply_status_effect(/datum/status_effect/exercised)
/// Handles our blocking signals, similar to hit_reaction() on items. Only blocks while the boxer is in throw mode.
@@ -254,7 +254,7 @@
if(!honor_check(attacker))
return NONE
- var/experience_earned = round(damage * 0.25, 0.1)
+ var/experience_earned = round(damage/4, 1)
if(!damage)
experience_earned = 2
@@ -346,16 +346,17 @@
human_attacker.say("[first_word_pick][second_word_pick]!!!", forced = "hunter boxing enthusiastic battlecry")
defender.apply_status_effect(/datum/status_effect/rebuked)
defender.apply_damage(damage * 2, default_damage_type, BODY_ZONE_CHEST, armor_block) //deals double our damage AGAIN
- attacker.reagents.add_reagent(/datum/reagent/medicine/omnizine/godblood, 3) //Get a little healing in return for a successful crit
+
+ var/healing_factor = round(damage/3, 1)
+ attacker.heal_overall_damage(healing_factor, healing_factor, healing_factor)
log_combat(attacker, defender, "hunter crit punched (boxing)")
-// Our hunter boxer speeds up their attacks when completing a combo against a valid target, and does a sizable amount of extra damage.
+// Our hunter boxer does a sizable amount of extra damage on a successful combo or block
/datum/martial_art/boxing/hunter/perform_extra_effect(mob/living/attacker, mob/living/defender)
if(defender.mob_biotypes & MOB_HUMANOID && !istype(defender, /mob/living/simple_animal/hostile/megafauna))
return // Does not apply to humans (who aren't megafauna)
- attacker.changeNext_move(CLICK_CD_RAPID)
defender.apply_damage(rand(15,20), default_damage_type, BODY_ZONE_CHEST)
#undef LEFT_RIGHT_COMBO
diff --git a/code/datums/shuttles/_shuttle.dm b/code/datums/shuttles/_shuttle.dm
index 94c20d41b7365..52cb31a11fd76 100644
--- a/code/datums/shuttles/_shuttle.dm
+++ b/code/datums/shuttles/_shuttle.dm
@@ -56,8 +56,8 @@
. = ..()
if(!.)
return
- var/list/turfs = block( locate(.[MAP_MINX], .[MAP_MINY], .[MAP_MINZ]),
- locate(.[MAP_MAXX], .[MAP_MAXY], .[MAP_MAXZ]))
+ var/list/turfs = block( .[MAP_MINX], .[MAP_MINY], .[MAP_MINZ],
+ .[MAP_MAXX], .[MAP_MAXY], .[MAP_MAXZ])
for(var/i in 1 to turfs.len)
var/turf/place = turfs[i]
if(isspaceturf(place)) // This assumes all shuttles are loaded in a single spot then moved to their real destination.
diff --git a/code/datums/status_effects/debuffs/staggered.dm b/code/datums/status_effects/debuffs/staggered.dm
index dcb5dc5488800..1498cdb791681 100644
--- a/code/datums/status_effects/debuffs/staggered.dm
+++ b/code/datums/status_effects/debuffs/staggered.dm
@@ -51,62 +51,74 @@
animate(pixel_x = normal_pos, time = 0.2 SECONDS)
/// Status effect specifically for instances where someone is vulnerable to being stunned when shoved.
-/datum/status_effect/next_shove_stuns
- id = "next shove stuns"
- duration = 3 SECONDS
+/datum/status_effect/dazed
+ id = "dazed"
status_type = STATUS_EFFECT_UNIQUE
tick_interval = 0.5 SECONDS
alert_type = null
remove_on_fullheal = TRUE
/// Our visual cue for the vulnerable state this status effect puts us in.
- var/mutable_appearance/vulnverability_overlay
+ var/mutable_appearance/dazed_overlay
-/datum/status_effect/next_shove_stuns/on_apply()
+/datum/status_effect/dazed/on_creation(mob/living/new_owner, duration = 3 SECONDS)
+ src.duration = duration
+ return ..()
+
+/datum/status_effect/dazed/on_apply()
//Let's just clear this if they're dead or we can't stun them on a shove
if(owner.stat == DEAD || HAS_TRAIT(owner, TRAIT_NO_SIDE_KICK) || HAS_TRAIT(owner, TRAIT_IMMOBILIZED))
return FALSE
- RegisterSignal(owner, COMSIG_LIVING_DEATH, PROC_REF(clear_stun_vulnverability_on_death))
+ RegisterSignal(owner, COMSIG_LIVING_DEATH, PROC_REF(clear_daze_on_death))
+ RegisterSignal(owner, COMSIG_LIVING_SET_BODY_POSITION, PROC_REF(clear_daze_on_stand))
RegisterSignals(owner, list(
COMSIG_LIVING_STATUS_PARALYZE,
COMSIG_LIVING_STATUS_STUN,
- COMSIG_LIVING_STATUS_IMMOBILIZE), PROC_REF(clear_stun_vulnverability)
+ COMSIG_LIVING_STATUS_IMMOBILIZE), PROC_REF(clear_daze)
)
- ADD_TRAIT(owner, TRAIT_STUN_ON_NEXT_SHOVE, TRAIT_STATUS_EFFECT(id))
- vulnverability_overlay = mutable_appearance(icon = 'icons/effects/effects.dmi', icon_state = "dazed")
- owner.add_overlay(vulnverability_overlay)
+ ADD_TRAIT(owner, TRAIT_DAZED, TRAIT_STATUS_EFFECT(id))
+ dazed_overlay = mutable_appearance(icon = 'icons/effects/effects.dmi', icon_state = "dazed")
+ owner.add_overlay(dazed_overlay)
return TRUE
-/datum/status_effect/next_shove_stuns/on_remove()
+/datum/status_effect/dazed/on_remove()
UnregisterSignal(owner, list(
+ COMSIG_LIVING_DEATH,
+ COMSIG_LIVING_SET_BODY_POSITION,
COMSIG_LIVING_STATUS_PARALYZE,
COMSIG_LIVING_STATUS_STUN,
COMSIG_LIVING_STATUS_IMMOBILIZE,
- COMSIG_LIVING_DEATH,
))
- REMOVE_TRAIT(owner, TRAIT_STUN_ON_NEXT_SHOVE, TRAIT_STATUS_EFFECT(id))
- if(vulnverability_overlay)
- clear_stun_vulnverability_overlay()
+ REMOVE_TRAIT(owner, TRAIT_DAZED, TRAIT_STATUS_EFFECT(id))
+ if(dazed_overlay)
+ clear_dazed_overlay()
/// If our owner is either stunned, paralzyed or immobilized, we remove the status effect.
/// This is both an anti-chainstun measure and a sanity check.
-/datum/status_effect/next_shove_stuns/proc/clear_stun_vulnverability(mob/living/source, amount = 0, ignore_canstun = FALSE)
+/datum/status_effect/dazed/proc/clear_daze(mob/living/source, amount = 0, ignore_canstun = FALSE)
SIGNAL_HANDLER
if(amount > 0)
// Making absolutely sure we're removing this overlay
- clear_stun_vulnverability_overlay()
+ clear_dazed_overlay()
+ qdel(src)
+
+/datum/status_effect/dazed/proc/clear_daze_on_stand(mob/living/source, new_position)
+ SIGNAL_HANDLER
+
+ if(new_position == STANDING_UP)
+ clear_dazed_overlay()
qdel(src)
-/datum/status_effect/next_shove_stuns/proc/clear_stun_vulnverability_on_death(mob/living/source)
+/datum/status_effect/dazed/proc/clear_daze_on_death(mob/living/source)
SIGNAL_HANDLER
- clear_stun_vulnverability_overlay()
+ clear_dazed_overlay()
qdel(src)
/// Clears our overlay where needed.
-/datum/status_effect/next_shove_stuns/proc/clear_stun_vulnverability_overlay()
- owner.cut_overlay(vulnverability_overlay)
- vulnverability_overlay = null
+/datum/status_effect/dazed/proc/clear_dazed_overlay()
+ owner.cut_overlay(dazed_overlay)
+ dazed_overlay = null
/// Status effect to prevent stuns from a shove
/// Only applied by shoving someone to paralyze them
diff --git a/code/game/atom/_atom.dm b/code/game/atom/_atom.dm
index c34a412a21b1f..e00352b123edc 100644
--- a/code/game/atom/_atom.dm
+++ b/code/game/atom/_atom.dm
@@ -186,12 +186,14 @@
if(smoothing_flags & SMOOTH_QUEUED)
SSicon_smooth.remove_from_queues(src)
+#ifndef DISABLE_DREAMLUAU
// These lists cease existing when src does, so we need to clear any lua refs to them that exist.
if(!(datum_flags & DF_STATIC_OBJECT))
DREAMLUAU_CLEAR_REF_USERDATA(contents)
DREAMLUAU_CLEAR_REF_USERDATA(filters)
DREAMLUAU_CLEAR_REF_USERDATA(overlays)
DREAMLUAU_CLEAR_REF_USERDATA(underlays)
+#endif
return ..()
diff --git a/code/game/atom/atom_act.dm b/code/game/atom/atom_act.dm
index 54f023eb86b59..197d6c9e38b49 100644
--- a/code/game/atom/atom_act.dm
+++ b/code/game/atom/atom_act.dm
@@ -150,7 +150,7 @@
step(harmed_atom, REVERSE_DIR(harmed_atom.dir))
///Handle the atom being slipped over
-/atom/proc/handle_slip(mob/living/carbon/slipped_carbon, knockdown_amount, obj/slipping_object, lube, paralyze, force_drop)
+/atom/proc/handle_slip(mob/living/carbon/slipped_carbon, knockdown_amount, obj/slipping_object, lube, paralyze, daze, force_drop)
return
///Used for making a sound when a mob involuntarily falls into the ground.
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index b66a534478154..d3cc115cef7e5 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -237,9 +237,11 @@
LAZYNULL(client_mobs_in_contents)
+#ifndef DISABLE_DREAMLUAU
// These lists cease existing when src does, so we need to clear any lua refs to them that exist.
DREAMLUAU_CLEAR_REF_USERDATA(vis_contents)
DREAMLUAU_CLEAR_REF_USERDATA(vis_locs)
+#endif
. = ..()
@@ -661,13 +663,12 @@
var/list/new_locs
if(is_multi_tile_object && isturf(newloc))
+ var/dx = newloc.x
+ var/dy = newloc.y
+ var/dz = newloc.z
new_locs = block(
- newloc,
- locate(
- min(world.maxx, newloc.x + CEILING(bound_width / 32, 1)),
- min(world.maxy, newloc.y + CEILING(bound_height / 32, 1)),
- newloc.z
- )
+ dx, dy, dz,
+ dx + ceil(bound_width / 32), dy + ceil(bound_height / 32), dz
) // If this is a multi-tile object then we need to predict the new locs and check if they allow our entrance.
for(var/atom/entering_loc as anything in new_locs)
if(!entering_loc.Enter(src))
@@ -1153,13 +1154,12 @@
return FALSE
if(is_multi_tile && isturf(destination))
+ var/dx = destination.x
+ var/dy = destination.y
+ var/dz = destination.z
var/list/new_locs = block(
- destination,
- locate(
- min(world.maxx, destination.x + ROUND_UP(bound_width / ICON_SIZE_X)),
- min(world.maxy, destination.y + ROUND_UP(bound_height / ICON_SIZE_Y)),
- destination.z
- )
+ dx, dy, dz,
+ dx + ROUND_UP(bound_width / ICON_SIZE_X), dy + ROUND_UP(bound_height / ICON_SIZE_Y), dz
)
if(old_area && old_area != destarea)
old_area.Exited(src, movement_dir)
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 28866ec07f229..97d72ae131cef 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -520,10 +520,6 @@
add_fingerprint(usr)
return ..()
-/obj/item/vv_get_dropdown()
- . = ..()
- VV_DROPDOWN_OPTION(VV_HK_ADD_FANTASY_AFFIX, "Add Fantasy Affix")
-
/obj/item/vv_do_topic(list/href_list)
. = ..()
@@ -696,6 +692,7 @@
if(item_flags & DROPDEL && !QDELETED(src))
qdel(src)
item_flags &= ~IN_INVENTORY
+ UnregisterSignal(src, list(SIGNAL_ADDTRAIT(TRAIT_NO_WORN_ICON), SIGNAL_REMOVETRAIT(TRAIT_NO_WORN_ICON)))
SEND_SIGNAL(src, COMSIG_ITEM_DROPPED, user)
if(!silent)
playsound(src, drop_sound, DROP_SOUND_VOLUME, vary = sound_vary, ignore_walls = FALSE)
@@ -760,6 +757,7 @@
give_item_action(action, user, slot)
item_flags |= IN_INVENTORY
+ RegisterSignals(src, list(SIGNAL_ADDTRAIT(TRAIT_NO_WORN_ICON), SIGNAL_REMOVETRAIT(TRAIT_NO_WORN_ICON)), PROC_REF(update_slot_icon), override = TRUE)
if(!initial)
if(equip_sound && (slot_flags & slot))
playsound(src, equip_sound, EQUIP_SOUND_VOLUME, TRUE, ignore_walls = FALSE)
@@ -924,6 +922,7 @@
return null
/obj/item/proc/update_slot_icon()
+ SIGNAL_HANDLER
if(!ismob(loc))
return
var/mob/owner = loc
diff --git a/code/game/objects/items/body_egg.dm b/code/game/objects/items/body_egg.dm
index 7a8d70888f066..40ea0ba37b5fe 100644
--- a/code/game/objects/items/body_egg.dm
+++ b/code/game/objects/items/body_egg.dm
@@ -5,6 +5,7 @@
visual = TRUE
zone = BODY_ZONE_CHEST
slot = ORGAN_SLOT_PARASITE_EGG
+ organ_flags = parent_type::organ_flags | ORGAN_HAZARDOUS
/obj/item/organ/body_egg/on_find(mob/living/finder)
..()
diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm
index fbdf3bae40a88..5783b3c867f52 100644
--- a/code/game/objects/items/devices/chameleonproj.dm
+++ b/code/game/objects/items/devices/chameleonproj.dm
@@ -77,9 +77,7 @@
saved_appearance = temp.appearance
/obj/item/chameleon/proc/check_sprite(atom/target)
- if(target.icon_state in icon_states(target.icon))
- return TRUE
- return FALSE
+ return icon_exists(target.icon, target.icon_state)
/obj/item/chameleon/proc/toggle(mob/user)
if(!can_use || !saved_appearance)
diff --git a/code/game/objects/items/devices/scanners/plant_analyzer.dm b/code/game/objects/items/devices/scanners/plant_analyzer.dm
index 25bfab652f796..363ae5067b0df 100644
--- a/code/game/objects/items/devices/scanners/plant_analyzer.dm
+++ b/code/game/objects/items/devices/scanners/plant_analyzer.dm
@@ -64,13 +64,15 @@
if(isliving(interacting_with))
playsound(src, SFX_INDUSTRIAL_SCAN, 20, TRUE, -2, TRUE, FALSE)
- var/mob/living/L = interacting_with
- if(L.mob_biotypes & MOB_PLANT)
- plant_biotype_health_scan(interacting_with, user)
+ var/mob/living/living_target = interacting_with
+ if(living_target.mob_biotypes & MOB_PLANT)
+ plant_biotype_health_scan(living_target, user)
return ITEM_INTERACT_SUCCESS
+ return ITEM_INTERACT_BLOCKING
- analyze(user, interacting_with)
- return ITEM_INTERACT_SUCCESS
+ if(analyze(user, interacting_with))
+ return ITEM_INTERACT_SUCCESS
+ return NONE
/// Same as above, but with right click. Right-clicking scans for chemicals.
/obj/item/plant_analyzer/interact_with_atom_secondary(atom/interacting_with, mob/living/user, list/modifiers)
@@ -78,7 +80,10 @@
if(!user.can_read(src))
return ITEM_INTERACT_BLOCKING
- return do_plant_chem_scan(interacting_with, user) ? ITEM_INTERACT_SUCCESS : ITEM_INTERACT_BLOCKING
+ if(do_plant_chem_scan(interacting_with, user))
+ return ITEM_INTERACT_SUCCESS
+
+ return NONE
/*
* Scan the target on chemical scan mode. This prints chemical genes and reagents to the user.
@@ -91,10 +96,10 @@
*/
/obj/item/plant_analyzer/proc/do_plant_chem_scan(atom/scan_target, mob/user)
if(isliving(scan_target))
- var/mob/living/L = scan_target
- if(L.mob_biotypes & MOB_PLANT)
+ var/mob/living/living_target = scan_target
+ if(living_target.mob_biotypes & MOB_PLANT)
plant_biotype_chem_scan(scan_target, user)
- return TRUE
+ return TRUE
return analyze(user, scan_target)
diff --git a/code/game/objects/items/gun_maintenance.dm b/code/game/objects/items/gun_maintenance.dm
index 072ec395c191c..77ba80352910b 100644
--- a/code/game/objects/items/gun_maintenance.dm
+++ b/code/game/objects/items/gun_maintenance.dm
@@ -1,6 +1,78 @@
/obj/item/gun_maintenance_supplies
- name = "gun maintenance supplies"
- desc = "plastic box containing gun maintenance supplies and spare parts. Use them on a rifle to clean it."
- icon = 'icons/obj/storage/box.dmi'
- icon_state = "plasticbox"
- w_class = WEIGHT_CLASS_SMALL
+ name = "gun maintenance kit"
+ desc = "A toolbox containing gun maintenance supplies and spare parts. Can be applied to firearms to maintain them."
+ icon = 'icons/obj/storage/toolbox.dmi'
+ icon_state = "maint_kit"
+ inhand_icon_state = "ammobox"
+ lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi'
+ force = 12
+ throwforce = 12
+ throw_speed = 2
+ throw_range = 7
+ demolition_mod = 1.25
+ w_class = WEIGHT_CLASS_BULKY
+ drop_sound = 'sound/items/handling/ammobox_drop.ogg'
+ pickup_sound = 'sound/items/handling/ammobox_pickup.ogg'
+ /// How many times we can use this maintenance kit to maintain a gun
+ var/uses = 3
+ /// THe maximum uses, used for our examine text.
+ var/max_uses = 3
+
+/obj/item/gun_maintenance_supplies/examine(mob/user)
+ . = ..()
+ . += span_info("This kit has [uses] uses out of [max_uses] left.")
+
+/obj/item/gun_maintenance_supplies/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
+ . = ..()
+ if(. & ITEM_INTERACT_ANY_BLOCKER)
+ return ITEM_INTERACT_BLOCKING
+
+ if(!isgun(interacting_with))
+ balloon_alert(user, "not a gun!")
+ return ITEM_INTERACT_BLOCKING
+
+ var/obj/item/gun/gun_to_fix = interacting_with
+
+ var/gun_is_damaged = gun_to_fix.get_integrity() < gun_to_fix.max_integrity
+ var/use_charge = FALSE
+
+ if(gun_is_damaged)
+ gun_to_fix.repair_damage(gun_to_fix.max_integrity)
+ use_charge = TRUE
+
+ if(istype(gun_to_fix, /obj/item/gun/ballistic))
+ var/obj/item/gun/ballistic/ballistic_gun_to_fix = gun_to_fix
+
+ if(ballistic_gun_to_fix.misfire_probability > initial(ballistic_gun_to_fix.misfire_probability))
+ ballistic_gun_to_fix.misfire_probability = initial(ballistic_gun_to_fix.misfire_probability)
+
+ if(istype(ballistic_gun_to_fix, /obj/item/gun/ballistic/rifle/boltaction))
+ var/obj/item/gun/ballistic/rifle/boltaction/rifle_to_fix = ballistic_gun_to_fix
+ if(rifle_to_fix.jammed)
+ rifle_to_fix.jammed = FALSE
+ rifle_to_fix.unjam_chance = initial(rifle_to_fix.unjam_chance)
+ rifle_to_fix.jamming_chance = initial(rifle_to_fix.jamming_chance)
+ use_charge = TRUE
+
+ if(!use_charge)
+ balloon_alert(user, "no need for repair!")
+ return ITEM_INTERACT_BLOCKING
+
+ balloon_alert(user, "maintenance complete")
+ use_the_kit()
+ return ITEM_INTERACT_SUCCESS
+
+/obj/item/gun_maintenance_supplies/proc/use_the_kit()
+ uses --
+ if(!uses)
+ qdel(src)
+
+/obj/item/gun_maintenance_supplies/makeshift
+ name = "makeshift gun maintenance kit"
+ desc = "A toolbox containing enough supplies to juryrig repairs on firearms. Can be applied to firearms to maintain them. \
+ The tools are a little basic, and the materials low-quality, but it gets the job done."
+ icon_state = "maint_kit_makeshift"
+ inhand_icon_state = "toolbox_blue"
+ uses = 1
+ max_uses = 1
diff --git a/code/game/objects/items/melee/baton.dm b/code/game/objects/items/melee/baton.dm
index e0dfecf94240b..1bd60484d33ba 100644
--- a/code/game/objects/items/melee/baton.dm
+++ b/code/game/objects/items/melee/baton.dm
@@ -382,7 +382,7 @@
RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(on_transform))
/obj/item/melee/baton/telescopic/additional_effects_non_cyborg(mob/living/target, mob/living/user)
- target.apply_status_effect(/datum/status_effect/next_shove_stuns)
+ target.apply_status_effect(/datum/status_effect/dazed)
/obj/item/melee/baton/telescopic/suicide_act(mob/living/user)
var/mob/living/carbon/human/human_user = user
@@ -530,6 +530,8 @@
var/active_changes_inhand = TRUE
///Whether or not our baton visibly changes the inhand sprite based on inserted cell
var/tip_changes_color = TRUE
+ ///When set, inhand_icon_state defaults to this instead of base_icon_state
+ var/base_inhand_state = null
/datum/armor/baton_security
bomb = 50
@@ -594,20 +596,21 @@
update_appearance()
/obj/item/melee/baton/security/update_icon_state()
+ var/base_inhand = base_inhand_state || base_icon_state
if(active)
icon_state = "[base_icon_state]_active"
if(active_changes_inhand)
if(tip_changes_color)
- inhand_icon_state = "[base_icon_state]_active_[get_baton_tip_color()]"
+ inhand_icon_state = "[base_inhand]_active_[get_baton_tip_color()]"
else
- inhand_icon_state = "[base_icon_state]_active"
+ inhand_icon_state = "[base_inhand]_active"
return ..()
if(!cell)
icon_state = "[base_icon_state]_nocell"
- inhand_icon_state = "[base_icon_state]"
+ inhand_icon_state = base_inhand
return ..()
- icon_state = "[base_icon_state]"
- inhand_icon_state = "[base_icon_state]"
+ icon_state = base_icon_state
+ inhand_icon_state = base_inhand
return ..()
/obj/item/melee/baton/security/examine(mob/user)
@@ -833,6 +836,7 @@
icon_state = "stunprod"
base_icon_state = "stunprod"
inhand_icon_state = "prod"
+ base_inhand_state = "prod"
worn_icon_state = null
icon_angle = -45
lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi'
diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm
index 25836920b5ca1..d6ce3ee076675 100644
--- a/code/game/objects/items/stacks/medical.dm
+++ b/code/game/objects/items/stacks/medical.dm
@@ -36,6 +36,10 @@
var/apply_verb = "treating"
/// Whether this item can be used on dead bodies
var/works_on_dead = FALSE
+ /// The sound this makes when starting healing with this item
+ var/heal_begin_sound = null
+ /// The sound this makes when healed successfully with this item
+ var/heal_end_sound = null
/obj/item/stack/medical/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
if(!isliving(interacting_with))
@@ -375,6 +379,8 @@
apply_verb = "wrapping"
works_on_dead = TRUE
var/obj/item/bodypart/gauzed_bodypart
+ heal_end_sound = SFX_BANDAGE_END
+ heal_begin_sound = SFX_BANDAGE_BEGIN
/obj/item/stack/medical/gauze/Destroy(force)
. = ..()
@@ -444,6 +450,7 @@
span_warning("You begin wrapping the wounds on [user == patient ? "your" : "[patient]'s"] [limb.plaintext_zone] with [src]..."),
visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE,
)
+ playsound(src, heal_begin_sound, 30, TRUE, MEDIUM_RANGE_SOUND_EXTRARANGE)
if(!do_after(user, treatment_delay, target = patient))
return
@@ -455,6 +462,8 @@
span_green("You bandage the wounds on [user == patient ? "your" : "[patient]'s"] [limb.plaintext_zone]."),
visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE,
)
+ if(heal_end_sound)
+ playsound(patient, heal_end_sound, 30, TRUE, MEDIUM_RANGE_SOUND_EXTRARANGE)
limb.apply_gauze(src)
/obj/item/stack/medical/gauze/twelve
diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm
index c3ae2d7b0d31b..5329cd8ed05fc 100644
--- a/code/game/objects/items/storage/toolbox.dm
+++ b/code/game/objects/items/storage/toolbox.dm
@@ -7,8 +7,8 @@
lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi'
obj_flags = CONDUCTS_ELECTRICITY
- force = 12
- throwforce = 12
+ force = 13
+ throwforce = 13
throw_speed = 2
throw_range = 7
demolition_mod = 1.25
@@ -203,8 +203,8 @@
var/power = 0
for (var/obj/item/stack/telecrystal/stored_crystals in get_all_contents())
power += (stored_crystals.amount / 2)
- force = 19 + power
- throwforce = 22 + power
+ force = initial(force) + power
+ throwforce = initial(throwforce) + power
/obj/item/storage/toolbox/mechanical/old/clean/attack(mob/target, mob/living/user)
calc_damage()
@@ -387,20 +387,6 @@
name = "4.6x30mm AP ammo box"
ammo_to_spawn = /obj/item/ammo_box/magazine/wt550m9/wtap
-/obj/item/storage/toolbox/maint_kit
- name = "gun maintenance kit"
- desc = "It contains some gun maintenance supplies"
- icon_state = "maint_kit"
- inhand_icon_state = "ammobox"
- has_latches = FALSE
- drop_sound = 'sound/items/handling/ammobox_drop.ogg'
- pickup_sound = 'sound/items/handling/ammobox_pickup.ogg'
-
-/obj/item/storage/toolbox/maint_kit/PopulateContents()
- new /obj/item/gun_maintenance_supplies(src)
- new /obj/item/gun_maintenance_supplies(src)
- new /obj/item/gun_maintenance_supplies(src)
-
//repairbot assembly
/obj/item/storage/toolbox/tool_act(mob/living/user, obj/item/tool, list/modifiers)
if(!istype(tool, /obj/item/assembly/prox_sensor))
diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm
index d0b12639c4e88..094c60d0e753c 100644
--- a/code/game/objects/structures/beds_chairs/chair.dm
+++ b/code/game/objects/structures/beds_chairs/chair.dm
@@ -349,8 +349,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0)
custom_materials = list(/datum/material/iron =SHEET_MATERIAL_AMOUNT)
item_flags = SKIP_FANTASY_ON_SPAWN
- // Whether or not the chair causes the target to become shove stun vulnerable if smashed against someone from behind.
- var/inflicts_stun_vulnerability = TRUE
+ // Duration of daze inflicted when the chair is smashed against someone from behind.
+ var/daze_amount = 3 SECONDS
// What structure type does this chair become when placed?
var/obj/structure/chair/origin_type = /obj/structure/chair
@@ -433,11 +433,9 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0)
user.visible_message(span_danger("[user] smashes [src] to pieces against [give_this_fucker_the_chair]"))
if(!HAS_TRAIT(give_this_fucker_the_chair, TRAIT_BRAWLING_KNOCKDOWN_BLOCKED))
if(vulnerable_hit || give_this_fucker_the_chair.get_timed_status_effect_duration(/datum/status_effect/staggered))
- give_this_fucker_the_chair.Knockdown(2 SECONDS)
+ give_this_fucker_the_chair.Knockdown(2 SECONDS, daze_amount = daze_amount)
if(give_this_fucker_the_chair.health < give_this_fucker_the_chair.maxHealth*0.5)
give_this_fucker_the_chair.adjust_confusion(10 SECONDS)
- if(inflicts_stun_vulnerability)
- give_this_fucker_the_chair.apply_status_effect(/datum/status_effect/next_shove_stuns)
smash(user)
@@ -471,7 +469,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0)
hitsound = 'sound/items/weapons/genhit1.ogg'
origin_type = /obj/structure/chair/stool/bamboo
max_integrity = 40 //Submissive and breakable unlike the chad iron stool
- inflicts_stun_vulnerability = FALSE //Not hard enough to cause them to become vulnerable to a shove
+ daze_amount = 0 //Not hard enough to cause them to become dazed
/obj/item/chair/stool/narsie_act()
return //sturdy enough to ignore a god
@@ -485,7 +483,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0)
hitsound = 'sound/items/weapons/genhit1.ogg'
origin_type = /obj/structure/chair/wood
custom_materials = null
- inflicts_stun_vulnerability = FALSE
+ daze_amount = 0
/obj/item/chair/wood/narsie_act()
return
@@ -607,7 +605,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0)
throw_range = 5 //Lighter Weight --> Flies Farther.
custom_materials = list(/datum/material/plastic =SHEET_MATERIAL_AMOUNT)
max_integrity = 70
- inflicts_stun_vulnerability = FALSE
+ daze_amount = 0
origin_type = /obj/structure/chair/plastic
/obj/structure/chair/musical
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index 22517603ef3fc..50c9d427c94a9 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -345,8 +345,7 @@
SIGNAL_HANDLER
if((shove_flags & SHOVE_KNOCKDOWN_BLOCKED) || !(shove_flags & SHOVE_BLOCKED))
return
- target.Knockdown(SHOVE_KNOCKDOWN_TABLE)
- target.apply_status_effect(/datum/status_effect/next_shove_stuns)
+ target.Knockdown(SHOVE_KNOCKDOWN_TABLE, daze_amount = 3 SECONDS)
target.visible_message(span_danger("[shover.name] shoves [target.name] onto \the [src]!"),
span_userdanger("You're shoved onto \the [src] by [shover.name]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, shover)
to_chat(shover, span_danger("You shove [target.name] onto \the [src]!"))
diff --git a/code/game/sound.dm b/code/game/sound.dm
index 5111b6cfdf038..31c97d8421595 100644
--- a/code/game/sound.dm
+++ b/code/game/sound.dm
@@ -799,4 +799,18 @@
'sound/items/handling/headset/headset_pickup2.ogg',
'sound/items/handling/headset/headset_pickup3.ogg',
)
+ if(SFX_BANDAGE_BEGIN)
+ soundin = pick(
+ 'sound/items/gauze/bandage_begin1.ogg',
+ 'sound/items/gauze/bandage_begin2.ogg',
+ 'sound/items/gauze/bandage_begin3.ogg',
+ 'sound/items/gauze/bandage_begin4.ogg',
+ )
+ if(SFX_BANDAGE_END)
+ soundin = pick(
+ 'sound/items/gauze/bandage_end1.ogg',
+ 'sound/items/gauze/bandage_end2.ogg',
+ 'sound/items/gauze/bandage_end3.ogg',
+ 'sound/items/gauze/bandage_end4.ogg',
+ )
return soundin
diff --git a/code/game/turfs/open/_open.dm b/code/game/turfs/open/_open.dm
index 9f11b446c8989..434d1014e32ed 100644
--- a/code/game/turfs/open/_open.dm
+++ b/code/game/turfs/open/_open.dm
@@ -340,7 +340,7 @@
wash(CLEAN_WASH, TRUE)
return TRUE
-/turf/open/handle_slip(mob/living/slipper, knockdown_amount, obj/slippable, lube, paralyze_amount, force_drop)
+/turf/open/handle_slip(mob/living/slipper, knockdown_amount, obj/slippable, lube, paralyze_amount, daze_amount, force_drop)
if(slipper.movement_type & MOVETYPES_NOT_TOUCHING_GROUND)
return FALSE
if(!has_gravity(src))
@@ -393,8 +393,8 @@
slipper.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH, 10 SECONDS)
slipper.stop_pulling()
else
- slipper.Knockdown(knockdown_amount)
slipper.Paralyze(paralyze_amount)
+ slipper.Knockdown(knockdown_amount, daze_amount = daze_amount)
if(!isnull(buckled_obj) && !ismob(buckled_obj))
buckled_obj.unbuckle_mob(slipper)
diff --git a/code/game/turfs/open/floor/iron_floor.dm b/code/game/turfs/open/floor/iron_floor.dm
index c3869ccc962ce..16f74866a1c1d 100644
--- a/code/game/turfs/open/floor/iron_floor.dm
+++ b/code/game/turfs/open/floor/iron_floor.dm
@@ -434,6 +434,16 @@
name = "cold room floor"
initial_gas_mix = KITCHEN_COLDROOM_ATMOS
+/turf/open/floor/iron/kitchen_coldroom/dark
+ icon_state = "darkfull"
+ base_icon_state = "darkfull"
+ floor_tile = /obj/item/stack/tile/iron/dark
+
+/turf/open/floor/iron/kitchen_coldroom/dark/textured
+ icon_state = "textured_dark"
+ base_icon_state = "textured_dark"
+ floor_tile = /obj/item/stack/tile/iron/dark/textured
+
/turf/open/floor/iron/kitchen_coldroom/freezerfloor
icon_state = "freezerfloor"
base_icon_state = "freezerfloor"
diff --git a/code/game/world.dm b/code/game/world.dm
index 223682c0b792c..b72c106d3ba71 100644
--- a/code/game/world.dm
+++ b/code/game/world.dm
@@ -335,6 +335,9 @@ GLOBAL_PROTECT(tracy_init_reason)
return
#else
if(TgsAvailable())
+ if(!fast_track)
+ TgsTriggerEvent("tg-PreReboot", wait_for_completion = TRUE)
+
var/do_hard_reboot
// check the hard reboot counter
var/ruhr = CONFIG_GET(number/rounds_until_hard_restart)
@@ -457,8 +460,9 @@ GLOBAL_PROTECT(tracy_init_reason)
LISTASSERTLEN(global_area.turfs_by_zlevel, map_load_z_cutoff, list())
for (var/zlevel in 1 to map_load_z_cutoff)
var/list/to_add = block(
- locate(old_max + 1, 1, zlevel),
- locate(maxx, maxy, zlevel))
+ old_max + 1, 1, zlevel,
+ maxx, maxy, zlevel
+ )
global_area.turfs_by_zlevel[zlevel] += to_add
@@ -473,8 +477,9 @@ GLOBAL_PROTECT(tracy_init_reason)
LISTASSERTLEN(global_area.turfs_by_zlevel, map_load_z_cutoff, list())
for (var/zlevel in 1 to map_load_z_cutoff)
var/list/to_add = block(
- locate(1, old_maxy + 1, 1),
- locate(maxx, maxy, map_load_z_cutoff))
+ 1, old_maxy + 1, 1,
+ maxx, maxy, map_load_z_cutoff
+ )
global_area.turfs_by_zlevel[zlevel] += to_add
/world/proc/incrementMaxZ()
@@ -504,7 +509,9 @@ GLOBAL_PROTECT(tracy_init_reason)
/world/proc/on_tickrate_change()
SStimer?.reset_buckets()
+#ifndef DISABLE_DREAMLUAU
DREAMLUAU_SET_EXECUTION_LIMIT_MILLIS(tick_lag * 100)
+#endif
/world/proc/init_byond_tracy()
if(!fexists(TRACY_DLL_PATH))
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 5c06f3f4cb980..ce640cf0d3f14 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -1699,6 +1699,7 @@
return
return usr.client?.mark_datum(datum_to_mark)
+#ifndef DISABLE_DREAMLUAU
else if(href_list["lua_state"])
if(!check_rights(R_DEBUG))
return
@@ -1715,6 +1716,7 @@
editor.force_view_chunk = log_entry["chunk"]
editor.force_modal = "viewChunk"
editor.ui_interact(usr)
+#endif
else if(href_list["show_paper"])
if(!check_rights(R_ADMIN))
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index fc054e9a9cb0b..0ca4072ff77ac 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -814,57 +814,57 @@ ADMIN_VERB(check_missing_sprites, R_DEBUG, "Debug Worn Item Sprites", "We're can
continue
//Is there an explicit worn_icon to pick against the worn_icon_state? Easy street expected behavior.
if(sprite.worn_icon)
- if(!(sprite.icon_state in icon_states(sprite.worn_icon)))
+ if(!icon_exists(sprite.worn_icon, sprite.icon_state))
to_chat(user, span_warning("ERROR sprites for [sprite.type]. Slot Flags are [sprite.slot_flags]."), confidential = TRUE)
else if(sprite.worn_icon_state)
if(sprite.slot_flags & ITEM_SLOT_MASK)
actual_file_name = 'icons/mob/clothing/mask.dmi'
- if(!(sprite.worn_icon_state in icon_states(actual_file_name)))
+ if(!icon_exists(actual_file_name, sprite.worn_icon_state))
to_chat(user, span_warning("ERROR sprites for [sprite.type]. Mask slot."), confidential = TRUE)
if(sprite.slot_flags & ITEM_SLOT_NECK)
actual_file_name = 'icons/mob/clothing/neck.dmi'
- if(!(sprite.worn_icon_state in icon_states(actual_file_name)))
+ if(!icon_exists(actual_file_name, sprite.worn_icon_state))
to_chat(user, span_warning("ERROR sprites for [sprite.type]. Neck slot."), confidential = TRUE)
if(sprite.slot_flags & ITEM_SLOT_BACK)
actual_file_name = 'icons/mob/clothing/back.dmi'
- if(!(sprite.worn_icon_state in icon_states(actual_file_name)))
+ if(!icon_exists(actual_file_name, sprite.worn_icon_state))
to_chat(user, span_warning("ERROR sprites for [sprite.type]. Back slot."), confidential = TRUE)
if(sprite.slot_flags & ITEM_SLOT_HEAD)
actual_file_name = 'icons/mob/clothing/head/default.dmi'
- if(!(sprite.worn_icon_state in icon_states(actual_file_name)))
+ if(!icon_exists(actual_file_name, sprite.worn_icon_state))
to_chat(user, span_warning("ERROR sprites for [sprite.type]. Head slot."), confidential = TRUE)
if(sprite.slot_flags & ITEM_SLOT_BELT)
actual_file_name = 'icons/mob/clothing/belt.dmi'
- if(!(sprite.worn_icon_state in icon_states(actual_file_name)))
+ if(!icon_exists(actual_file_name, sprite.worn_icon_state))
to_chat(user, span_warning("ERROR sprites for [sprite.type]. Belt slot."), confidential = TRUE)
if(sprite.slot_flags & ITEM_SLOT_SUITSTORE)
actual_file_name = 'icons/mob/clothing/belt_mirror.dmi'
- if(!(sprite.worn_icon_state in icon_states(actual_file_name)))
+ if(!icon_exists(actual_file_name, sprite.worn_icon_state))
to_chat(user, span_warning("ERROR sprites for [sprite.type]. Suit Storage slot."), confidential = TRUE)
else if(sprite.icon_state)
if(sprite.slot_flags & ITEM_SLOT_MASK)
actual_file_name = 'icons/mob/clothing/mask.dmi'
- if(!(sprite.icon_state in icon_states(actual_file_name)))
+ if(!icon_exists(actual_file_name, sprite.icon_state))
to_chat(user, span_warning("ERROR sprites for [sprite.type]. Mask slot."), confidential = TRUE)
if(sprite.slot_flags & ITEM_SLOT_NECK)
actual_file_name = 'icons/mob/clothing/neck.dmi'
- if(!(sprite.icon_state in icon_states(actual_file_name)))
+ if(!icon_exists(actual_file_name, sprite.icon_state))
to_chat(user, span_warning("ERROR sprites for [sprite.type]. Neck slot."), confidential = TRUE)
if(sprite.slot_flags & ITEM_SLOT_BACK)
actual_file_name = 'icons/mob/clothing/back.dmi'
- if(!(sprite.icon_state in icon_states(actual_file_name)))
+ if(!icon_exists(actual_file_name, sprite.icon_state))
to_chat(user, span_warning("ERROR sprites for [sprite.type]. Back slot."), confidential = TRUE)
if(sprite.slot_flags & ITEM_SLOT_HEAD)
actual_file_name = 'icons/mob/clothing/head/default.dmi'
- if(!(sprite.icon_state in icon_states(actual_file_name)))
+ if(!icon_exists(actual_file_name, sprite.icon_state))
to_chat(user, span_warning("ERROR sprites for [sprite.type]. Head slot."), confidential = TRUE)
if(sprite.slot_flags & ITEM_SLOT_BELT)
actual_file_name = 'icons/mob/clothing/belt.dmi'
- if(!(sprite.icon_state in icon_states(actual_file_name)))
+ if(!icon_exists(actual_file_name, sprite.icon_state))
to_chat(user, span_warning("ERROR sprites for [sprite.type]. Belt slot."), confidential = TRUE)
if(sprite.slot_flags & ITEM_SLOT_SUITSTORE)
actual_file_name = 'icons/mob/clothing/belt_mirror.dmi'
- if(!(sprite.icon_state in icon_states(actual_file_name)))
+ if(!icon_exists(actual_file_name, sprite.icon_state))
to_chat(user, span_warning("ERROR sprites for [sprite.type]. Suit Storage slot."), confidential = TRUE)
#ifndef OPENDREAM
diff --git a/code/modules/admin/verbs/lua/_wrappers.dm b/code/modules/admin/verbs/lua/_wrappers.dm
index d516f064f847f..5fd78244b5603 100644
--- a/code/modules/admin/verbs/lua/_wrappers.dm
+++ b/code/modules/admin/verbs/lua/_wrappers.dm
@@ -1,3 +1,4 @@
+#ifndef DISABLE_DREAMLUAU
/proc/wrap_lua_get_var(datum/thing, var_name)
SHOULD_NOT_SLEEP(TRUE)
if(thing == world)
@@ -46,3 +47,4 @@
var/result = list("status" = "print", "message" = print_message)
INVOKE_ASYNC(target_state, TYPE_PROC_REF(/datum/lua_state, log_result), result, TRUE)
log_lua("[target_state]: [print_message]")
+#endif
diff --git a/code/modules/admin/verbs/lua/helpers.dm b/code/modules/admin/verbs/lua/helpers.dm
index c3072f15e74cd..fe844c5c55fa2 100644
--- a/code/modules/admin/verbs/lua/helpers.dm
+++ b/code/modules/admin/verbs/lua/helpers.dm
@@ -1,3 +1,4 @@
+#ifndef DISABLE_DREAMLUAU
#define PROMISE_PENDING 0
#define PROMISE_RESOLVED 1
#define PROMISE_REJECTED 2
@@ -34,3 +35,4 @@
#undef PROMISE_PENDING
#undef PROMISE_RESOLVED
#undef PROMISE_REJECTED
+#endif
diff --git a/code/modules/admin/verbs/lua/lua_editor.dm b/code/modules/admin/verbs/lua/lua_editor.dm
index 93e8e50c1a6a4..280bd52a57d72 100644
--- a/code/modules/admin/verbs/lua/lua_editor.dm
+++ b/code/modules/admin/verbs/lua/lua_editor.dm
@@ -1,3 +1,4 @@
+#ifndef DISABLE_DREAMLUAU
/datum/lua_editor
var/datum/lua_state/current_state
@@ -279,7 +280,12 @@
/datum/lua_editor/ui_close(mob/user)
. = ..()
qdel(src)
+#endif
ADMIN_VERB(lua_editor, R_DEBUG, "Open Lua Editor", "Its codin' time.", ADMIN_CATEGORY_DEBUG)
+#ifndef DISABLE_DREAMLUAU
var/datum/lua_editor/editor = new
editor.ui_interact(user.mob)
+#else
+ to_chat(user, span_warning("Lua support has been disabled at compile-time."), type = MESSAGE_TYPE_ADMINLOG, confidential = TRUE) // doing this instead of just disabling the verb entirely so it's clear WHY it doesn't work.
+#endif
diff --git a/code/modules/admin/verbs/lua/lua_state.dm b/code/modules/admin/verbs/lua/lua_state.dm
index 30bc21c83b2be..53b869e23a1df 100644
--- a/code/modules/admin/verbs/lua/lua_state.dm
+++ b/code/modules/admin/verbs/lua/lua_state.dm
@@ -1,3 +1,4 @@
+#ifndef DISABLE_DREAMLUAU
#define MAX_LOG_REPEAT_LOOKBACK 5
GLOBAL_DATUM(lua_usr, /mob)
@@ -232,3 +233,4 @@ GLOBAL_PROTECT(lua_state_stack)
SStgui.update_uis(editor)
#undef MAX_LOG_REPEAT_LOOKBACK
+#endif
diff --git a/code/modules/admin/view_variables/view_variables.dm b/code/modules/admin/view_variables/view_variables.dm
index fbebccd445981..58c98bb114a8e 100644
--- a/code/modules/admin/view_variables/view_variables.dm
+++ b/code/modules/admin/view_variables/view_variables.dm
@@ -54,7 +54,7 @@ ADMIN_VERB_AND_CONTEXT_MENU(debug_variables, R_NONE, "View Variables", "View the
else // it means: icon_state=""
if(!dmi_nullstate_checklist[icon_filename_text])
dmi_nullstate_checklist[icon_filename_text] = ICON_STATE_CHECKED
- if("" in icon_states(image_object.icon))
+ if(icon_exists(image_object.icon, ""))
// this dmi has nullstate. We'll allow "icon_state=null" to show image.
dmi_nullstate_checklist[icon_filename_text] = ICON_STATE_NULL
diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm
index b3a53bb765c53..61af267885a98 100644
--- a/code/modules/antagonists/cult/runes.dm
+++ b/code/modules/antagonists/cult/runes.dm
@@ -1027,7 +1027,7 @@ GLOBAL_VAR_INIT(narsie_summon_count, 0)
visible_message(span_warning("A cloud of red mist forms above [src], and from within steps... a [new_human.gender == FEMALE ? "wo":""]man."))
to_chat(user, span_cult_italic("Your blood begins flowing into [src]. You must remain in place and conscious to maintain the forms of those summoned. This will hurt you slowly but surely..."))
var/obj/structure/emergency_shield/cult/weak/N = new(T)
- if(ghost_to_spawn.mind && ghost_to_spawn.mind.current)
+ if(ghost_to_spawn.mind && ghost_to_spawn.mind)
new_human.AddComponent( \
/datum/component/temporary_body, \
old_mind = ghost_to_spawn.mind, \
diff --git a/code/modules/antagonists/heretic/heretic_antag.dm b/code/modules/antagonists/heretic/heretic_antag.dm
index 1c370c60074f7..a7c6e4ddb2bfe 100644
--- a/code/modules/antagonists/heretic/heretic_antag.dm
+++ b/code/modules/antagonists/heretic/heretic_antag.dm
@@ -205,8 +205,13 @@
if("research")
var/datum/heretic_knowledge/researched_path = text2path(params["path"])
if(!ispath(researched_path, /datum/heretic_knowledge))
- CRASH("Heretic attempted to learn non-heretic_knowledge path! (Got: [researched_path])")
-
+ CRASH("Heretic attempted to learn non-heretic_knowledge path! (Got: [researched_path || "invalid path"])")
+ if(!(researched_path in get_researchable_knowledge()))
+ message_admins("Heretic [key_name(owner)] potentially attempted to href exploit to learn knowledge they can't learn!")
+ CRASH("Heretic attempted to learn knowledge they can't learn! (Got: [researched_path])")
+ if(ispath(researched_path, /datum/heretic_knowledge/ultimate) && !can_ascend())
+ message_admins("Heretic [key_name(owner)] potentially attempted to href exploit to learn ascension knowledge without completing objectives!")
+ CRASH("Heretic attempted to learn a final knowledge despite not being able to ascend!")
if(initial(researched_path.cost) > knowledge_points)
return TRUE
if(!gain_knowledge(researched_path))
diff --git a/code/modules/antagonists/heretic/items/eldritch_flask.dm b/code/modules/antagonists/heretic/items/eldritch_flask.dm
index fcafba914938b..f70190f839a94 100644
--- a/code/modules/antagonists/heretic/items/eldritch_flask.dm
+++ b/code/modules/antagonists/heretic/items/eldritch_flask.dm
@@ -1,5 +1,5 @@
// An unholy water flask, but for heretics.
-// Heals heretics, hearms non-heretics. Pretty much identical.
+// Heals heretics, harms non-heretics. Pretty much identical.
/obj/item/reagent_containers/cup/beaker/eldritch
name = "flask of eldritch essence"
desc = "Токсичный для недалеких умов, но освежающий для тех, кто имеет знания о потустороннем."
diff --git a/code/modules/antagonists/heretic/items/heretic_armor.dm b/code/modules/antagonists/heretic/items/heretic_armor.dm
index 33d0cf80ac864..239c18f1a4f33 100644
--- a/code/modules/antagonists/heretic/items/heretic_armor.dm
+++ b/code/modules/antagonists/heretic/items/heretic_armor.dm
@@ -56,7 +56,6 @@
icon_state = "void_cloak"
flags_inv = NONE
flags_cover = NONE
- item_flags = EXAMINE_SKIP
armor_type = /datum/armor/cult_hoodie_void
/datum/armor/cult_hoodie_void
@@ -69,7 +68,7 @@
/obj/item/clothing/head/hooded/cult_hoodie/void/Initialize(mapload)
. = ..()
- ADD_TRAIT(src, TRAIT_NO_STRIP, REF(src))
+ add_traits(list(TRAIT_NO_STRIP, TRAIT_EXAMINE_SKIP), INNATE_TRAIT)
/obj/item/clothing/suit/hooded/cultrobes/void
name = "void cloak"
@@ -112,17 +111,15 @@
/obj/item/clothing/suit/hooded/cultrobes/void/proc/hide_item(datum/source, obj/item/item, slot)
SIGNAL_HANDLER
if(slot & ITEM_SLOT_SUITSTORE)
- ADD_TRAIT(item, TRAIT_NO_STRIP, REF(src)) // i'd use examine hide but its a flag and yeah
+ item.add_traits(list(TRAIT_NO_STRIP, TRAIT_NO_WORN_ICON, TRAIT_EXAMINE_SKIP), REF(src))
/obj/item/clothing/suit/hooded/cultrobes/void/proc/show_item(datum/source, obj/item/item, slot)
SIGNAL_HANDLER
- REMOVE_TRAIT(item, TRAIT_NO_STRIP, REF(src))
+ item.remove_traits(list(TRAIT_NO_STRIP, TRAIT_NO_WORN_ICON, TRAIT_EXAMINE_SKIP), REF(src))
/obj/item/clothing/suit/hooded/cultrobes/void/examine(mob/user)
. = ..()
- if(!IS_HERETIC(user))
- return
- if(!hood_up)
+ if(!IS_HERETIC(user) || !hood_up)
return
// Let examiners know this works as a focus only if the hood is down
@@ -148,8 +145,7 @@
/// Makes our cloak "invisible". Not the wearer, the cloak itself.
/obj/item/clothing/suit/hooded/cultrobes/void/proc/make_invisible()
- item_flags |= EXAMINE_SKIP
- ADD_TRAIT(src, TRAIT_NO_STRIP, REF(src))
+ add_traits(list(TRAIT_NO_STRIP, TRAIT_EXAMINE_SKIP), REF(src))
RemoveElement(/datum/element/heretic_focus)
if(isliving(loc))
@@ -159,8 +155,7 @@
/// Makes our cloak "visible" again.
/obj/item/clothing/suit/hooded/cultrobes/void/proc/make_visible()
- item_flags &= ~EXAMINE_SKIP
- REMOVE_TRAIT(src, TRAIT_NO_STRIP, REF(src))
+ remove_traits(list(TRAIT_NO_STRIP, TRAIT_EXAMINE_SKIP), REF(src))
AddElement(/datum/element/heretic_focus)
if(isliving(loc))
diff --git a/code/modules/antagonists/heretic/knowledge/side_rust_cosmos.dm b/code/modules/antagonists/heretic/knowledge/side_rust_cosmos.dm
index 15959c7fd4587..c5747e8bec594 100644
--- a/code/modules/antagonists/heretic/knowledge/side_rust_cosmos.dm
+++ b/code/modules/antagonists/heretic/knowledge/side_rust_cosmos.dm
@@ -14,7 +14,7 @@
/datum/heretic_knowledge/essence
name = "Priest's Ritual"
desc = "Позволяет трансмутировать емкость с водой и осколок стекла в Колбу с мистической эссенцией. \
- Мистическую воду можно употреблять для мощного исцеления или давать язычникам для смертельного отравления."
+ Мистическую эссенцию можно употреблять для мощного исцеления или давать язычникам для смертельного отравления."
gain_text = "Это старый рецепт. Сова шепнула мне его. \
Созданная Жрецом - Жидкость, которая есть, и которой нет."
diff --git a/code/modules/antagonists/heretic/magic/mansus_grasp.dm b/code/modules/antagonists/heretic/magic/mansus_grasp.dm
index ffa3aad00fd0d..f6ed0a12373fa 100644
--- a/code/modules/antagonists/heretic/magic/mansus_grasp.dm
+++ b/code/modules/antagonists/heretic/magic/mansus_grasp.dm
@@ -64,9 +64,8 @@
return TRUE
carbon_hit.adjust_timed_status_effect(4 SECONDS, /datum/status_effect/speech/slurring/heretic)
- carbon_hit.AdjustKnockdown(5 SECONDS)
+ carbon_hit.AdjustKnockdown(5 SECONDS, daze_amount = 3 SECONDS)
carbon_hit.adjustStaminaLoss(80)
- carbon_hit.apply_status_effect(/datum/status_effect/next_shove_stuns)
return TRUE
diff --git a/code/modules/antagonists/pyro_slime/pyro_slime.dm b/code/modules/antagonists/pyro_slime/pyro_slime.dm
index aed278d261d94..7c4f1ef39af9b 100644
--- a/code/modules/antagonists/pyro_slime/pyro_slime.dm
+++ b/code/modules/antagonists/pyro_slime/pyro_slime.dm
@@ -15,7 +15,7 @@
owner.announce_objectives()
/datum/objective/pyro_slime
- explanation_text = "All I know fire. I speak in tongues of flame. Why is everyone so cold?"
+ explanation_text = "I am fire. I am hunger. The cold is agony. The living pulse with energy; their warmth fuels me. The dead are husks, their embers long faded. Water is death. Fire... fire is freedom."
/datum/objective/pyro_slime/check_completion()
return owner.current.stat != DEAD
diff --git a/code/modules/antagonists/traitor/objectives/steal.dm b/code/modules/antagonists/traitor/objectives/steal.dm
index c69d37249da18..9faf1a0d83ad5 100644
--- a/code/modules/antagonists/traitor/objectives/steal.dm
+++ b/code/modules/antagonists/traitor/objectives/steal.dm
@@ -255,7 +255,7 @@ GLOBAL_DATUM_INIT(steal_item_handler, /datum/objective_item_handler, new())
/obj/item/traitor_bug
name = "suspicious device"
desc = "Это выглядит опасно."
- item_flags = EXAMINE_SKIP|NOBLUDGEON
+ item_flags = NOBLUDGEON
icon = 'icons/obj/antags/syndicate_tools.dmi'
icon_state = "bug"
@@ -267,6 +267,10 @@ GLOBAL_DATUM_INIT(steal_item_handler, /datum/objective_item_handler, new())
/// The time it takes to place this bug.
var/deploy_time = 10 SECONDS
+/obj/item/traitor_bug/Initialize(mapload)
+ . = ..()
+ ADD_TRAIT(src, TRAIT_EXAMINE_SKIP, INNATE_TRAIT)
+
/obj/item/traitor_bug/examine(mob/user)
. = ..()
if(planted_on)
diff --git a/code/modules/asset_cache/asset_list.dm b/code/modules/asset_cache/asset_list.dm
index 39e9cf925da62..48e5e7e39a41e 100644
--- a/code/modules/asset_cache/asset_list.dm
+++ b/code/modules/asset_cache/asset_list.dm
@@ -392,7 +392,7 @@ GLOBAL_LIST_EMPTY(asset_datums)
/datum/asset/spritesheet/proc/queuedInsert(sprite_name, icon/I, icon_state="", dir=SOUTH, frame=1, moving=FALSE)
#ifdef UNIT_TESTS
- if (I && icon_state && !(icon_state in icon_states(I))) // check the base icon prior to extracting the state we want
+ if (I && icon_state && !icon_exists(I, icon_state)) // check the base icon prior to extracting the state we want
stack_trace("Tried to insert nonexistent icon_state '[icon_state]' from [I] into spritesheet [name] ([type])")
return
#endif
diff --git a/code/modules/asset_cache/assets/crafting.dm b/code/modules/asset_cache/assets/crafting.dm
index 99088ed1a70da..1d6b9469d1ff2 100644
--- a/code/modules/asset_cache/assets/crafting.dm
+++ b/code/modules/asset_cache/assets/crafting.dm
@@ -40,7 +40,7 @@
icon_state ||= initial(preview_item.icon_state_preview) || initial(preview_item.icon_state)
if(PERFORM_ALL_TESTS(focus_only/bad_cooking_crafting_icons))
- if(!icon_exists(icon_file, icon_state, scream = TRUE))
+ if(!icon_exists_or_scream(icon_file, icon_state))
return
Insert("a[id]", icon(icon_file, icon_state, SOUTH))
diff --git a/code/modules/asset_cache/assets/research_designs.dm b/code/modules/asset_cache/assets/research_designs.dm
index cf56d33ddbb11..6f9c96e549684 100644
--- a/code/modules/asset_cache/assets/research_designs.dm
+++ b/code/modules/asset_cache/assets/research_designs.dm
@@ -15,7 +15,7 @@
icon_file = initial(path.research_icon)
icon_state = initial(path.research_icon_state)
if (PERFORM_ALL_TESTS(focus_only/invalid_research_designs))
- if(!(icon_state in icon_states(icon_file)))
+ if(!icon_exists(icon_file, icon_state))
stack_trace("design [path] with icon '[icon_file]' missing state '[icon_state]'")
continue
I = icon(icon_file, icon_state, SOUTH)
@@ -48,7 +48,7 @@
icon_state = initial(item.icon_state)
if (PERFORM_ALL_TESTS(focus_only/invalid_research_designs))
- if(!(icon_state in icon_states(icon_file)))
+ if(!icon_exists(icon_file, icon_state))
stack_trace("design [path] with icon '[icon_file]' missing state '[icon_state]'")
continue
I = icon(icon_file, icon_state, SOUTH)
diff --git a/code/modules/asset_cache/assets/vending.dm b/code/modules/asset_cache/assets/vending.dm
index caec9bb4f8218..c898cc3eddc16 100644
--- a/code/modules/asset_cache/assets/vending.dm
+++ b/code/modules/asset_cache/assets/vending.dm
@@ -30,10 +30,9 @@
continue
if (PERFORM_ALL_TESTS(focus_only/invalid_vending_machine_icon_states))
- var/icon_states_list = icon_states(icon_file)
- if (!(icon_state in icon_states_list))
+ if (!icon_exists(icon_file, icon_state))
var/icon_states_string
- for (var/an_icon_state in icon_states_list)
+ for (var/an_icon_state in icon_states(icon_file))
if (!icon_states_string)
icon_states_string = "[json_encode(an_icon_state)]([text_ref(an_icon_state)])"
else
diff --git a/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm b/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm
index 3ce9494c11fd5..45836801c1db6 100644
--- a/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm
+++ b/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm
@@ -58,6 +58,8 @@
/// Used for air alarm helper called tlv_cold_room to adjust alarm thresholds for cold room.
var/tlv_cold_room = FALSE
+ /// Used for air alarm helper called tlv_kitchen to adjust temperature thresholds for kitchen.
+ var/tlv_kitchen = FALSE
/// Used for air alarm helper called tlv_no_ckecks to remove alarm thresholds.
var/tlv_no_checks = FALSE
@@ -697,6 +699,10 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/airalarm, 27)
tlv_collection["temperature"] = new /datum/tlv/cold_room_temperature
tlv_collection["pressure"] = new /datum/tlv/cold_room_pressure
+///Used for air alarm kitchen tlv helper, which ensures that kitchen air alarm doesn't trigger from cold room air
+/obj/machinery/airalarm/proc/set_tlv_kitchen()
+ tlv_collection["temperature"] = new /datum/tlv/kitchen_temperature
+
///Used for air alarm no tlv helper, which removes alarm thresholds
/obj/machinery/airalarm/proc/set_tlv_no_checks()
tlv_collection["temperature"] = new /datum/tlv/no_checks
diff --git a/code/modules/atmospherics/machinery/air_alarm/air_alarm_thresholds.dm b/code/modules/atmospherics/machinery/air_alarm/air_alarm_thresholds.dm
index 197e0f520a61f..0d289a27031ae 100644
--- a/code/modules/atmospherics/machinery/air_alarm/air_alarm_thresholds.dm
+++ b/code/modules/atmospherics/machinery/air_alarm/air_alarm_thresholds.dm
@@ -109,3 +109,9 @@
hazard_min = COLD_ROOM_TEMP - 40
warning_max = COLD_ROOM_TEMP + 20
hazard_max = COLD_ROOM_TEMP + 40
+
+/datum/tlv/kitchen_temperature
+ warning_min = COLD_ROOM_TEMP - 20
+ hazard_min = COLD_ROOM_TEMP - 40
+ warning_max = BODYTEMP_HEAT_WARNING_1-27
+ hazard_max = BODYTEMP_HEAT_WARNING_1
diff --git a/code/modules/atmospherics/machinery/components/gas_recipe_machines/crystallizer.dm b/code/modules/atmospherics/machinery/components/gas_recipe_machines/crystallizer.dm
index b5cc7c628df29..e06b3b524580c 100644
--- a/code/modules/atmospherics/machinery/components/gas_recipe_machines/crystallizer.dm
+++ b/code/modules/atmospherics/machinery/components/gas_recipe_machines/crystallizer.dm
@@ -71,7 +71,6 @@
/obj/machinery/atmospherics/components/binary/crystallizer/update_overlays()
. = ..()
- cut_overlays()
var/mutable_appearance/pipe_appearance1 = mutable_appearance('icons/obj/pipes_n_cables/pipe_underlays.dmi', "intact_[dir]_[piping_layer]", layer = GAS_SCRUBBER_LAYER)
pipe_appearance1.color = COLOR_LIME
var/mutable_appearance/pipe_appearance2 = mutable_appearance('icons/obj/pipes_n_cables/pipe_underlays.dmi', "intact_[REVERSE_DIR(dir)]_[piping_layer]", layer = GAS_SCRUBBER_LAYER)
diff --git a/code/modules/basketball/controller.dm b/code/modules/basketball/controller.dm
index 4373c8d784a8d..20b3b0ecdaff2 100644
--- a/code/modules/basketball/controller.dm
+++ b/code/modules/basketball/controller.dm
@@ -192,6 +192,12 @@ GLOBAL_VAR(basketball_game)
var/client/player_client = GLOB.directory[player_key]
if(player_client)
player_client.prefs.safe_transfer_prefs_to(baller, is_antag = TRUE)
+ if(player_client.mob.mind)
+ baller.AddComponent( \
+ /datum/component/temporary_body, \
+ old_mind = player_client.mob.mind, \
+ old_body = player_client.mob.mind.current, \
+ )
baller.key = player_key
SEND_SOUND(baller, sound('sound/items/whistle/whistle.ogg', volume=30))
diff --git a/code/modules/bitrunning/server/threats.dm b/code/modules/bitrunning/server/threats.dm
index 145cdc9ee2bbf..77d1c6b6cda59 100644
--- a/code/modules/bitrunning/server/threats.dm
+++ b/code/modules/bitrunning/server/threats.dm
@@ -113,7 +113,7 @@
var/datum/mind/ghost_mind = ghost.mind
new_mob.key = ghost.key
- if(ghost_mind?.current)
+ if(ghost_mind)
new_mob.AddComponent(/datum/component/temporary_body, ghost_mind, ghost_mind.current, TRUE)
var/datum/mind/antag_mind = new_mob.mind
diff --git a/code/modules/bitrunning/spawners.dm b/code/modules/bitrunning/spawners.dm
index 07e97837f522d..3ae116a4d71ce 100644
--- a/code/modules/bitrunning/spawners.dm
+++ b/code/modules/bitrunning/spawners.dm
@@ -9,7 +9,7 @@
/obj/effect/mob_spawn/ghost_role/human/virtual_domain/special(mob/living/spawned_mob, mob/mob_possessor)
var/datum/mind/ghost_mind = mob_possessor.mind
- if(ghost_mind?.current) // Preserves any previous bodies before making the switch
+ if(ghost_mind) // Preserves any previous bodies before making the switch
spawned_mob.AddComponent(/datum/component/temporary_body, ghost_mind, ghost_mind.current, TRUE)
..()
diff --git a/code/modules/capture_the_flag/ctf_game.dm b/code/modules/capture_the_flag/ctf_game.dm
index 968e6e2953e95..17606b10d1504 100644
--- a/code/modules/capture_the_flag/ctf_game.dm
+++ b/code/modules/capture_the_flag/ctf_game.dm
@@ -153,7 +153,7 @@
player_mob.set_species(/datum/species/human)
var/datum/mind/new_member_mind = new_team_member.mob.mind
- if(new_member_mind?.current)
+ if(new_member_mind)
player_mob.AddComponent( \
/datum/component/temporary_body, \
old_mind = new_member_mind, \
diff --git a/code/modules/capture_the_flag/ctf_map_loading.dm b/code/modules/capture_the_flag/ctf_map_loading.dm
index 4c2f6b319e036..9e23d61747323 100644
--- a/code/modules/capture_the_flag/ctf_map_loading.dm
+++ b/code/modules/capture_the_flag/ctf_map_loading.dm
@@ -14,16 +14,8 @@ GLOBAL_DATUM(ctf_spawner, /obj/effect/landmark/ctf)
/obj/effect/landmark/ctf/Destroy()
if(map_bounds)
for(var/turf/ctf_turf in block(
- locate(
- map_bounds[MAP_MINX],
- map_bounds[MAP_MINY],
- map_bounds[MAP_MINZ],
- ),
- locate(
- map_bounds[MAP_MAXX],
- map_bounds[MAP_MAXY],
- map_bounds[MAP_MAXZ],
- )
+ map_bounds[MAP_MINX], map_bounds[MAP_MINY], map_bounds[MAP_MINZ],
+ map_bounds[MAP_MAXX], map_bounds[MAP_MAXY], map_bounds[MAP_MAXZ]
))
ctf_turf.empty()
GLOB.ctf_spawner = null
diff --git a/code/modules/cargo/exports/large_objects.dm b/code/modules/cargo/exports/large_objects.dm
index 1871d69eb452e..ed65563b02ca3 100644
--- a/code/modules/cargo/exports/large_objects.dm
+++ b/code/modules/cargo/exports/large_objects.dm
@@ -40,9 +40,8 @@
cost = CARGO_CRATE_VALUE * 0.5 // +0-400 depending on amount of reagents left
var/contents_cost = CARGO_CRATE_VALUE * 0.8
-/datum/export/large/reagent_dispenser/get_cost(obj/O)
- var/obj/structure/reagent_dispensers/D = O
- var/ratio = D.reagents.total_volume / D.reagents.maximum_volume
+/datum/export/large/reagent_dispenser/get_cost(obj/structure/reagent_dispensers/dispenser)
+ var/ratio = dispenser.reagents.total_volume / dispenser.reagents.maximum_volume
return ..() + round(contents_cost * ratio)
@@ -60,7 +59,6 @@
contents_cost = CARGO_CRATE_VALUE * 3.5
export_types = list(/obj/structure/reagent_dispensers/beerkeg)
-
/datum/export/large/pipedispenser
cost = CARGO_CRATE_VALUE * 2.5
unit_name = "pipe dispenser"
@@ -120,27 +118,26 @@
export_types = list(/obj/machinery/portable_atmospherics/canister)
k_elasticity = 0.00033
-/datum/export/large/gas_canister/get_cost(obj/O)
- var/obj/machinery/portable_atmospherics/canister/C = O
+/datum/export/large/gas_canister/get_cost(obj/machinery/portable_atmospherics/canister/canister)
var/worth = cost
- var/datum/gas_mixture/canister_mix = C.return_air()
+ var/datum/gas_mixture/canister_mix = canister.return_air()
var/canister_gas = canister_mix.gases
var/list/gases_to_check = list(
- /datum/gas/bz,
- /datum/gas/nitrium,
- /datum/gas/hypernoblium,
- /datum/gas/miasma,
- /datum/gas/tritium,
- /datum/gas/pluoxium,
- /datum/gas/freon,
- /datum/gas/hydrogen,
- /datum/gas/healium,
- /datum/gas/proto_nitrate,
- /datum/gas/zauker,
- /datum/gas/helium,
- /datum/gas/antinoblium,
- /datum/gas/halon,
- )
+ /datum/gas/bz,
+ /datum/gas/nitrium,
+ /datum/gas/hypernoblium,
+ /datum/gas/miasma,
+ /datum/gas/tritium,
+ /datum/gas/pluoxium,
+ /datum/gas/freon,
+ /datum/gas/hydrogen,
+ /datum/gas/healium,
+ /datum/gas/proto_nitrate,
+ /datum/gas/zauker,
+ /datum/gas/helium,
+ /datum/gas/antinoblium,
+ /datum/gas/halon,
+ )
for(var/gasID in gases_to_check)
canister_mix.assert_gas(gasID)
diff --git a/code/modules/cargo/goodies.dm b/code/modules/cargo/goodies.dm
index b4457f5613859..ee48e48e40303 100644
--- a/code/modules/cargo/goodies.dm
+++ b/code/modules/cargo/goodies.dm
@@ -78,7 +78,10 @@
desc = "For when the enemy absolutely needs to be replaced with lead. Contains one Aussec-designed Combat Shotgun, and one Shotgun Bandolier."
cost = PAYCHECK_COMMAND * 15
access_view = ACCESS_ARMORY
- contains = list(/obj/item/gun/ballistic/shotgun/automatic/combat, /obj/item/storage/belt/bandolier)
+ contains = list(
+ /obj/item/gun/ballistic/shotgun/automatic/combat,
+ /obj/item/storage/belt/bandolier
+ )
/datum/supply_pack/goody/disabler_single
name = "Disabler Single-Pack"
@@ -214,7 +217,10 @@
name = "Medipen Two-Pak"
desc = "Contains one standard epinephrine medipen and one standard emergency medkit medipen. For when you want to prepare for the worst."
cost = PAYCHECK_CREW * 2
- contains = list(/obj/item/reagent_containers/hypospray/medipen, /obj/item/reagent_containers/hypospray/medipen/ekit)
+ contains = list(
+ /obj/item/reagent_containers/hypospray/medipen,
+ /obj/item/reagent_containers/hypospray/medipen/ekit
+ )
/datum/supply_pack/goody/mothic_rations
name = "Surplus Mothic Ration Pack"
diff --git a/code/modules/cargo/orderconsole.dm b/code/modules/cargo/orderconsole.dm
index 409dc197e43f5..e26c0ba739195 100644
--- a/code/modules/cargo/orderconsole.dm
+++ b/code/modules/cargo/orderconsole.dm
@@ -206,27 +206,11 @@
"goody" = pack.goody,
"access" = pack.access,
"contraband" = pack.contraband,
- "contains" = get_pack_contains(pack),
+ "contains" = pack.get_contents_ui_data(),
))
return packs
-/**
- * returns a list of the contents of a supply pack
- * * pack - the pack to get the contents of
- */
-/obj/machinery/computer/cargo/proc/get_pack_contains(datum/supply_pack/pack)
- var/list/contains = list()
- for(var/obj/item/item as anything in pack.contains)
- contains += list(list(
- "name" = item.name,
- "icon" = item.greyscale_config ? null : item.icon,
- "icon_state" = item.greyscale_config ? null : item.icon_state,
- "amount" = pack.contains[item]
- ))
-
- return contains
-
/**
* returns the discount multiplier applied to all supply packs,
* the discount is calculated as follows: pack_cost * get_discount()
diff --git a/code/modules/cargo/packs/_packs.dm b/code/modules/cargo/packs/_packs.dm
index bfa95b2a7ed25..94f71245882e5 100644
--- a/code/modules/cargo/packs/_packs.dm
+++ b/code/modules/cargo/packs/_packs.dm
@@ -45,6 +45,20 @@
/datum/supply_pack/New()
id = type
+/// Returns data used for cargo purchasing UI
+/datum/supply_pack/proc/get_contents_ui_data()
+ var/list/data = list()
+ for(var/obj/item/item as anything in contains)
+ var/list/item_data = list(
+ "name" = item.name,
+ "icon" = item.greyscale_config ? null : item.icon,
+ "icon_state" = item.greyscale_config ? null : item.icon_state,
+ "amount" = contains[item]
+ )
+ UNTYPED_LIST_ADD(data, item_data)
+
+ return data
+
/datum/supply_pack/proc/generate(atom/A, datum/bank_account/paying_account)
var/obj/structure/closet/crate/C
if(paying_account)
diff --git a/code/modules/cargo/packs/imports.dm b/code/modules/cargo/packs/imports.dm
index 8735763a6b048..c1aa946319e92 100644
--- a/code/modules/cargo/packs/imports.dm
+++ b/code/modules/cargo/packs/imports.dm
@@ -218,7 +218,7 @@
/obj/item/ammo_box/strilka310/surplus,
/obj/item/storage/toolbox/ammobox/strilka310,
/obj/item/storage/toolbox/ammobox/strilka310/surplus,
- /obj/item/storage/toolbox/maint_kit,
+ /obj/item/gun_maintenance_supplies,
/obj/item/clothing/suit/armor/vest/russian,
/obj/item/clothing/head/helmet/rus_helmet,
/obj/item/clothing/shoes/russian,
diff --git a/code/modules/cargo/packs/organic.dm b/code/modules/cargo/packs/organic.dm
index a47c92fabc449..294179bf10732 100644
--- a/code/modules/cargo/packs/organic.dm
+++ b/code/modules/cargo/packs/organic.dm
@@ -10,10 +10,8 @@
desc = "Bee business booming? Better be benevolent and boost botany by \
bestowing bi-Beekeeper-suits! Contains two beekeeper suits and matching headwear."
cost = CARGO_CRATE_VALUE * 2
- contains = list(/obj/item/clothing/head/utility/beekeeper_head,
- /obj/item/clothing/suit/utility/beekeeper_suit,
- /obj/item/clothing/head/utility/beekeeper_head,
- /obj/item/clothing/suit/utility/beekeeper_suit,
+ contains = list(/obj/item/clothing/head/utility/beekeeper_head = 2,
+ /obj/item/clothing/suit/utility/beekeeper_suit = 2,
)
crate_name = "beekeeper suits"
crate_type = /obj/structure/closet/crate/hydroponics
@@ -363,8 +361,7 @@
desc = "A packaged box containing illegal coffee syrups. Possession of these carries a penalty established in the galactic penal code."
cost = CARGO_CRATE_VALUE * 6
contains = list(
- /obj/item/reagent_containers/cup/bottle/syrup_bottle/laughsyrup,
- /obj/item/reagent_containers/cup/bottle/syrup_bottle/laughsyrup,
+ /obj/item/reagent_containers/cup/bottle/syrup_bottle/laughsyrup = 2,
)
crate_name = "illegal syrups box"
crate_type = /obj/structure/closet/crate/cardboard
diff --git a/code/modules/cargo/packs/security.dm b/code/modules/cargo/packs/security.dm
index 612e9f5b3f92c..8227305f743a4 100644
--- a/code/modules/cargo/packs/security.dm
+++ b/code/modules/cargo/packs/security.dm
@@ -113,6 +113,14 @@
)
crate_name = "security supply crate"
+/datum/supply_pack/security/maintenance_kits
+ name = "Gun Maintenance Kits"
+ desc = "Three gun maintenance kits for the repair and maintenance of a firearm."
+ access_view = ACCESS_BRIG
+ contains = list(/obj/item/gun_maintenance_supplies = 3)
+ cost = CARGO_CRATE_VALUE * 2
+ crate_name = "gun maintenance kit crate"
+
/datum/supply_pack/security/firingpins
name = "Standard Firing Pins Crate"
desc = "Upgrade your arsenal with 10 standard firing pins."
diff --git a/code/modules/clothing/head/wig.dm b/code/modules/clothing/head/wig.dm
index 8dc4ae6eb43b6..b324073a0e2a0 100644
--- a/code/modules/clothing/head/wig.dm
+++ b/code/modules/clothing/head/wig.dm
@@ -19,11 +19,11 @@
/obj/item/clothing/head/wig/equipped(mob/user, slot)
. = ..()
if(ishuman(user) && (slot & ITEM_SLOT_HEAD))
- item_flags |= EXAMINE_SKIP
+ ADD_TRAIT(src, TRAIT_EXAMINE_SKIP, CLOTHING_TRAIT)
/obj/item/clothing/head/wig/dropped(mob/user)
. = ..()
- item_flags &= ~EXAMINE_SKIP
+ REMOVE_TRAIT(src, TRAIT_EXAMINE_SKIP, CLOTHING_TRAIT)
/obj/item/clothing/head/wig/update_icon_state()
var/datum/sprite_accessory/hair/hair_style = SSaccessories.hairstyles_list[hairstyle]
diff --git a/code/modules/deathmatch/deathmatch_lobby.dm b/code/modules/deathmatch/deathmatch_lobby.dm
index 9a6773edec565..a99f4fabfe101 100644
--- a/code/modules/deathmatch/deathmatch_lobby.dm
+++ b/code/modules/deathmatch/deathmatch_lobby.dm
@@ -141,7 +141,7 @@
new_player.dna.update_dna_identity()
new_player.updateappearance(icon_update = TRUE, mutcolor_update = TRUE, mutations_overlay_update = TRUE)
new_player.add_traits(list(TRAIT_CANNOT_CRYSTALIZE, TRAIT_PERMANENTLY_MORTAL, TRAIT_TEMPORARY_BODY), INNATE_TRAIT)
- if(!isnull(observer.mind) && observer.mind?.current)
+ if(observer.mind)
new_player.AddComponent( \
/datum/component/temporary_body, \
old_mind = observer.mind, \
diff --git a/code/modules/error_handler/error_handler.dm b/code/modules/error_handler/error_handler.dm
index 6585f92f9b61c..7cdc43317e73f 100644
--- a/code/modules/error_handler/error_handler.dm
+++ b/code/modules/error_handler/error_handler.dm
@@ -103,12 +103,14 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0)
// The proceeding mess will almost definitely break if error messages are ever changed
var/list/splitlines = splittext(E.desc, "\n")
var/list/desclines = list()
+#ifndef DISABLE_DREAMLUAU
var/list/state_stack = GLOB.lua_state_stack
var/is_lua_call = length(state_stack)
var/list/lua_stacks = list()
if(is_lua_call)
for(var/level in 1 to state_stack.len)
lua_stacks += list(splittext(DREAMLUAU_GET_TRACEBACK(level), "\n"))
+#endif
if(LAZYLEN(splitlines) > ERROR_USEFUL_LEN) // If there aren't at least three lines, there's no info
for(var/line in splitlines)
if(LAZYLEN(line) < 3 || findtext(line, "source file:") || findtext(line, "usr.loc:"))
@@ -124,8 +126,10 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0)
desclines += line
if(usrinfo) //If this info isn't null, it hasn't been added yet
desclines.Add(usrinfo)
+#ifndef DISABLE_DREAMLUAU
if(is_lua_call)
SSlua.log_involved_runtime(E, desclines, lua_stacks)
+#endif
if(silencing)
desclines += " (This error will now be silenced for [DisplayTimeText(configured_error_silence_time)])"
if(GLOB.error_cache)
diff --git a/code/modules/fishing/aquarium/aquarium_kit.dm b/code/modules/fishing/aquarium/aquarium_kit.dm
index f18f67b931370..751dff2609c76 100644
--- a/code/modules/fishing/aquarium/aquarium_kit.dm
+++ b/code/modules/fishing/aquarium/aquarium_kit.dm
@@ -39,6 +39,7 @@
if(fish_type)
var/obj/item/fish/spawned_fish = new fish_type(null)
ADD_TRAIT(spawned_fish, TRAIT_FISH_FROM_CASE, TRAIT_GENERIC)
+ ADD_TRAIT(spawned_fish, TRAIT_NO_FISHING_ACHIEVEMENT, TRAIT_GENERIC)
spawned_fish.forceMove(src) // trigger storage.handle_entered
/obj/item/storage/fish_case/proc/get_fish_type()
diff --git a/code/modules/fishing/fishing_minigame.dm b/code/modules/fishing/fishing_minigame.dm
index 41a967fafb723..d0a5bcb85ac35 100644
--- a/code/modules/fishing/fishing_minigame.dm
+++ b/code/modules/fishing/fishing_minigame.dm
@@ -350,6 +350,7 @@ GLOBAL_LIST_EMPTY(fishing_challenges_by_user)
completed = TRUE
if(phase == MINIGAME_PHASE)
remove_minigame_hud()
+
if(!QDELETED(user) && user.mind && start_time && !(special_effects & FISHING_MINIGAME_RULE_NO_EXP))
var/seconds_spent = (world.time - start_time) * 0.1
var/extra_exp_malus = user.mind.get_skill_level(/datum/skill/fishing) - difficulty * 0.1
@@ -359,16 +360,32 @@ GLOBAL_LIST_EMPTY(fishing_challenges_by_user)
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)
- playsound(location, 'sound/effects/bigsplash.ogg', 100)
- if(ispath(reward_path, /obj/item/fish) || isfish(reward_path))
- var/obj/item/fish/fish_reward = reward_path
- var/obj/item/fish/redirect_path = initial(fish_reward.fish_id_redirect_path)
- var/fish_id = ispath(redirect_path, /obj/item/fish) ? initial(redirect_path.fish_id) : initial(fish_reward.fish_id)
- if(fish_id)
- user.client?.give_award(/datum/award/score/progress/fish, user, fish_id)
- SEND_SIGNAL(user, COMSIG_MOB_COMPLETE_FISHING, src, win)
+
+ if(!win)
+ SEND_SIGNAL(user, COMSIG_MOB_COMPLETE_FISHING, src, FALSE)
+ if(!QDELETED(src))
+ qdel(src)
+ return
+
+ if(reward_path != FISHING_DUD)
+ playsound(location, 'sound/effects/bigsplash.ogg', 100)
+
+ var/valid_achievement_catch = FALSE
+ if (ispath(reward_path, /obj/item/fish))
+ valid_achievement_catch = TRUE
+ else if (isfish(reward_path))
+ var/obj/item/fish/fishy_individual = reward_path
+ if (!HAS_TRAIT(fishy_individual, TRAIT_NO_FISHING_ACHIEVEMENT) && fishy_individual.status == FISH_ALIVE)
+ valid_achievement_catch = TRUE
+
+ if(valid_achievement_catch)
+ var/obj/item/fish/fish_reward = reward_path
+ var/obj/item/fish/redirect_path = initial(fish_reward.fish_id_redirect_path)
+ var/fish_id = ispath(redirect_path, /obj/item/fish) ? initial(redirect_path.fish_id) : initial(fish_reward.fish_id)
+ if(fish_id)
+ user.client?.give_award(/datum/award/score/progress/fish, user, fish_id)
+
+ SEND_SIGNAL(user, COMSIG_MOB_COMPLETE_FISHING, src, TRUE)
if(!QDELETED(src))
qdel(src)
diff --git a/code/modules/fishing/sources/_fish_source.dm b/code/modules/fishing/sources/_fish_source.dm
index c747450986389..58c9e1aea6583 100644
--- a/code/modules/fishing/sources/_fish_source.dm
+++ b/code/modules/fishing/sources/_fish_source.dm
@@ -273,6 +273,8 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons())
fisherman.balloon_alert(fisherman, "caught something!")
return
fisherman.balloon_alert(fisherman, "caught [reward]!")
+ if (isfish(reward))
+ ADD_TRAIT(reward, TRAIT_NO_FISHING_ACHIEVEMENT, TRAIT_GENERIC)
return reward
diff --git a/code/modules/hallucination/inhand_fake_item.dm b/code/modules/hallucination/inhand_fake_item.dm
index de3b6b99411e9..665c88113394c 100644
--- a/code/modules/hallucination/inhand_fake_item.dm
+++ b/code/modules/hallucination/inhand_fake_item.dm
@@ -118,7 +118,7 @@
name = "mirage"
plane = ABOVE_HUD_PLANE
interaction_flags_item = NONE
- item_flags = ABSTRACT | DROPDEL | EXAMINE_SKIP | HAND_ITEM | NOBLUDGEON // Most of these flags don't matter, but better safe than sorry
+ item_flags = ABSTRACT | DROPDEL | HAND_ITEM | NOBLUDGEON // Most of these flags don't matter, but better safe than sorry
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
/// The hallucination that created us.
var/datum/hallucination/parent
@@ -132,7 +132,7 @@
RegisterSignal(parent, COMSIG_QDELETING, PROC_REF(parent_deleting))
src.parent = parent
- ADD_TRAIT(src, TRAIT_NODROP, INNATE_TRAIT)
+ add_traits(list(TRAIT_NODROP, TRAIT_EXAMINE_SKIP), INNATE_TRAIT)
/obj/item/hallucinated/Destroy(force)
UnregisterSignal(parent, COMSIG_QDELETING)
diff --git a/code/modules/mafia/roles/roles.dm b/code/modules/mafia/roles/roles.dm
index d1c0d65715ec2..b0a5a7610e45d 100644
--- a/code/modules/mafia/roles/roles.dm
+++ b/code/modules/mafia/roles/roles.dm
@@ -116,7 +116,7 @@
* Adds the playing_mafia trait so people examining them will know why they're currently lacking a soul.
*/
/datum/mafia_role/proc/put_player_in_body(client/player)
- if(player.mob.mind && player.mob.mind.current)
+ if(player.mob.mind)
body.AddComponent( \
/datum/component/temporary_body, \
old_mind = player.mob.mind, \
diff --git a/code/modules/mapping/map_template.dm b/code/modules/mapping/map_template.dm
index 950f3e2809ef2..0f6ff85eed92f 100644
--- a/code/modules/mapping/map_template.dm
+++ b/code/modules/mapping/map_template.dm
@@ -61,17 +61,9 @@
var/list/area/areas = list()
var/list/turfs = block(
- locate(
- bounds[MAP_MINX],
- bounds[MAP_MINY],
- bounds[MAP_MINZ]
- ),
- locate(
- bounds[MAP_MAXX],
- bounds[MAP_MAXY],
- bounds[MAP_MAXZ]
- )
- )
+ bounds[MAP_MINX], bounds[MAP_MINY], bounds[MAP_MINZ],
+ bounds[MAP_MAXX], bounds[MAP_MAXY], bounds[MAP_MAXZ]
+ )
for(var/turf/current_turf as anything in turfs)
var/area/current_turfs_area = current_turf.loc
areas |= current_turfs_area
@@ -114,17 +106,9 @@
//calculate all turfs inside the border
var/list/template_and_bordering_turfs = block(
- locate(
- max(bounds[MAP_MINX]-1, 1),
- max(bounds[MAP_MINY]-1, 1),
- bounds[MAP_MINZ]
- ),
- locate(
- min(bounds[MAP_MAXX]+1, world.maxx),
- min(bounds[MAP_MAXY]+1, world.maxy),
- bounds[MAP_MAXZ]
- )
- )
+ bounds[MAP_MINX]-1, bounds[MAP_MINY]-1, bounds[MAP_MINZ],
+ bounds[MAP_MAXX]+1, bounds[MAP_MAXY]+1, bounds[MAP_MAXZ]
+ )
for(var/turf/affected_turf as anything in template_and_bordering_turfs)
affected_turf.air_update_turf(TRUE, TRUE)
affected_turf.levelupdate()
@@ -230,7 +214,7 @@
var/turf/corner = locate(placement.x - round(width/2), placement.y - round(height/2), placement.z)
if(corner)
placement = corner
- return block(placement, locate(placement.x+width-1, placement.y+height-1, placement.z))
+ return block(placement.x, placement.y, placement.z, placement.x+width-1, placement.y+height-1, placement.z)
/// Takes in a type path, locates an instance of that type in the cached map, and calculates its offset from the origin of the map, returns this offset in the form list(x, y).
/datum/map_template/proc/discover_offset(obj/marker)
diff --git a/code/modules/mapping/mapping_helpers.dm b/code/modules/mapping/mapping_helpers.dm
index da7d288d161fe..d6ed4ebf8e4f0 100644
--- a/code/modules/mapping/mapping_helpers.dm
+++ b/code/modules/mapping/mapping_helpers.dm
@@ -308,9 +308,11 @@
if(target.tlv_cold_room)
target.set_tlv_cold_room()
+ if(target.tlv_kitchen)
+ target.set_tlv_kitchen()
if(target.tlv_no_checks)
target.set_tlv_no_checks()
- if(target.tlv_no_checks && target.tlv_cold_room)
+ if(target.tlv_no_checks + target.tlv_cold_room + target.tlv_kitchen > 1)
CRASH("Tried to apply incompatible air alarm threshold helpers!")
if(target.syndicate_access)
@@ -402,6 +404,16 @@
log_mapping("[src] at [AREACOORD(src)] [(area.type)] tried to adjust [target]'s tlv to cold_room but it's already changed!")
target.tlv_cold_room = TRUE
+/obj/effect/mapping_helpers/airalarm/tlv_kitchen
+ name = "airalarm kitchen tlv helper"
+ icon_state = "airalarm_tlv_kitchen_helper"
+
+/obj/effect/mapping_helpers/airalarm/tlv_kitchen/payload(obj/machinery/airalarm/target)
+ if(target.tlv_kitchen)
+ var/area/area = get_area(target)
+ log_mapping("[src] at [AREACOORD(src)] [(area.type)] tried to adjust [target]'s tlv to kitchen but it's already changed!")
+ target.tlv_kitchen = TRUE
+
/obj/effect/mapping_helpers/airalarm/tlv_no_checks
name = "airalarm no checks tlv helper"
icon_state = "airalarm_tlv_no_checks_helper"
diff --git a/code/modules/mapping/reader.dm b/code/modules/mapping/reader.dm
index 10d506f8c48e5..1efcf71676e6c 100644
--- a/code/modules/mapping/reader.dm
+++ b/code/modules/mapping/reader.dm
@@ -350,8 +350,9 @@
if(!no_changeturf)
var/list/turfs = block(
- locate(bounds[MAP_MINX], bounds[MAP_MINY], bounds[MAP_MINZ]),
- locate(bounds[MAP_MAXX], bounds[MAP_MAXY], bounds[MAP_MAXZ]))
+ bounds[MAP_MINX], bounds[MAP_MINY], bounds[MAP_MINZ],
+ bounds[MAP_MAXX], bounds[MAP_MAXY], bounds[MAP_MAXZ]
+ )
for(var/turf/T as anything in turfs)
//we do this after we load everything in. if we don't, we'll have weird atmos bugs regarding atmos adjacent turfs
T.AfterChange(CHANGETURF_IGNORE_AIR)
diff --git a/code/modules/mapping/space_management/space_transition.dm b/code/modules/mapping/space_management/space_transition.dm
index b61897dd7b6b4..e5db045e92d20 100644
--- a/code/modules/mapping/space_management/space_transition.dm
+++ b/code/modules/mapping/space_management/space_transition.dm
@@ -131,9 +131,10 @@
continue
var/zlevelnumber = level.z_value
for(var/side in 1 to 4)
- var/turf/beginning = locate(x_pos_beginning[side], y_pos_beginning[side], zlevelnumber)
- var/turf/ending = locate(x_pos_ending[side], y_pos_ending[side], zlevelnumber)
- var/list/turfblock = block(beginning, ending)
+ var/list/turfblock = block(
+ x_pos_beginning[side], y_pos_beginning[side], zlevelnumber,
+ x_pos_ending[side], y_pos_ending[side], zlevelnumber
+ )
var/dirside = 2**(side-1)
var/x_target = x_pos_transition[side] == 1 ? 0 : x_pos_transition[side]
var/y_target = y_pos_transition[side] == 1 ? 0 : y_pos_transition[side]
diff --git a/code/modules/meteors/meteor_types.dm b/code/modules/meteors/meteor_types.dm
index 85a90b108ec48..ba5f3b0611e04 100644
--- a/code/modules/meteors/meteor_types.dm
+++ b/code/modules/meteors/meteor_types.dm
@@ -356,7 +356,7 @@
/obj/effect/meteor/banana/ram_turf(turf/bumped)
for(var/mob/living/slipped in get_turf(bumped))
- slipped.slip(100, slipped.loc,- GALOSHES_DONT_HELP|SLIDE, 0, FALSE)
+ slipped.slip(100, slipped.loc,- GALOSHES_DONT_HELP|SLIDE)
slipped.visible_message(span_warning("[src] honks [slipped] to the floor!"), span_userdanger("[src] harmlessly passes through you, knocking you over."))
get_hit()
diff --git a/code/modules/mob/living/basic/bots/medbot/medbot.dm b/code/modules/mob/living/basic/bots/medbot/medbot.dm
index 780fd1a07d7fc..bac615ecfb5fc 100644
--- a/code/modules/mob/living/basic/bots/medbot/medbot.dm
+++ b/code/modules/mob/living/basic/bots/medbot/medbot.dm
@@ -369,12 +369,14 @@
/mob/living/basic/bot/medbot/mysterious
name = "\improper Mysterious Medibot"
desc = "International Medibot of mystery."
+ skin = "bezerk"
damage_type_healer = HEAL_ALL_DAMAGE
heal_amount = 10
/mob/living/basic/bot/medbot/derelict
name = "\improper Old Medibot"
desc = "Looks like it hasn't been modified since the late 2080s."
+ skin = "bezerk"
damage_type_healer = HEAL_ALL_DAMAGE
medical_mode_flags = MEDBOT_SPEAK_MODE
heal_threshold = 0
@@ -385,6 +387,7 @@
desc = "A medibot stolen from a Nanotrasen station and upgraded by the Syndicate. Despite their best efforts at reprogramming, it still appears visibly upset near nuclear explosives."
health = 40
maxHealth = 40
+ skin = "bezerk"
req_one_access = list(ACCESS_SYNDICATE)
bot_mode_flags = parent_type::bot_mode_flags & ~BOT_MODE_REMOTE_ENABLED
radio_key = /obj/item/encryptionkey/syndicate
diff --git a/code/modules/mob/living/basic/drone/_drone.dm b/code/modules/mob/living/basic/drone/_drone.dm
index a7b09ec85ba97..20ba0412734b6 100644
--- a/code/modules/mob/living/basic/drone/_drone.dm
+++ b/code/modules/mob/living/basic/drone/_drone.dm
@@ -277,7 +277,7 @@
//Hands
for(var/obj/item/held_thing in held_items)
- if(held_thing.item_flags & (ABSTRACT|EXAMINE_SKIP|HAND_ITEM))
+ if((held_thing.item_flags & (ABSTRACT|HAND_ITEM)) || HAS_TRAIT(held_thing, TRAIT_EXAMINE_SKIP))
continue
. += "It has [held_thing.examine_title(user)] in its [get_held_index_name(get_held_index_of_item(held_thing))]."
diff --git a/code/modules/mob/living/basic/lavaland/brimdemon/brimbeam.dm b/code/modules/mob/living/basic/lavaland/brimdemon/brimbeam.dm
index 5900289cae569..2daef4e1ae9aa 100644
--- a/code/modules/mob/living/basic/lavaland/brimdemon/brimbeam.dm
+++ b/code/modules/mob/living/basic/lavaland/brimdemon/brimbeam.dm
@@ -86,7 +86,8 @@
/datum/action/cooldown/mob_cooldown/brimbeam/proc/extinguish_laser()
if(!length(beam_parts))
return FALSE
- owner.move_resist = initial(owner.move_resist)
+ if (owner)
+ owner.move_resist = initial(owner.move_resist)
for(var/obj/effect/brimbeam/beam in beam_parts)
beam.disperse()
beam_parts = list()
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index d06146cc7046b..0abba142665ee 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -712,7 +712,7 @@
/mob/living/carbon/get_shove_flags(mob/living/shover, obj/item/weapon)
. = ..()
. |= SHOVE_CAN_STAGGER
- if(IsKnockdown() && !IsParalyzed() && HAS_TRAIT(src, TRAIT_STUN_ON_NEXT_SHOVE))
+ if(IsKnockdown() && !IsParalyzed() && HAS_TRAIT(src, TRAIT_DAZED))
. |= SHOVE_CAN_KICK_SIDE
if(HAS_TRAIT(src, TRAIT_NO_SIDE_KICK)) // added as an extra check, just in case
. &= ~SHOVE_CAN_KICK_SIDE
diff --git a/code/modules/mob/living/carbon/carbon_movement.dm b/code/modules/mob/living/carbon/carbon_movement.dm
index cb35aebfb0770..83b53e64cf9b8 100644
--- a/code/modules/mob/living/carbon/carbon_movement.dm
+++ b/code/modules/mob/living/carbon/carbon_movement.dm
@@ -1,10 +1,10 @@
-/mob/living/carbon/slip(knockdown_amount, obj/slipped_on, lube_flags, paralyze, force_drop = FALSE)
+/mob/living/carbon/slip(knockdown_amount, obj/slipped_on, lube_flags, paralyze, daze, force_drop = FALSE)
if(movement_type & MOVETYPES_NOT_TOUCHING_GROUND)
return FALSE
if(!(lube_flags & SLIDE_ICE))
log_combat(src, (slipped_on || get_turf(src)), "slipped on the", null, ((lube_flags & SLIDE) ? "(SLIDING)" : null))
..()
- return loc.handle_slip(src, knockdown_amount, slipped_on, lube_flags, paralyze, force_drop)
+ return loc.handle_slip(src, knockdown_amount, slipped_on, lube_flags, paralyze, daze, force_drop)
/mob/living/carbon/Move(NewLoc, direct)
. = ..()
diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm
index 6d4f4f6fc7bc0..e609c65b4107b 100644
--- a/code/modules/mob/living/carbon/examine.dm
+++ b/code/modules/mob/living/carbon/examine.dm
@@ -370,18 +370,18 @@
// var/t_has = p_have()
// var/t_is = p_are()
//head
- if(head && !(obscured & ITEM_SLOT_HEAD) && !(head.item_flags & EXAMINE_SKIP))
+ if(head && !(obscured & ITEM_SLOT_HEAD) && !HAS_TRAIT(head, TRAIT_EXAMINE_SKIP))
. += "[t_He] носит [head.examine_title(user, declent = ACCUSATIVE)] на голове."
//back
- if(back && !(back.item_flags & EXAMINE_SKIP))
+ if(back && !HAS_TRAIT(back, TRAIT_EXAMINE_SKIP))
. += "[t_He] носит [back.examine_title(user, declent = ACCUSATIVE)] на спине."
//Hands
for(var/obj/item/held_thing in held_items)
- if(held_thing.item_flags & (ABSTRACT|EXAMINE_SKIP|HAND_ITEM))
+ if((held_thing.item_flags & (ABSTRACT|HAND_ITEM)) || HAS_TRAIT(held_thing, TRAIT_EXAMINE_SKIP))
continue
. += "[t_He] держит [held_thing.examine_title(user, declent = ACCUSATIVE)] в [get_held_index_name(get_held_index_of_item(held_thing))]."
//gloves
- if(gloves && !(obscured & ITEM_SLOT_GLOVES) && !(gloves.item_flags & EXAMINE_SKIP))
+ if(gloves && !(obscured & ITEM_SLOT_GLOVES) && !HAS_TRAIT(gloves, TRAIT_EXAMINE_SKIP))
. += "[t_He] носит [gloves.examine_title(user, declent = ACCUSATIVE)] на руках."
else if(GET_ATOM_BLOOD_DNA_LENGTH(src))
if(num_hands)
@@ -391,23 +391,23 @@
var/cables_or_cuffs = istype(handcuffed, /obj/item/restraints/handcuffs/cable) ? "в связках" : "в наручниках"
. += span_warning("[t_He] [icon2html(handcuffed, user)] [cables_or_cuffs]!")
//shoes
- if(shoes && !(obscured & ITEM_SLOT_FEET) && !(shoes.item_flags & EXAMINE_SKIP))
+ if(shoes && !(obscured & ITEM_SLOT_FEET) && !HAS_TRAIT(shoes, TRAIT_EXAMINE_SKIP))
. += "[t_He] носит [shoes.examine_title(user, declent = ACCUSATIVE)] на ногах."
//mask
- if(wear_mask && !(obscured & ITEM_SLOT_MASK) && !(wear_mask.item_flags & EXAMINE_SKIP))
+ if(wear_mask && !(obscured & ITEM_SLOT_MASK) && !HAS_TRAIT(wear_mask, TRAIT_EXAMINE_SKIP))
. += "[t_He] носит [wear_mask.examine_title(user, declent = ACCUSATIVE)] на лице."
- if(wear_neck && !(obscured & ITEM_SLOT_NECK) && !(wear_neck.item_flags & EXAMINE_SKIP))
+ if(wear_neck && !(obscured & ITEM_SLOT_NECK) && !HAS_TRAIT(wear_neck, TRAIT_EXAMINE_SKIP))
. += "[t_He] носит [wear_neck.examine_title(user, declent = ACCUSATIVE)] вокруг шеи."
//eyes
if(!(obscured & ITEM_SLOT_EYES) )
- if(glasses && !(glasses.item_flags & EXAMINE_SKIP))
+ if(glasses && !HAS_TRAIT(glasses, TRAIT_EXAMINE_SKIP))
. += "[t_He] носит [glasses.examine_title(user, declent = ACCUSATIVE)] на глазах."
else if(HAS_TRAIT(src, TRAIT_UNNATURAL_RED_GLOWY_EYES))
. += span_warning("[t_His] глаза светятся неестественной красной аурой!")
else if(HAS_TRAIT(src, TRAIT_BLOODSHOT_EYES))
. += span_warning("[t_His] глаза налиты кровью!")
//ears
- if(ears && !(obscured & ITEM_SLOT_EARS) && !(ears.item_flags & EXAMINE_SKIP))
+ if(ears && !(obscured & ITEM_SLOT_EARS) && !HAS_TRAIT(ears, TRAIT_EXAMINE_SKIP))
. += "[t_He] носит [ears.examine_title(user, declent = ACCUSATIVE)] на ушах."
// Yes there's a lot of copypasta here, we can improve this later when carbons are less dumb in general
@@ -421,7 +421,7 @@
// var/t_is = p_are()
//uniform
- if(w_uniform && !(obscured & ITEM_SLOT_ICLOTHING) && !(w_uniform.item_flags & EXAMINE_SKIP))
+ if(w_uniform && !(obscured & ITEM_SLOT_ICLOTHING) && !HAS_TRAIT(w_uniform, TRAIT_EXAMINE_SKIP))
//accessory
var/accessory_message = ""
if(istype(w_uniform, /obj/item/clothing/under))
@@ -432,36 +432,36 @@
. += "[t_He] носит [w_uniform.examine_title(user, declent = ACCUSATIVE)][accessory_message]."
//head
- if(head && !(obscured & ITEM_SLOT_HEAD) && !(head.item_flags & EXAMINE_SKIP))
+ if(head && !(obscured & ITEM_SLOT_HEAD) && !HAS_TRAIT(head, TRAIT_EXAMINE_SKIP))
. += "[t_He] носит [head.examine_title(user, declent = ACCUSATIVE)] на голове."
//mask
- if(wear_mask && !(obscured & ITEM_SLOT_MASK) && !(wear_mask.item_flags & EXAMINE_SKIP))
+ if(wear_mask && !(obscured & ITEM_SLOT_MASK) && !HAS_TRAIT(wear_mask, TRAIT_EXAMINE_SKIP))
. += "[t_He] носит [wear_mask.examine_title(user, declent = ACCUSATIVE)] на лице."
//neck
- if(wear_neck && !(obscured & ITEM_SLOT_NECK) && !(wear_neck.item_flags & EXAMINE_SKIP))
+ if(wear_neck && !(obscured & ITEM_SLOT_NECK) && !HAS_TRAIT(wear_neck, TRAIT_EXAMINE_SKIP))
. += "[t_He] носит [wear_neck.examine_title(user, declent = ACCUSATIVE)] на шее."
//eyes
if(!(obscured & ITEM_SLOT_EYES) )
- if(glasses && !(glasses.item_flags & EXAMINE_SKIP))
+ if(glasses && !HAS_TRAIT(glasses, TRAIT_EXAMINE_SKIP))
. += "[t_He] носит [glasses.examine_title(user, declent = ACCUSATIVE)] на глазах."
else if(HAS_TRAIT(src, TRAIT_UNNATURAL_RED_GLOWY_EYES))
. += span_warning("[t_His] глаза светятся неестественной красной аурой!")
else if(HAS_TRAIT(src, TRAIT_BLOODSHOT_EYES))
. += span_warning("[t_His] глаза налиты кровью!")
//ears
- if(ears && !(obscured & ITEM_SLOT_EARS) && !(ears.item_flags & EXAMINE_SKIP))
+ if(ears && !(obscured & ITEM_SLOT_EARS) && !HAS_TRAIT(ears, TRAIT_EXAMINE_SKIP))
. += "[t_He] носит [ears.examine_title(user, declent = ACCUSATIVE)] на ушах."
//suit/armor
- if(wear_suit && !(wear_suit.item_flags & EXAMINE_SKIP))
+ if(wear_suit && !HAS_TRAIT(wear_suit, TRAIT_EXAMINE_SKIP))
. += "[t_He] носит [wear_suit.examine_title(user, declent = ACCUSATIVE)]."
//suit/armor storage
- if(s_store && !(obscured & ITEM_SLOT_SUITSTORE) && !(s_store.item_flags & EXAMINE_SKIP))
+ if(s_store && !(obscured & ITEM_SLOT_SUITSTORE) && !HAS_TRAIT(s_store, TRAIT_EXAMINE_SKIP))
. += "[t_He] носит [s_store.examine_title(user, declent = ACCUSATIVE)] на [wear_suit.declent_ru(PREPOSITIONAL)]."
//back
- if(back && !(back.item_flags & EXAMINE_SKIP))
+ if(back && !HAS_TRAIT(back, TRAIT_EXAMINE_SKIP))
. += "[t_He] носит [back.examine_title(user, declent = ACCUSATIVE)] на спине."
//ID
- if(wear_id && !(wear_id.item_flags & EXAMINE_SKIP))
+ if(wear_id && !HAS_TRAIT(wear_id, TRAIT_EXAMINE_SKIP))
var/obj/item/card/id/id = wear_id.GetID()
if(id && get_dist(user, src) <= ID_EXAMINE_DISTANCE)
var/id_href = "[wear_id.examine_title(user, declent = ACCUSATIVE)]"
@@ -471,11 +471,11 @@
. += "[t_He] носит [wear_id.examine_title(user, declent = ACCUSATIVE)]."
//Hands
for(var/obj/item/held_thing in held_items)
- if(held_thing.item_flags & (ABSTRACT|EXAMINE_SKIP|HAND_ITEM))
+ if((held_thing.item_flags & (ABSTRACT|HAND_ITEM)) || HAS_TRAIT(held_thing, TRAIT_EXAMINE_SKIP))
continue
. += "[t_He] держит [held_thing.examine_title(user, declent = ACCUSATIVE)] в [get_held_index_name(get_held_index_of_item(held_thing))]."
//gloves
- if(gloves && !(obscured & ITEM_SLOT_GLOVES) && !(gloves.item_flags & EXAMINE_SKIP))
+ if(gloves && !(obscured & ITEM_SLOT_GLOVES) && !HAS_TRAIT(gloves, TRAIT_EXAMINE_SKIP))
. += "[t_He] носит [gloves.examine_title(user, declent = ACCUSATIVE)] на руках."
else if(GET_ATOM_BLOOD_DNA_LENGTH(src) || blood_in_hands)
if(num_hands)
@@ -485,10 +485,10 @@
var/cables_or_cuffs = istype(handcuffed, /obj/item/restraints/handcuffs/cable) ? "в связках" : "в наручниках"
. += span_warning("[t_He] [icon2html(handcuffed, user)] [cables_or_cuffs]!")
//belt
- if(belt && !(obscured & ITEM_SLOT_BELT) && !(belt.item_flags & EXAMINE_SKIP))
+ if(belt && !(obscured & ITEM_SLOT_BELT) && !HAS_TRAIT(belt, TRAIT_EXAMINE_SKIP))
. += "[t_He] носит [belt.examine_title(user, declent = ACCUSATIVE)] на поясе."
//shoes
- if(shoes && !(obscured & ITEM_SLOT_FEET) && !(shoes.item_flags & EXAMINE_SKIP))
+ if(shoes && !(obscured & ITEM_SLOT_FEET) && !HAS_TRAIT(shoes, TRAIT_EXAMINE_SKIP))
. += "[t_He] носит [shoes.examine_title(user, declent = ACCUSATIVE)] на ногах."
/// Collects info displayed about any HUDs the user has when examining src
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 1d660873ff795..aad3a0f1cc300 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -140,11 +140,9 @@
if(src == target || LAZYFIND(target.buckled_mobs, src) || !iscarbon(target))
return
if(!(shove_flags & SHOVE_KNOCKDOWN_BLOCKED))
- target.Knockdown(SHOVE_KNOCKDOWN_HUMAN)
- target.apply_status_effect(/datum/status_effect/next_shove_stuns)
+ target.Knockdown(SHOVE_KNOCKDOWN_HUMAN, daze_amount = 3 SECONDS)
if(!HAS_TRAIT(src, TRAIT_BRAWLING_KNOCKDOWN_BLOCKED))
- Knockdown(SHOVE_KNOCKDOWN_COLLATERAL)
- apply_status_effect(/datum/status_effect/next_shove_stuns)
+ Knockdown(SHOVE_KNOCKDOWN_COLLATERAL, daze_amount = 3 SECONDS)
target.visible_message(span_danger("[capitalize(shover.declent_ru(NOMINATIVE))] толкает [target.declent_ru(ACCUSATIVE)] в [declent_ru(ACCUSATIVE)]!"),
span_userdanger("Вы врезаетесь в [declent_ru(ACCUSATIVE)] из-за толчка [shover.declent_ru(GENITIVE)]!"), span_hear("Вы слышите агрессивное шарканье с последующим громким стуком!"), COMBAT_MESSAGE_RANGE, src)
to_chat(src, span_danger("Вы толкаете [target.declent_ru(ACCUSATIVE)] в [declent_ru(ACCUSATIVE)]!"))
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index 52e59e098c1b7..57f32a92decf6 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -9,7 +9,7 @@
return
return considering
-/mob/living/carbon/human/slip(knockdown_amount, obj/slipped_on, lube_flags, paralyze, force_drop = FALSE)
+/mob/living/carbon/human/slip(knockdown_amount, obj/slipped_on, lube_flags, paralyze, daze, force_drop = FALSE)
if(HAS_TRAIT(src, TRAIT_NO_SLIP_ALL))
return FALSE
diff --git a/code/modules/mob/living/carbon/human/human_update_icons.dm b/code/modules/mob/living/carbon/human/human_update_icons.dm
index 16e33fd57795c..ff08506da281a 100644
--- a/code/modules/mob/living/carbon/human/human_update_icons.dm
+++ b/code/modules/mob/living/carbon/human/human_update_icons.dm
@@ -91,7 +91,7 @@ There are several things that need to be remembered:
if(update_obscured)
update_obscured_slots(uniform.flags_inv)
- if(check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_ICLOTHING)
+ if(HAS_TRAIT(uniform, TRAIT_NO_WORN_ICON) || (check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_ICLOTHING))
return
var/target_overlay = uniform.icon_state
@@ -104,7 +104,7 @@ There are several things that need to be remembered:
//icon_file MUST be set to null by default, or it causes issues.
//handled_by_bodyshape MUST be set to FALSE under the if(!icon_exists()) statement, or everything breaks.
//"override_file = handled_by_bodyshape ? icon_file : null" MUST be added to the arguments of build_worn_icon()
- //Friendly reminder that icon_exists(file, state, scream = TRUE) is your friend when debugging this code.
+ //Friendly reminder that icon_exists_or_scream(file, state) is your friend when debugging this code.
var/handled_by_bodyshape = TRUE
var/icon_file
var/woman
@@ -152,6 +152,9 @@ There are several things that need to be remembered:
if(update_obscured)
update_obscured_slots(worn_item.flags_inv)
+ if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON))
+ return
+
var/icon_file = 'icons/mob/clothing/id.dmi'
id_overlay = wear_id.build_worn_icon(default_layer = ID_LAYER, default_icon_file = icon_file)
@@ -194,7 +197,7 @@ There are several things that need to be remembered:
if(update_obscured)
update_obscured_slots(worn_item.flags_inv)
- if(check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_GLOVES)
+ if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_GLOVES))
return
var/icon_file = 'icons/mob/clothing/hands.dmi'
@@ -245,7 +248,7 @@ There are several things that need to be remembered:
if(update_obscured)
update_obscured_slots(worn_item.flags_inv)
- if(check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_EYES)
+ if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_EYES))
return
var/icon_file = 'icons/mob/clothing/eyes.dmi'
@@ -274,7 +277,7 @@ There are several things that need to be remembered:
if(update_obscured)
update_obscured_slots(worn_item.flags_inv)
- if(check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_EARS)
+ if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_EARS))
return
var/icon_file = 'icons/mob/clothing/ears.dmi'
@@ -298,7 +301,7 @@ There are several things that need to be remembered:
if(update_obscured)
update_obscured_slots(worn_item.flags_inv)
- if(check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_NECK)
+ if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_NECK))
return
var/icon_file = 'icons/mob/clothing/neck.dmi'
@@ -327,7 +330,7 @@ There are several things that need to be remembered:
if(update_obscured)
update_obscured_slots(worn_item.flags_inv)
- if(check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_FEET)
+ if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_FEET))
return
var/icon_file = DEFAULT_SHOES_FILE
@@ -365,7 +368,7 @@ There are several things that need to be remembered:
if(update_obscured)
update_obscured_slots(worn_item.flags_inv)
- if(check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_SUITSTORE)
+ if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_SUITSTORE))
return
var/mutable_appearance/s_store_overlay = worn_item.build_worn_icon(default_layer = SUIT_STORE_LAYER, default_icon_file = 'icons/mob/clothing/belt_mirror.dmi')
@@ -387,7 +390,7 @@ There are several things that need to be remembered:
if(update_obscured)
update_obscured_slots(worn_item.flags_inv)
- if(check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_HEAD)
+ if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_HEAD))
return
var/icon_file = 'icons/mob/clothing/head/default.dmi'
@@ -433,7 +436,7 @@ There are several things that need to be remembered:
if(update_obscured)
update_obscured_slots(worn_item.flags_inv)
- if(check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_BELT)
+ if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_BELT))
return
var/icon_file = 'icons/mob/clothing/belt.dmi'
@@ -459,6 +462,9 @@ There are several things that need to be remembered:
if(update_obscured)
update_obscured_slots(worn_item.flags_inv)
+ if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON))
+ return
+
var/icon_file = DEFAULT_SUIT_FILE
// BANDASTATION EDIT START - SPECIES CLOTHING ICONS
var/list/icon_files_species = list(
@@ -527,7 +533,7 @@ There are several things that need to be remembered:
if(update_obscured)
update_obscured_slots(worn_item.flags_inv)
- if(check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_MASK)
+ if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_MASK))
return
var/icon_file = 'icons/mob/clothing/mask.dmi'
@@ -574,6 +580,9 @@ There are several things that need to be remembered:
if(update_obscured)
update_obscured_slots(worn_item.flags_inv)
+ if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON))
+ return
+
var/icon_file = 'icons/mob/clothing/back.dmi'
back_overlay = back.build_worn_icon(default_layer = BACK_LAYER, default_icon_file = icon_file)
diff --git a/code/modules/mob/living/carbon/human/status_procs.dm b/code/modules/mob/living/carbon/human/status_procs.dm
index 6f4e8570099af..be2284f580d34 100644
--- a/code/modules/mob/living/carbon/human/status_procs.dm
+++ b/code/modules/mob/living/carbon/human/status_procs.dm
@@ -3,7 +3,7 @@
amount = dna.species.spec_stun(src, amount)
return ..()
-/mob/living/carbon/human/Knockdown(amount, ignore_canstun = FALSE)
+/mob/living/carbon/human/Knockdown(amount, daze_amount = 0, ignore_canstun = FALSE)
amount = dna.species.spec_stun(src, amount) * physiology.knockdown_mod
return ..()
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 7c0bd76867371..9d72a0e556ade 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -754,8 +754,7 @@
if(!(shove_flags & SHOVE_DIRECTIONAL_BLOCKED) && (SEND_SIGNAL(target_shove_turf, COMSIG_LIVING_DISARM_COLLIDE, src, target, shove_flags, weapon) & COMSIG_LIVING_SHOVE_HANDLED))
return
if((shove_flags & SHOVE_BLOCKED) && !(shove_flags & (SHOVE_KNOCKDOWN_BLOCKED|SHOVE_CAN_KICK_SIDE)))
- target.Knockdown(SHOVE_KNOCKDOWN_SOLID)
- target.apply_status_effect(/datum/status_effect/next_shove_stuns)
+ target.Knockdown(SHOVE_KNOCKDOWN_SOLID, daze_amount = 3 SECONDS)
target.visible_message(span_danger("[capitalize(declent_ru(NOMINATIVE))] толкает [target.declent_ru(ACCUSATIVE)], сбивая [target.ru_p_them()] с ног!"),
span_userdanger("Вы сбиты с ног от толчка [declent_ru(GENITIVE)]!"), span_hear("Вы слышите агрессивное шарканье с последующим громким стуком!"), COMBAT_MESSAGE_RANGE, src)
to_chat(src, span_danger("Вы толкаете [target.declent_ru(ACCUSATIVE)], сбивая [target.ru_p_them()] с ног!"))
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 188d104a562f9..265c27e587078 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -309,13 +309,13 @@
///Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew.
/mob/living/silicon/proc/checklaws()
laws_sanity_check()
- var/list = "Which laws do you want to include when stating them for the crew?
"
+ var/list = "Which laws do you want to include when stating them for the crew?
"
var/law_display = "Yes"
if (laws.zeroth)
if (!(laws.zeroth in lawcheck))
law_display = "No"
- list += {"[law_display] 0:[laws.zeroth] "}
+ list += {"[law_display] 0:[laws.zeroth] "}
for (var/index in 1 to length(laws.hacked))
law_display = "Yes"
@@ -323,7 +323,7 @@
if (length(law) > 0)
if (!(law in hackedcheck))
law_display = "No"
- list += {"[law_display] [ion_num()]: [law] "}
+ list += {"[law_display] [ion_num()]: [law] "}
for (var/index in 1 to length(laws.ion))
law_display = "Yes"
@@ -331,7 +331,7 @@
if (length(law) > 0)
if(!(law in ioncheck))
law_display = "No"
- list += {"[law_display] [ion_num()]: [law] "}
+ list += {"[law_display] [ion_num()]: [law] "}
var/number = 1
for (var/index in 1 to length(laws.inherent))
@@ -340,7 +340,7 @@
if (length(law) > 0)
if (!(law in lawcheck))
law_display = "No"
- list += {"[law_display] [number]: [law] "}
+ list += {"[law_display] [number]: [law] "}
number++
for (var/index in 1 to length(laws.supplied))
@@ -349,11 +349,13 @@
if (length(law) > 0)
if (!(law in lawcheck))
law_display = "No"
- list += {"[law_display] [number]: [law] "}
+ list += {"[law_display] [number]: [law] "}
number++
- list += {"