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 += {"

State Laws"} + list += {"

State Laws"} - usr << browse(list, "window=laws") + var/datum/browser/browser = new(usr, "laws") + browser.set_content(list) + browser.open() /mob/living/silicon/proc/ai_roster() if(!client) diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index 11815d71b1220..967b7cdabfd68 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -89,7 +89,7 @@ return K.duration - world.time return 0 -/mob/living/proc/Knockdown(amount, ignore_canstun = FALSE) //Can't go below remaining duration +/mob/living/proc/Knockdown(amount, daze_amount = 0, ignore_canstun = FALSE) //Can't go below remaining duration if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_KNOCKDOWN, amount, ignore_canstun) & COMPONENT_NO_STUN) return if(check_stun_immunity(CANKNOCKDOWN, ignore_canstun)) @@ -99,6 +99,8 @@ K.duration = max(world.time + amount, K.duration) else if(amount > 0) K = apply_status_effect(/datum/status_effect/incapacitating/knockdown, amount) + if(daze_amount > 0) + apply_status_effect(/datum/status_effect/dazed, daze_amount) return K /mob/living/proc/SetKnockdown(amount, ignore_canstun = FALSE) //Sets remaining duration @@ -117,7 +119,7 @@ K = apply_status_effect(/datum/status_effect/incapacitating/knockdown, amount) return K -/mob/living/proc/AdjustKnockdown(amount, ignore_canstun = FALSE) //Adds to remaining duration +/mob/living/proc/AdjustKnockdown(amount, daze_amount = 0, ignore_canstun = FALSE) //Adds to remaining duration if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_KNOCKDOWN, amount, ignore_canstun) & COMPONENT_NO_STUN) return if(check_stun_immunity(CANKNOCKDOWN, ignore_canstun)) @@ -127,6 +129,8 @@ K.duration += amount else if(amount > 0) K = apply_status_effect(/datum/status_effect/incapacitating/knockdown, amount) + if(daze_amount > 0) + apply_status_effect(/datum/status_effect/dazed, daze_amount) return K /* IMMOBILIZED */ diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 0d8001fb1b651..9f12deb331244 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -376,12 +376,13 @@ * slipped_on - optional, what'd we slip on? if not set, we assume they just fell over * lube - bitflag of "lube flags", see [mobs.dm] for more information * paralyze - time (in deciseconds) the slip leaves them paralyzed / unable to move + * daze - time (in deciseconds) the slip leaves them vulnerable to shove stuns * force_drop = the slip forces them to drop held items */ -/mob/proc/slip(knockdown_amount, obj/slipped_on, lube_flags, paralyze, force_drop = FALSE) +/mob/proc/slip(knockdown_amount, obj/slipped_on, lube_flags, paralyze, daze, force_drop = FALSE) add_mob_memory(/datum/memory/was_slipped, antagonist = slipped_on) - SEND_SIGNAL(src, COMSIG_MOB_SLIPPED, knockdown_amount, slipped_on, lube_flags, paralyze, force_drop) + SEND_SIGNAL(src, COMSIG_MOB_SLIPPED, knockdown_amount, slipped_on, lube_flags, paralyze, daze, force_drop) //bodypart selection verbs - Cyberboss //8: repeated presses toggles through head - eyes - mouth diff --git a/code/modules/mob_spawn/ghost_roles/mining_roles.dm b/code/modules/mob_spawn/ghost_roles/mining_roles.dm index 5e8767f09c05c..b9a227c479819 100644 --- a/code/modules/mob_spawn/ghost_roles/mining_roles.dm +++ b/code/modules/mob_spawn/ghost_roles/mining_roles.dm @@ -309,6 +309,8 @@ shoes = /obj/item/clothing/shoes/combat r_pocket = /obj/item/gun/ballistic/automatic/pistol r_hand = /obj/item/gun/ballistic/rifle/sniper_rifle + belt = /obj/item/storage/belt/utility/full + glasses = /obj/item/clothing/glasses/welding/up implants = list(/obj/item/implant/weapons_auth) @@ -320,6 +322,8 @@ suit = /obj/item/clothing/suit/armor/vest mask = /obj/item/clothing/mask/chameleon/gps r_hand = /obj/item/melee/energy/sword/saber + belt = /obj/item/storage/belt/utility/full + glasses = /obj/item/clothing/glasses/welding/up /datum/outfit/lavaland_syndicate/comms/icemoon name = "Icemoon Syndicate Comms Agent" diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm index 91fb00c633b06..050bee6ff2baf 100644 --- a/code/modules/mod/mod_types.dm +++ b/code/modules/mod/mod_types.dm @@ -82,9 +82,11 @@ /obj/item/mod/module/t_ray, /obj/item/mod/module/quick_carry, /obj/item/mod/module/headprotector, + /obj/item/mod/module/mister/atmos, ) default_pins = list( /obj/item/mod/module/magboot, + /obj/item/mod/module/mister/atmos, /obj/item/mod/module/flashlight, ) diff --git a/code/modules/mod/modules/modules_antag.dm b/code/modules/mod/modules/modules_antag.dm index ba5e1711fcb29..be3f7730b14af 100644 --- a/code/modules/mod/modules/modules_antag.dm +++ b/code/modules/mod/modules/modules_antag.dm @@ -526,10 +526,10 @@ var/list/traits_to_add = list(TRAIT_SILENT_FOOTSTEPS, TRAIT_UNKNOWN, TRAIT_HEAD_INJURY_BLOCKED) /obj/item/mod/module/infiltrator/on_install() - mod.item_flags |= EXAMINE_SKIP + ADD_TRAIT(mod, TRAIT_EXAMINE_SKIP, REF(src)) /obj/item/mod/module/infiltrator/on_uninstall(deleting = FALSE) - mod.item_flags &= ~EXAMINE_SKIP + REMOVE_TRAIT(mod, TRAIT_EXAMINE_SKIP, REF(src)) /obj/item/mod/module/infiltrator/on_part_activation() mod.wearer.add_traits(traits_to_add, REF(src)) diff --git a/code/modules/mod/modules/modules_security.dm b/code/modules/mod/modules/modules_security.dm index f0fd48471b424..f0b9986f54506 100644 --- a/code/modules/mod/modules/modules_security.dm +++ b/code/modules/mod/modules/modules_security.dm @@ -112,7 +112,6 @@ incompatible_modules = list(/obj/item/mod/module/holster) cooldown_time = 0.5 SECONDS allow_flags = MODULE_ALLOW_INACTIVE - required_slots = list(ITEM_SLOT_OCLOTHING|ITEM_SLOT_GLOVES|ITEM_SLOT_FEET) /// Gun we have holstered. var/obj/item/gun/holstered diff --git a/code/modules/modular_computers/file_system/programs/budgetordering.dm b/code/modules/modular_computers/file_system/programs/budgetordering.dm index 75ebebd8c5c1e..018c11b49965d 100644 --- a/code/modules/modular_computers/file_system/programs/budgetordering.dm +++ b/code/modules/modular_computers/file_system/programs/budgetordering.dm @@ -94,13 +94,18 @@ ) if((P.hidden && (P.contraband && !contraband) || (P.special && !P.special_enabled) || P.drop_pod_only)) continue + + var/obj/item/first_item = length(P.contains) > 0 ? P.contains[1] : null data["supplies"][P.group]["packs"] += list(list( "name" = P.name, "cost" = P.get_cost(), "id" = pack, "desc" = P.desc || P.name, // If there is a description, use it. Otherwise use the pack's name. + "first_item_icon" = first_item?.icon, + "first_item_icon_state" = first_item?.icon_state, "goody" = P.goody, - "access" = P.access + "access" = P.access, + "contains" = P.get_contents_ui_data(), )) //Data regarding the User's capability to buy things. diff --git a/code/modules/modular_computers/file_system/programs/virtual_pet.dm b/code/modules/modular_computers/file_system/programs/virtual_pet.dm index d0ec279867706..22c456a7844f7 100644 --- a/code/modules/modular_computers/file_system/programs/virtual_pet.dm +++ b/code/modules/modular_computers/file_system/programs/virtual_pet.dm @@ -17,6 +17,7 @@ GLOBAL_LIST_EMPTY(virtual_pets_list) filedesc = "Virtual Pet" downloader_category = PROGRAM_CATEGORY_GAMES extended_desc = "Загрузите свой собственный Orbie сегодня!" + program_open_overlay = "generic" program_flags = PROGRAM_ON_NTNET_STORE size = 3 tgui_id = "NtosVirtualPet" diff --git a/code/modules/power/rtg.dm b/code/modules/power/rtg.dm index 69693af3a4a92..99f61186180d7 100644 --- a/code/modules/power/rtg.dm +++ b/code/modules/power/rtg.dm @@ -112,7 +112,7 @@ name = "Lava powered RTG" desc = "This device only works when exposed to the toxic fumes of Lavaland" circuit = null - power_gen = 1500 + power_gen = 20000 anchored = TRUE resistance_flags = LAVA_PROOF diff --git a/code/modules/procedural_mapping/mapGenerators/repair.dm b/code/modules/procedural_mapping/mapGenerators/repair.dm index da086773591de..e33f3e1f0cc42 100644 --- a/code/modules/procedural_mapping/mapGenerators/repair.dm +++ b/code/modules/procedural_mapping/mapGenerators/repair.dm @@ -50,8 +50,9 @@ require_area_resort() var/list/generation_turfs = block( - locate(bounds[MAP_MINX], bounds[MAP_MINY], SSmapping.station_start), - locate(bounds[MAP_MAXX], bounds[MAP_MAXY], z_offset - 1)) + bounds[MAP_MINX], bounds[MAP_MINY], SSmapping.station_start, + bounds[MAP_MAXX], bounds[MAP_MAXY], z_offset - 1 + ) for(var/turf/gen_turf as anything in generation_turfs) atoms += gen_turf for(var/atom in gen_turf) diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index 50f451ea7e4ad..0628650799289 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -452,10 +452,6 @@ if (sawoff(user, A)) return - if(misfire_probability && istype(A, /obj/item/stack/sheet/cloth)) - if(guncleaning(user, A)) - return - return FALSE /obj/item/gun/ballistic/proc/check_if_held(mob/user) @@ -686,19 +682,6 @@ GLOBAL_LIST_INIT(gun_saw_types, typecacheof(list( update_appearance() return TRUE -/obj/item/gun/ballistic/proc/guncleaning(mob/user, obj/item/A) - if(misfire_probability == initial(misfire_probability)) - balloon_alert(user, "уже очищено!") - return - - user.changeNext_move(CLICK_CD_MELEE) - balloon_alert(user, "очистка...") - - if(do_after(user, 10 SECONDS, target = src)) - misfire_probability = initial(misfire_probability) - balloon_alert(user, "очищено") - return TRUE - /obj/item/gun/ballistic/wrench_act(mob/living/user, obj/item/I) if(!can_modify_ammo) return diff --git a/code/modules/projectiles/guns/ballistic/rifle.dm b/code/modules/projectiles/guns/ballistic/rifle.dm index 2bbbabca4af8d..1113cc9e0cb9c 100644 --- a/code/modules/projectiles/guns/ballistic/rifle.dm +++ b/code/modules/projectiles/guns/ballistic/rifle.dm @@ -77,17 +77,16 @@ update_appearance() /obj/item/gun/ballistic/rifle/boltaction/attack_self(mob/user) - if(can_jam) - if(jammed) - if(prob(unjam_chance)) - jammed = FALSE - unjam_chance = 10 - else - unjam_chance += 10 - balloon_alert(user, "jammed!") - playsound(user,'sound/items/weapons/jammed.ogg', 75, TRUE) - return FALSE - ..() + if(jammed) + if(prob(unjam_chance)) + jammed = FALSE + unjam_chance = initial(unjam_chance) + else + unjam_chance += 10 + balloon_alert(user, "jammed!") + playsound(user,'sound/items/weapons/jammed.ogg', 75, TRUE) + return FALSE + return ..() /obj/item/gun/ballistic/rifle/boltaction/process_fire(mob/user) if(can_jam) @@ -105,15 +104,6 @@ . = ..() - if(istype(item, /obj/item/gun_maintenance_supplies)) - if(!can_jam) - balloon_alert(user, "can't jam!") - return - if(do_after(user, 10 SECONDS, target = src)) - user.visible_message(span_notice("[user] finishes maintaining [src].")) - jamming_chance = initial(jamming_chance) - qdel(item) - /obj/item/gun/ballistic/rifle/boltaction/blow_up(mob/user) . = FALSE if(chambered?.loaded_projectile) diff --git a/code/modules/projectiles/projectile/bullets/special.dm b/code/modules/projectiles/projectile/bullets/special.dm index cd1439cbb01ae..1c9a5e4f38214 100644 --- a/code/modules/projectiles/projectile/bullets/special.dm +++ b/code/modules/projectiles/projectile/bullets/special.dm @@ -23,7 +23,7 @@ if(M.can_block_magic()) return BULLET_ACT_BLOCK else - M.slip(100, M.loc, GALOSHES_DONT_HELP|SLIDE, 0, FALSE) + M.slip(100, M.loc, GALOSHES_DONT_HELP|SLIDE) // Mime diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index 755e2b5e31a8f..a91734acf6180 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -453,7 +453,7 @@ total_weight += item_weight //use power according to the total weight of items grinded - use_energy((active_power_usage * (duration / 1 SECONDS)) * (total_weight / maximum_weight)) + use_energy((active_power_usage * (duration / (1 SECONDS))) * (total_weight / maximum_weight)) addtimer(CALLBACK(src, PROC_REF(stop_operating)), duration) @@ -513,6 +513,6 @@ beaker.reagents.convert_reagent(/datum/reagent/consumable/cream, /datum/reagent/consumable/whipped_cream) //power consumed based on the ratio of total reagents mixed - use_energy((active_power_usage * (duration / 1 SECONDS)) * (beaker.reagents.total_volume / beaker.reagents.maximum_volume)) + use_energy((active_power_usage * (duration / (1 SECONDS))) * (beaker.reagents.total_volume / beaker.reagents.maximum_volume)) operating = FALSE diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 90d2aad0ecbae..41b44a135f27e 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -517,12 +517,14 @@ * Water reaction to turf */ -/datum/reagent/hydrogen_peroxide/expose_turf(turf/open/exposed_turf, reac_volume) +/datum/reagent/hydrogen_peroxide/expose_turf(turf/exposed_turf, reac_volume) . = ..() - if(!istype(exposed_turf)) + if (reac_volume < 1.5) return - if(reac_volume >= 5) - exposed_turf.MakeSlippery(TURF_WET_WATER, 10 SECONDS, min(reac_volume*1.5 SECONDS, 60 SECONDS)) + if (!isplatingturf(exposed_turf) && exposed_turf.type != /turf/closed/wall) + return + if (!HAS_TRAIT(exposed_turf, TRAIT_RUSTY)) + exposed_turf.AddElement(/datum/element/rust) /* * Water reaction to a mob */ @@ -2901,6 +2903,11 @@ if(need_mob_update) return UPDATE_MOB_HEALTH +/datum/reagent/eldritch/expose_turf(turf/exposed_turf, reac_volume) + . = ..() + if ((reac_volume >= 1.5 || isplatingturf(exposed_turf)) && !HAS_TRAIT(exposed_turf, TRAIT_RUSTY)) + exposed_turf.rust_turf() + /datum/reagent/universal_indicator name = "Universal Indicator" description = "A solution that can be used to create pH paper booklets, or sprayed on things to colour them by their pH." diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm index 25576568eb56f..32b659365c2f4 100644 --- a/code/modules/reagents/chemistry/recipes/others.dm +++ b/code/modules/reagents/chemistry/recipes/others.dm @@ -594,8 +594,9 @@ // spawn from popssible fishes for(var/i in 1 to rand(1, created_volume)) // More flop. - var/obj/item/fish/spawned_fish = pick(fish_types) - new spawned_fish(location) + var/spawned_fish = pick(fish_types) + var/obj/item/fish/new_fish = new spawned_fish(location) + ADD_TRAIT(new_fish, TRAIT_NO_FISHING_ACHIEVEMENT, TRAIT_GENERIC) return ..() //monkey powder heehoo @@ -951,7 +952,7 @@ for(var/mob/living/nearby_mob in range(location, 3)) do_sparks(3,FALSE,nearby_mob) do_teleport(nearby_mob, get_turf(holder.my_atom), 3, no_effects=TRUE) - nearby_mob.Knockdown(20, TRUE) + nearby_mob.Knockdown(20, ignore_canstun = TRUE) nearby_mob.add_atom_colour("#cebfff", WASHABLE_COLOUR_PRIORITY) do_sparks(3,FALSE,nearby_mob) clear_products(holder, step_volume_added) diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index dbb4fc5386b23..28b2516fda84c 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -109,10 +109,11 @@ ///returns turfs within our projected rectangle in no particular order /obj/docking_port/proc/return_turfs() - var/list/L = return_coords() - var/turf/T0 = locate(L[1],L[2],z) - var/turf/T1 = locate(L[3],L[4],z) - return block(T0,T1) + var/list/coords = return_coords() + return block( + coords[1], coords[2], z, + coords[3], coords[4], z + ) ///returns turfs within our projected rectangle in a specific order.this ensures that turfs are copied over in the same order, regardless of any rotation /obj/docking_port/proc/return_ordered_turfs(_x, _y, _z, _dir) @@ -147,17 +148,15 @@ /obj/docking_port/proc/highlight(_color = "#f00") SetInvisibility(INVISIBILITY_NONE) SET_PLANE_IMPLICIT(src, GHOST_PLANE) - var/list/L = return_coords() - var/turf/T0 = locate(L[1],L[2],z) - var/turf/T1 = locate(L[3],L[4],z) - for(var/turf/T in block(T0,T1)) + var/list/coords = return_coords() + for(var/turf/T in block(coords[1], coords[2], z, coords[3], coords[4], z)) T.color = _color LAZYINITLIST(T.atom_colours) T.maptext = null if(_color) - var/turf/T = locate(L[1], L[2], z) + var/turf/T = locate(coords[1], coords[2], z) T.color = "#0f0" - T = locate(L[3], L[4], z) + T = locate(coords[3], coords[4], z) T.color = "#00f" #endif diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index c303a14c5aaef..b700a00062913 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -1062,7 +1062,7 @@ else limb.icon_state = "[limb_id]_[body_zone]" - icon_exists(limb.icon, limb.icon_state, TRUE) //Prints a stack trace on the first failure of a given iconstate. + icon_exists_or_scream(limb.icon, limb.icon_state) //Prints a stack trace on the first failure of a given iconstate. . += limb diff --git a/code/modules/transport/transport_module.dm b/code/modules/transport/transport_module.dm index 2c02b507bf27e..83fd824bd6af0 100644 --- a/code/modules/transport/transport_module.dm +++ b/code/modules/transport/transport_module.dm @@ -304,15 +304,16 @@ var/x_offset = ROUND_UP(bound_width / ICON_SIZE_X) - 1 //how many tiles our horizontally farthest edge is from us var/y_offset = ROUND_UP(bound_height / ICON_SIZE_Y) - 1 //how many tiles our vertically farthest edge is from us + var/destination_x = destination.x + var/destination_y = destination.y + var/destination_z = destination.z //the x coordinate of the edge furthest from our future destination, which would be our right hand side - var/back_edge_x = destination.x + x_offset//if we arent multitile this should just be destination.x - var/upper_edge_y = destination.y + y_offset - - var/turf/upper_right_corner = locate(min(world.maxx, back_edge_x), min(world.maxy, upper_edge_y), destination.z) + var/back_edge_x = destination_x + x_offset//if we arent multitile this should just be destination.x + var/upper_edge_y = destination_y + y_offset var/list/dest_locs = block( - destination, - upper_right_corner + destination_x, destination_y, destination_z, + back_edge_x, upper_edge_y, destination_z ) var/list/entering_locs = dest_locs - locs diff --git a/code/modules/unit_tests/suit_storage_icons.dm b/code/modules/unit_tests/suit_storage_icons.dm index 7cc987bb46801..543db168851bd 100644 --- a/code/modules/unit_tests/suit_storage_icons.dm +++ b/code/modules/unit_tests/suit_storage_icons.dm @@ -35,12 +35,12 @@ continue if(worn_icon) //easiest to check since we override everything. - if(!(icon_state in icon_states(worn_icon))) + if(!icon_exists(worn_icon, icon_state)) log_test("\t[count] - [item_path] using invalid [worn_icon_state ? "worn_icon_state" : "icon_state"], \"[icon_state]\" in worn_icon override file, '[worn_icon]'") count++ continue - if(!(icon_state in icon_states('icons/mob/clothing/belt_mirror.dmi'))) + if(!icon_exists('icons/mob/clothing/belt_mirror.dmi', icon_state)) already_warned_icons += icon_state log_test("\t[count] - [item_path] using invalid [worn_icon_state ? "worn_icon_state" : "icon_state"], \"[icon_state]\"") count++ diff --git a/code/modules/unit_tests/turf_icons.dm b/code/modules/unit_tests/turf_icons.dm index 6f37117289880..945130ada0c45 100644 --- a/code/modules/unit_tests/turf_icons.dm +++ b/code/modules/unit_tests/turf_icons.dm @@ -9,7 +9,7 @@ var/icon_file = initial(turf_path.icon) if(isnull(icon_state) || isnull(icon_file)) continue - if(!(icon_state in icon_states(icon_file))) + if(!icon_exists(icon_file, icon_state)) TEST_FAIL("[turf_path] using invalid icon_state - \"[icon_state]\" in icon file, '[icon_file]") for(var/turf/closed/mineral/turf_path as anything in typesof(/turf/closed/mineral)) //minerals use a special (read: snowflake) MAP_SWITCH definition that changes their icon based on if we're just compiling or if we're actually PLAYING the game. @@ -18,7 +18,7 @@ var/icon_file = initial(turf_path.icon) if(isnull(icon_state) || isnull(icon_file)) continue - if(!(icon_state in icon_states(icon_file))) + if(!icon_exists(icon_file, icon_state)) if(modular_mineral_turf_file && (icon_state in icon_states(modular_mineral_turf_file, 1))) continue if(!(icon_state in icon_states('icons/turf/mining.dmi', 1))) @@ -45,13 +45,13 @@ var/list/burnt_states = instanced_turf.burnt_states() for(var/state in burnt_states) - if(!(state in icon_states(damaged_dmi))) + if(!icon_exists(damaged_dmi, state)) TEST_FAIL("[open_turf_path] has an invalid icon in burnt_states - \"[state]\", in '[damaged_dmi]'") var/list/broken_states = instanced_turf.broken_states() for(var/state in broken_states) - if(!(state in icon_states(damaged_dmi))) + if(!icon_exists(damaged_dmi, state)) TEST_FAIL("[open_turf_path] has an invalid icon in broken_states - \"[state]\", in '[damaged_dmi]'") run_loc_floor_bottom_left = run_loc_floor_bottom_left.ChangeTurf(initial_turf_type) //cleanup. diff --git a/code/modules/vending/security.dm b/code/modules/vending/security.dm index 7a6f6a239fbe7..a4c7da74d6f18 100644 --- a/code/modules/vending/security.dm +++ b/code/modules/vending/security.dm @@ -17,6 +17,7 @@ /obj/item/restraints/legcuffs/bola/energy = 7, /obj/item/clothing/gloves/tackler = 5, /obj/item/holosign_creator/security = 2, + /obj/item/gun_maintenance_supplies = 2, ) contraband = list( /obj/item/clothing/glasses/sunglasses = 2, diff --git a/code/modules/wiremod/components/action/soundemitter.dm b/code/modules/wiremod/components/action/soundemitter.dm index 676ce8744385f..144a56295dd90 100644 --- a/code/modules/wiremod/components/action/soundemitter.dm +++ b/code/modules/wiremod/components/action/soundemitter.dm @@ -33,11 +33,19 @@ var/list/options_map +/obj/item/circuit_component/soundemitter/Initialize(mapload) + if(CONFIG_GET(flag/disallow_circuit_sounds)) + update_ui_alerts(new_flag=CIRCUIT_FLAG_DISABLED) + . = ..() + /obj/item/circuit_component/soundemitter/get_ui_notices() . = ..() . += create_ui_notice("Sound Cooldown: [DisplayTimeText(sound_cooldown)]", "orange", "stopwatch") if(CONFIG_GET(flag/disallow_circuit_sounds)) . += create_ui_notice("Non-functional", "red", "exclamation") + update_ui_alerts(new_flag=CIRCUIT_FLAG_DISABLED) + else + update_ui_alerts(remove_flag=CIRCUIT_FLAG_DISABLED) /obj/item/circuit_component/soundemitter/populate_ports() @@ -79,10 +87,11 @@ /obj/item/circuit_component/soundemitter/input_received(datum/port/input/port) if(CONFIG_GET(flag/disallow_circuit_sounds)) - ui_color = "red" + // Without constantly checking the config 24/7 or sending a signal to every circuit, best we can do to update existing emitters is this. + update_ui_alerts(new_flag=CIRCUIT_FLAG_DISABLED) return else - ui_color = initial(ui_color) + update_ui_alerts(remove_flag=CIRCUIT_FLAG_DISABLED) if(!parent.shell) return diff --git a/code/modules/wiremod/core/component.dm b/code/modules/wiremod/core/component.dm index 07f3a5b55a379..7dda865fb6409 100644 --- a/code/modules/wiremod/core/component.dm +++ b/code/modules/wiremod/core/component.dm @@ -64,6 +64,10 @@ /// The UI buttons of this circuit component. An assoc list that has this format: "button_icon" = "action_name" var/ui_buttons = null + /// The "important" UI tooltips of this circuit component. Used for important things like instant & disabled circuits, they're drawn next to the default tooltip icon. + /// An assoc list with the format ui_alerts["alert_icon"] = "alert_name". + var/ui_alerts = list() + /// Called when the option ports should be set up /obj/item/circuit_component/proc/populate_options() return @@ -86,8 +90,7 @@ trigger_input = add_input_port("Trigger", PORT_TYPE_SIGNAL, order = 2) if((circuit_flags & CIRCUIT_FLAG_OUTPUT_SIGNAL) && !trigger_output) trigger_output = add_output_port("Triggered", PORT_TYPE_SIGNAL, order = 2) - if(circuit_flags & CIRCUIT_FLAG_INSTANT) - ui_color = "orange" + update_ui_alerts() /obj/item/circuit_component/Destroy() if(parent) @@ -113,6 +116,21 @@ if(circuit_flags & CIRCUIT_FLAG_REFUSE_MODULE) . += span_notice("It's incompatible with module components.") +/// updates the ui alerts in the given component. new_flag adds flags, remove_flag removes them +/obj/item/circuit_component/proc/update_ui_alerts(new_flag, remove_flag) + if(new_flag) + circuit_flags |= new_flag + if(remove_flag) + circuit_flags &= ~remove_flag + if(circuit_flags & CIRCUIT_FLAG_INSTANT) + ui_alerts["tachometer-alt"] = "Instant" + else + ui_alerts -= "tachometer-alt" + if(circuit_flags & CIRCUIT_FLAG_DISABLED) + ui_alerts["exclamation"] = "Non-functional" + else + ui_alerts -= "exclamation" + /** * Called when a shell is registered from the component/the component is added to a circuit. * diff --git a/code/modules/wiremod/core/integrated_circuit.dm b/code/modules/wiremod/core/integrated_circuit.dm index 1023a59eb2100..dfaef0abcaa47 100644 --- a/code/modules/wiremod/core/integrated_circuit.dm +++ b/code/modules/wiremod/core/integrated_circuit.dm @@ -380,6 +380,8 @@ GLOBAL_LIST_EMPTY_TYPED(integrated_circuits, /obj/item/integrated_circuit) component_data["y"] = component.rel_y component_data["removable"] = component.removable component_data["color"] = component.ui_color + component_data["category"] = component.category + component_data["ui_alerts"] = component.ui_alerts component_data["ui_buttons"] = component.ui_buttons .["components"] += list(component_data) diff --git a/html/changelogs/archive/2025-02.yml b/html/changelogs/archive/2025-02.yml index b8f62a6d620be..3484856421bcd 100644 --- a/html/changelogs/archive/2025-02.yml +++ b/html/changelogs/archive/2025-02.yml @@ -34,3 +34,124 @@ in the ruin, however. zoomachina: - bugfix: showers wash things under them when they're turned on again +2025-02-03: + Absolucy: + - bugfix: Random messages should no longer be dropped and not appear in chat. + SmArtKar: + - bugfix: Fixed an issue with persisting brimbeams + jlsnow301: + - bugfix: Character pref dropdowns should have their display names fixed + necromanceranne: + - balance: The force of most standard varieties of toolboxes has increased from + 12 to 13 force. + - code_imp: Removed some magic numbers from the calculations for ancient toolboxes + damage scaling. + siliconOpossum: + - bugfix: Lathes interfaces are no longer unscrollable on 516 +2025-02-04: + necromanceranne: + - bugfix: Allows MOD holsters to once again activate while the modsuit is inactive + and undeployed. +2025-02-05: + Melbert: + - qol: Map vote tallies explains how they work if you hover them +2025-02-06: + Absolucy: + - bugfix: Void Cloaks now properly hide blades and such in the suit storage from + the wearer's sprite. + Ben10Omintrix: + - bugfix: fixes virtual pet app changing PDA's colors when open + Exester509: + - map: The Syndicate Lavaland base has been generally improved, with more defenses + and comms equipment. + Gaxeer: + - bugfix: fix image display in `NT IRN` PDA app for preview and contents + Holoo-1: + - bugfix: fixed state laws window on 516 + Jacquerel: + - bugfix: AI-controlled ventcrawling mobs (botanical spiderlings and legioned monkeys) + can once more do so without killing themselves shortly afterwards. + JohnFulpWillard: + - bugfix: Autolathes no longer have a scrollbar that sends you off the screen. + - bugfix: Exosuit fabricators' queue list & Techfab/Autolathe's left side (with + the sections of printables) now have a scrollbar when the full list doesn't + fit on the UI for 516 users. Techfab/Autolathe also now does this for the list + of items too, instead of always having one. + SmArtKar: + - bugfix: Tactical medkits should no longer create invisible medbots + - image: Implemented the missing bezerk medbot skin + - bugfix: Fixed another two missing areas on icebox + - bugfix: Fixed incorrect power consumption on reagent grinders + - bugfix: Fixed wrong area/wall in Icemoon Underground + - map: Added cooling loops and cold tiles to all kitchen freezers that were missing + them + - bugfix: Fixed plant analyzers not being placeable on tables/in backpacks + - bugfix: Fixed stunprod's missing inhands sprite + TiviPlus: + - bugfix: fixed some admin links not working on 516 + Y0SH1M4S73R: + - bugfix: Joining a minigame or taking certain ghost roles, while you have a mind + without a body, will no longer DNR you, just in case you can be resurrected + by some means. + - bugfix: If your old body is permanently destroyed while you are playing a minigame + or as certain ghost roles, you will still return to your character's original + mind, just in case you can be resurrected by some means. + - bugfix: The basketball minigame now gives its players and referee temporary bodies. +2025-02-07: + Runi-c: + - balance: slips now make you eligible for being shove stunned + SmArtKar: + - balance: Removed an oversight which allowed you to farm fishing achievements + TiviPlus: + - server: An issue where more than 16 admin flags could not exist in the DB has + been corrected +2025-02-08: + Absolucy: + - bugfix: Fixed some mistakes I made while fixing the void cloak. + Holoo-1: + - bugfix: fixed camera consoles, spyglasses etc. client crush on 516 + MTandi: + - qol: Tile context menu tweaks (Loot panel) + Thunder12345: + - map: Removed a mounted machine gun from the Meta Central bitrunning domain, expect + 85% less instant wipes. + Wallem: + - qol: Integrated Circuit nodes are now colored depending on their type. + necromanceranne: + - balance: Hunter boxing now directly heals you instead of injecting you with healing + chems on a successful crit. + - balance: Your combos no longer cause you to screw up your next combo by changing + your attack speed for exactly one punch. + - code_imp: Fixes up a bit of odd rounding that occurs in the experience gain totals + and uses division instead of multipliers where it makes sense. + - refactor: Gun maintenance is now consolidated into a single item, the gun maintenance + kit, rather than multiple different item interactions. It is handled on the + maintenance kit itself, and not in gun code. + - qol: You can order maintenance kits from cargo, and get some out of the security + equipment vendor. Helpful if someone spilled acid onto your disabler. You can + also make a makeshift one from maintenance trash. + vinylspiders: + - qol: alien eggs (xeno embryos, headslugs, etc) will now show up on the advanced + medical scanner +2025-02-09: + Likteer: + - qol: Added the resin mister module to the roundstart atmos MODsuit. + Melbert: + - rscadd: Adds two fantasy affixes + SmArtKar: + - rscadd: Hydrogen Peroxide and Eldritch Essence now can rust turfs, with latter + producing heretic instead of normal rust. + - spellcheck: Fixed a misspelled comment and a reference to non-existent Eldritch + water (as opposed to Eldritch Essence) + TealSeer: + - bugfix: Fixed the crystallizer missing pipe connectors + grungussuss: + - sound: gauze now makes sounds when applied + loganuk: + - qol: Pyro Slime Objective Text Edit + necromanceranne: + - code_imp: Removes a variable in the riddable creature component that shouldn't + be doing what it is doing. + timothymtorres: + - code_imp: Add error message logs to screenshot CI test failure when screenshots + do not exist. diff --git a/icons/effects/mapping_helpers.dmi b/icons/effects/mapping_helpers.dmi index c415d4dcff1f4..cd8d331a5e7e6 100644 Binary files a/icons/effects/mapping_helpers.dmi and b/icons/effects/mapping_helpers.dmi differ diff --git a/icons/mob/silicon/aibots.dmi b/icons/mob/silicon/aibots.dmi index 7a4d3ca9c9cf4..b0bc6261f6de5 100644 Binary files a/icons/mob/silicon/aibots.dmi and b/icons/mob/silicon/aibots.dmi differ diff --git a/icons/obj/storage/toolbox.dmi b/icons/obj/storage/toolbox.dmi index 49385d5b73cf2..ccc9c2cc4397e 100644 Binary files a/icons/obj/storage/toolbox.dmi and b/icons/obj/storage/toolbox.dmi differ diff --git a/sound/items/gauze/attribution.txt b/sound/items/gauze/attribution.txt new file mode 100644 index 0000000000000..3b5f511e695a6 --- /dev/null +++ b/sound/items/gauze/attribution.txt @@ -0,0 +1,10 @@ +{ +bandage_begin1.ogg +bandage_begin2.ogg +bandage_begin3.ogg +bandage_begin4.ogg +bandage_end1.ogg +bandage_end2.ogg +bandage_end3.ogg +bandage_end4.ogg +} - made by sadboyssuss \ No newline at end of file diff --git a/sound/items/gauze/bandage_begin1.ogg b/sound/items/gauze/bandage_begin1.ogg new file mode 100644 index 0000000000000..47c2c6c28881c Binary files /dev/null and b/sound/items/gauze/bandage_begin1.ogg differ diff --git a/sound/items/gauze/bandage_begin2.ogg b/sound/items/gauze/bandage_begin2.ogg new file mode 100644 index 0000000000000..6372d03f2dbcb Binary files /dev/null and b/sound/items/gauze/bandage_begin2.ogg differ diff --git a/sound/items/gauze/bandage_begin3.ogg b/sound/items/gauze/bandage_begin3.ogg new file mode 100644 index 0000000000000..aeb1c8e9be82f Binary files /dev/null and b/sound/items/gauze/bandage_begin3.ogg differ diff --git a/sound/items/gauze/bandage_begin4.ogg b/sound/items/gauze/bandage_begin4.ogg new file mode 100644 index 0000000000000..53c8dcc2f58c6 Binary files /dev/null and b/sound/items/gauze/bandage_begin4.ogg differ diff --git a/sound/items/gauze/bandage_end1.ogg b/sound/items/gauze/bandage_end1.ogg new file mode 100644 index 0000000000000..0a786d15cdbd8 Binary files /dev/null and b/sound/items/gauze/bandage_end1.ogg differ diff --git a/sound/items/gauze/bandage_end2.ogg b/sound/items/gauze/bandage_end2.ogg new file mode 100644 index 0000000000000..49510d9275c45 Binary files /dev/null and b/sound/items/gauze/bandage_end2.ogg differ diff --git a/sound/items/gauze/bandage_end3.ogg b/sound/items/gauze/bandage_end3.ogg new file mode 100644 index 0000000000000..97b34cc13d8e9 Binary files /dev/null and b/sound/items/gauze/bandage_end3.ogg differ diff --git a/sound/items/gauze/bandage_end4.ogg b/sound/items/gauze/bandage_end4.ogg new file mode 100644 index 0000000000000..6cbaf67489a8f Binary files /dev/null and b/sound/items/gauze/bandage_end4.ogg differ diff --git a/tgstation.dme b/tgstation.dme index b9b6bcead502a..e6d8ab36d33af 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1466,6 +1466,7 @@ #include "code\datums\elements\can_barricade.dm" #include "code\datums\elements\can_shatter.dm" #include "code\datums\elements\caseless.dm" +#include "code\datums\elements\chain_lightning_attack.dm" #include "code\datums\elements\chemical_transfer.dm" #include "code\datums\elements\chewable.dm" #include "code\datums\elements\cleaning.dm" @@ -1582,6 +1583,7 @@ #include "code\datums\elements\skill_reward.dm" #include "code\datums\elements\skittish.dm" #include "code\datums\elements\slapcrafting.dm" +#include "code\datums\elements\slow_target_click_cd_attack.dm" #include "code\datums\elements\soft_landing.dm" #include "code\datums\elements\spooky.dm" #include "code\datums\elements\squish.dm" diff --git a/tgui/packages/tgui-panel/chat/middleware.js b/tgui/packages/tgui-panel/chat/middleware.js index 83fc28dc86a99..f221f3a7c53f6 100644 --- a/tgui/packages/tgui-panel/chat/middleware.js +++ b/tgui/packages/tgui-panel/chat/middleware.js @@ -135,13 +135,14 @@ export const chatMiddleware = (store) => { requesting < sequence; requesting++ ) { - requested_sequences.push(requesting); + sequences_requested.push(requesting); Byond.sendMessage('chat/resend', requesting); } } } chatRenderer.processBatch([payload_obj.content]); + sequences.push(sequence); return; } if (type === loadChat.type) { diff --git a/tgui/packages/tgui/interfaces/Autolathe.tsx b/tgui/packages/tgui/interfaces/Autolathe.tsx index 34e33caaf3e00..3f60a32785057 100644 --- a/tgui/packages/tgui/interfaces/Autolathe.tsx +++ b/tgui/packages/tgui/interfaces/Autolathe.tsx @@ -53,7 +53,7 @@ export const Autolathe = (props) => { return ( - +
diff --git a/tgui/packages/tgui/interfaces/ExosuitFabricator.tsx b/tgui/packages/tgui/interfaces/ExosuitFabricator.tsx index f2d331ede6a0d..56f09c990c785 100644 --- a/tgui/packages/tgui/interfaces/ExosuitFabricator.tsx +++ b/tgui/packages/tgui/interfaces/ExosuitFabricator.tsx @@ -242,8 +242,8 @@ const Queue = (props: QueueProps) => { />
- -
+ +
(
- -
+ +
( />
- -
+ +
{searchText.length > 0 ? ( {sortBy( diff --git a/tgui/packages/tgui/interfaces/IntegratedCircuit/DisplayComponent.jsx b/tgui/packages/tgui/interfaces/IntegratedCircuit/DisplayComponent.jsx index b0251a09e64bf..23269cd156744 100644 --- a/tgui/packages/tgui/interfaces/IntegratedCircuit/DisplayComponent.jsx +++ b/tgui/packages/tgui/interfaces/IntegratedCircuit/DisplayComponent.jsx @@ -1,5 +1,6 @@ import { Component, createRef } from 'react'; import { Box, Button, Stack } from 'tgui-core/components'; +import { classes } from 'tgui-core/react'; import { noop } from './constants'; import { Port } from './Port'; @@ -39,24 +40,35 @@ export class DisplayComponent extends Component { render() { const { component, fixedSize, ...rest } = this.props; + const categoryClass = `ObjectComponent__Category__${component.category || 'Unassigned'}`; return (
{component.name} + {!!component.ui_alerts && + Object.keys(component.ui_alerts).map((icon) => ( + + ); if (is_blind) return content; - return {content}; + return content; } diff --git a/tgui/packages/tgui/interfaces/LootPanel/RawContents.tsx b/tgui/packages/tgui/interfaces/LootPanel/RawContents.tsx index 9a4f97362f8a6..1b70487f2df39 100644 --- a/tgui/packages/tgui/interfaces/LootPanel/RawContents.tsx +++ b/tgui/packages/tgui/interfaces/LootPanel/RawContents.tsx @@ -1,4 +1,4 @@ -import { Flex } from 'tgui-core/components'; +import { Box } from 'tgui-core/components'; import { createSearch } from 'tgui-core/string'; import { LootBox } from './LootBox'; @@ -17,12 +17,10 @@ export function RawContents(props: Props) { ); return ( - + {filteredContents.map((item) => ( - - - + ))} - + ); } diff --git a/tgui/packages/tgui/interfaces/LootPanel/index.tsx b/tgui/packages/tgui/interfaces/LootPanel/index.tsx index 6c3c358636a2a..a010982357d5c 100644 --- a/tgui/packages/tgui/interfaces/LootPanel/index.tsx +++ b/tgui/packages/tgui/interfaces/LootPanel/index.tsx @@ -1,6 +1,8 @@ import { useState } from 'react'; -import { Button, Input, Section, Stack } from 'tgui-core/components'; +import { useMemo } from 'react'; +import { Box, Button, Input, Section } from 'tgui-core/components'; import { isEscape } from 'tgui-core/keys'; +import { clamp } from 'tgui-core/math'; import { BooleanLike } from 'tgui-core/react'; import { useBackend } from '../../backend'; @@ -18,54 +20,78 @@ export function LootPanel(props) { const { act, data } = useBackend(); const { contents = [], searching } = data; + // limitations: items with different stack counts, charges etc. + const contentsByPathName = useMemo(() => { + const acc: Record = {}; + + for (let i = 0; i < contents.length; i++) { + const item = contents[i]; + if (item.path) { + if (!acc[item.path + item.name]) { + acc[item.path + item.name] = []; + } + acc[item.path + item.name].push(item); + } else { + acc[item.ref] = [item]; + } + } + return acc; + }, [contents]); + const [grouping, setGrouping] = useState(true); const [searchText, setSearchText] = useState(''); - const total = contents.length ? contents.length - 1 : 0; + const headerHeight = 38; + const itemHeight = 38; + const minHeight = headerHeight + itemHeight; + const maxHeight = headerHeight + itemHeight * 10; + const height: number = clamp( + headerHeight + + (!grouping ? contents.length : Object.keys(contentsByPathName).length) * + itemHeight, + minHeight, + maxHeight, + ); return ( - + + setSearchText(value)} + placeholder={`Search items...`} + /> +