diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 9d11a11473320..f63a030c882a1 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -22,6 +22,7 @@ balance: rebalanced something fix: fixed a few things sound: added/modified/removed audio or sound effects image: added/modified/removed some icons or images +map: added/modified/removed map content spellcheck: fixed a few typos code: changed some code refactor: refactored some code diff --git a/.github/workflows/discord_discussions.yml b/.github/workflows/discord_discussions.yml new file mode 100644 index 0000000000000..439315cbb9546 --- /dev/null +++ b/.github/workflows/discord_discussions.yml @@ -0,0 +1,52 @@ +name: Discord Discussions + +on: + pull_request_target: + types: + - opened + - reopened + - edited + - labeled + - closed + branches: + - master + +concurrency: + group: "discord-discussions-${{ github.head_ref }}" + cancel-in-progress: true + +jobs: + manage-discord-discussion: + name: Manage Discord Discussion + runs-on: ubuntu-latest + if: contains(github.event.pull_request.labels.*.name, 'Discord Discussion') + steps: + - name: Fail if vars.DISCORD_DISCUSSIONS_CHANNEL_ID is unset + if: ${{ vars.DISCORD_DISCUSSIONS_CHANNEL_ID == '' }} + run: | + echo "vars.DISCORD_DISCUSSIONS_CHANNEL_ID (${{ vars.DISCORD_DISCUSSIONS_CHANNEL_ID }}) must be set to use this label!" + exit 1 + + - name: Setup dotnet + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + dotnet-quality: ga + + - name: Checkout + uses: actions/checkout@v4 + + - name: Build Tgstation.DiscordDiscussions + run: dotnet publish -c Release -o discord_discussions_bins tools/Tgstation.DiscordDiscussions/Tgstation.DiscordDiscussions.csproj + + - name: Generate App Token + id: app-token-generation + uses: getsentry/action-github-app-token@d4b5da6c5e37703f8c3b3e43abb5705b46e159cc + with: + app_id: ${{ secrets.APP_ID }} + private_key: ${{ secrets.APP_PRIVATE_KEY }} + + - name: Run Tgstation.DiscordDiscussions + run: dotnet discord_discussions_bins/Tgstation.DiscordDiscussions.dll ${{ steps.app-token-generation.outputs.token }} ${{ github.repository_owner }} ${{ github.event.repository.name }} ${{ github.event.pull_request.number }} ${{ github.event.pull_request.merged && 'merged' || github.event.pull_request.state }} ${{ secrets.DISCORD_DISCUSSIONS_TOKEN }} ${{ vars.DISCORD_DISCUSSIONS_CHANNEL_ID }} ${{ github.event.action == 'reopened' && 'true' || 'false' }} ${{ vars.DISCORD_JOIN_LINK }} + env: + GITHUB_PULL_REQUEST_TITLE: ${{ github.event.pull_request.title }} diff --git a/.github/workflows/generate_documentation.yml b/.github/workflows/generate_documentation.yml index 40710a9044b74..388c907b25296 100644 --- a/.github/workflows/generate_documentation.yml +++ b/.github/workflows/generate_documentation.yml @@ -27,7 +27,7 @@ jobs: touch dmdoc/.nojekyll echo codedocs.tgstation13.org > dmdoc/CNAME - name: Deploy - uses: JamesIves/github-pages-deploy-action@v4.6.4 + uses: JamesIves/github-pages-deploy-action@v4.6.8 with: branch: gh-pages clean: true diff --git a/.github/workflows/tgs_test.yml b/.github/workflows/tgs_test.yml index 37062e440735a..4b7853aa77cfe 100644 --- a/.github/workflows/tgs_test.yml +++ b/.github/workflows/tgs_test.yml @@ -14,6 +14,7 @@ on: - 'code/__DEFINES/tgs.dm' - 'code/game/world.dm' - 'code/modules/tgs/**' + - 'tools/bootstrap/**' - 'tools/tgs_scripts/**' - 'tools/tgs_test/**' pull_request: @@ -28,6 +29,7 @@ on: - 'code/__DEFINES/tgs.dm' - 'code/game/world.dm' - 'code/modules/tgs/**' + - 'tools/bootstrap/**' - 'tools/tgs_scripts/**' - 'tools/tgs_test/**' merge_group: diff --git a/.gitignore b/.gitignore index 8ef9946abc935..28e074442df9c 100644 --- a/.gitignore +++ b/.gitignore @@ -180,6 +180,10 @@ Temporary Items /tools/MapAtmosFixer/MapAtmosFixer/bin/* /tools/CreditsTool/bin/* /tools/CreditsTool/obj/* +/tools/Tgstation.DiscordDiscussions/.vs/* +/tools/Tgstation.DiscordDiscussions/bin/* +/tools/Tgstation.DiscordDiscussions/obj/* +/tools/Tgstation.DiscordDiscussions/Properties/launchSettings.json #GitHub Atom .atom-build.json diff --git a/_maps/RandomRuins/IceRuins/icemoon_surface_lodge.dmm b/_maps/RandomRuins/IceRuins/icemoon_surface_lodge.dmm new file mode 100644 index 0000000000000..d35fc52db02b4 --- /dev/null +++ b/_maps/RandomRuins/IceRuins/icemoon_surface_lodge.dmm @@ -0,0 +1,4641 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"ac" = ( +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"aw" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/floor, +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"aA" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = 5; + pixel_y = 8 + }, +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/turf/open/floor/carpet/royalblack, +/area/ruin/huntinglodge) +"aE" = ( +/obj/item/shovel, +/obj/structure/rack, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 5 + }, +/obj/item/shovel{ + pixel_x = -5; + pixel_y = 1 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"aU" = ( +/obj/effect/decal/cleanable/blood/footprints{ + dir = 8 + }, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"be" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 6 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"bs" = ( +/obj/machinery/door/airlock/wood{ + color = "#beada5" + }, +/obj/effect/decal/cleanable/blood/tracks{ + dir = 4 + }, +/obj/structure/fans/tiny, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"bR" = ( +/obj/structure/railing{ + dir = 8; + color = "#beada5" + }, +/obj/structure/railing{ + dir = 4; + color = "#beada5" + }, +/obj/effect/decal/cleanable/blood/drip, +/turf/open/floor/iron/stairs{ + color = "#5d341f" + }, +/area/ruin/huntinglodge) +"bV" = ( +/obj/effect/decal/cleanable/blood/trails{ + dir = 10 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"bX" = ( +/obj/structure/table, +/obj/machinery/gibber, +/obj/machinery/light/warm/directional/south, +/turf/open/floor/iron/checker, +/area/ruin/huntinglodge) +"ca" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/blood/footprints{ + dir = 1 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/mob/living/basic/viscerator, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"cy" = ( +/obj/structure/chair/wood/wings{ + dir = 4 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/obj/effect/mob_spawn/corpse/human/skeleton/cultist, +/obj/effect/decal/cleanable/blood/splatter, +/obj/effect/decal/cleanable/blood/gibs/old, +/turf/open/floor/carpet/lone/star, +/area/ruin/huntinglodge) +"cC" = ( +/obj/effect/turf_decal/siding/wood, +/obj/effect/decal/cleanable/plastic, +/obj/effect/decal/cleanable/dirt, +/mob/living/basic/viscerator, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"cJ" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/kitchenspike, +/obj/effect/decal/cleanable/blood/gibs/old, +/turf/open/floor/iron/checker, +/area/ruin/huntinglodge) +"cO" = ( +/obj/effect/decal/cleanable/blood/drip, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"cQ" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/table/wood, +/obj/item/reagent_containers/cup/glass/coffee{ + pixel_x = 6; + pixel_y = 7 + }, +/obj/effect/spawner/random/food_or_drink/jelly_donuts{ + pixel_x = -4; + pixel_y = 2 + }, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"cS" = ( +/obj/effect/decal/cleanable/blood/trails{ + dir = 5 + }, +/turf/open/misc/hay/icemoon, +/area/ruin/huntinglodge) +"dc" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/obj/item/ammo_casing/c45{ + pixel_x = 2; + pixel_y = -4 + }, +/obj/item/gun/ballistic/automatic/pistol/m1911/no_mag, +/obj/effect/decal/cleanable/blood/trails{ + dir = 5 + }, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"dr" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/obj/machinery/light/floor, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"du" = ( +/obj/item/ammo_casing/c45{ + pixel_x = 8; + pixel_y = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"dC" = ( +/obj/machinery/door/airlock/wood{ + color = "#beada5" + }, +/obj/structure/fans/tiny, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"dP" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 5 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/machinery/light/small/dim/directional/west, +/obj/structure/railing{ + dir = 5; + color = "#beada5" + }, +/obj/structure/railing/corner{ + color = "#beada5" + }, +/turf/open/floor/stone, +/area/ruin/huntinglodge) +"dQ" = ( +/obj/effect/decal/cleanable/wrapping, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/mob_spawn/corpse/human/assistant, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"eh" = ( +/obj/effect/turf_decal/siding/wood, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/warm/directional/south, +/obj/structure/closet/crate/bin, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"ej" = ( +/obj/effect/decal/cleanable/blood/gibs/limb, +/obj/effect/decal/cleanable/blood/drip, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"et" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 9 + }, +/obj/item/kirbyplants/random, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"eB" = ( +/turf/open/floor/iron/stairs/left{ + color = "#5d341f"; + dir = 1 + }, +/area/ruin/huntinglodge) +"eD" = ( +/obj/effect/turf_decal/siding/wood/end{ + dir = 4 + }, +/obj/structure/railing/corner{ + dir = 8; + color = "#beada5" + }, +/obj/effect/decal/cleanable/blood/drip, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"eE" = ( +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = 5; + pixel_y = 6 + }, +/obj/effect/mapping_helpers/broken_floor, +/obj/item/chair/wood{ + dir = 1 + }, +/obj/effect/decal/cleanable/blood/footprints{ + dir = 4 + }, +/obj/machinery/light/small/dim/directional/north, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"eQ" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/turf/open/floor/carpet, +/area/ruin/huntinglodge) +"eX" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/mob/living/basic/viscerator, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"fb" = ( +/obj/effect/decal/cleanable/blood/trails{ + dir = 1 + }, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"fe" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"fi" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"fB" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/obj/item/kirbyplants/random, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"fK" = ( +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"fO" = ( +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = -4; + pixel_y = -3 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/chem_pile, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"fP" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 9 + }, +/obj/effect/decal/cleanable/blood/drip, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"gu" = ( +/obj/structure/table/wood, +/obj/effect/spawner/random/entertainment/toy{ + pixel_x = -6; + pixel_y = 7 + }, +/obj/effect/spawner/random/entertainment/toy, +/obj/effect/spawner/random/entertainment/plushie{ + pixel_x = -14; + pixel_y = 0 + }, +/obj/item/stack/wrapping_paper, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"gA" = ( +/obj/effect/decal/cleanable/blood/footprints{ + dir = 2 + }, +/obj/structure/chair/comfy/brown, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/effect/mob_spawn/corpse/human/minesite/overseer, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"gB" = ( +/obj/effect/decal/cleanable/blood/gibs/old, +/obj/effect/decal/cleanable/blood/footprints{ + dir = 4 + }, +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = 11; + pixel_y = -13 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/machinery/light/warm/directional/north, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"gM" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"gS" = ( +/obj/item/ammo_casing/c45{ + pixel_x = -4; + pixel_y = -7 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"gY" = ( +/turf/open/floor/light/colour_cycle/dancefloor_b, +/area/ruin/huntinglodge) +"gZ" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 10 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"hb" = ( +/obj/structure/railing{ + dir = 10; + color = "#beada5" + }, +/obj/structure/hedge, +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/obj/machinery/light/small/dim/directional/north, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"hf" = ( +/obj/structure/chair/wood/wings{ + dir = 8 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/obj/effect/mob_spawn/corpse/human/skeleton/cultist, +/obj/effect/decal/cleanable/blood/gibs/core, +/turf/open/floor/carpet/lone/star, +/area/ruin/huntinglodge) +"hl" = ( +/obj/effect/decal/cleanable/blood/tracks{ + dir = 4 + }, +/obj/effect/decal/cleanable/ash, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 4 + }, +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = -3; + pixel_y = -8 + }, +/obj/item/gun/ballistic/shotgun/riot, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"hm" = ( +/turf/open/floor/iron/stairs/right{ + color = "#5d341f"; + dir = 8 + }, +/area/ruin/huntinglodge) +"hE" = ( +/obj/effect/decal/cleanable/blood/footprints{ + dir = 1 + }, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"hK" = ( +/obj/effect/turf_decal/siding/wood/end{ + dir = 4 + }, +/obj/machinery/door/airlock/wood{ + color = "#beada5" + }, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"hP" = ( +/obj/structure/table/wood, +/obj/item/paper{ + pixel_x = 3; + pixel_y = 6 + }, +/obj/item/pen/fountain{ + pixel_x = -10; + pixel_y = 3 + }, +/obj/effect/turf_decal/siding/wood/end, +/obj/machinery/light/small/dim/directional/south, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"hV" = ( +/obj/effect/spawner/structure/window/reinforced{ + color = "#beada5" + }, +/obj/structure/curtain/cloth/fancy, +/obj/effect/decal/cleanable/blood/splatter/over_window, +/obj/effect/mapping_helpers/damaged_window, +/turf/open/floor/plating, +/area/ruin/huntinglodge) +"hZ" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/effect/decal/cleanable/blood/drip, +/obj/item/ammo_casing/c45{ + pixel_x = 7; + pixel_y = -5 + }, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"ic" = ( +/obj/item/ammo_casing/shotgun/buckshot/spent, +/obj/item/gift{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/effect/decal/cleanable/blood/gibs/body, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"if" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/blood/splatter, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"iq" = ( +/obj/effect/decal/cleanable/vomit, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"iZ" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 9 + }, +/obj/item/gift, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"jl" = ( +/obj/item/ammo_casing/c45{ + pixel_x = 2; + pixel_y = -3 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 10 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"jp" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 4 + }, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 8 + }, +/obj/item/bodypart/head/ethereal, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/obj/item/chair/stool, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"jr" = ( +/obj/structure/fermenting_barrel, +/obj/item/reagent_containers/cup/bucket/wooden{ + pixel_x = 1; + pixel_y = 13 + }, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"jF" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/obj/effect/decal/cleanable/blood/footprints{ + dir = 4 + }, +/obj/effect/decal/cleanable/brimdust, +/turf/open/floor/carpet/royalblack, +/area/ruin/huntinglodge) +"jK" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"jN" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/obj/effect/decal/cleanable/brimdust, +/turf/open/floor/carpet, +/area/ruin/huntinglodge) +"jQ" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/checker, +/area/ruin/huntinglodge) +"kf" = ( +/obj/structure/bookcase/random, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"kk" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/effect/decal/cleanable/blood/footprints{ + dir = 4 + }, +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = -5; + pixel_y = 6 + }, +/obj/effect/decal/cleanable/blood, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"kl" = ( +/obj/effect/turf_decal/siding/wood, +/obj/effect/decal/cleanable/ash, +/obj/effect/decal/cleanable/glass, +/turf/open/floor/carpet/royalblack, +/area/ruin/huntinglodge) +"kn" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 10 + }, +/turf/open/misc/hay/icemoon, +/area/icemoon/surface/outdoors/nospawn) +"kD" = ( +/mob/living/basic/viscerator, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 1 + }, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"kH" = ( +/obj/effect/decal/cleanable/blood/drip, +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/item/kirbyplants/random, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"kI" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/effect/decal/cleanable/blood/gibs/core, +/obj/effect/decal/cleanable/dirt/dust, +/obj/item/chair/stool{ + pixel_x = -10; + pixel_y = -14 + }, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"kJ" = ( +/obj/structure/chair/comfy/brown{ + dir = 4 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"kP" = ( +/obj/effect/turf_decal/siding/wood, +/obj/effect/decal/cleanable/blood/drip, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"kR" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 9 + }, +/obj/effect/decal/cleanable/blood/footprints{ + dir = 4 + }, +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/turf/open/floor/carpet/royalblack, +/area/ruin/huntinglodge) +"lc" = ( +/obj/effect/mob_spawn/corpse/human/skeleton/cultist, +/obj/effect/decal/cleanable/blood/gibs, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 8 + }, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"lv" = ( +/obj/machinery/light/small/dim/directional/west, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/ruin/huntinglodge) +"lC" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/obj/effect/decal/cleanable/dirt, +/obj/item/kirbyplants/random, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"lE" = ( +/obj/effect/turf_decal/siding/wood, +/obj/effect/decal/cleanable/blood/gibs/down, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"lJ" = ( +/obj/structure/table/wood, +/obj/effect/spawner/random/entertainment/toy_figure{ + pixel_x = -5; + pixel_y = 3 + }, +/obj/effect/spawner/random/entertainment/plushie{ + pixel_x = 11; + pixel_y = 0 + }, +/obj/effect/spawner/random/entertainment/musical_instrument{ + pixel_x = 11; + pixel_y = 0 + }, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"lL" = ( +/obj/structure/table/wood, +/obj/item/toy/talking/ai{ + pixel_x = -2; + pixel_y = 7 + }, +/obj/effect/spawner/random/entertainment/plushie{ + pixel_x = -18; + pixel_y = 7 + }, +/obj/effect/spawner/random/entertainment/plushie, +/obj/effect/spawner/random/entertainment/musical_instrument{ + pixel_x = -9; + pixel_y = 10 + }, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"lO" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/siding/wood/corner, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"lU" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/structure/chair/comfy/brown, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"mb" = ( +/obj/item/ammo_casing/shotgun/buckshot/spent, +/obj/effect/decal/cleanable/blood/trails{ + dir = 10 + }, +/obj/item/gun/ballistic/automatic/pistol/m1911/no_mag, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"mm" = ( +/obj/structure/table/wood, +/obj/item/storage/cans/sixbeer, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"mo" = ( +/obj/effect/turf_decal/siding/wood/end{ + dir = 8 + }, +/obj/effect/decal/cleanable/blood/drip, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"mq" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 9 + }, +/obj/effect/mob_spawn/corpse/human, +/obj/machinery/light/small/dim/directional/west, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"mr" = ( +/obj/structure/bed{ + dir = 4 + }, +/obj/item/bedsheet/rainbow{ + dir = 1 + }, +/obj/effect/mob_spawn/corpse/human/miner/explorer, +/obj/effect/turf_decal/siding/wood/end{ + dir = 4 + }, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"mA" = ( +/obj/machinery/light/small/dim/directional/south, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/ruin/huntinglodge) +"mG" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/structure/chair/stool/directional/north, +/obj/item/gun/ballistic/shotgun/riot, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"mX" = ( +/obj/structure/dresser, +/obj/machinery/light/small/dim/directional/north, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"nt" = ( +/obj/effect/mob_spawn/corpse/human/skeleton/cultist, +/obj/effect/turf_decal/siding/wood/end{ + dir = 4 + }, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"nC" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = -9; + pixel_y = -2 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/confetti, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"nI" = ( +/obj/effect/turf_decal/siding/wood, +/obj/structure/flora/tree/pine/xmas/presentless{ + pixel_x = -15; + pixel_y = 10 + }, +/turf/open/floor/carpet, +/area/ruin/huntinglodge) +"nK" = ( +/obj/structure/ore_container/food_trough/raptor_trough, +/turf/open/misc/hay/icemoon, +/area/ruin/huntinglodge) +"nX" = ( +/obj/structure/table/wood/fancy, +/obj/item/bodypart/head/ethereal, +/obj/machinery/light/warm/directional/east, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"og" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 9 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"oF" = ( +/obj/structure/bookcase/random, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"oT" = ( +/obj/machinery/computer/security/wooden_tv, +/obj/effect/decal/cleanable/cobweb/cobweb2, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"oW" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 6 + }, +/obj/effect/decal/cleanable/blood/drip, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"oY" = ( +/obj/structure/railing{ + dir = 10; + color = "#beada5" + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 10 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 6 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"pl" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = 0; + pixel_y = -2 + }, +/obj/effect/decal/cleanable/chem_pile, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"pr" = ( +/obj/effect/turf_decal/siding/wood, +/obj/effect/decal/cleanable/dirt, +/obj/item/chair/stool{ + dir = 4; + pixel_x = 0; + pixel_y = 4 + }, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"pE" = ( +/obj/structure/rack, +/obj/item/reagent_containers/cup/bucket/wooden{ + pixel_x = 3; + pixel_y = 10 + }, +/obj/item/reagent_containers/cup/bucket/wooden{ + pixel_x = -7; + pixel_y = 3 + }, +/turf/open/misc/hay/icemoon, +/area/ruin/huntinglodge) +"pF" = ( +/obj/effect/decal/cleanable/blood, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"pJ" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"pN" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/obj/machinery/light/small/dim/directional/west, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/decal/cleanable/confetti, +/obj/item/kirbyplants/random, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"pU" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/closet/secure_closet/freezer/fridge/all_access, +/obj/item/food/grown/carrot{ + pixel_x = 1; + pixel_y = 2 + }, +/obj/item/food/grown/carrot{ + pixel_x = 6; + pixel_y = -2 + }, +/obj/structure/sink/kitchen/directional/west, +/obj/machinery/light/warm/directional/north, +/turf/open/floor/iron/checker, +/area/ruin/huntinglodge) +"pX" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 1 + }, +/obj/effect/turf_decal/siding/wood/corner, +/obj/effect/decal/cleanable/blood/gibs/down, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"qp" = ( +/obj/effect/decal/cleanable/blood/splatter, +/obj/item/paper/crumpled/bloody, +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"qH" = ( +/obj/item/ammo_casing/c45{ + pixel_x = 2; + pixel_y = 2 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 9 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"qL" = ( +/obj/structure/table/wood/fancy/orange, +/obj/item/trash/tray{ + pixel_x = 0; + pixel_y = 3 + }, +/obj/item/bodypart/head{ + pixel_x = 0; + pixel_y = 3 + }, +/turf/open/floor/carpet/lone/star, +/area/ruin/huntinglodge) +"qO" = ( +/obj/effect/turf_decal/siding/wood/corner, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 1 + }, +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = -4; + pixel_y = -13 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"qU" = ( +/obj/item/hatchet/wooden{ + pixel_x = -8; + pixel_y = 17 + }, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"qW" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/obj/item/chair/stool, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"qZ" = ( +/obj/effect/decal/cleanable/blood/splatter, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"ry" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 5 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"rI" = ( +/obj/effect/decal/cleanable/blood/tracks, +/obj/effect/decal/cleanable/blood/trails{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"rS" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 9 + }, +/turf/open/floor/carpet, +/area/ruin/huntinglodge) +"sU" = ( +/obj/item/ammo_casing/c45, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 10 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"sX" = ( +/obj/structure/table/wood/fancy/royalblack, +/obj/effect/spawner/random/food_or_drink/jelly_donuts{ + pixel_x = 6; + pixel_y = 0 + }, +/obj/effect/spawner/random/food_or_drink/jelly_donuts{ + pixel_x = -5; + pixel_y = 11 + }, +/obj/effect/spawner/random/food_or_drink/jelly_donuts{ + pixel_x = -14; + pixel_y = 0 + }, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"ta" = ( +/obj/effect/decal/cleanable/blood/drip, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"td" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/blood/trails{ + dir = 10 + }, +/obj/effect/decal/cleanable/brimdust, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"tk" = ( +/obj/effect/turf_decal/siding/wood/end, +/obj/structure/rack, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/item/clothing/suit/hooded/wintercoat{ + pixel_x = -3; + pixel_y = 0 + }, +/obj/item/clothing/suit/hooded/wintercoat{ + pixel_x = -6; + pixel_y = 0 + }, +/obj/item/pickaxe, +/obj/item/pickaxe{ + pixel_x = 5; + pixel_y = -2 + }, +/obj/item/pickaxe{ + pixel_x = 2; + pixel_y = -1 + }, +/obj/item/flashlight{ + pixel_x = 0; + pixel_y = -2 + }, +/obj/item/flashlight{ + pixel_x = 5; + pixel_y = -4 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"tq" = ( +/obj/machinery/jukebox, +/turf/open/floor/carpet, +/area/ruin/huntinglodge) +"tT" = ( +/obj/effect/turf_decal/siding/wood, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"tY" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 8 + }, +/obj/item/gift{ + pixel_x = 0; + pixel_y = 3 + }, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"uc" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/mob_spawn/corpse/human/cook, +/turf/open/floor/iron/checker, +/area/ruin/huntinglodge) +"uU" = ( +/obj/structure/barricade/wooden/crude/snow, +/obj/machinery/door/airlock/wood, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/structure/fans/tiny, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"uZ" = ( +/obj/machinery/light/warm/directional/north, +/turf/open/misc/hay/icemoon, +/area/ruin/huntinglodge) +"vc" = ( +/obj/item/knife/combat/bone{ + pixel_x = -19; + pixel_y = -2 + }, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"vg" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/vomit, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"vr" = ( +/obj/structure/chair/wood/wings{ + dir = 8 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/obj/effect/mob_spawn/corpse/human/skeleton/cultist, +/obj/effect/decal/cleanable/blood, +/turf/open/floor/carpet/lone/star, +/area/ruin/huntinglodge) +"vv" = ( +/obj/structure/railing{ + dir = 10; + color = "#beada5" + }, +/obj/structure/hedge, +/obj/machinery/light/small/dim/directional/north, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"vH" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt, +/obj/item/kirbyplants/random, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"vK" = ( +/obj/effect/decal/cleanable/blood/footprints{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"vO" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/obj/structure/table/wood/fancy, +/obj/item/gift{ + pixel_x = 0; + pixel_y = 1 + }, +/obj/item/gift{ + pixel_x = 5; + pixel_y = 10 + }, +/obj/item/gift{ + pixel_x = -12; + pixel_y = 11 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"vW" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/obj/effect/decal/cleanable/blood/trails{ + dir = 5 + }, +/obj/item/kirbyplants/random, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"wd" = ( +/obj/structure/table/wood/fancy, +/obj/item/flashlight/lamp/green{ + pixel_x = 0; + pixel_y = 6 + }, +/turf/open/floor/carpet, +/area/ruin/huntinglodge) +"ws" = ( +/obj/structure/musician/piano{ + color = "#beada5" + }, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"ww" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/vending/dinnerware, +/turf/open/floor/iron/checker, +/area/ruin/huntinglodge) +"wC" = ( +/obj/structure/chair/wood/wings{ + dir = 4 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/turf/open/floor/carpet/lone/star, +/area/ruin/huntinglodge) +"wI" = ( +/obj/structure/noticeboard/directional/north, +/obj/item/gun/ballistic/shotgun/riot{ + pixel_x = 1; + pixel_y = 27 + }, +/obj/effect/turf_decal/siding/wood/end{ + dir = 8 + }, +/obj/structure/table/wood, +/obj/item/flashlight/lamp/green{ + pixel_x = -1; + pixel_y = 5 + }, +/turf/open/floor/stone, +/area/ruin/huntinglodge) +"wO" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"wP" = ( +/obj/effect/decal/cleanable/blood/gibs/up, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"wV" = ( +/obj/structure/fireplace, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/effect/turf_decal/siding/wood, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/stone, +/area/ruin/huntinglodge) +"xh" = ( +/obj/effect/turf_decal/siding/wood/end{ + dir = 4 + }, +/obj/effect/decal/cleanable/blood/old, +/obj/effect/decal/cleanable/blood/tracks, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"xv" = ( +/obj/effect/decal/cleanable/blood/gibs/down, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"xy" = ( +/obj/structure/chair/sofa/bench/left{ + dir = 8 + }, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"xz" = ( +/obj/effect/decal/cleanable/blood/gibs/body, +/obj/effect/decal/cleanable/blood/trails, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/siding/wood/corner, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 8 + }, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"xB" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = -4; + pixel_y = 8 + }, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"xE" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 9 + }, +/obj/structure/table/wood/fancy, +/obj/item/gift{ + pixel_x = -5; + pixel_y = 8 + }, +/obj/item/gift{ + pixel_x = 4; + pixel_y = 9 + }, +/obj/item/gift{ + pixel_x = 2; + pixel_y = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"xG" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 4 + }, +/obj/structure/railing{ + color = "#beada5" + }, +/obj/effect/turf_decal/siding/thinplating{ + color = "#beada5" + }, +/obj/effect/decal/cleanable/blood/drip, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"xH" = ( +/obj/effect/decal/cleanable/insectguts, +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/obj/item/kirbyplants/random, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"xM" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/structure/table/wood/fancy/royalblack, +/obj/machinery/light/warm/directional/west, +/obj/item/reagent_containers/cup/glass/coffee{ + pixel_x = -6; + pixel_y = 1 + }, +/obj/item/reagent_containers/cup/glass/coffee{ + pixel_x = 8; + pixel_y = 9 + }, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"xQ" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/obj/structure/chair/comfy/brown{ + dir = 1 + }, +/obj/effect/decal/cleanable/blood, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"ye" = ( +/obj/structure/table/wood, +/obj/effect/spawner/random/entertainment/toy{ + pixel_x = -17; + pixel_y = -1 + }, +/obj/effect/spawner/random/entertainment/plushie{ + pixel_x = 1; + pixel_y = 2 + }, +/obj/effect/spawner/random/entertainment/musical_instrument, +/obj/item/stack/wrapping_paper, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"yk" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/item/kirbyplants/random, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"yt" = ( +/obj/structure/chair/wood/wings{ + dir = 4 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 9 + }, +/turf/open/floor/carpet/lone/star, +/area/ruin/huntinglodge) +"yB" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/obj/effect/mob_spawn/corpse/human/skeleton/cultist, +/turf/open/floor/carpet, +/area/ruin/huntinglodge) +"yG" = ( +/obj/effect/turf_decal/siding/wood, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/mob_spawn/corpse/human/miner/explorer, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"yN" = ( +/obj/effect/decal/cleanable/blood/drip, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"yO" = ( +/obj/effect/decal/cleanable/garbage, +/obj/effect/decal/cleanable/blood/trails, +/obj/effect/decal/cleanable/blood/footprints{ + dir = 2 + }, +/obj/effect/decal/cleanable/dirt, +/mob/living/basic/viscerator, +/turf/open/floor/iron/checker, +/area/ruin/huntinglodge) +"yR" = ( +/obj/item/ammo_casing/c45{ + pixel_x = 7; + pixel_y = 3 + }, +/obj/item/ammo_casing/c45{ + pixel_x = -10; + pixel_y = -9 + }, +/obj/item/ammo_casing/c45{ + pixel_x = 1; + pixel_y = -7 + }, +/obj/item/ammo_casing/c45{ + pixel_x = -2; + pixel_y = 5 + }, +/obj/effect/decal/cleanable/ash, +/mob/living/basic/viscerator, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"yW" = ( +/obj/structure/railing/corner{ + color = "#beada5" + }, +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"zr" = ( +/obj/effect/decal/cleanable/blood/splatter/over_window, +/obj/effect/spawner/structure/window/reinforced{ + color = "#beada5" + }, +/obj/structure/curtain/cloth/fancy, +/turf/open/floor/plating, +/area/ruin/huntinglodge) +"zM" = ( +/obj/item/chair/stool/bamboo{ + dir = 8; + color = "#463934" + }, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"zN" = ( +/turf/open/floor/iron/stairs{ + color = "#5d341f" + }, +/area/ruin/huntinglodge) +"Ah" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/blood/gibs/core, +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"Ao" = ( +/obj/structure/table/wood, +/obj/effect/spawner/random/entertainment/toy{ + pixel_x = -10; + pixel_y = 7 + }, +/obj/effect/spawner/random/entertainment/toy_figure{ + pixel_x = 3; + pixel_y = 0 + }, +/obj/effect/spawner/random/entertainment/musical_instrument{ + pixel_x = -2; + pixel_y = -2 + }, +/obj/item/stack/wrapping_paper, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"Ar" = ( +/obj/effect/turf_decal/siding/wood/corner, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/decal/cleanable/blood/gibs/core, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"As" = ( +/obj/effect/decal/cleanable/blood/trails{ + dir = 5 + }, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"Aw" = ( +/obj/effect/decal/cleanable/blood/trails{ + dir = 10 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/decal/cleanable/blood/tracks, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"AF" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 6 + }, +/obj/effect/decal/cleanable/blood/tracks{ + dir = 10 + }, +/turf/open/misc/hay/icemoon, +/area/icemoon/surface/outdoors/nospawn) +"AG" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/obj/effect/decal/cleanable/blood/trails{ + dir = 10 + }, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"AV" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/oven/range, +/turf/open/floor/iron/checker, +/area/ruin/huntinglodge) +"AX" = ( +/obj/structure/table/wood, +/obj/item/clothing/suit/space/santa, +/obj/item/storage/backpack/santabag{ + pixel_x = -9; + pixel_y = 3 + }, +/obj/item/clothing/head/costume/santa{ + pixel_x = 8; + pixel_y = 8 + }, +/obj/item/ammo_box/magazine/m45{ + pixel_x = 8; + pixel_y = 0 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"Bl" = ( +/obj/structure/railing{ + dir = 6; + color = "#beada5" + }, +/obj/structure/hedge, +/obj/machinery/light/small/dim/directional/north, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"Bm" = ( +/obj/item/ammo_casing/c45{ + pixel_x = -5; + pixel_y = -4 + }, +/obj/item/ammo_casing/c45{ + pixel_x = -4; + pixel_y = 0 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"BE" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/structure/table/wood/fancy/orange, +/obj/item/plate/small{ + pixel_x = -6; + pixel_y = 8 + }, +/obj/item/plate/small{ + pixel_x = 7; + pixel_y = 1 + }, +/obj/item/reagent_containers/cup/glass{ + pixel_x = 7; + pixel_y = 17 + }, +/obj/item/food/meat/steak/plain/human{ + pixel_x = -6; + pixel_y = 10 + }, +/obj/item/food/meat/steak/plain/human{ + pixel_x = 7; + pixel_y = 1 + }, +/obj/item/reagent_containers/cup/glass{ + pixel_x = -8; + pixel_y = 3 + }, +/turf/open/floor/carpet/lone/star, +/area/ruin/huntinglodge) +"BI" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"Cv" = ( +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/misc/hay/icemoon, +/area/icemoon/surface/outdoors/nospawn) +"Cy" = ( +/obj/structure/noticeboard/directional/north, +/obj/item/bodypart/head{ + pixel_x = -1; + pixel_y = 25 + }, +/obj/effect/turf_decal/siding/wood/end{ + dir = 4 + }, +/obj/structure/table/wood, +/obj/item/paper/crumpled/bloody, +/obj/machinery/coffeemaker/impressa, +/turf/open/floor/stone, +/area/ruin/huntinglodge) +"CA" = ( +/turf/closed/mineral/snowmountain/cavern/icemoon, +/area/icemoon/surface/outdoors/nospawn) +"CC" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/obj/structure/chair/stool/directional/west, +/obj/effect/mob_spawn/corpse/human/skeleton/cultist, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/light/warm/dim/directional/east, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"CD" = ( +/turf/open/floor/iron/stairs/right{ + color = "#5d341f"; + dir = 1 + }, +/area/ruin/huntinglodge) +"CE" = ( +/obj/machinery/light/small/dim/directional/north, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/ruin/huntinglodge) +"CL" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/structure/table/wood/fancy, +/obj/item/gift{ + pixel_x = -18; + pixel_y = 10 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/item/flashlight/lamp/green{ + pixel_x = -1; + pixel_y = 4 + }, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"CS" = ( +/obj/effect/turf_decal/siding/wood/end{ + dir = 8 + }, +/obj/machinery/door/airlock/wood{ + color = "#beada5" + }, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"Dc" = ( +/obj/effect/turf_decal/siding/wood, +/obj/structure/chair/stool/directional/south, +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/obj/effect/decal/cleanable/confetti, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"Dp" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/obj/effect/decal/cleanable/dirt, +/obj/item/kirbyplants/random, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"Dq" = ( +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"Ds" = ( +/obj/effect/turf_decal/siding/wood, +/obj/structure/chair/comfy/brown{ + dir = 1 + }, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"DE" = ( +/obj/item/ammo_casing/c45{ + pixel_x = -9; + pixel_y = -2 + }, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"DF" = ( +/obj/structure/flora/tree/pine/style_2, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"DH" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/obj/machinery/light/warm/directional/east, +/obj/structure/table/wood, +/obj/item/clothing/shoes/winterboots/ice_boots, +/obj/item/clothing/shoes/winterboots/ice_boots{ + pixel_x = -5; + pixel_y = 11 + }, +/obj/item/clothing/shoes/winterboots/ice_boots{ + pixel_x = 6; + pixel_y = 9 + }, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"DM" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"DO" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/effect/decal/cleanable/blood/footprints, +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = 8; + pixel_y = -7 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"DX" = ( +/obj/effect/decal/cleanable/blood/footprints{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"Ea" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/obj/structure/table/wood, +/obj/effect/decal/cleanable/blood/splatter/over_window{ + pixel_x = -32; + pixel_y = 0 + }, +/obj/item/gift{ + pixel_x = 7; + pixel_y = 3 + }, +/obj/item/gift{ + pixel_x = -6; + pixel_y = -1 + }, +/obj/item/gift{ + pixel_x = -5; + pixel_y = 15 + }, +/obj/item/gift{ + pixel_x = 4; + pixel_y = 13 + }, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"Ei" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/item/ammo_casing/c45{ + pixel_x = -5; + pixel_y = -4 + }, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"Ej" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 9 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"Es" = ( +/obj/structure/table/wood/fancy, +/obj/item/gift{ + pixel_x = -1; + pixel_y = -11 + }, +/obj/item/gift{ + pixel_x = -6; + pixel_y = 4 + }, +/obj/item/gift{ + pixel_x = 9; + pixel_y = -11 + }, +/obj/item/gift{ + pixel_x = 10; + pixel_y = 0 + }, +/obj/item/gift{ + pixel_x = 6; + pixel_y = 12 + }, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"EB" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/obj/effect/decal/cleanable/blood/gibs/torso, +/obj/effect/decal/cleanable/chem_pile, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"EG" = ( +/obj/structure/bed, +/obj/item/bedsheet/gondola, +/obj/effect/turf_decal/siding/wood/end{ + dir = 8 + }, +/obj/effect/mob_spawn/corpse/human/miner/explorer, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"EJ" = ( +/turf/template_noop, +/area/template_noop) +"EK" = ( +/obj/effect/decal/cleanable/ash, +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = -28; + pixel_y = 10 + }, +/obj/effect/turf_decal/siding/wood, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"EY" = ( +/obj/effect/decal/cleanable/blood/trails{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 5 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"Fw" = ( +/obj/structure/railing{ + dir = 6; + color = "#beada5" + }, +/obj/structure/hedge, +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/obj/machinery/light/small/dim/directional/north, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"Fz" = ( +/obj/item/chair/stool/bamboo{ + dir = 4; + color = "#463934" + }, +/obj/item/flashlight/lantern/on{ + pixel_x = -2; + pixel_y = 4 + }, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"FN" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/obj/effect/decal/cleanable/garbage, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"FX" = ( +/obj/effect/turf_decal/siding/wood, +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = -9; + pixel_y = 5 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/machinery/light/warm/directional/north, +/obj/effect/decal/cleanable/blood, +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = 0; + pixel_y = -7 + }, +/obj/effect/decal/cleanable/chem_pile, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"Gj" = ( +/obj/structure/bed/double{ + dir = 1 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 9 + }, +/obj/item/bedsheet/patriot/double{ + dir = 4 + }, +/obj/effect/mob_spawn/corpse/human/laborer, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"Gl" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/decal/cleanable/blood/tracks{ + dir = 8 + }, +/obj/structure/railing/corner/end{ + dir = 4; + color = "#beada5" + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"Gn" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/obj/effect/decal/cleanable/dirt, +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = 5; + pixel_y = 8 + }, +/obj/item/kirbyplants/random, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"Gp" = ( +/obj/effect/spawner/structure/window/reinforced{ + color = "#beada5" + }, +/obj/structure/curtain/cloth/fancy, +/turf/open/floor/plating, +/area/ruin/huntinglodge) +"Gy" = ( +/obj/structure/falsewall/wood, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"GA" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 9 + }, +/obj/item/kirbyplants/random, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"GD" = ( +/obj/item/ammo_casing/shotgun/buckshot/spent, +/obj/item/gift{ + pixel_x = -6; + pixel_y = 11 + }, +/obj/effect/decal/cleanable/blood/footprints, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"GF" = ( +/obj/structure/chair/sofa/bench{ + dir = 8 + }, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"GN" = ( +/obj/item/ammo_casing/c45{ + pixel_x = 2; + pixel_y = 4 + }, +/obj/item/ammo_casing/c45{ + pixel_x = 3; + pixel_y = -4 + }, +/obj/item/ammo_casing/c45{ + pixel_x = -5; + pixel_y = 0 + }, +/obj/effect/decal/cleanable/blood/splatter, +/obj/item/gun/ballistic/automatic/pistol/m1911/no_mag, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"GU" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/decal/cleanable/blood/footprints{ + dir = 8 + }, +/obj/effect/decal/cleanable/blood/tracks{ + dir = 10 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"Hi" = ( +/obj/structure/table/wood/fancy, +/obj/effect/turf_decal/siding/wood, +/obj/item/stack/wrapping_paper, +/obj/item/stack/wrapping_paper{ + pixel_x = 0; + pixel_y = 12 + }, +/obj/item/gift{ + pixel_x = -10; + pixel_y = 8 + }, +/obj/item/gift{ + pixel_x = 0; + pixel_y = 14 + }, +/obj/item/gift{ + pixel_x = -7; + pixel_y = 1 + }, +/obj/item/gift{ + pixel_x = 7; + pixel_y = 7 + }, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"Hm" = ( +/obj/effect/decal/cleanable/blood/tracks{ + dir = 4 + }, +/obj/machinery/door/airlock/wood{ + color = "#beada5" + }, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"Ho" = ( +/obj/structure/closet/crate/trashcart, +/obj/item/storage/cans/sixbeer, +/obj/item/knife/hunting{ + pixel_x = -1; + pixel_y = -4 + }, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"Hq" = ( +/obj/effect/turf_decal/siding/wood/end{ + dir = 8 + }, +/obj/effect/decal/cleanable/blood/footprints, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"Hr" = ( +/obj/effect/decal/cleanable/blood/footprints{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt/dust, +/mob/living/basic/viscerator, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"Hv" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"Hw" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 9 + }, +/obj/item/trash/candle, +/turf/open/floor/carpet/royalblack, +/area/ruin/huntinglodge) +"Hx" = ( +/obj/effect/mapping_helpers/broken_floor, +/obj/effect/decal/cleanable/blood/gibs/core, +/turf/open/floor/iron/checker, +/area/ruin/huntinglodge) +"HC" = ( +/obj/structure/chair/wood/wings{ + dir = 8 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/turf/open/floor/carpet/lone/star, +/area/ruin/huntinglodge) +"HK" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/decal/cleanable/blood/drip, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"HL" = ( +/obj/structure/table/wood, +/obj/effect/spawner/random/entertainment/toy{ + pixel_x = 7; + pixel_y = 9 + }, +/obj/effect/spawner/random/entertainment/toy, +/obj/item/clothing/mask/facehugger/toy{ + pixel_x = -13; + pixel_y = 5 + }, +/obj/effect/spawner/random/entertainment/musical_instrument{ + pixel_x = 2; + pixel_y = 8 + }, +/obj/item/stack/wrapping_paper, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"Ia" = ( +/obj/effect/decal/cleanable/blood/gibs/core, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/decal/cleanable/brimdust, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"If" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/turf/open/floor/carpet, +/area/ruin/huntinglodge) +"Ig" = ( +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = -6; + pixel_y = -1 + }, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 8 + }, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"Ip" = ( +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = -4; + pixel_y = 2 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"Iq" = ( +/obj/effect/turf_decal/siding/wood, +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = -9; + pixel_y = 5 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/machinery/light/small/dim/directional/south, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"Iw" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = 4; + pixel_y = 7 + }, +/obj/effect/decal/cleanable/vomit, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"Iz" = ( +/obj/machinery/door/airlock/wood{ + color = "#beada5" + }, +/obj/effect/decal/cleanable/blood/footprints{ + dir = 2 + }, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"IH" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/table/wood, +/obj/item/storage/cans/sixbeer, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"IZ" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/mob/living/basic/viscerator, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"Jb" = ( +/turf/closed/wall/mineral/wood/nonmetal, +/area/ruin/huntinglodge) +"Jj" = ( +/obj/effect/mob_spawn/corpse/human/skeleton/cultist, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"Jk" = ( +/obj/effect/turf_decal/siding/wood, +/obj/structure/noticeboard/directional/north, +/obj/structure/sign/poster/contraband/blood_geometer/directional/east, +/obj/structure/table/wood, +/obj/item/paper{ + pixel_x = 3; + pixel_y = 6 + }, +/obj/machinery/light/small/dim/directional/east, +/obj/item/stack/wrapping_paper, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"Jo" = ( +/obj/effect/turf_decal/siding/wood, +/obj/structure/chair/stool/directional/south, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"JQ" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = 6; + pixel_y = 10 + }, +/obj/effect/decal/cleanable/blood{ + icon_state = "floor6-old" + }, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"JZ" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/obj/effect/decal/cleanable/confetti, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"Kc" = ( +/obj/effect/decal/cleanable/blood/drip, +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"Kl" = ( +/obj/structure/railing/corner{ + dir = 8; + color = "#beada5" + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"KB" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/obj/effect/decal/cleanable/blood/gibs/limb, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"KU" = ( +/obj/effect/turf_decal/siding/wood/end{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"Lt" = ( +/obj/effect/decal/cleanable/blood/drip, +/obj/effect/decal/cleanable/blood/gibs/core, +/obj/effect/turf_decal/siding/wood/corner, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"Lv" = ( +/obj/structure/table/wood, +/obj/effect/spawner/random/entertainment/toy_figure{ + pixel_x = -7; + pixel_y = 0 + }, +/obj/effect/spawner/random/entertainment/toy{ + pixel_x = 7; + pixel_y = 6 + }, +/obj/item/dualsaber/toy{ + pixel_x = -16; + pixel_y = 0 + }, +/obj/item/toy/toy_dagger{ + pixel_x = 4; + pixel_y = -9 + }, +/obj/effect/spawner/random/entertainment/musical_instrument{ + pixel_x = 2; + pixel_y = 4 + }, +/obj/item/stack/wrapping_paper, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"LQ" = ( +/obj/effect/mapping_helpers/broken_floor, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/obj/effect/decal/cleanable/blood/footprints{ + dir = 4 + }, +/obj/item/chair/wood/wings, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"Mb" = ( +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = 5; + pixel_y = 8 + }, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"Mc" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"Mf" = ( +/obj/machinery/light/warm/directional/west, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/ruin/huntinglodge) +"Mw" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/item/paper/crumpled, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"MJ" = ( +/obj/effect/turf_decal/siding/wood, +/obj/effect/turf_decal/siding/wood, +/obj/structure/chair/stool/directional/south, +/obj/effect/decal/cleanable/plastic, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"MQ" = ( +/obj/effect/mob_spawn/corpse/human/skeleton/cultist, +/obj/effect/decal/cleanable/blood/gibs, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"Nj" = ( +/obj/effect/decal/cleanable/blood/old, +/obj/effect/decal/cleanable/dirt/dust, +/mob/living/basic/viscerator, +/obj/effect/decal/cleanable/brimdust, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"Nl" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/structure/chair/stool/directional/north, +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/obj/effect/decal/cleanable/confetti, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"Nu" = ( +/turf/open/floor/light/colour_cycle/dancefloor_a, +/area/ruin/huntinglodge) +"Nw" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/item/ammo_casing/c45{ + pixel_x = -5; + pixel_y = -4 + }, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"NE" = ( +/obj/effect/turf_decal/siding/wood/end{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"NL" = ( +/obj/effect/turf_decal/siding/wood, +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = 15; + pixel_y = 9 + }, +/obj/machinery/light/small/dim/directional/south, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"NN" = ( +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"NP" = ( +/obj/structure/fermenting_barrel, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 6 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"NW" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"Oa" = ( +/obj/effect/turf_decal/siding/wood, +/obj/machinery/light/warm/directional/south, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/decal/cleanable/brimdust, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"Of" = ( +/obj/effect/turf_decal/siding/wood, +/obj/effect/decal/cleanable/blood/gibs/body, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"Ok" = ( +/obj/effect/turf_decal/siding/wood, +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"Oq" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 9 + }, +/obj/effect/decal/cleanable/brimdust, +/obj/item/kirbyplants/random, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"Ot" = ( +/obj/structure/table/wood/fancy, +/obj/item/gift{ + pixel_x = -4; + pixel_y = 9 + }, +/obj/item/gift{ + pixel_x = 7; + pixel_y = 3 + }, +/obj/item/gift{ + pixel_x = -4; + pixel_y = -1 + }, +/obj/item/gift{ + pixel_x = 2; + pixel_y = 10 + }, +/obj/item/gift{ + pixel_x = 7; + pixel_y = -3 + }, +/obj/item/gift{ + pixel_x = 7; + pixel_y = 17 + }, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"Oz" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/structure/table/wood, +/obj/effect/spawner/random/entertainment/musical_instrument{ + pixel_x = 3; + pixel_y = 2 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"OA" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/mob/living/basic/viscerator, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"OH" = ( +/obj/structure/noticeboard/directional/north, +/obj/item/paper/crumpled/bloody, +/obj/item/paper/crumpled/bloody, +/turf/open/misc/hay/icemoon, +/area/ruin/huntinglodge) +"ON" = ( +/obj/item/flashlight/lantern/on, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"OY" = ( +/obj/machinery/light/small/dim/directional/south, +/obj/structure/table/wood, +/obj/item/flashlight/lamp/green{ + pixel_x = 1; + pixel_y = 5 + }, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"OZ" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/decal/cleanable/blood/tracks{ + dir = 8 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"Pa" = ( +/obj/effect/decal/cleanable/blood/gibs/up, +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"Pd" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/effect/decal/cleanable/blood/drip, +/turf/open/floor/carpet/royalblack, +/area/ruin/huntinglodge) +"Pi" = ( +/obj/effect/decal/cleanable/blood/drip, +/obj/item/ammo_casing/c45{ + pixel_x = 7; + pixel_y = -5 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/obj/structure/closet/crate/bin, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"PK" = ( +/obj/structure/railing{ + dir = 9; + color = "#beada5" + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 5 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 9 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"PS" = ( +/obj/effect/spawner/structure/window/reinforced{ + color = "#beada5" + }, +/obj/structure/curtain/cloth/fancy, +/obj/effect/decal/cleanable/blood/splatter/over_window, +/turf/open/floor/plating, +/area/ruin/huntinglodge) +"PU" = ( +/turf/open/floor/iron/stairs/medium{ + color = "#5d341f" + }, +/area/ruin/huntinglodge) +"Qp" = ( +/obj/effect/turf_decal/siding/wood, +/obj/structure/table/wood/fancy/orange, +/obj/item/plate/small{ + pixel_x = -5; + pixel_y = 0 + }, +/obj/item/plate/small{ + pixel_x = 6; + pixel_y = 8 + }, +/obj/item/reagent_containers/cup/glass{ + pixel_x = -7; + pixel_y = 15 + }, +/obj/item/food/meat/steak/plain/human{ + pixel_x = -6; + pixel_y = 0 + }, +/obj/item/food/meat/steak/plain/human{ + pixel_x = 6; + pixel_y = 10 + }, +/obj/item/reagent_containers/cup/glass{ + pixel_x = 9; + pixel_y = 3 + }, +/turf/open/floor/carpet/lone/star, +/area/ruin/huntinglodge) +"Qy" = ( +/obj/effect/decal/cleanable/blood/footprints{ + dir = 4 + }, +/obj/effect/decal/cleanable/blood/gibs/limb, +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 1 + }, +/turf/open/floor/carpet/royalblack, +/area/ruin/huntinglodge) +"QB" = ( +/obj/machinery/door/airlock/wood{ + color = "#beada5" + }, +/obj/effect/decal/cleanable/blood/tracks, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"QG" = ( +/obj/effect/decal/cleanable/blood/tracks{ + dir = 8 + }, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"QS" = ( +/obj/effect/decal/cleanable/blood/footprints, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"Rg" = ( +/obj/effect/decal/cleanable/blood/footprints{ + dir = 4 + }, +/obj/effect/decal/cleanable/blood/footprints{ + dir = 4 + }, +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 4 + }, +/turf/open/floor/carpet/royalblack, +/area/ruin/huntinglodge) +"Rl" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/effect/decal/cleanable/blood/trails{ + dir = 5 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/mob/living/basic/viscerator, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"RB" = ( +/obj/effect/decal/cleanable/blood/gibs/body, +/obj/effect/decal/cleanable/blood/trails, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/checker, +/area/ruin/huntinglodge) +"RH" = ( +/obj/effect/turf_decal/siding/thinplating{ + color = "#beada5" + }, +/obj/structure/railing{ + color = "#beada5" + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"Sf" = ( +/obj/structure/rack, +/obj/item/gps/mining, +/obj/item/gps/mining{ + pixel_x = -7; + pixel_y = 4 + }, +/turf/open/misc/hay/icemoon, +/area/ruin/huntinglodge) +"Sg" = ( +/obj/effect/decal/cleanable/blood, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 4 + }, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"Sl" = ( +/obj/structure/chair/sofa/bench/right{ + dir = 8 + }, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"So" = ( +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = 5; + pixel_y = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 10 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"Sp" = ( +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/item/gift{ + pixel_x = -10; + pixel_y = 8 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"SK" = ( +/obj/structure/table/wood, +/obj/item/toy/talking{ + pixel_x = 1; + pixel_y = 10 + }, +/obj/item/stack/wrapping_paper, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"SL" = ( +/obj/effect/turf_decal/siding/wood, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/chem_pile, +/obj/effect/decal/cleanable/blood/footprints, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"SN" = ( +/mob/living/basic/raptor/green, +/turf/open/misc/hay/icemoon, +/area/ruin/huntinglodge) +"SO" = ( +/obj/effect/decal/cleanable/vomit, +/obj/effect/decal/cleanable/garbage, +/obj/effect/decal/cleanable/blood/footprints, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"SS" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/obj/machinery/light/small/dim/directional/east, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"SW" = ( +/obj/item/flashlight/lantern/on, +/obj/effect/decal/cleanable/blood/footprints{ + dir = 8 + }, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"Th" = ( +/obj/effect/decal/cleanable/blood/gibs, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"Tp" = ( +/obj/effect/turf_decal/siding/wood, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/decal/cleanable/blood/tracks, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"Tv" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"TC" = ( +/obj/effect/decal/cleanable/blood, +/obj/effect/decal/cleanable/blood/footprints{ + dir = 2 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/item/gift{ + pixel_x = -10; + pixel_y = -6 + }, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"TI" = ( +/obj/effect/turf_decal/siding/wood, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/item/gun/ballistic/shotgun/doublebarrel, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"TN" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 9 + }, +/obj/structure/chair/comfy/brown, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"TO" = ( +/turf/open/floor/iron/stairs/right{ + color = "#5d341f" + }, +/area/ruin/huntinglodge) +"TV" = ( +/mob/living/basic/migo/hatsune, +/turf/open/floor/light/colour_cycle, +/area/ruin/huntinglodge) +"Uv" = ( +/obj/effect/decal/cleanable/blood/gibs/down, +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"Ux" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/table, +/obj/item/knife/butcher, +/obj/item/chainsaw{ + pixel_x = 1; + pixel_y = 2 + }, +/obj/item/knife, +/turf/open/floor/iron/checker, +/area/ruin/huntinglodge) +"UB" = ( +/obj/structure/bed{ + dir = 4 + }, +/obj/item/bedsheet/rainbow{ + dir = 1 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/obj/effect/mob_spawn/corpse/human/miner/explorer, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"UJ" = ( +/obj/effect/decal/cleanable/blood/tracks, +/turf/open/misc/hay/icemoon, +/area/ruin/huntinglodge) +"US" = ( +/obj/structure/railing{ + color = "#beada5" + }, +/obj/effect/turf_decal/siding/thinplating{ + color = "#beada5" + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"Vb" = ( +/obj/effect/decal/cleanable/blood/tracks{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/item/ammo_casing/c45{ + pixel_x = -5; + pixel_y = -11 + }, +/obj/effect/decal/cleanable/glass, +/mob/living/basic/viscerator, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"Vk" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 8 + }, +/obj/effect/decal/cleanable/blood/drip, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/light/small/dim/directional/north, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"VC" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/effect/decal/cleanable/blood/footprints{ + dir = 2 + }, +/obj/item/gift, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"VE" = ( +/turf/open/floor/iron/stairs/left{ + color = "#5d341f" + }, +/area/ruin/huntinglodge) +"VO" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/machinery/light/small/dim/directional/west, +/turf/open/floor/stone, +/area/ruin/huntinglodge) +"VW" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 6 + }, +/obj/item/storage/cans/sixbeer{ + pixel_x = -4; + pixel_y = -15 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"Wn" = ( +/obj/effect/decal/cleanable/blood/splatter, +/obj/effect/decal/cleanable/blood/innards, +/obj/effect/decal/cleanable/blood/footprints, +/obj/effect/decal/cleanable/dirt/dust, +/mob/living/basic/viscerator, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"Ws" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/closet/crate/bin, +/turf/open/floor/iron/checker, +/area/ruin/huntinglodge) +"WC" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 8 + }, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 4 + }, +/obj/effect/decal/cleanable/blood/gibs/core, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/confetti, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"WX" = ( +/obj/effect/decal/cleanable/blood/footprints{ + dir = 4 + }, +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = 7; + pixel_y = -1 + }, +/obj/effect/turf_decal/siding/wood/corner, +/obj/item/gift, +/turf/open/floor/carpet/green, +/area/ruin/huntinglodge) +"Xa" = ( +/obj/effect/decal/cleanable/blood/gibs/up, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/checker, +/area/ruin/huntinglodge) +"Xd" = ( +/obj/effect/decal/cleanable/blood/drip, +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/turf/open/floor/carpet/royalblack, +/area/ruin/huntinglodge) +"Xf" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"Xk" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/mob/living/basic/viscerator, +/turf/open/floor/carpet/royalblack, +/area/ruin/huntinglodge) +"Xl" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/table/wood, +/obj/effect/turf_decal/siding/wood{ + dir = 9 + }, +/obj/item/flashlight/lamp/green{ + pixel_x = 0; + pixel_y = 4 + }, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"Xs" = ( +/obj/structure/railing{ + dir = 4; + color = "#beada5" + }, +/obj/structure/railing{ + dir = 8; + color = "#beada5" + }, +/turf/open/floor/iron/stairs{ + color = "#5d341f" + }, +/area/ruin/huntinglodge) +"Xu" = ( +/obj/effect/decal/cleanable/blood/footprints{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 5 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"XF" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/blood/footprints{ + dir = 1 + }, +/obj/machinery/griddle, +/turf/open/floor/iron/checker, +/area/ruin/huntinglodge) +"XL" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/light/floor, +/obj/effect/decal/cleanable/chem_pile, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"XN" = ( +/obj/effect/turf_decal/siding/wood, +/obj/effect/decal/cleanable/blood, +/obj/machinery/light/warm/dim/directional/south, +/turf/open/floor/carpet/royalblack, +/area/ruin/huntinglodge) +"XY" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 9 + }, +/obj/machinery/light/floor, +/obj/effect/decal/cleanable/dirt, +/obj/structure/closet/crate/bin, +/turf/open/floor/wood/large, +/area/ruin/huntinglodge) +"Yr" = ( +/obj/machinery/door/airlock/wood{ + color = "#beada5" + }, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"Yu" = ( +/obj/effect/turf_decal/siding/wood, +/obj/effect/mob_spawn/corpse/human/skeleton/cultist, +/obj/effect/decal/cleanable/glass, +/turf/open/floor/carpet/royalblack, +/area/ruin/huntinglodge) +"Yy" = ( +/obj/item/ammo_casing/c45{ + pixel_x = -1; + pixel_y = -1 + }, +/obj/effect/decal/cleanable/blood/trails{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 5 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"YD" = ( +/obj/effect/spawner/structure/window/reinforced{ + color = "#beada5" + }, +/obj/structure/curtain/cloth/fancy/mechanical/start_closed, +/turf/open/floor/plating, +/area/ruin/huntinglodge) +"YQ" = ( +/turf/open/misc/hay/icemoon, +/area/ruin/huntinglodge) +"YR" = ( +/obj/structure/chair/comfy/brown{ + dir = 8 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"YZ" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/mob/living/basic/viscerator, +/turf/open/floor/carpet/royalblack, +/area/ruin/huntinglodge) +"Zg" = ( +/obj/machinery/door/airlock/wood{ + color = "#beada5" + }, +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/obj/structure/fans/tiny, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) +"Zi" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 9 + }, +/obj/item/ammo_casing/shotgun/buckshot/spent, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/light/small/dim/directional/west, +/obj/item/kirbyplants/random, +/turf/open/floor/wood/tile, +/area/ruin/huntinglodge) +"Zk" = ( +/obj/effect/mob_spawn/corpse/human/skeleton/cultist, +/turf/open/misc/asteroid/snow/icemoon/do_not_chasm, +/area/icemoon/surface/outdoors/nospawn) +"Zs" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 9 + }, +/turf/open/floor/stone, +/area/icemoon/surface/outdoors/nospawn) +"ZA" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 6 + }, +/obj/machinery/light/small/dim/directional/east, +/turf/open/floor/stone, +/area/ruin/huntinglodge) +"ZB" = ( +/obj/structure/table/wood/fancy, +/obj/item/storage/fancy/candle_box{ + pixel_x = -1; + pixel_y = 5 + }, +/obj/effect/spawner/random/entertainment/lighter{ + pixel_x = 6; + pixel_y = -1 + }, +/turf/open/floor/carpet, +/area/ruin/huntinglodge) +"ZI" = ( +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/obj/item/bodypart/head/ethereal, +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/closet/crate/bin, +/turf/open/floor/wood, +/area/ruin/huntinglodge) +"ZN" = ( +/turf/open/floor/iron/stairs/left{ + color = "#5d341f"; + dir = 8 + }, +/area/ruin/huntinglodge) +"ZT" = ( +/obj/structure/table/wood, +/obj/effect/spawner/random/entertainment/toy{ + pixel_x = 5; + pixel_y = 0 + }, +/obj/effect/spawner/random/entertainment/toy_figure{ + pixel_x = -4; + pixel_y = 6 + }, +/obj/effect/spawner/random/entertainment/plushie{ + pixel_x = -10; + pixel_y = 4 + }, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"ZV" = ( +/obj/structure/table/wood, +/obj/effect/spawner/random/entertainment/toy_figure{ + pixel_x = 2; + pixel_y = 7 + }, +/obj/effect/spawner/random/entertainment/toy_figure{ + pixel_x = -5; + pixel_y = 0 + }, +/obj/effect/spawner/random/entertainment/plushie{ + pixel_x = 8; + pixel_y = 1 + }, +/obj/item/stack/wrapping_paper, +/turf/open/floor/carpet/red, +/area/ruin/huntinglodge) +"ZW" = ( +/obj/effect/turf_decal/siding/wood, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/dark/herringbone, +/area/ruin/huntinglodge) + +(1,1,1) = {" +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +"} +(2,1,1) = {" +EJ +EJ +CA +CA +fK +EJ +EJ +EJ +fK +DF +EJ +EJ +EJ +EJ +EJ +EJ +Zs +HK +wO +HK +wO +wO +gZ +fK +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +"} +(3,1,1) = {" +EJ +CA +CA +fK +fK +fK +fK +fK +fK +fK +fK +EJ +EJ +EJ +Zs +wO +oW +fK +ON +fK +Th +fb +EY +bV +So +fK +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +"} +(4,1,1) = {" +EJ +CA +CA +fK +ta +fK +Jb +hV +Gp +Jb +fK +fK +Zs +HK +be +ta +fK +Jb +Gp +Jb +fK +fK +Mb +As +ry +gZ +fK +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +"} +(5,1,1) = {" +EJ +CA +fK +DF +fK +Jb +Jb +Gj +AX +Jb +Jb +fK +NW +fK +fK +fK +Jb +Jb +eE +Jb +Gp +Gp +Jb +fK +hE +ry +fe +gZ +fK +EJ +EJ +EJ +EJ +EJ +EJ +"} +(6,1,1) = {" +EJ +EJ +fK +fK +mA +Jb +mX +dc +KB +oF +Jb +fP +ZA +fK +DF +fK +Jb +Jk +dQ +Iz +og +Mc +Jb +Jb +fK +fK +fK +NW +fK +EJ +EJ +EJ +EJ +EJ +EJ +"} +(7,1,1) = {" +EJ +EJ +EJ +fK +fK +Jb +oT +Vb +Bm +OY +Jb +dC +Jb +fK +fK +Jb +Jb +Jb +Jb +Jb +TC +lc +Dp +Jb +Jb +Jb +fK +NW +fK +EJ +EJ +EJ +EJ +EJ +EJ +"} +(8,1,1) = {" +EJ +EJ +EJ +fK +fK +Jb +Jb +Hm +Jb +Jb +Jb +mo +Jb +Jb +fK +Jb +TN +xM +xQ +Jb +DX +Sp +Ig +mq +kJ +Gp +aU +NW +fK +fK +EJ +EJ +EJ +EJ +EJ +"} +(9,1,1) = {" +EJ +EJ +fK +fK +Jb +Jb +Oq +BI +Gn +Jb +Jb +Vk +tk +Jb +Jb +Jb +lU +sX +Ds +Jb +gB +NN +xv +qZ +Hi +zr +fK +NW +DF +fK +EJ +EJ +EJ +EJ +EJ +"} +(10,1,1) = {" +EJ +EJ +ta +Jb +Jb +XY +eX +Ip +xB +vH +Jb +Yr +Jb +Jb +Jb +iZ +pl +IZ +Iw +Jb +QS +MQ +lO +Pa +YR +Gp +fK +NW +fK +fK +EJ +EJ +EJ +EJ +EJ +"} +(11,1,1) = {" +EJ +EJ +mA +Jb +wI +Ei +yt +wC +cy +SL +Yr +Hq +zN +Hq +VE +DO +rS +yB +tY +Kc +kD +fO +EK +Jb +Jb +Jb +fK +ry +gZ +fK +EJ +EJ +EJ +EJ +EJ +"} +(12,1,1) = {" +EJ +EJ +fK +Jb +wV +yR +BE +qL +Qp +Oa +Jb +Iq +Jb +FX +PU +hZ +eQ +nI +Lt +Uv +Sg +Hr +tT +Jb +fK +fK +fK +fK +NW +fK +EJ +EJ +EJ +EJ +EJ +"} +(13,1,1) = {" +EJ +EJ +fK +Jb +Cy +Nw +vr +hf +HC +Tp +QB +xh +zN +nt +TO +VC +If +jN +NL +Jb +xH +LQ +kH +Jb +CA +fK +fK +Zs +fi +sU +fK +EJ +EJ +EJ +EJ +"} +(14,1,1) = {" +EJ +fK +DF +Jb +Jb +dr +gM +if +Ar +yk +Jb +Jb +Jb +Jb +Jb +qp +hl +WX +Pi +Jb +YD +Yr +YD +Jb +CA +CA +Zs +be +Fz +Xu +jl +EJ +EJ +EJ +EJ +"} +(15,1,1) = {" +EJ +EJ +fK +CA +Jb +Jb +vW +AG +fB +Jb +Jb +Nu +TV +gY +Jb +Jb +Jj +pF +Jb +Jb +Xl +wP +kf +Jb +Jb +CA +NW +fK +DF +jr +du +EJ +EJ +EJ +EJ +"} +(16,1,1) = {" +EJ +EJ +fK +CA +CA +Jb +Jb +Zg +Jb +Jb +Jb +Gy +Jb +Jb +Jb +Jb +ZN +hm +Jb +kf +ca +xz +gA +hP +Jb +CA +ry +gZ +zM +qH +be +EJ +EJ +EJ +EJ +"} +(17,1,1) = {" +EJ +fK +fK +fK +ta +Mf +aE +Dq +NP +Jb +et +yW +Xs +KU +Jb +Bl +kR +YZ +Jb +kf +SS +ej +kf +Jb +Jb +CA +fK +Yy +gS +be +fK +EJ +EJ +EJ +EJ +"} +(18,1,1) = {" +EJ +fK +fK +fK +fK +fK +fK +Tv +fK +PS +Oz +US +xE +TI +Gp +Hw +Qy +XN +Jb +Jb +Jb +uU +Jb +Jb +fK +fK +fK +Ho +NW +fK +fK +EJ +EJ +EJ +EJ +"} +(19,1,1) = {" +EJ +DF +Jb +Jb +Jb +fK +fK +yN +fK +Gp +ws +RH +CL +kP +Yr +Pd +Xd +Yu +Gp +fK +dP +ac +VO +fK +fK +fK +fK +Zs +be +fK +fK +EJ +EJ +EJ +EJ +"} +(20,1,1) = {" +EJ +Jb +Jb +YQ +Jb +Jb +fK +NW +fK +Gp +CC +xG +vO +ZW +Gp +Xk +Rg +kl +hV +GN +Zk +EY +rI +Aw +GU +fe +wO +be +fK +fK +EJ +EJ +EJ +EJ +EJ +"} +(21,1,1) = {" +EJ +Jb +nK +SN +YQ +Jb +fK +vK +mA +Jb +Jb +eD +bR +NE +Jb +vv +jF +aA +Gp +DE +vc +fK +ta +fK +OZ +fK +fK +fK +fK +EJ +EJ +EJ +EJ +EJ +EJ +"} +(22,1,1) = {" +EJ +Jb +Sf +YQ +YQ +YQ +kn +Xf +fK +fK +Jb +Gp +Jb +Jb +Jb +Jb +ZN +hm +Jb +Jb +fK +DF +fK +fK +Gl +fK +fK +fK +fK +EJ +EJ +EJ +EJ +EJ +EJ +"} +(23,1,1) = {" +EJ +Jb +uZ +YQ +Jb +OH +Cv +cO +fK +ta +lv +fK +fK +Jb +Jb +Zi +kk +JQ +pN +Jb +Jb +fK +fK +PK +Kl +oY +fK +fK +DF +fK +EJ +EJ +EJ +EJ +EJ +"} +(24,1,1) = {" +EJ +Jb +pE +cS +UJ +YQ +AF +ry +gZ +fK +fK +DF +fK +Jb +GA +qO +nC +vg +jp +IH +Jb +Jb +Gp +Gp +bs +Gp +Jb +fK +fK +fK +EJ +EJ +EJ +EJ +EJ +"} +(25,1,1) = {" +EJ +Jb +nK +SN +YQ +Jb +QG +fK +Hv +fe +gZ +fK +Jb +Jb +XL +MJ +lJ +SK +Rl +yG +Jb +Fw +UB +Ea +Ej +mr +Jb +Jb +fK +EJ +EJ +EJ +EJ +EJ +EJ +"} +(26,1,1) = {" +EJ +Jb +Jb +YQ +Jb +Jb +QG +fK +Xf +DF +NW +fK +Gp +ZB +kI +Ok +ZV +lL +Nl +lE +CS +eB +SO +GD +Wn +Ia +mm +Jb +CE +fK +EJ +EJ +EJ +EJ +EJ +"} +(27,1,1) = {" +EJ +CA +Jb +Jb +Jb +fK +QG +SW +ry +wO +VW +fK +Gp +tq +Mw +Dc +Lv +ye +JZ +pr +hK +CD +mb +Nj +iq +ic +ZI +Jb +fK +DF +fK +EJ +EJ +EJ +EJ +"} +(28,1,1) = {" +CA +CA +fK +fK +fK +fK +Zk +qU +Sl +GF +xy +fK +Gp +wd +Ah +Jo +Ao +HL +qW +Of +Jb +hb +EG +EB +DH +EG +Jb +Jb +fK +fK +fK +EJ +EJ +EJ +EJ +"} +(29,1,1) = {" +CA +CA +CA +fK +fK +DF +fK +fK +DF +fK +fK +DF +Jb +Jb +aw +cC +gu +ZT +mG +eh +Jb +Jb +Jb +Yr +Jb +Jb +Jb +fK +fK +fK +EJ +EJ +EJ +EJ +EJ +"} +(30,1,1) = {" +EJ +CA +CA +fK +fK +fK +fK +fK +fK +DF +fK +fK +CA +Jb +lC +WC +td +OA +pX +cQ +Jb +AV +Xa +jQ +ww +Jb +fK +fK +EJ +EJ +EJ +EJ +EJ +EJ +EJ +"} +(31,1,1) = {" +EJ +CA +CA +CA +CA +CA +fK +fK +fK +fK +DF +CA +CA +Jb +Jb +jK +FN +DM +pJ +Jb +Jb +XF +RB +yO +bX +Jb +CE +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +"} +(32,1,1) = {" +EJ +EJ +CA +CA +CA +CA +CA +CA +CA +fK +fK +CA +CA +CA +Jb +Es +nX +Ot +Ot +Jb +pU +uc +jQ +Hx +cJ +Jb +fK +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +"} +(33,1,1) = {" +EJ +EJ +EJ +EJ +CA +CA +CA +CA +CA +CA +CA +CA +CA +CA +Jb +Gp +Gp +Gp +Gp +Jb +Jb +Ux +jQ +Ws +Jb +Jb +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +"} +(34,1,1) = {" +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +CA +CA +CA +CA +fK +lv +EJ +EJ +EJ +EJ +lv +Jb +Jb +dC +Jb +Jb +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +"} +(35,1,1) = {" +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +EJ +"} diff --git a/_maps/RandomRuins/IceRuins/icemoon_underground_syndielab.dmm b/_maps/RandomRuins/IceRuins/icemoon_underground_syndielab.dmm index 8d90a5079dbb1..15a51d2858a1e 100644 --- a/_maps/RandomRuins/IceRuins/icemoon_underground_syndielab.dmm +++ b/_maps/RandomRuins/IceRuins/icemoon_underground_syndielab.dmm @@ -571,7 +571,9 @@ pixel_y = -3; pixel_x = -3 }, -/obj/structure/closet/crate/secure/cybersun/dawn, +/obj/structure/closet/crate/secure/syndicate/cybersun/dawn{ + req_access = null + }, /turf/open/floor/mineral/plastitanium/red, /area/ruin/syndielab) "Hs" = ( @@ -781,9 +783,7 @@ "UM" = ( /obj/item/ammo_box/c9mm, /obj/item/ammo_box/magazine/m9mm, -/obj/structure/closet/crate/secure/gorlex_weapons{ - req_one_access = list("syndicate") - }, +/obj/structure/closet/crate/secure/syndicate/gorlex/weapons, /turf/open/floor/mineral/plastitanium/red, /area/ruin/syndielab) "Vf" = ( diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm index 7b7cec2c72a05..35492d9e9f2e0 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm @@ -63,12 +63,7 @@ /obj/item/cult_shift, /obj/effect/decal/remains/human, /obj/item/melee/cultblade/dagger, -/obj/effect/step_trigger/sound_effect{ - happens_once = 1; - name = "\proper a grave mistake"; - sound = 'sound/effects/hallucinations/i_see_you1.ogg'; - triggerer_only = 1 - }, +/obj/effect/step_trigger/sound_effect/lavaland_cult_altar, /obj/effect/step_trigger/message{ message = "You've made a grave mistake, haven't you?"; name = "ohfuck" diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm index 5653125ca0e60..6e29288ba6737 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm @@ -376,7 +376,7 @@ /obj/item/storage/box/lights/bulbs, /obj/item/storage/toolbox/mechanical/old, /obj/item/gift{ - contains_type = /obj/item/gun/ballistic/automatic/toy/unrestricted + contains_type = /obj/item/gun/ballistic/automatic/toy }, /obj/item/gift{ contains_type = /obj/item/gun/ballistic/automatic/pistol/toy diff --git a/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm b/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm index 4bdf2af01f19d..a52a428a8258a 100644 --- a/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm +++ b/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm @@ -573,13 +573,7 @@ /area/ruin/space/has_grav/derelictoutpost) "cC" = ( /obj/structure/alien/weeds/creature, -/mob/living/basic/creature{ - desc = "Awh its so sm-OH GOD WHAT THE FUCK."; - health = 25; - maxHealth = 25; - name = "hatchling"; - current_size = 0.85 - }, +/mob/living/basic/creature/hatchling, /turf/open/floor/iron, /area/ruin/space/has_grav/derelictoutpost) "cD" = ( @@ -765,9 +759,7 @@ /area/ruin/space/has_grav/derelictoutpost) "dl" = ( /obj/structure/alien/weeds/creature, -/mob/living/basic/creature{ - name = "Miss Tiggles" - }, +/mob/living/basic/creature/tiggles, /turf/open/floor/iron, /area/ruin/space/has_grav/derelictoutpost) "dm" = ( diff --git a/_maps/RandomRuins/SpaceRuins/commsbuoy_lowtech.dmm b/_maps/RandomRuins/SpaceRuins/commsbuoy_lowtech.dmm new file mode 100644 index 0000000000000..994589f0e51e0 --- /dev/null +++ b/_maps/RandomRuins/SpaceRuins/commsbuoy_lowtech.dmm @@ -0,0 +1,283 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/template_noop, +/area/template_noop) +"c" = ( +/obj/structure/lattice/catwalk, +/obj/structure/marker_beacon/burgundy, +/turf/template_noop, +/area/space/nearstation) +"d" = ( +/obj/structure/fluff/tram_rail/end{ + dir = 1 + }, +/obj/structure/fluff/tram_rail, +/turf/template_noop, +/area/space/nearstation) +"j" = ( +/obj/structure/lattice/catwalk, +/turf/template_noop, +/area/space/nearstation) +"m" = ( +/obj/structure/fluff/tram_rail/end{ + dir = 8 + }, +/turf/template_noop, +/area/space/nearstation) +"n" = ( +/obj/structure/fluff/tram_rail/end{ + dir = 4 + }, +/turf/template_noop, +/area/space/nearstation) +"o" = ( +/obj/structure/fluff/sat_dish{ + pixel_y = -15; + pixel_x = -11 + }, +/obj/structure/fluff/sat_dish{ + pixel_y = -9; + pixel_x = 12 + }, +/turf/template_noop, +/area/space/nearstation) +"p" = ( +/obj/structure/fluff/tram_rail/end, +/obj/structure/fluff/tram_rail{ + dir = 1 + }, +/turf/template_noop, +/area/space/nearstation) +"s" = ( +/obj/structure/fluff/sat_dish{ + pixel_x = 15; + dir = 8; + pixel_y = -7 + }, +/turf/template_noop, +/area/space/nearstation) +"t" = ( +/obj/structure/marker_beacon/burgundy, +/turf/open/floor/plating/reinforced/airless, +/area/space/nearstation) +"x" = ( +/obj/structure/fluff/tram_rail/anchor, +/turf/template_noop, +/area/space/nearstation) +"z" = ( +/obj/structure/fluff/commsbuoy_broadcaster, +/turf/open/floor/iron/recharge_floor/Airless, +/area/space/nearstation) +"C" = ( +/obj/structure/fluff/sat_dish{ + pixel_y = 11; + dir = 1 + }, +/turf/template_noop, +/area/space/nearstation) +"D" = ( +/obj/structure/fluff/tram_rail/end{ + dir = 1 + }, +/turf/template_noop, +/area/space/nearstation) +"E" = ( +/obj/structure/fluff/tram_rail, +/obj/structure/fluff/tram_rail/end{ + dir = 1 + }, +/turf/template_noop, +/area/space/nearstation) +"F" = ( +/obj/structure/fluff/tram_rail, +/obj/structure/fluff/tram_rail{ + dir = 1 + }, +/turf/template_noop, +/area/space/nearstation) +"G" = ( +/turf/template_noop, +/area/space/nearstation) +"I" = ( +/obj/structure/fluff/tram_rail, +/turf/template_noop, +/area/space/nearstation) +"K" = ( +/obj/structure/fluff/tram_rail{ + dir = 1 + }, +/turf/template_noop, +/area/space/nearstation) +"L" = ( +/turf/closed/wall/mineral/titanium, +/area/space/nearstation) +"M" = ( +/turf/closed/wall/mineral/titanium, +/area/ruin/space/unpowered) +"N" = ( +/turf/closed/wall/mineral/titanium/nodiagonal, +/area/ruin/space/unpowered) +"O" = ( +/obj/structure/fluff/commsbuoy_receiver, +/turf/open/floor/iron/recharge_floor/Airless, +/area/space/nearstation) +"P" = ( +/obj/structure/fluff/tram_rail/end, +/turf/template_noop, +/area/space/nearstation) +"S" = ( +/obj/structure/fluff/tram_rail{ + dir = 1 + }, +/obj/structure/fluff/tram_rail/end{ + dir = 8 + }, +/turf/template_noop, +/area/space/nearstation) +"U" = ( +/obj/structure/fluff/commsbuoy_processor, +/turf/open/floor/plating/reinforced/airless, +/area/space/nearstation) +"X" = ( +/obj/structure/lattice, +/turf/template_noop, +/area/space/nearstation) +"Y" = ( +/obj/structure/lattice/catwalk, +/obj/structure/fluff/sat_dish{ + pixel_y = 9; + dir = 1; + pixel_x = 8 + }, +/obj/structure/fluff/sat_dish{ + pixel_y = 15; + dir = 1; + pixel_x = -11 + }, +/turf/template_noop, +/area/space/nearstation) +"Z" = ( +/turf/open/floor/iron/solarpanel/airless, +/area/space/nearstation) + +(1,1,1) = {" +a +a +a +a +a +n +a +a +a +"} +(2,1,1) = {" +a +n +o +N +C +K +a +a +a +"} +(3,1,1) = {" +m +K +s +N +X +O +Z +Z +a +"} +(4,1,1) = {" +I +S +M +N +c +L +j +Z +Z +"} +(5,1,1) = {" +I +F +N +N +G +p +a +a +a +"} +(6,1,1) = {" +x +U +j +N +M +D +a +a +a +"} +(7,1,1) = {" +x +t +X +N +N +Y +Z +Z +a +"} +(8,1,1) = {" +I +d +a +N +j +X +Z +Z +Z +"} +(9,1,1) = {" +P +P +a +z +a +a +a +a +a +"} +(10,1,1) = {" +a +a +a +E +a +a +a +a +a +"} +(11,1,1) = {" +a +a +a +P +a +a +a +a +a +"} diff --git a/_maps/RandomRuins/SpaceRuins/commsbuoy_nt.dmm b/_maps/RandomRuins/SpaceRuins/commsbuoy_nt.dmm new file mode 100644 index 0000000000000..4fa47033077dc --- /dev/null +++ b/_maps/RandomRuins/SpaceRuins/commsbuoy_nt.dmm @@ -0,0 +1,1209 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aJ" = ( +/obj/machinery/door/airlock/titanium{ + name = "Comms Buoy Airlock" + }, +/obj/effect/mapping_helpers/airlock/cutaiwire, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"aL" = ( +/obj/structure/fluff/tram_rail{ + dir = 1 + }, +/obj/structure/fluff/tram_rail, +/turf/template_noop, +/area/space/nearstation) +"bj" = ( +/turf/closed/wall/mineral/titanium/nodiagonal, +/area/ruin/space/nt_commsbuoy) +"dO" = ( +/obj/effect/decal/cleanable/blood/splatter, +/turf/open/floor/mineral/titanium/white, +/area/ruin/space/nt_commsbuoy) +"dX" = ( +/obj/machinery/computer/terminal/nt_commsbuoy, +/turf/open/floor/mineral/titanium/blue, +/area/ruin/space/nt_commsbuoy) +"et" = ( +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"ew" = ( +/obj/structure/fluff{ + name = "telecommunication hub"; + desc = "A mighty piece of hardware used to send/receive massive amounts of data."; + icon = 'icons/obj/machines/telecomms.dmi'; + icon_state = "hub" + }, +/turf/open/floor/mineral/titanium/blue, +/area/ruin/space/nt_commsbuoy) +"eX" = ( +/obj/structure/lattice/catwalk, +/turf/template_noop, +/area/space/nearstation) +"fx" = ( +/obj/structure/fluff{ + icon = 'icons/obj/machines/wallmounts.dmi'; + icon_state = "pod_off"; + name = "radio dish controller"; + desc = "A console for adjusting the satellite's radio dishes manually. The screen won't even power on without proper authorization, which you know you're never getting."; + pixel_y = 30 + }, +/turf/open/floor/mineral/titanium/blue, +/area/ruin/space/nt_commsbuoy) +"fJ" = ( +/turf/template_noop, +/area/template_noop) +"gw" = ( +/obj/structure/sign/nanotrasen{ + pixel_x = -32 + }, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"hb" = ( +/obj/structure/fluff/tram_rail/end{ + dir = 1 + }, +/obj/structure/fluff/tram_rail/end, +/turf/template_noop, +/area/space/nearstation) +"hk" = ( +/obj/structure/table, +/obj/item/paper/fluff/ruins/nt_commsbuoy/inspection{ + pixel_y = 3; + pixel_x = 6 + }, +/obj/item/reagent_containers/cup/glass/mug/nanotrasen{ + pixel_y = 5; + pixel_x = 4 + }, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"hn" = ( +/obj/structure/lattice, +/turf/template_noop, +/area/space/nearstation) +"hH" = ( +/obj/structure/rack, +/obj/item/clothing/suit/space{ + pixel_y = 5; + pixel_x = -10 + }, +/obj/item/clothing/suit/space{ + pixel_y = 1; + pixel_x = 5 + }, +/obj/item/clothing/head/helmet/space{ + pixel_x = -7; + pixel_y = -5 + }, +/obj/item/clothing/head/helmet/space{ + pixel_y = -10; + pixel_x = 8 + }, +/obj/machinery/light/small/directional/east, +/turf/open/floor/plating, +/area/ruin/space/nt_commsbuoy) +"in" = ( +/obj/structure/fluff{ + icon = 'icons/obj/machines/wallmounts.dmi'; + icon_state = "pod_off"; + name = "radio dish controller"; + desc = "A console for adjusting the satellite's radio dishes manually. The screen won't even power on without proper authorization, which you know you're never getting."; + pixel_y = 30 + }, +/obj/effect/decal/cleanable/blood/gibs/old, +/obj/effect/mob_spawn/corpse/human/engineer, +/obj/item/keycard/nt_commsbuoy{ + pixel_y = 9; + pixel_x = 3 + }, +/turf/open/floor/mineral/titanium/blue, +/area/ruin/space/nt_commsbuoy) +"io" = ( +/obj/machinery/light/small/directional/east, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"it" = ( +/obj/machinery/computer/terminal/nt_commsbuoy/blackbox, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"iv" = ( +/obj/item/stock_parts/subspace/treatment, +/obj/item/stock_parts/subspace/transmitter, +/obj/item/stock_parts/subspace/filter, +/obj/item/stock_parts/subspace/crystal, +/obj/item/stock_parts/subspace/ansible, +/obj/item/stock_parts/subspace/analyzer, +/obj/item/stock_parts/subspace/amplifier, +/obj/structure/closet/crate/centcom, +/obj/item/storage/box/lights/bulbs, +/obj/effect/spawner/random/exotic/technology, +/turf/open/floor/plating, +/area/ruin/space/nt_commsbuoy) +"jy" = ( +/obj/structure/sign/nanotrasen{ + pixel_y = -32 + }, +/obj/machinery/light/small/directional/south, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"jz" = ( +/obj/structure/sign/nanotrasen{ + pixel_y = 32 + }, +/obj/machinery/light/small/directional/north, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"kZ" = ( +/obj/effect/decal/cleanable/blood/splatter, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"lu" = ( +/obj/machinery/porta_turret/syndicate/energy, +/turf/open/floor/mineral/titanium/yellow, +/area/ruin/space/nt_commsbuoy) +"lB" = ( +/obj/effect/decal/cleanable/blood/trails{ + dir = 4 + }, +/obj/effect/decal/cleanable/blood/footprints{ + dir = 4 + }, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"lT" = ( +/obj/structure/fluff/tram_rail{ + dir = 1 + }, +/turf/template_noop, +/area/space/nearstation) +"lY" = ( +/obj/structure/table, +/obj/structure/noticeboard/directional/north, +/obj/item/paper/fluff/ruins/nt_commsbuoy/table_of_contents, +/obj/machinery/light/small/directional/east, +/obj/item/gps/spaceruin{ + pixel_y = 4; + pixel_x = 5 + }, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"mu" = ( +/obj/structure/fluff/fake_camera{ + dir = 9 + }, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"nn" = ( +/obj/structure/frame/computer{ + dir = 1 + }, +/obj/item/shard, +/obj/effect/decal/cleanable/glass, +/turf/open/floor/mineral/titanium/blue, +/area/ruin/space/nt_commsbuoy) +"oA" = ( +/obj/structure/fluff/tram_rail/end{ + dir = 8 + }, +/turf/template_noop, +/area/space/nearstation) +"pC" = ( +/obj/machinery/door/puzzle/keycard/nt_commsbuoy, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"pR" = ( +/turf/open/floor/mineral/titanium/white/airless, +/area/space/nearstation) +"qi" = ( +/obj/structure/fluff/tram_rail, +/obj/structure/fluff/tram_rail{ + dir = 1 + }, +/turf/template_noop, +/area/space/nearstation) +"ri" = ( +/obj/structure/fluff/tram_rail/end{ + dir = 1 + }, +/obj/structure/fluff/tram_rail, +/turf/template_noop, +/area/space/nearstation) +"rl" = ( +/obj/structure/fluff{ + icon = 'icons/mob/simple/hivebot.dmi'; + icon_state = "def_radar-off"; + name = "radio dish component"; + desc = "Remarkable Nanotrasen technology. This does... something to make the radio dish work."; + pixel_y = 16 + }, +/turf/open/floor/plating/reinforced/airless, +/area/space/nearstation) +"tq" = ( +/obj/item/storage/toolbox/electrical{ + pixel_y = 9 + }, +/obj/structure/rack, +/obj/effect/spawner/random/engineering/tool_advanced, +/obj/machinery/light/small/directional/west, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"tx" = ( +/turf/closed/wall/mineral/titanium/nodiagonal, +/area/space/nearstation) +"tO" = ( +/obj/structure/fluff{ + icon = 'icons/obj/machines/wallmounts.dmi'; + icon_state = "airlock_control_standby"; + name = "radio dish component"; + desc = "Remarkable Nanotrasen technology. This does... something to make the radio dish work."; + pixel_y = 32; + pixel_x = 6 + }, +/turf/open/floor/mineral/titanium/blue, +/area/ruin/space/nt_commsbuoy) +"uG" = ( +/obj/structure/fluff/commsbuoy_receiver, +/turf/open/floor/plating/reinforced/airless, +/area/space/nearstation) +"uH" = ( +/obj/structure/fluff/tram_rail, +/obj/structure/fluff/tram_rail/end{ + dir = 4 + }, +/turf/template_noop, +/area/space/nearstation) +"vr" = ( +/obj/machinery/door/airlock/external/ruin{ + name = "Comms Buoy External Airlock" + }, +/obj/structure/fans/tiny, +/turf/open/floor/plating, +/area/ruin/space/nt_commsbuoy) +"wS" = ( +/obj/structure/lattice, +/obj/structure/fluff/tram_rail{ + dir = 1 + }, +/obj/structure/fluff/tram_rail, +/turf/template_noop, +/area/space/nearstation) +"xI" = ( +/obj/structure/cable, +/obj/machinery/power/smes/full, +/turf/open/floor/plating, +/area/ruin/space/nt_commsbuoy) +"yk" = ( +/obj/structure/fluff/tram_rail/end{ + dir = 4 + }, +/turf/template_noop, +/area/space/nearstation) +"zt" = ( +/obj/effect/decal/cleanable/blood, +/obj/effect/mapping_helpers/airlock/cutaiwire, +/obj/machinery/door/airlock/titanium{ + name = "Comms Buoy Airlock" + }, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"zA" = ( +/obj/structure/fluff/tram_rail, +/obj/structure/fluff/tram_rail/anchor{ + dir = 1 + }, +/turf/template_noop, +/area/space/nearstation) +"zO" = ( +/obj/structure/lattice, +/obj/structure/fluff/tram_rail{ + dir = 1 + }, +/turf/template_noop, +/area/space/nearstation) +"Ad" = ( +/obj/structure/fluff/tram_rail/end{ + dir = 8 + }, +/obj/structure/fluff/tram_rail{ + dir = 1 + }, +/turf/template_noop, +/area/space/nearstation) +"AA" = ( +/obj/structure/fluff/tram_rail, +/obj/structure/fluff/tram_rail/end{ + dir = 1 + }, +/turf/template_noop, +/area/space/nearstation) +"AD" = ( +/obj/machinery/computer/terminal/nt_commsbuoy/relay{ + dir = 1 + }, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"AE" = ( +/obj/structure/sign/warning/vacuum/external/directional/east, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"Br" = ( +/obj/structure/cable, +/turf/open/floor/mineral/titanium/yellow, +/area/ruin/space/nt_commsbuoy) +"CN" = ( +/obj/effect/mob_spawn/corpse/human/nanotrasensoldier, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"DW" = ( +/obj/structure/fluff/sat_dish{ + dir = 8; + pixel_y = -5; + pixel_x = 17 + }, +/obj/structure/fluff/sat_dish{ + pixel_y = -10; + pixel_x = -5 + }, +/turf/template_noop, +/area/space/nearstation) +"EA" = ( +/obj/structure/closet/firecloset/full, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"EQ" = ( +/obj/structure/fluff/sat_dish{ + pixel_y = -18; + pixel_x = 6 + }, +/turf/template_noop, +/area/space/nearstation) +"ES" = ( +/turf/open/floor/mineral/titanium/white, +/area/ruin/space/nt_commsbuoy) +"FC" = ( +/turf/closed/wall/mineral/iron, +/area/ruin/space/nt_commsbuoy) +"FH" = ( +/obj/structure/sign/nanotrasen{ + pixel_x = -32 + }, +/obj/structure/rack, +/obj/item/clothing/suit/space/syndicate/orange{ + pixel_x = 6; + pixel_y = 4 + }, +/obj/item/clothing/head/helmet/space/syndicate/orange{ + pixel_x = 9; + pixel_y = -5 + }, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"FK" = ( +/obj/structure/fluff/tram_rail/end, +/turf/template_noop, +/area/space/nearstation) +"Gd" = ( +/obj/structure/fluff/commsbuoy_processor, +/obj/structure/sign/nanotrasen{ + pixel_x = 32 + }, +/turf/open/floor/mineral/titanium/blue, +/area/ruin/space/nt_commsbuoy) +"Gq" = ( +/obj/structure/sign/warning/radiation/directional/south, +/turf/open/floor/mineral/titanium/yellow, +/area/ruin/space/nt_commsbuoy) +"Gw" = ( +/obj/structure/cable, +/obj/machinery/power/apc/auto_name/directional/south, +/obj/effect/mapping_helpers/apc/cell_5k, +/obj/effect/mapping_helpers/apc/full_charge, +/obj/effect/mapping_helpers/apc/unlocked, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"HC" = ( +/obj/structure/fluff/commsbuoy_broadcaster, +/turf/open/floor/plating/reinforced/airless, +/area/space/nearstation) +"II" = ( +/obj/structure/tank_dispenser/oxygen, +/turf/open/floor/plating, +/area/ruin/space/nt_commsbuoy) +"Jp" = ( +/obj/structure/cable, +/obj/machinery/power/rtg/advanced, +/turf/open/floor/plating, +/area/ruin/space/nt_commsbuoy) +"Jv" = ( +/obj/structure/fluff/tram_rail{ + dir = 1 + }, +/obj/structure/fluff/tram_rail, +/obj/structure/lattice, +/turf/template_noop, +/area/space/nearstation) +"Kr" = ( +/obj/machinery/power/rtg/advanced, +/obj/structure/cable, +/turf/open/floor/plating, +/area/ruin/space/nt_commsbuoy) +"Lc" = ( +/turf/open/floor/mineral/titanium/blue, +/area/ruin/space/nt_commsbuoy) +"LI" = ( +/obj/machinery/telecomms/relay/preset/telecomms, +/obj/structure/fluff/fake_camera{ + dir = 1 + }, +/turf/open/floor/mineral/titanium/blue, +/area/ruin/space/nt_commsbuoy) +"Mc" = ( +/obj/effect/decal/cleanable/greenglow/radioactive, +/turf/open/floor/plating, +/area/ruin/space/nt_commsbuoy) +"Mp" = ( +/obj/structure/fluff/fake_camera{ + dir = 8 + }, +/obj/machinery/light/small/directional/west, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"Qb" = ( +/obj/structure/cable, +/obj/effect/mapping_helpers/airlock/cutaiwire, +/obj/machinery/door/airlock/titanium{ + name = "Comms Buoy Airlock" + }, +/turf/open/floor/mineral/titanium/yellow, +/area/ruin/space/nt_commsbuoy) +"Qd" = ( +/obj/effect/decal/cleanable/blood/trails{ + dir = 6 + }, +/obj/item/paper/fluff/ruins/nt_commsbuoy/torn_page, +/obj/structure/fluff/fake_camera{ + dir = 5 + }, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"Re" = ( +/obj/structure/fluff/tram_rail/end{ + dir = 1 + }, +/turf/template_noop, +/area/space/nearstation) +"RY" = ( +/obj/structure/fluff/tram_rail, +/obj/structure/fluff/tram_rail{ + dir = 1 + }, +/obj/structure/lattice, +/turf/template_noop, +/area/space/nearstation) +"TS" = ( +/obj/structure/fluff/tram_rail{ + dir = 1 + }, +/obj/structure/fluff/tram_rail/end, +/turf/template_noop, +/area/space/nearstation) +"UR" = ( +/obj/structure/fluff/tram_rail{ + dir = 1 + }, +/obj/structure/fluff/tram_rail/end{ + dir = 8 + }, +/turf/template_noop, +/area/space/nearstation) +"Vg" = ( +/obj/structure/fluff/tram_rail, +/turf/template_noop, +/area/space/nearstation) +"VI" = ( +/obj/structure/fluff/fake_camera{ + dir = 8 + }, +/turf/template_noop, +/area/template_noop) +"Ws" = ( +/obj/structure/marker_beacon/cerulean, +/turf/open/floor/plating/reinforced/airless, +/area/space/nearstation) +"WI" = ( +/obj/structure/fluff{ + name = "comms buoy blackbox recorder"; + desc = "A recording device that logs recent events and communications in the event of a catastrophic failiure or accident. This one is haphazardly adjusted to print the readout onto the accompanying console."; + icon = 'icons/obj/machines/telecomms.dmi'; + icon_state = "blackbox" + }, +/turf/open/floor/mineral/titanium/blue, +/area/ruin/space/nt_commsbuoy) +"Xi" = ( +/obj/structure/cable, +/turf/open/floor/plating, +/area/ruin/space/nt_commsbuoy) +"Yp" = ( +/obj/structure/fluff/fake_camera{ + dir = 5 + }, +/obj/machinery/light/small/directional/south, +/turf/open/floor/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"Yr" = ( +/turf/closed/wall/mineral/titanium, +/area/ruin/space/nt_commsbuoy) +"YN" = ( +/obj/structure/cable, +/obj/machinery/power/terminal{ + dir = 8 + }, +/obj/machinery/light/small/directional/south, +/turf/open/floor/plating, +/area/ruin/space/nt_commsbuoy) +"YY" = ( +/turf/open/floor/plating, +/area/ruin/space/nt_commsbuoy) + +(1,1,1) = {" +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +"} +(2,1,1) = {" +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +uG +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +"} +(3,1,1) = {" +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +hn +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +"} +(4,1,1) = {" +fJ +fJ +fJ +fJ +fJ +fJ +fJ +Yr +fJ +hn +fJ +Yr +fJ +fJ +fJ +fJ +fJ +fJ +"} +(5,1,1) = {" +fJ +fJ +fJ +fJ +fJ +fJ +fJ +Yr +Yr +pR +Yr +Yr +fJ +fJ +fJ +fJ +fJ +fJ +"} +(6,1,1) = {" +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +Yr +bj +Yr +fJ +fJ +fJ +fJ +fJ +fJ +fJ +"} +(7,1,1) = {" +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +FC +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +"} +(8,1,1) = {" +fJ +fJ +fJ +fJ +fJ +fJ +fJ +Yr +bj +bj +bj +Yr +fJ +fJ +fJ +fJ +fJ +fJ +"} +(9,1,1) = {" +fJ +fJ +fJ +fJ +fJ +fJ +fJ +bj +fx +Mp +hk +bj +fJ +fJ +fJ +fJ +fJ +fJ +"} +(10,1,1) = {" +fJ +fJ +fJ +fJ +fJ +fJ +fJ +bj +dX +et +AD +bj +fJ +fJ +fJ +fJ +fJ +fJ +"} +(11,1,1) = {" +fJ +fJ +fJ +fJ +fJ +fJ +Yr +bj +bj +aJ +bj +bj +fJ +fJ +fJ +fJ +fJ +fJ +"} +(12,1,1) = {" +fJ +yk +fJ +fJ +fJ +fJ +bj +tq +gw +et +EA +bj +Yr +fJ +fJ +fJ +fJ +fJ +"} +(13,1,1) = {" +fJ +UR +fJ +fJ +fJ +DW +bj +it +et +et +bj +bj +bj +Yr +fJ +fJ +fJ +fJ +"} +(14,1,1) = {" +fJ +aL +fJ +yk +EQ +Yr +bj +WI +et +Gq +bj +YY +iv +bj +fJ +fJ +yk +fJ +"} +(15,1,1) = {" +fJ +wS +hn +zO +hn +bj +bj +ew +et +Br +Qb +Xi +xI +bj +fJ +fJ +lT +fJ +"} +(16,1,1) = {" +fJ +ri +yk +UR +fJ +eX +bj +LI +et +Br +bj +Mc +YN +bj +fJ +oA +lT +fJ +"} +(17,1,1) = {" +fJ +FK +zO +wS +fJ +hn +bj +Gd +io +Gw +bj +Kr +Jp +bj +fJ +Vg +Ad +fJ +"} +(18,1,1) = {" +fJ +fJ +lT +hb +fJ +fJ +Yr +bj +bj +pC +bj +bj +bj +Yr +fJ +Vg +Jv +fJ +"} +(19,1,1) = {" +fJ +fJ +Re +fJ +fJ +fJ +fJ +bj +et +et +et +EA +bj +fJ +fJ +Vg +aL +fJ +"} +(20,1,1) = {" +fJ +fJ +fJ +fJ +fJ +fJ +fJ +bj +jz +ES +ES +jy +bj +fJ +fJ +uH +TS +fJ +"} +(21,1,1) = {" +fJ +fJ +fJ +fJ +fJ +fJ +fJ +bj +mu +ES +ES +et +bj +fJ +fJ +qi +lT +fJ +"} +(22,1,1) = {" +fJ +fJ +fJ +fJ +fJ +fJ +Yr +bj +et +ES +ES +et +bj +Yr +fJ +qi +UR +fJ +"} +(23,1,1) = {" +fJ +fJ +Yr +Yr +fJ +fJ +bj +lu +et +ES +ES +et +lu +bj +fJ +HC +aL +fJ +"} +(24,1,1) = {" +fJ +fJ +fJ +Yr +Yr +fJ +bj +tO +et +ES +ES +et +Lc +bj +eX +tx +zA +fJ +"} +(25,1,1) = {" +fJ +rl +hn +pR +bj +FC +bj +in +et +ES +ES +et +nn +bj +Ws +tx +RY +fJ +"} +(26,1,1) = {" +fJ +fJ +fJ +Yr +Yr +fJ +bj +dX +CN +ES +dO +Yp +bj +bj +fJ +tx +zA +fJ +"} +(27,1,1) = {" +fJ +fJ +Yr +Yr +fJ +fJ +bj +lY +kZ +AE +lB +et +bj +fJ +fJ +qi +aL +fJ +"} +(28,1,1) = {" +fJ +fJ +fJ +fJ +fJ +fJ +Yr +bj +bj +bj +zt +bj +Yr +fJ +fJ +AA +TS +fJ +"} +(29,1,1) = {" +fJ +fJ +fJ +fJ +fJ +fJ +fJ +bj +FH +CN +Qd +bj +fJ +fJ +fJ +Vg +Re +fJ +"} +(30,1,1) = {" +fJ +fJ +fJ +fJ +fJ +fJ +fJ +bj +II +YY +hH +bj +fJ +fJ +fJ +FK +fJ +fJ +"} +(31,1,1) = {" +fJ +fJ +fJ +fJ +fJ +fJ +fJ +Yr +bj +vr +bj +Yr +fJ +fJ +fJ +fJ +fJ +fJ +"} +(32,1,1) = {" +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +VI +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +fJ +"} diff --git a/_maps/RandomRuins/SpaceRuins/commsbuoy_pirate.dmm b/_maps/RandomRuins/SpaceRuins/commsbuoy_pirate.dmm new file mode 100644 index 0000000000000..18f2117135c4d --- /dev/null +++ b/_maps/RandomRuins/SpaceRuins/commsbuoy_pirate.dmm @@ -0,0 +1,299 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/template_noop, +/area/template_noop) +"c" = ( +/obj/structure/fluff/tram_rail/end{ + dir = 4 + }, +/turf/template_noop, +/area/space/nearstation) +"d" = ( +/obj/structure/fluff/tram_rail{ + dir = 1 + }, +/obj/structure/fluff/tram_rail, +/turf/template_noop, +/area/space/nearstation) +"f" = ( +/obj/structure/fluff/tram_rail{ + dir = 1 + }, +/turf/template_noop, +/area/space/nearstation) +"g" = ( +/turf/closed/wall/mineral/plastitanium, +/area/ruin/space/unpowered) +"h" = ( +/obj/structure/fluff/tram_rail/end{ + dir = 8 + }, +/turf/template_noop, +/area/space/nearstation) +"i" = ( +/obj/structure/lattice, +/obj/structure/sign/poster/contraband/self_ai_liberation/directional/north, +/turf/template_noop, +/area/space/nearstation) +"j" = ( +/obj/structure/sign/poster/contraband/syndicate_recruitment/directional/west, +/obj/structure/fluff/commsbuoy_broadcaster, +/turf/open/floor/plating/reinforced/airless, +/area/space/nearstation) +"m" = ( +/obj/structure/billboard/nanotrasen/defaced, +/turf/open/floor/plating/reinforced/airless, +/area/space/nearstation) +"o" = ( +/obj/structure/fluff/tram_rail/end{ + dir = 8 + }, +/obj/structure/fluff/tram_rail{ + dir = 1 + }, +/turf/template_noop, +/area/space/nearstation) +"r" = ( +/obj/structure/marker_beacon/burgundy, +/turf/open/floor/plating/reinforced/airless, +/area/space/nearstation) +"s" = ( +/obj/structure/lattice/catwalk, +/obj/structure/marker_beacon/burgundy, +/turf/template_noop, +/area/space/nearstation) +"u" = ( +/obj/structure/lattice/catwalk, +/obj/structure/sign/poster/contraband/free_key/directional/south, +/turf/template_noop, +/area/space/nearstation) +"v" = ( +/obj/structure/lattice, +/turf/template_noop, +/area/space/nearstation) +"w" = ( +/obj/structure/fluff/tram_rail/anchor{ + dir = 1 + }, +/obj/structure/fluff/tram_rail/end{ + dir = 8 + }, +/turf/template_noop, +/area/space/nearstation) +"x" = ( +/obj/structure/fluff/tram_rail/end, +/turf/template_noop, +/area/space/nearstation) +"B" = ( +/obj/structure/fluff/commsbuoy_processor, +/turf/open/floor/plating/reinforced/airless, +/area/space/nearstation) +"C" = ( +/obj/structure/fluff/sat_dish{ + pixel_y = -15; + pixel_x = -11 + }, +/obj/structure/fluff/sat_dish{ + pixel_y = -9; + pixel_x = 12 + }, +/obj/structure/lattice, +/turf/template_noop, +/area/space/nearstation) +"D" = ( +/obj/structure/fluff/tram_rail/end{ + dir = 1 + }, +/obj/structure/fluff/tram_rail, +/turf/template_noop, +/area/space/nearstation) +"E" = ( +/turf/open/floor/iron/solarpanel/airless, +/area/space/nearstation) +"F" = ( +/obj/structure/lattice, +/obj/structure/fluff/tram_rail{ + dir = 1 + }, +/turf/template_noop, +/area/space/nearstation) +"G" = ( +/obj/structure/fluff/tram_rail/end{ + dir = 1 + }, +/turf/template_noop, +/area/space/nearstation) +"J" = ( +/turf/open/floor/plating/reinforced/airless, +/area/space/nearstation) +"K" = ( +/turf/closed/wall/mineral/plastitanium/nodiagonal, +/area/ruin/space/unpowered) +"O" = ( +/turf/closed/wall/mineral/plastitanium/nodiagonal, +/area/space/nearstation) +"P" = ( +/obj/structure/fluff/commsbuoy_receiver, +/turf/open/floor/plating/reinforced/airless, +/area/space/nearstation) +"Q" = ( +/obj/structure/fluff/tram_rail, +/turf/template_noop, +/area/space/nearstation) +"S" = ( +/obj/structure/fluff/sat_dish{ + pixel_y = 11; + dir = 1 + }, +/turf/template_noop, +/area/space/nearstation) +"T" = ( +/obj/structure/fluff/sat_dish{ + pixel_x = 17; + dir = 8; + pixel_y = -8 + }, +/turf/template_noop, +/area/space/nearstation) +"W" = ( +/obj/structure/lattice/catwalk, +/turf/template_noop, +/area/space/nearstation) +"X" = ( +/obj/structure/fluff/tram_rail/end{ + dir = 1 + }, +/obj/structure/fluff/tram_rail/anchor, +/turf/template_noop, +/area/space/nearstation) +"Y" = ( +/obj/structure/fluff/tram_rail/anchor, +/turf/template_noop, +/area/space/nearstation) +"Z" = ( +/obj/structure/fluff/tram_rail/anchor{ + dir = 1 + }, +/turf/template_noop, +/area/space/nearstation) + +(1,1,1) = {" +a +c +a +a +a +c +a +a +"} +(2,1,1) = {" +a +F +C +K +S +o +a +a +"} +(3,1,1) = {" +h +f +T +K +i +P +E +a +"} +(4,1,1) = {" +Y +w +g +K +s +O +E +E +"} +(5,1,1) = {" +x +d +K +K +g +G +W +E +"} +(6,1,1) = {" +h +B +u +K +K +m +E +E +"} +(7,1,1) = {" +Y +r +v +K +K +v +W +E +"} +(8,1,1) = {" +Q +D +a +K +g +J +E +E +"} +(9,1,1) = {" +Q +x +a +j +c +E +E +a +"} +(10,1,1) = {" +x +a +a +X +Z +a +a +a +"} +(11,1,1) = {" +a +a +a +x +f +a +a +a +"} +(12,1,1) = {" +a +a +a +a +G +a +a +a +"} diff --git a/_maps/RandomRuins/SpaceRuins/dangerous_research.dmm b/_maps/RandomRuins/SpaceRuins/dangerous_research.dmm index edd734ee6f586..025a2b62e0a83 100644 --- a/_maps/RandomRuins/SpaceRuins/dangerous_research.dmm +++ b/_maps/RandomRuins/SpaceRuins/dangerous_research.dmm @@ -1062,7 +1062,6 @@ /turf/open/floor/iron/dark, /area/ruin/space/has_grav/dangerous_research/lab) "oJ" = ( -/obj/structure/closet/crate/secure/interdyne, /obj/item/stack/medical/suture/emergency, /obj/item/stack/medical/gauze/twelve, /obj/item/reagent_containers/hypospray/medipen/blood_loss, @@ -1070,6 +1069,9 @@ /obj/effect/turf_decal/tile/dark_red/anticorner{ dir = 4 }, +/obj/structure/closet/crate/secure/freezer/interdyne{ + req_access = null + }, /turf/open/floor/iron/dark, /area/ruin/space/has_grav/dangerous_research) "oW" = ( @@ -2155,7 +2157,6 @@ /turf/open/floor/iron/dark, /area/ruin/space/has_grav/dangerous_research/lab) "BG" = ( -/obj/structure/closet/crate/secure/interdyne, /obj/item/stack/sheet/mineral/plasma/thirty, /obj/item/stack/sheet/mineral/wood/fifty, /obj/item/stack/sheet/iron/fifty, @@ -2164,6 +2165,9 @@ amount = 30 }, /obj/effect/decal/cleanable/dirt, +/obj/structure/closet/crate/secure/syndicate/interdyne{ + req_access = null + }, /turf/open/floor/iron, /area/ruin/space/has_grav/dangerous_research/maint) "BJ" = ( @@ -3658,7 +3662,6 @@ /turf/open/floor/iron/dark, /area/ruin/space/has_grav/dangerous_research) "VQ" = ( -/obj/structure/closet/crate/secure/interdyne, /obj/item/reagent_containers/cup/glass/waterbottle/large, /obj/item/reagent_containers/cup/glass/waterbottle/large, /obj/item/reagent_containers/cup/glass/waterbottle/large, @@ -3669,6 +3672,9 @@ /obj/effect/turf_decal/tile/yellow/anticorner/contrasted{ dir = 8 }, +/obj/structure/closet/crate/secure/syndicate/interdyne{ + req_access = null + }, /turf/open/floor/iron, /area/ruin/space/has_grav/dangerous_research/maint) "Wm" = ( diff --git a/_maps/RandomRuins/SpaceRuins/hauntedtradingpost.dmm b/_maps/RandomRuins/SpaceRuins/hauntedtradingpost.dmm index df3c3ca64277e..9efa8cd365454 100644 --- a/_maps/RandomRuins/SpaceRuins/hauntedtradingpost.dmm +++ b/_maps/RandomRuins/SpaceRuins/hauntedtradingpost.dmm @@ -5468,11 +5468,9 @@ /area/ruin/space/has_grav/hauntedtradingpost/employees/breakroom) "Vl" = ( /obj/structure/table/wood, -/obj/item/toy/figure/wizard{ +/obj/item/toy/figure/wizard/special{ pixel_y = 9; pixel_x = -4; - toysay = "CLANG!"; - toysound = 'sound/effects/clang.ogg' }, /obj/item/toy/figure/warden{ name = "\improper Knight action figure"; diff --git a/_maps/RandomZLevels/SnowCabin.dmm b/_maps/RandomZLevels/SnowCabin.dmm index bfbc5a18c56a1..0c30bb3c51d51 100644 --- a/_maps/RandomZLevels/SnowCabin.dmm +++ b/_maps/RandomZLevels/SnowCabin.dmm @@ -4122,7 +4122,7 @@ pixel_x = -1; pixel_y = 10 }, -/obj/item/gun/ballistic/shotgun/toy/unrestricted{ +/obj/item/gun/ballistic/shotgun/toy{ pixel_y = -2 }, /obj/effect/light_emitter{ diff --git a/_maps/deathmatch/lattice_battles.dmm b/_maps/deathmatch/lattice_battles.dmm index eab56ca3064a0..25508fc93d462 100644 --- a/_maps/deathmatch/lattice_battles.dmm +++ b/_maps/deathmatch/lattice_battles.dmm @@ -9,30 +9,19 @@ dir = 1 }, /obj/item/clothing/head/cone, -/obj/effect/playeronly_barrier, +/obj/effect/invisible_wall, /turf/open/misc/asteroid/moon, /area/deathmatch/fullbright) "cN" = ( /obj/structure/railing/unbreakable{ dir = 8 }, -/obj/effect/playeronly_barrier, +/obj/effect/invisible_wall, /turf/open/misc/asteroid/moon, /area/deathmatch/fullbright) -"df" = ( -/obj/structure/lattice/catwalk, -/obj/effect/decal/cleanable/dirt/dust, -/turf/open/chasm, -/area/deathmatch/fullbright) "dM" = ( /turf/open/chasm, /area/deathmatch/fullbright) -"eK" = ( -/obj/structure/lattice/catwalk, -/obj/effect/landmark/deathmatch_player_spawn, -/obj/effect/decal/cleanable/dirt/dust, -/turf/open/chasm, -/area/deathmatch/fullbright) "gz" = ( /obj/structure/flora/rock/pile/style_random, /turf/open/misc/asteroid/moon, @@ -45,12 +34,12 @@ dir = 1 }, /obj/structure/flora/lunar_plant/style_1, -/obj/effect/playeronly_barrier, +/obj/effect/invisible_wall, /turf/open/misc/asteroid/moon, /area/deathmatch/fullbright) "ho" = ( /obj/structure/flora/lunar_plant/style_1, -/obj/effect/playeronly_barrier, +/obj/effect/invisible_wall, /obj/structure/railing/unbreakable{ dir = 6 }, @@ -62,7 +51,7 @@ }, /obj/structure/flora/rock/pile/style_random, /obj/structure/flora/lunar_plant/style_3, -/obj/effect/playeronly_barrier, +/obj/effect/invisible_wall, /turf/open/misc/asteroid/moon, /area/deathmatch/fullbright) "jb" = ( @@ -75,7 +64,7 @@ }, /obj/structure/flora/rock/pile/style_random, /obj/structure/flora/lunar_plant/style_3, -/obj/effect/playeronly_barrier, +/obj/effect/invisible_wall, /turf/open/misc/asteroid/moon, /area/deathmatch/fullbright) "rE" = ( @@ -96,12 +85,12 @@ /obj/structure/railing/unbreakable{ dir = 4 }, -/obj/effect/playeronly_barrier, +/obj/effect/invisible_wall, /turf/open/misc/asteroid/moon, /area/deathmatch/fullbright) "tL" = ( /obj/structure/railing/unbreakable, -/obj/effect/playeronly_barrier, +/obj/effect/invisible_wall, /turf/open/misc/asteroid/moon, /area/deathmatch/fullbright) "uJ" = ( @@ -109,7 +98,7 @@ dir = 4 }, /obj/item/clothing/head/cone, -/obj/effect/playeronly_barrier, +/obj/effect/invisible_wall, /turf/open/misc/asteroid/moon, /area/deathmatch/fullbright) "uO" = ( @@ -139,7 +128,7 @@ dir = 8 }, /obj/structure/flora/lunar_plant/style_1, -/obj/effect/playeronly_barrier, +/obj/effect/invisible_wall, /turf/open/misc/asteroid/moon, /area/deathmatch/fullbright) "AS" = ( @@ -150,7 +139,7 @@ /obj/structure/railing/unbreakable{ dir = 1 }, -/obj/effect/playeronly_barrier, +/obj/effect/invisible_wall, /turf/open/misc/asteroid/moon, /area/deathmatch/fullbright) "Cf" = ( @@ -190,7 +179,7 @@ dir = 10 }, /obj/structure/flora/lunar_plant/style_1, -/obj/effect/playeronly_barrier, +/obj/effect/invisible_wall, /turf/open/misc/asteroid/moon, /area/deathmatch/fullbright) "KO" = ( @@ -199,7 +188,7 @@ /area/deathmatch/fullbright) "LN" = ( /obj/structure/railing/corner, -/obj/effect/playeronly_barrier, +/obj/effect/invisible_wall, /turf/open/misc/asteroid/moon, /area/deathmatch/fullbright) "MF" = ( @@ -217,12 +206,11 @@ /area/deathmatch/fullbright) "NA" = ( /obj/structure/flora/lunar_plant/style_2, -/obj/effect/playeronly_barrier, +/obj/effect/invisible_wall, /turf/open/misc/asteroid/moon, /area/deathmatch/fullbright) "NG" = ( /obj/structure/lattice/catwalk, -/obj/effect/decal/cleanable/dirt/dust, /obj/structure/closet/crate/cardboard, /obj/item/statuebust, /turf/open/chasm, @@ -233,7 +221,7 @@ /turf/open/chasm, /area/deathmatch/fullbright) "NY" = ( -/obj/effect/playeronly_barrier, +/obj/effect/invisible_wall, /obj/structure/railing/unbreakable, /turf/open/misc/asteroid/moon, /area/deathmatch/fullbright) @@ -245,21 +233,15 @@ /mob/living/basic/spider/giant/nurse/away_caves, /turf/open/misc/asteroid/moon, /area/deathmatch/fullbright) -"Sv" = ( -/obj/structure/lattice/catwalk, -/obj/effect/decal/cleanable/dirt/dust, -/obj/effect/decal/cleanable/rubble, -/turf/open/chasm, -/area/deathmatch/fullbright) "SL" = ( /obj/structure/flora/rock/pile/style_random, /obj/structure/flora/lunar_plant/style_3, -/obj/effect/playeronly_barrier, +/obj/effect/invisible_wall, /turf/open/misc/asteroid/moon, /area/deathmatch/fullbright) "Uy" = ( /obj/item/clothing/head/cone, -/obj/effect/playeronly_barrier, +/obj/effect/invisible_wall, /obj/structure/railing/corner/unbreakable{ dir = 1 }, @@ -270,7 +252,7 @@ dir = 9 }, /obj/structure/flora/rock/style_random, -/obj/effect/playeronly_barrier, +/obj/effect/invisible_wall, /turf/open/misc/asteroid/moon, /area/deathmatch/fullbright) "Xf" = ( @@ -285,7 +267,7 @@ /area/deathmatch/fullbright) "Xo" = ( /obj/structure/flora/rock/style_random, -/obj/effect/playeronly_barrier, +/obj/effect/invisible_wall, /turf/open/misc/asteroid/moon, /area/deathmatch/fullbright) "Yu" = ( @@ -294,11 +276,11 @@ dir = 6 }, /obj/structure/flora/lunar_plant/style_3, -/obj/effect/playeronly_barrier, +/obj/effect/invisible_wall, /turf/open/misc/asteroid/moon, /area/deathmatch/fullbright) "YH" = ( -/obj/effect/playeronly_barrier, +/obj/effect/invisible_wall, /turf/open/misc/asteroid/moon, /area/deathmatch/fullbright) "YV" = ( @@ -466,9 +448,9 @@ MF MF MF vk -df vk -df +vk +vk vk MF dM @@ -571,12 +553,12 @@ vk MF MF vk -df -Sv +vk +NI vk MF vk -df +vk MF vk vk @@ -595,7 +577,7 @@ CI tL MF vk -df +vk MF MF vk @@ -603,10 +585,10 @@ vk MF MF vk -df vk vk -df +vk +vk vk hH gN @@ -633,7 +615,7 @@ vk vk vk vk -df +vk NG gN gN @@ -649,7 +631,7 @@ gN Yu MF MF -eK +wb vk vk vk @@ -703,7 +685,7 @@ gN gN gN bm -df +vk vk vk vk @@ -738,7 +720,7 @@ MF vk vk vk -df +vk MF vk vk @@ -795,7 +777,7 @@ vk vk vk vk -df +vk gN gN gN diff --git a/_maps/deathmatch/ragnarok.dmm b/_maps/deathmatch/ragnarok.dmm index 328055398e71a..89273eb45ada2 100644 --- a/_maps/deathmatch/ragnarok.dmm +++ b/_maps/deathmatch/ragnarok.dmm @@ -7,13 +7,17 @@ /obj/structure/flora/rock/pile/jungle/style_random, /turf/open/misc/asteroid/moon, /area/deathmatch) +"aR" = ( +/obj/structure/bonfire/dense/prelit, +/turf/open/misc/grass/jungle, +/area/deathmatch) "bb" = ( /obj/structure/flora/coconuts, /turf/open/misc/dirt/jungle, /area/deathmatch) "bj" = ( /obj/effect/turf_decal/siding/wood/corner, -/obj/structure/bonfire/prelit, +/obj/structure/bonfire/dense/prelit, /turf/open/floor/wood/large, /area/deathmatch) "bn" = ( @@ -24,7 +28,7 @@ dir = 4 }, /obj/effect/turf_decal/siding/wood, -/turf/open/water/jungle, +/turf/open/misc/dirt/jungle, /area/deathmatch) "bI" = ( /turf/open/misc/asteroid/moon, @@ -122,7 +126,7 @@ /obj/effect/turf_decal/siding/wood{ dir = 1 }, -/turf/open/water/jungle, +/turf/open/misc/dirt/jungle, /area/deathmatch) "fO" = ( /obj/effect/decal/cleanable/dirt/dust, @@ -224,7 +228,7 @@ /obj/effect/turf_decal/weather/dirt{ dir = 6 }, -/turf/open/water/jungle, +/turf/open/misc/dirt/jungle, /area/deathmatch) "jv" = ( /obj/structure/flora/grass/jungle/b/style_random, @@ -263,7 +267,7 @@ /area/deathmatch) "lr" = ( /obj/effect/turf_decal/siding/wood, -/obj/structure/bonfire/prelit, +/obj/structure/bonfire/dense/prelit, /turf/open/floor/wood/large, /area/deathmatch) "lx" = ( @@ -321,7 +325,7 @@ /obj/effect/turf_decal/weather/dirt{ dir = 8 }, -/turf/open/water/jungle, +/turf/open/misc/dirt/jungle, /area/deathmatch) "ox" = ( /obj/effect/cosmic_rune, @@ -344,7 +348,7 @@ /obj/effect/turf_decal/weather/dirt{ dir = 6 }, -/turf/open/water/jungle, +/turf/open/misc/dirt/jungle, /area/deathmatch) "pr" = ( /obj/structure/flora/bush/jungle/a/style_random, @@ -426,7 +430,7 @@ /obj/effect/turf_decal/weather/dirt{ dir = 4 }, -/turf/open/water/jungle, +/turf/open/misc/dirt/jungle, /area/deathmatch) "rH" = ( /obj/effect/turf_decal/siding/wood{ @@ -522,6 +526,12 @@ /obj/effect/turf_decal/siding/wood/corner, /turf/open/floor/wood/large, /area/deathmatch) +"wJ" = ( +/obj/effect/turf_decal/weather/dirt{ + dir = 5 + }, +/turf/open/misc/dirt/jungle, +/area/deathmatch) "wP" = ( /obj/structure/flora/rock/style_random, /obj/effect/turf_decal/weather/dirt{ @@ -564,6 +574,11 @@ /obj/effect/spawner/random/decoration/glowstick/on, /turf/open/floor/plating/heretic_rust, /area/deathmatch) +"yZ" = ( +/obj/structure/flora/grass/jungle/b/style_random, +/obj/effect/landmark/deathmatch_player_spawn, +/turf/open/misc/dirt/jungle, +/area/deathmatch) "zo" = ( /obj/structure/flora/rock/pile/jungle/style_random, /obj/effect/landmark/deathmatch_player_spawn, @@ -616,8 +631,10 @@ /turf/open/floor/wood/tile, /area/deathmatch) "AO" = ( -/obj/effect/decal/cleanable/ants, -/turf/closed/wall/heretic_rust, +/obj/effect/turf_decal/weather/dirt{ + dir = 8 + }, +/turf/open/misc/dirt/jungle, /area/deathmatch) "Ba" = ( /obj/structure/destructible/cult/pylon, @@ -648,7 +665,7 @@ /obj/effect/turf_decal/weather/dirt{ dir = 6 }, -/turf/open/water/jungle, +/turf/open/misc/dirt/jungle, /area/deathmatch) "CB" = ( /obj/structure/destructible/eldritch_crucible, @@ -664,7 +681,7 @@ /obj/effect/turf_decal/weather/dirt{ dir = 8 }, -/turf/open/water/jungle, +/turf/open/misc/dirt/jungle, /area/deathmatch) "CR" = ( /mob/living/carbon/human/species/monkey, @@ -681,14 +698,14 @@ /obj/effect/turf_decal/weather/dirt{ dir = 9 }, -/turf/open/water/jungle, +/turf/open/misc/dirt/jungle, /area/deathmatch) "Ds" = ( /obj/effect/turf_decal/weather/dirt{ dir = 8 }, /obj/effect/turf_decal/siding/wood, -/turf/open/water/jungle, +/turf/open/misc/dirt/jungle, /area/deathmatch) "Du" = ( /obj/structure/flora/rock/pile/style_random, @@ -705,7 +722,13 @@ /obj/effect/turf_decal/weather/dirt{ dir = 6 }, -/turf/open/water/jungle, +/turf/open/misc/dirt/jungle, +/area/deathmatch) +"Ed" = ( +/obj/effect/turf_decal/weather/dirt{ + dir = 4 + }, +/turf/open/misc/dirt/jungle, /area/deathmatch) "EF" = ( /obj/effect/decal/cleanable/dirt, @@ -731,7 +754,6 @@ /area/deathmatch) "FQ" = ( /obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/ants, /turf/open/misc/grass/jungle, /area/deathmatch) "FS" = ( @@ -785,7 +807,9 @@ /turf/open/floor/cult, /area/deathmatch) "Ic" = ( -/obj/effect/decal/cleanable/ants, +/obj/effect/turf_decal/weather/dirt{ + dir = 9 + }, /turf/open/misc/dirt/jungle, /area/deathmatch) "Ig" = ( @@ -827,7 +851,8 @@ /turf/open/misc/grass/jungle, /area/deathmatch) "Kg" = ( -/turf/open/water/jungle, +/obj/structure/flora/rock/style_4, +/turf/open/misc/dirt/jungle, /area/deathmatch) "Kl" = ( /obj/effect/spawner/structure/window/bronze, @@ -855,6 +880,15 @@ /obj/structure/flora/grass/jungle/a/style_random, /turf/open/misc/grass/jungle, /area/deathmatch) +"LW" = ( +/obj/effect/turf_decal/weather/dirt{ + dir = 4 + }, +/obj/effect/turf_decal/weather/dirt{ + dir = 6 + }, +/turf/open/water/jungle, +/area/deathmatch) "My" = ( /obj/structure/table/wood, /obj/item/food/grown/holymelon, @@ -883,7 +917,8 @@ /obj/effect/turf_decal/siding/wood{ dir = 1 }, -/turf/open/water/jungle, +/obj/structure/flora/rock/style_4, +/turf/open/misc/dirt/jungle, /area/deathmatch) "Or" = ( /obj/structure/flora/tree/jungle/style_random, @@ -899,12 +934,18 @@ dir = 6 }, /obj/effect/turf_decal/siding/wood, -/turf/open/water/jungle, +/turf/open/misc/dirt/jungle, /area/deathmatch) "Px" = ( /obj/structure/flora/tree/jungle/style_random, /turf/open/misc/grass/jungle, /area/deathmatch) +"PC" = ( +/obj/effect/turf_decal/weather/dirt{ + dir = 10 + }, +/turf/open/misc/dirt/jungle, +/area/deathmatch) "PH" = ( /obj/effect/visible_heretic_influence, /turf/open/misc/dirt/jungle, @@ -940,10 +981,6 @@ /obj/effect/forcefield/cult/permanent, /turf/open/misc/dirt/jungle/dark, /area/deathmatch) -"RE" = ( -/obj/structure/bonfire/prelit, -/turf/open/misc/grass/jungle, -/area/deathmatch) "RL" = ( /obj/effect/turf_decal/siding/wood, /obj/structure/flora/rock/pile/jungle/style_random, @@ -1057,7 +1094,7 @@ /obj/effect/turf_decal/siding/wood{ dir = 1 }, -/turf/open/water/jungle, +/turf/open/misc/dirt/jungle, /area/deathmatch) "VF" = ( /obj/effect/turf_decal/siding/wood{ @@ -1098,6 +1135,15 @@ /obj/structure/flora/grass/jungle/b/style_random, /turf/open/misc/dirt/jungle/dark, /area/deathmatch) +"Ww" = ( +/obj/effect/turf_decal/weather/dirt{ + dir = 10 + }, +/obj/effect/turf_decal/weather/dirt{ + dir = 6 + }, +/turf/open/water/jungle, +/area/deathmatch) "Xa" = ( /obj/structure/rack/skeletal, /obj/item/clothing/head/helmet/chaplain/ancient{ @@ -1114,8 +1160,13 @@ /turf/closed/wall/mineral/cult/artificer, /area/deathmatch) "Yn" = ( -/obj/effect/decal/cleanable/ants, -/turf/open/misc/grass/jungle, +/obj/effect/turf_decal/weather/dirt{ + dir = 9 + }, +/obj/effect/turf_decal/weather/dirt{ + dir = 6 + }, +/turf/open/water/jungle, /area/deathmatch) "Ys" = ( /obj/effect/turf_decal/siding/wood{ @@ -1193,7 +1244,7 @@ /turf/open/misc/grass/jungle, /area/deathmatch) "ZY" = ( -/obj/structure/bonfire/prelit, +/obj/structure/bonfire/dense/prelit, /turf/open/misc/dirt/jungle, /area/deathmatch) @@ -1362,7 +1413,7 @@ jL jv CR LU -Yn +qa Sw Sw yY @@ -1464,7 +1515,7 @@ eL Be XL VP -AO +SC tm qa vI @@ -1515,7 +1566,7 @@ GD qa LU Fn -qa +aR Sw Sw oC @@ -1528,7 +1579,7 @@ dI lx PI Vm -iJ +Ic TN qh FK @@ -1543,7 +1594,7 @@ Ig Ig wR ZY -Ic +FK FK FK sC @@ -1561,8 +1612,8 @@ PI NX NQ NQ -NQ -TN +Ed +AO CE DA Ig @@ -1576,7 +1627,7 @@ iJ TN TN TN -qh +Ww FK FK FK @@ -1586,16 +1637,16 @@ eB SC FK sC -iJ +Ic Ds PI Bp FK FK wR -SE +wJ FK -sC +yZ Ig Ig Ig @@ -1606,18 +1657,18 @@ Ig SE NQ NQ -NQ +LW Kg -TN -qh +AO +PC FK FK -iJ -qh +Yn +PC RL PI Do -Kg +FK Pi PI gx @@ -1638,24 +1689,24 @@ sC sC FK bb -SE -NQ +wJ +Ed bv PI ou -NQ -Kg +Ed +FK Ds ft Vv oO FK -ZY -qa +FK +aR GD qa jv -Yn +qa GD RW jL @@ -1675,7 +1726,7 @@ RL PI Bp bb -SE +wJ rD YI jb @@ -1770,7 +1821,7 @@ QO Jf Yv qa -RE +aR Ov qg qg @@ -1954,7 +2005,7 @@ YN Wp qa qa -Yn +qa qa qa qa @@ -1982,7 +2033,7 @@ KL Nf Sf Jf -RE +aR Px Ik GO diff --git a/_maps/icebox.json b/_maps/icebox.json index caa2c41d93675..ea24dd3360455 100644 --- a/_maps/icebox.json +++ b/_maps/icebox.json @@ -14,7 +14,6 @@ }, "traits": [ { - "Up": true, "Mining": true, "Linkage": null, "Gravity": true, @@ -23,8 +22,6 @@ "No Parallax": true }, { - "Down": true, - "Up": true, "Mining": true, "Linkage": null, "Gravity": true, @@ -33,7 +30,6 @@ "No Parallax": true }, { - "Down": true, "Mining": true, "Linkage": null, "Gravity": true, diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm index 06be9312ae9f9..465d8fab85f23 100644 --- a/_maps/map_files/Birdshot/birdshot.dmm +++ b/_maps/map_files/Birdshot/birdshot.dmm @@ -1,10 +1,4 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"aae" = ( -/obj/item/kirbyplants/random, -/obj/machinery/camera/directional/north, -/obj/machinery/light/small/directional/north, -/turf/open/floor/iron, -/area/station/maintenance/port/fore) "aal" = ( /obj/machinery/camera/directional/east{ c_tag = "Atmospherics Tank - N2" @@ -71,6 +65,19 @@ /obj/machinery/power/tracker, /turf/open/space/basic, /area/station/solars/aft) +"abv" = ( +/obj/structure/table, +/obj/item/paper/crumpled{ + pixel_x = -27; + pixel_y = 2 + }, +/obj/item/storage/medkit/regular{ + pixel_x = -5; + pixel_y = 6 + }, +/obj/effect/landmark/event_spawn, +/turf/open/floor/iron, +/area/station/cargo/sorting) "abB" = ( /obj/structure/disposalpipe/segment, /turf/closed/wall/r_wall, @@ -152,20 +159,6 @@ }, /turf/open/floor/grass/Airless, /area/station/hallway/primary/central/aft) -"ael" = ( -/obj/machinery/door/airlock/public/glass/incinerator/atmos_interior, -/obj/effect/mapping_helpers/airlock/locked, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/visible/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible, -/obj/machinery/airlock_controller/incinerator_atmos{ - pixel_x = -40; - pixel_y = -8 - }, -/turf/open/floor/engine, -/area/station/maintenance/disposal/incinerator) "aem" = ( /obj/machinery/power/terminal, /obj/structure/cable, @@ -205,21 +198,6 @@ }, /turf/open/floor/engine, /area/station/engineering/supermatter/room) -"aeH" = ( -/obj/machinery/atmospherics/components/trinary/filter/flipped/layer2{ - dir = 4 - }, -/obj/machinery/light/small/directional/north, -/obj/machinery/button/door/incinerator_vent_atmos_aux{ - pixel_x = 8; - pixel_y = 24 - }, -/obj/machinery/button/door/incinerator_vent_atmos_main{ - pixel_x = 8; - pixel_y = 36 - }, -/turf/open/floor/plating, -/area/station/maintenance/disposal/incinerator) "aeX" = ( /obj/structure/window/spawner/directional/east, /obj/item/kirbyplants/random, @@ -347,6 +325,7 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/disposalpipe/segment, +/obj/effect/mapping_helpers/airlock/access/any/engineering/general, /turf/open/floor/catwalk_floor, /area/station/engineering/break_room) "ahf" = ( @@ -395,6 +374,17 @@ /obj/effect/turf_decal/siding/yellow, /turf/open/floor/wood/tile, /area/station/command/bridge) +"ahI" = ( +/obj/structure/table, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/item/folder/yellow{ + pixel_x = -3; + pixel_y = 3 + }, +/turf/open/floor/iron, +/area/station/cargo/sorting) "ahW" = ( /obj/structure/railing{ dir = 1 @@ -518,6 +508,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"amq" = ( +/obj/effect/turf_decal/bot_white, +/obj/effect/spawner/random/maintenance, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/dark, +/area/station/cargo/storage) "amE" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -542,6 +539,15 @@ /obj/machinery/airalarm/directional/west, /turf/open/floor/iron/freezer, /area/station/service/kitchen/coldroom) +"amX" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/item/radio/intercom/directional/south, +/obj/effect/turf_decal/tile/neutral, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/iron, +/area/station/hallway/primary/port) "anb" = ( /obj/effect/turf_decal/siding/thinplating_new/terracotta, /obj/effect/turf_decal/siding/red/corner{ @@ -552,6 +558,14 @@ }, /turf/open/floor/wood/tile, /area/station/command/bridge) +"and" = ( +/obj/structure/cable, +/obj/effect/mapping_helpers/airlock/access/all/supply, +/obj/machinery/door/airlock/mining{ + name = "Mining Office" + }, +/turf/open/floor/plating, +/area/station/cargo/miningfoundry) "ani" = ( /obj/effect/turf_decal/weather/dirt{ dir = 1 @@ -601,6 +615,10 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/station/maintenance/fore/lesser) +"api" = ( +/obj/machinery/skill_station, +/turf/open/floor/wood/parquet, +/area/station/service/library) "apk" = ( /obj/structure/disposalpipe/segment, /obj/effect/turf_decal/tile/dark_red{ @@ -644,6 +662,11 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, /area/station/science/lab) +"apP" = ( +/obj/effect/spawner/random/trash, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "apZ" = ( /turf/open/floor/engine/helium, /area/station/ai_monitored/turret_protected/ai) @@ -816,11 +839,6 @@ /obj/structure/sign/poster/contraband/lusty_xenomorph/directional/north, /turf/open/floor/light/colour_cycle/dancefloor_b, /area/station/maintenance/starboard/central) -"atx" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/spawner/random/structure/closet_maintenance, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "atB" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -1103,10 +1121,6 @@ }, /turf/closed/wall, /area/station/hallway/primary/central/aft) -"axj" = ( -/obj/item/radio/intercom/directional/east, -/turf/open/floor/iron, -/area/station/cargo/storage) "axq" = ( /turf/open/floor/plating/airless, /area/station/science/ordnance/bomb) @@ -1140,6 +1154,15 @@ }, /turf/open/floor/engine, /area/station/science/xenobiology) +"axP" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/effect/turf_decal/tile/brown/anticorner{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/lobby) "axX" = ( /obj/effect/turf_decal/siding/yellow, /obj/effect/turf_decal/tile/yellow/diagonal_centre, @@ -1194,17 +1217,6 @@ }, /turf/open/floor/wood, /area/station/engineering/main) -"ayT" = ( -/obj/effect/turf_decal/delivery/white{ - color = "#52B4E9" - }, -/obj/structure/reagent_dispensers/watertank/high, -/obj/effect/turf_decal/siding/thinplating_new/light{ - dir = 9 - }, -/obj/machinery/light/small/dim/directional/north, -/turf/open/floor/iron/white/small, -/area/station/service/hydroponics) "ayV" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -1266,13 +1278,6 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/wood/large, /area/station/command/corporate_suite) -"azK" = ( -/obj/effect/turf_decal/siding/red, -/obj/item/kirbyplants/random, -/obj/item/storage/toolbox/mechanical, -/obj/machinery/light/cold/directional/east, -/turf/open/floor/iron, -/area/station/cargo/storage) "azN" = ( /obj/structure/chair{ dir = 4 @@ -1389,6 +1394,14 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/port) +"aBt" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "aBu" = ( /obj/effect/turf_decal/siding/wood{ dir = 5 @@ -1430,6 +1443,18 @@ }, /turf/open/floor/carpet/blue, /area/station/commons/dorms) +"aBQ" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/office) "aBV" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/tile/neutral{ @@ -1484,16 +1509,6 @@ }, /turf/open/floor/plating/airless, /area/station/science/ordnance/bomb) -"aDJ" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/structure/sign/directions/vault/directional/west{ - dir = 2 - }, -/turf/open/floor/iron, -/area/station/hallway/primary/central/fore) "aEa" = ( /obj/effect/turf_decal/stripes/white/line, /turf/open/floor/tram, @@ -1677,23 +1692,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/central/lesser) -"aGI" = ( -/obj/structure/table, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/cell_charger{ - pixel_x = -1; - pixel_y = 4 - }, -/obj/item/stock_parts/power_store/cell/high{ - pixel_x = -1; - pixel_y = 4 - }, -/obj/item/assembly/timer{ - pixel_x = 14; - pixel_y = 6 - }, -/turf/open/floor/iron/dark, -/area/station/commons/storage/tools) "aGU" = ( /obj/machinery/light/small/directional/west, /turf/open/floor/iron, @@ -1722,17 +1720,6 @@ /obj/machinery/airalarm/directional/west, /turf/open/floor/grass, /area/station/security/prison/garden) -"aHS" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/trimline/neutral/line{ - dir = 8 - }, -/obj/effect/turf_decal/trimline/neutral/line{ - dir = 4 - }, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/hallway/primary/central/fore) "aIb" = ( /obj/machinery/door/airlock{ name = "Maintenance" @@ -1809,6 +1796,10 @@ "aJq" = ( /turf/closed/mineral/random/stationside, /area/space/nearstation) +"aJD" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "aJE" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/siding/wood{ @@ -1902,9 +1893,6 @@ /obj/machinery/light/cold/directional/south, /turf/open/floor/iron/dark/small, /area/station/ai_monitored/security/armory) -"aLm" = ( -/turf/closed/wall/rust, -/area/station/cargo/drone_bay) "aLr" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -1980,6 +1968,18 @@ /obj/machinery/atmospherics/pipe/layer_manifold/supply/visible, /turf/open/floor/plating, /area/station/science/ordnance/testlab) +"aMI" = ( +/obj/machinery/mineral/ore_redemption{ + dir = 4; + input_dir = 8; + output_dir = 4 + }, +/obj/machinery/door/window/right/directional/east{ + name = "Ore Redemtion Window" + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/iron/textured_large, +/area/station/cargo/office) "aNd" = ( /turf/open/floor/engine, /area/station/engineering/supermatter/room) @@ -2005,6 +2005,14 @@ /obj/structure/sign/poster/official/random/directional/north, /turf/open/floor/iron/dark/small, /area/station/medical/storage) +"aNE" = ( +/obj/machinery/computer/cargo{ + dir = 4 + }, +/turf/open/floor/iron/dark/textured_half{ + dir = 1 + }, +/area/station/cargo/storage) "aNJ" = ( /obj/structure/table/reinforced, /obj/machinery/door/window/left/directional/north{ @@ -2700,18 +2708,6 @@ /obj/effect/spawner/structure/window/reinforced/plasma, /turf/open/floor/plating, /area/station/engineering/supermatter) -"bbK" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/decal/cleanable/dirt, -/obj/structure/railing{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/item/kirbyplants/organic/applebush{ - pixel_y = 5 - }, -/turf/open/floor/wood, -/area/station/cargo/miningfoundry) "bbT" = ( /obj/structure/chair/sofa/bench/left{ dir = 8 @@ -2725,6 +2721,15 @@ }, /turf/open/floor/iron, /area/station/maintenance/port/aft) +"bbV" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/catwalk_floor/iron_white, +/area/station/cargo/storage) "bcr" = ( /obj/effect/turf_decal/stripes/end, /turf/open/floor/plating/airless, @@ -2761,6 +2766,12 @@ dir = 4 }, /area/station/science/xenobiology) +"bdi" = ( +/obj/structure/cable, +/obj/effect/turf_decal/siding/wood, +/obj/machinery/light/small/directional/west, +/turf/open/floor/iron/smooth, +/area/station/command/heads_quarters/qm) "bdN" = ( /obj/structure/falsewall, /turf/open/floor/plating, @@ -2794,14 +2805,6 @@ }, /turf/open/floor/wood, /area/station/service/chapel) -"bes" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/grimy, -/area/station/service/library) "bey" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 4 @@ -2836,6 +2839,14 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark/herringbone, /area/station/service/abandoned_gambling_den/gaming) +"bfS" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/tile/neutral, +/obj/structure/disposalpipe/junction/flip{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/hallway/primary/port) "bfU" = ( /obj/machinery/atmospherics/components/binary/pump/on{ name = "Air to Distro staging" @@ -2853,6 +2864,23 @@ /obj/machinery/camera/autoname/directional/east, /turf/open/floor/iron/white/small, /area/station/science/server) +"bgl" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/obj/structure/table/glass, +/obj/item/flashlight/lamp/green{ + pixel_x = 2; + pixel_y = 9 + }, +/obj/item/taperecorder{ + pixel_x = -15; + pixel_y = 3 + }, +/obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/machinery/light_switch/directional/north, +/turf/open/floor/iron/grimy, +/area/station/service/library/private) "bgn" = ( /obj/machinery/door/airlock/maintenance{ name = "Atmospherics Maintenance" @@ -2962,6 +2990,11 @@ /obj/machinery/holopad, /turf/open/floor/iron/white/small, /area/station/science/lobby) +"biV" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/camera/autoname/directional/south, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "bja" = ( /obj/structure/railing/corner/end/flip{ dir = 8 @@ -2987,6 +3020,19 @@ }, /turf/open/floor/iron/white/side, /area/station/hallway/primary/central/aft) +"bjf" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/structure/table, +/obj/effect/turf_decal/delivery/white, +/obj/machinery/microwave{ + pixel_y = 6 + }, +/obj/machinery/camera/autoname/directional/south, +/obj/structure/sign/poster/official/random/directional/south, +/turf/open/floor/iron/smooth, +/area/station/cargo/sorting) "bjh" = ( /obj/structure/cable, /obj/machinery/power/apc/auto_name/directional/west, @@ -3005,6 +3051,9 @@ /obj/machinery/power/apc/auto_name/directional/north, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) +"bjt" = ( +/turf/open/floor/engine/vacuum, +/area/station/engineering/atmos) "bjL" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/structure/table, @@ -3175,6 +3224,16 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/stairs, /area/station/maintenance/department/engine/atmos) +"bmO" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/delivery/white, +/turf/closed/wall, +/area/station/maintenance/port/fore) "bmT" = ( /obj/effect/turf_decal/stripes/white/line{ dir = 4 @@ -3305,6 +3364,17 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/catwalk_floor, /area/station/engineering/break_room) +"boG" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/obj/structure/extinguisher_cabinet/directional/north, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/light/warm/directional/north, +/turf/open/floor/iron, +/area/station/cargo/storage) "boI" = ( /obj/machinery/mecha_part_fabricator/maint{ name = "forgotten exosuit fabricator" @@ -3450,6 +3520,18 @@ name = "Holodeck Projector Floor" }, /area/station/holodeck/rec_center) +"bqA" = ( +/obj/effect/turf_decal/weather/dirt, +/obj/effect/turf_decal/weather/dirt{ + dir = 1 + }, +/obj/structure/flora/bush/flowers_yw, +/obj/structure/flora/bush/large/style_random{ + pixel_x = -20; + pixel_y = 3 + }, +/turf/open/floor/grass, +/area/station/service/chapel) "bqD" = ( /mob/living/basic/slime, /turf/open/floor/engine, @@ -3527,6 +3609,14 @@ /obj/machinery/atmospherics/pipe/smart/simple/cyan/visible, /turf/closed/wall/r_wall, /area/station/engineering/atmos) +"brO" = ( +/obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "brZ" = ( /obj/machinery/door/airlock{ name = "Maintenance" @@ -3536,6 +3626,16 @@ /obj/structure/barricade/wooden/crude, /turf/open/floor/plating, /area/station/maintenance/aft) +"bst" = ( +/obj/machinery/portable_atmospherics/canister/air, +/obj/effect/turf_decal/bot{ + dir = 1 + }, +/obj/machinery/power/apc/auto_name/directional/west, +/obj/structure/cable, +/obj/machinery/light/small/directional/west, +/turf/open/floor/iron/dark, +/area/station/engineering/atmos/storage) "bsu" = ( /obj/structure/barricade/wooden/crude, /obj/effect/mapping_helpers/broken_floor, @@ -3729,29 +3829,23 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/central/greater) -"bvV" = ( -/obj/structure/disposalpipe/trunk{ - dir = 1 - }, -/obj/machinery/disposal/bin, -/obj/structure/cable, -/turf/open/floor/wood, -/area/station/command/heads_quarters/qm) -"bwy" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 8 - }, -/obj/structure/sign/poster/official/random/directional/west, -/obj/structure/destructible/cult/item_dispenser/archives/library, -/obj/item/book/codex_gigas, -/obj/machinery/light/small/dim/directional/west, -/turf/open/floor/iron/grimy, -/area/station/service/library) "bwz" = ( /obj/effect/spawner/random/entertainment/arcade, /obj/machinery/light/cold/directional/north, /turf/open/floor/iron/cafeteria, /area/station/security/prison/mess) +"bwW" = ( +/obj/structure/table/reinforced, +/obj/effect/turf_decal/siding/yellow{ + dir = 4 + }, +/obj/effect/spawner/random/food_or_drink/donkpockets{ + pixel_y = 6 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable, +/turf/open/floor/wood, +/area/station/engineering/break_room) "bxa" = ( /obj/structure/chair/sofa/bench/right{ dir = 4 @@ -3889,6 +3983,13 @@ }, /turf/open/floor/wood, /area/station/engineering/atmos/pumproom) +"bzW" = ( +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/office) "bzZ" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, @@ -3989,30 +4090,6 @@ }, /turf/open/floor/iron, /area/station/security/processing) -"bCh" = ( -/obj/effect/turf_decal/stripes{ - dir = 4 - }, -/obj/effect/turf_decal/trimline/brown/line{ - dir = 8 - }, -/obj/effect/turf_decal/trimline/brown/line{ - dir = 4 - }, -/obj/effect/turf_decal/stripes{ - dir = 8 - }, -/obj/machinery/door/airlock/mining{ - name = "Bitrunning Den" - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/mapping_helpers/airlock/access/any/supply/bit_den, -/turf/open/floor/iron/dark/smooth_half{ - dir = 1 - }, -/area/station/cargo/bitrunning/den) "bCn" = ( /obj/effect/turf_decal/tile/blue, /obj/structure/extinguisher_cabinet/directional/west, @@ -4054,16 +4131,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/science/lower) -"bCZ" = ( -/obj/effect/turf_decal/trimline/yellow/filled/line{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/arrows{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/sorting) "bDg" = ( /obj/machinery/atmospherics/components/binary/pump{ dir = 1 @@ -4081,6 +4148,16 @@ /obj/structure/cable, /turf/open/floor/iron/diagonal, /area/station/engineering/lobby) +"bDi" = ( +/obj/machinery/atmospherics/components/binary/pump/on{ + name = "O2 to Airmix" + }, +/obj/machinery/light/no_nightlight/directional/north, +/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/engineering/atmos) "bDj" = ( /obj/effect/landmark/start/medical_doctor, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, @@ -4136,6 +4213,10 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) +"bEv" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "bEw" = ( /obj/structure/sign/directions/supply{ dir = 1; @@ -4284,13 +4365,6 @@ /obj/structure/reagent_dispensers/watertank, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) -"bGU" = ( -/obj/machinery/door/airlock/mining/glass{ - name = "Filing Room" - }, -/obj/effect/mapping_helpers/airlock/access/all/supply/general, -/turf/open/floor/catwalk_floor/iron_dark, -/area/station/cargo/office) "bGX" = ( /obj/structure/chair/office, /obj/effect/turf_decal/siding/wideplating{ @@ -4334,6 +4408,12 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) +"bHw" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/maintenance/port/greater) "bHy" = ( /obj/structure/chair/office/light, /obj/effect/landmark/start/scientist, @@ -4361,6 +4441,11 @@ /obj/structure/window/spawner/directional/south, /turf/open/misc/sandy_dirt, /area/station/science/research) +"bIu" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/wood, +/area/station/command/heads_quarters/qm) "bIJ" = ( /obj/effect/turf_decal/weather/dirt{ dir = 4 @@ -4395,27 +4480,6 @@ /obj/effect/turf_decal/siding/wood, /turf/open/floor/wood, /area/station/service/chapel) -"bJH" = ( -/obj/effect/turf_decal/tile/brown/opposingcorners, -/obj/machinery/atmospherics/pipe/smart/simple/cyan/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/door/airlock/engineering{ - name = "Engineering Office" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ - cycle_id = "atmos_airlock_1" - }, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/all/engineering/atmos, -/turf/open/floor/iron, -/area/station/engineering/atmos/office) "bJK" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -4444,16 +4508,6 @@ /obj/effect/turf_decal/weather/dirt, /turf/open/floor/grass, /area/station/service/chapel) -"bKz" = ( -/obj/structure/disposalpipe/junction{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/machinery/light/small/directional/north, -/turf/open/floor/iron/smooth, -/area/station/command/heads_quarters/qm) "bKE" = ( /obj/effect/turf_decal/siding/red{ dir = 1 @@ -4509,6 +4563,14 @@ /obj/machinery/light/no_nightlight/directional/north, /turf/open/floor/iron, /area/station/engineering/atmos) +"bLG" = ( +/obj/effect/spawner/structure/window, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plating, +/area/station/cargo/office) "bLS" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -4648,13 +4710,6 @@ /obj/structure/sign/poster/official/random/directional/north, /turf/open/misc/sandy_dirt, /area/station/hallway/secondary/entry) -"bOY" = ( -/obj/structure/sign/poster/random/directional/east, -/obj/machinery/conveyor{ - id = "mining" - }, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) "bPd" = ( /obj/machinery/atmospherics/pipe/smart/simple/cyan/visible{ dir = 4 @@ -4771,6 +4826,9 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/smooth, /area/station/security/checkpoint/customs/auxiliary) +"bRA" = ( +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/cargo/lobby) "bRK" = ( /obj/effect/turf_decal/siding/thinplating_new/light{ dir = 4 @@ -4840,6 +4898,12 @@ /obj/machinery/atmospherics/components/unary/outlet_injector/monitored/incinerator_input, /turf/open/floor/engine/vacuum, /area/station/maintenance/disposal/incinerator) +"bUq" = ( +/obj/structure/cable, +/obj/item/reagent_containers/pill/maintenance, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "bUr" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/tile/blue{ @@ -4972,12 +5036,6 @@ /obj/machinery/chem_heater/withbuffer, /turf/open/floor/iron, /area/station/science/xenobiology) -"bXb" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/maintenance/department/electrical) "bXi" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -5135,25 +5193,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/department/engine) -"cag" = ( -/obj/effect/turf_decal/tile/brown/opposingcorners, -/obj/machinery/atmospherics/pipe/smart/simple/orange/hidden{ - dir = 4 - }, -/obj/machinery/door/airlock/engineering{ - name = "Engineering Office" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ - cycle_id = "atmos_airlock_1" - }, -/obj/structure/cable, -/obj/machinery/door/firedoor, -/obj/structure/disposalpipe/segment{ - dir = 8 - }, -/obj/effect/mapping_helpers/airlock/access/all/engineering/atmos, -/turf/open/floor/iron, -/area/station/engineering/atmos/office) "cam" = ( /obj/machinery/flasher/directional/east{ id = "AI"; @@ -5249,6 +5288,15 @@ "cbm" = ( /turf/closed/wall/rust, /area/station/ai_monitored/aisat/exterior) +"cbq" = ( +/obj/structure/cable, +/obj/machinery/airalarm/directional/north, +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/obj/machinery/disposal/bin, +/turf/open/floor/iron/smooth, +/area/station/command/heads_quarters/qm) "cbt" = ( /obj/structure/cable, /obj/structure/table/bronze, @@ -5346,6 +5394,13 @@ /obj/machinery/light/cold/dim/directional/east, /turf/open/floor/iron, /area/station/hallway/primary/fore) +"ccO" = ( +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 1 + }, +/obj/effect/spawner/random/vending/snackvend, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "cdg" = ( /obj/machinery/light/small/directional/west, /turf/open/floor/grass, @@ -5354,6 +5409,16 @@ /obj/machinery/telecomms/server/presets/medical, /turf/open/floor/circuit, /area/station/tcommsat/server) +"cdp" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 1; + name = "CO2 to Pure" + }, +/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/engineering/atmos) "cdz" = ( /obj/effect/turf_decal/tile/yellow, /obj/machinery/light/cold/dim/directional/west, @@ -5371,14 +5436,6 @@ }, /turf/open/floor/grass, /area/station/service/chapel) -"cdC" = ( -/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/structure/sign/departments/exodrone/directional/west, -/turf/open/floor/plating, -/area/station/maintenance/port/greater) "cdY" = ( /obj/structure/cable, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -5391,6 +5448,20 @@ /obj/structure/window/spawner/directional/south, /turf/open/space/basic, /area/space/nearstation) +"ceD" = ( +/obj/machinery/door/airlock/grunge{ + name = "Janitorial Closet" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron/textured_half{ + dir = 8 + }, +/area/station/service/janitor) "ceN" = ( /obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible{ dir = 4 @@ -5636,6 +5707,22 @@ /obj/effect/turf_decal/tile/purple/opposingcorners, /turf/open/floor/iron/cafeteria, /area/station/science/circuits) +"cjc" = ( +/obj/structure/chair/stool/directional/south, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/siding/wood{ + dir = 9 + }, +/turf/open/floor/carpet/orange, +/area/station/command/heads_quarters/qm) +"cjf" = ( +/obj/machinery/door/firedoor, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/iron/small, +/area/station/cargo/lobby) "cjm" = ( /obj/structure/closet/firecloset, /obj/machinery/status_display/evac/directional/south, @@ -5713,6 +5800,14 @@ /obj/structure/barricade/wooden/crude, /turf/open/floor/noslip, /area/station/maintenance/department/medical/central) +"cky" = ( +/obj/machinery/airalarm/directional/north, +/obj/item/kirbyplants/organic/applebush{ + pixel_y = 5 + }, +/obj/machinery/light/small/directional/west, +/turf/open/floor/iron/smooth, +/area/station/cargo/miningfoundry) "ckL" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -5733,16 +5828,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/port) -"ckR" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 1; - name = "Plasma to Pure" - }, -/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/engineering/atmos) "ckV" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -6112,6 +6197,18 @@ }, /turf/open/floor/iron/small, /area/station/security/brig) +"csj" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/loading_area{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "csl" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -6142,18 +6239,6 @@ /obj/machinery/light/cold/directional/west, /turf/open/floor/iron/small, /area/station/medical/medbay/lobby) -"csA" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ - cycle_id = "sci-entrance" - }, -/obj/machinery/door/airlock/maintenance{ - name = "Maintenance" - }, -/obj/effect/mapping_helpers/airlock/access/any/supply/maintenance, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "csE" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 8 @@ -6224,6 +6309,13 @@ /obj/machinery/light/cold/directional/north, /turf/open/floor/iron, /area/station/security/prison/rec) +"cuZ" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/siding/thinplating_new, +/turf/open/floor/iron/smooth, +/area/station/cargo/miningfoundry) "cvc" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -6403,6 +6495,25 @@ /obj/structure/cable, /turf/open/floor/iron/dark/small, /area/station/command/heads_quarters/ce) +"cyQ" = ( +/obj/effect/mapping_helpers/broken_floor, +/obj/structure/rack, +/obj/item/clothing/ears/earmuffs{ + pixel_x = -3; + pixel_y = -2 + }, +/obj/item/clothing/ears/earmuffs{ + pixel_x = -8; + pixel_y = 11 + }, +/obj/item/clothing/ears/earmuffs{ + pixel_x = 4; + pixel_y = 6 + }, +/obj/item/pickaxe, +/obj/machinery/newscaster/directional/west, +/turf/open/floor/iron/smooth, +/area/station/cargo/miningfoundry) "cyU" = ( /obj/effect/spawner/random/structure/table, /obj/effect/spawner/random/maintenance, @@ -6434,6 +6545,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/station/medical/treatment_center) +"czh" = ( +/obj/machinery/light/floor, +/obj/structure/flora/bush/flowers_br, +/obj/structure/flora/bush/flowers_br/style_3, +/turf/open/floor/grass, +/area/station/hallway/primary/central/fore) "czq" = ( /obj/structure/curtain/cloth, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -6446,13 +6563,6 @@ dir = 8 }, /area/station/service/janitor) -"czu" = ( -/obj/structure/table/wood, -/obj/item/paper_bin, -/obj/item/pen, -/obj/structure/cable, -/turf/open/floor/carpet/lone, -/area/station/service/chapel/office) "cAb" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -6588,6 +6698,15 @@ }, /turf/open/floor/iron, /area/station/maintenance/hallway/abandoned_command) +"cCC" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/office) "cCD" = ( /obj/structure/cable, /obj/machinery/door/airlock/maintenance/external{ @@ -6707,6 +6826,15 @@ dir = 1 }, /area/station/maintenance/starboard/greater) +"cDQ" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/wood, +/area/station/service/chapel/office) "cDV" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/smart/simple/purple/visible{ @@ -6727,6 +6855,11 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron, /area/station/hallway/primary/central/aft) +"cEp" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/portable_atmospherics/canister/air, +/turf/open/floor/plating, +/area/station/maintenance/port/greater) "cED" = ( /obj/structure/railing/corner, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, @@ -6911,6 +7044,13 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/iron/dark, /area/station/service/lawoffice) +"cHD" = ( +/obj/machinery/atmospherics/pipe/bridge_pipe/yellow/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible, +/turf/open/floor/iron, +/area/station/engineering/atmos) "cHG" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -7161,6 +7301,12 @@ /obj/machinery/door/poddoor/incinerator_atmos_aux, /turf/open/floor/plating, /area/station/maintenance/disposal/incinerator) +"cMH" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/maintenance/central/greater) "cMS" = ( /obj/structure/cable, /obj/structure/chair/stool/directional/north, @@ -7186,6 +7332,21 @@ /obj/machinery/camera/autoname/directional/east, /turf/open/floor/iron, /area/station/commons/fitness/locker_room) +"cNl" = ( +/obj/structure/railing{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/obj/effect/turf_decal/siding/thinplating_new{ + dir = 4 + }, +/turf/open/floor/iron/smooth, +/area/station/cargo/miningfoundry) +"cNw" = ( +/obj/effect/turf_decal/siding/red, +/obj/item/kirbyplants/random, +/turf/open/floor/iron, +/area/station/cargo/storage) "cNR" = ( /obj/structure/chair/office{ dir = 4 @@ -7206,6 +7367,16 @@ }, /turf/open/floor/engine, /area/station/science/xenobiology) +"cOa" = ( +/obj/structure/table, +/obj/item/screwdriver{ + pixel_y = -6 + }, +/obj/item/storage/toolbox/mechanical{ + pixel_y = 7 + }, +/turf/open/floor/iron/dark, +/area/station/commons/storage/tools) "cOd" = ( /obj/structure/flora/bush/flowers_yw/style_random, /obj/structure/flora/rock/pile/style_2{ @@ -7216,6 +7387,13 @@ /obj/structure/window/spawner/directional/west, /turf/open/misc/sandy_dirt, /area/station/commons/fitness/recreation/entertainment) +"cOs" = ( +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/structure/table, +/turf/open/floor/iron, +/area/station/cargo/sorting) "cOC" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -7349,15 +7527,6 @@ }, /turf/open/floor/plating, /area/station/ai_monitored/turret_protected/aisat/maint) -"cQV" = ( -/obj/machinery/door/airlock/engineering/glass{ - name = "Engineering Storage" - }, -/obj/effect/mapping_helpers/airlock/access/all/engineering/engine_equipment, -/turf/open/floor/iron/smooth_half{ - dir = 8 - }, -/area/station/engineering/main) "cRc" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -7602,6 +7771,13 @@ dir = 1 }, /area/station/hallway/primary/aft) +"cUV" = ( +/obj/effect/turf_decal/siding/wood, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 4 + }, +/turf/open/floor/iron/smooth, +/area/station/command/heads_quarters/qm) "cUY" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, @@ -7652,16 +7828,6 @@ }, /turf/open/floor/iron/dark/herringbone, /area/station/security/execution/education) -"cVO" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/obj/structure/cable, -/turf/open/floor/wood, -/area/station/service/chapel/office) "cVQ" = ( /obj/machinery/firealarm/directional/south, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -7678,6 +7844,11 @@ dir = 4 }, /area/station/maintenance/fore/lesser) +"cWC" = ( +/obj/item/reagent_containers/cup/watering_can/wood, +/obj/structure/table, +/turf/open/floor/plating, +/area/station/maintenance/starboard/greater) "cWM" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -7831,11 +8002,6 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron/smooth, /area/station/cargo/drone_bay) -"cYT" = ( -/obj/structure/hedge, -/obj/structure/sign/poster/contraband/random/directional/east, -/turf/open/floor/iron/grimy, -/area/station/command/heads_quarters/qm) "cYW" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/spawner/random/structure/steam_vent, @@ -7964,6 +8130,13 @@ dir = 1 }, /area/station/science/lower) +"day" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/landmark/event_spawn, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/lobby) "daC" = ( /obj/structure/hedge, /obj/effect/turf_decal/siding/thinplating_new{ @@ -8015,10 +8188,6 @@ "dbF" = ( /turf/open/floor/plating/rust, /area/station/ai_monitored/turret_protected/aisat/maint) -"dbJ" = ( -/obj/effect/landmark/start/librarian, -/turf/open/floor/iron/grimy, -/area/station/service/library) "dbZ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/disposalpipe/segment{ @@ -8035,6 +8204,11 @@ /obj/machinery/firealarm/directional/west, /turf/open/floor/iron/dark, /area/station/security/interrogation) +"dcu" = ( +/obj/structure/cable, +/obj/machinery/power/apc/auto_name/directional/north, +/turf/open/floor/iron/smooth, +/area/station/cargo/warehouse) "dcx" = ( /obj/effect/turf_decal/siding/white{ dir = 10 @@ -8238,10 +8412,12 @@ /obj/machinery/status_display/ai/directional/north, /turf/open/floor/circuit/red, /area/station/ai_monitored/turret_protected/ai) -"dfN" = ( -/obj/structure/window/spawner/directional/west, -/obj/structure/window/spawner/directional/south, -/turf/open/floor/grass, +"dfM" = ( +/obj/structure/rack, +/obj/item/storage/medkit/regular, +/turf/open/floor/iron/dark/textured_half{ + dir = 1 + }, /area/station/cargo/storage) "dfT" = ( /obj/effect/turf_decal/bot{ @@ -8280,6 +8456,25 @@ /obj/structure/cable, /turf/open/floor/iron/white/corner, /area/station/science/lower) +"dgt" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 9 + }, +/obj/item/storage/fancy/candle_box, +/obj/structure/rack/skeletal, +/obj/machinery/camera/autoname/directional/west, +/obj/structure/sign/poster/official/random/directional/north, +/turf/open/floor/iron/grimy, +/area/station/service/library/private) +"dgy" = ( +/obj/structure/chair/office{ + dir = 1 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/turf/open/floor/carpet, +/area/station/maintenance/hallway/abandoned_recreation) "dgV" = ( /obj/effect/turf_decal/stripes/white/line{ dir = 5 @@ -8436,6 +8631,13 @@ /obj/effect/landmark/start/mime, /turf/open/floor/iron/smooth, /area/station/service/greenroom) +"diN" = ( +/obj/effect/spawner/structure/window, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/plating, +/area/station/cargo/office) "diP" = ( /turf/open/floor/iron, /area/station/hallway/primary/central/aft) @@ -8536,6 +8738,12 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron, /area/station/security/tram) +"dkD" = ( +/obj/structure/closet/secure_closet/engineering_personal, +/obj/item/clothing/suit/hooded/wintercoat/engineering, +/obj/structure/cable, +/turf/open/floor/iron/small, +/area/station/engineering/break_room) "dkI" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -8610,6 +8818,9 @@ /obj/structure/tram, /turf/open/floor/tram, /area/station/maintenance/port/aft) +"dmO" = ( +/turf/open/floor/iron/dark, +/area/station/cargo/lobby) "dmT" = ( /obj/machinery/camera/directional/north{ c_tag = "Xenobiology - Cell 2"; @@ -8645,10 +8856,6 @@ /obj/machinery/light_switch/directional/south, /turf/open/floor/stone, /area/station/service/abandoned_gambling_den) -"dny" = ( -/obj/structure/cable, -/turf/open/floor/carpet/lone, -/area/station/service/chapel/office) "dnK" = ( /obj/item/kirbyplants/random, /obj/item/storage/briefcase{ @@ -8679,12 +8886,12 @@ /obj/machinery/door/airlock/maintenance{ name = "Maintenance" }, -/obj/effect/mapping_helpers/airlock/access/all/engineering/general, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance, /turf/open/floor/plating, /area/station/maintenance/department/engine) "dob" = ( @@ -8715,13 +8922,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) -"doi" = ( -/obj/machinery/vending/wardrobe/chap_wardrobe, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/camera/autoname/directional/south, -/obj/structure/cable, -/turf/open/floor/carpet/lone, -/area/station/service/chapel/office) "doj" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, @@ -8778,14 +8978,6 @@ }, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) -"dpz" = ( -/obj/machinery/atmospherics/pipe/smart/simple/purple/visible, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light_switch/directional/west, -/obj/effect/landmark/event_spawn, -/obj/machinery/portable_atmospherics/pump/lil_pump, -/turf/open/floor/iron/dark, -/area/station/science/ordnance) "dpH" = ( /obj/machinery/atmospherics/components/unary/vent_pump/siphon/monitored/mix_output{ dir = 8 @@ -8808,6 +9000,23 @@ /obj/item/clothing/head/utility/chefhat, /turf/open/floor/iron/dark/small, /area/station/commons/fitness/locker_room) +"dqF" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/structure/table/glass, +/obj/item/paper_bin{ + pixel_x = -3; + pixel_y = 7 + }, +/obj/item/pen/invisible{ + pixel_x = -2; + pixel_y = 7 + }, +/obj/machinery/newscaster/directional/north, +/obj/item/storage/photo_album/library, +/turf/open/floor/iron/grimy, +/area/station/service/library/private) "dqO" = ( /turf/open/floor/iron/dark/small, /area/station/security/checkpoint/customs/auxiliary) @@ -9061,6 +9270,15 @@ }, /turf/open/floor/iron/smooth, /area/station/security/checkpoint/customs) +"dvP" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/stripes/white/corner{ + dir = 1 + }, +/turf/open/floor/iron/dark/corner{ + dir = 1 + }, +/area/station/cargo/storage) "dvY" = ( /obj/effect/turf_decal/siding/wood{ dir = 10 @@ -9086,6 +9304,9 @@ }, /turf/open/misc/sandy_dirt, /area/station/security/tram) +"dwy" = ( +/turf/open/floor/catwalk_floor/iron_white, +/area/station/cargo/storage) "dwC" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -9264,11 +9485,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) -"dzH" = ( -/obj/machinery/portable_atmospherics/canister/plasma, -/obj/machinery/atmospherics/pipe/smart/simple/yellow/visible, -/turf/open/floor/engine/plasma, -/area/station/engineering/atmos) "dAn" = ( /obj/structure/disposalpipe/segment, /turf/open/floor/plating, @@ -9337,6 +9553,10 @@ /obj/structure/cable, /turf/open/floor/iron/smooth, /area/station/security/evidence) +"dAZ" = ( +/obj/structure/cable, +/turf/open/floor/iron/dark, +/area/station/cargo/lobby) "dBh" = ( /obj/effect/turf_decal/siding/wood{ dir = 6 @@ -9349,6 +9569,14 @@ /obj/effect/turf_decal/tile/neutral/opposingcorners, /turf/open/floor/iron, /area/station/commons/fitness/recreation/entertainment) +"dBn" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/sign/departments/cargo/directional/west, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "dBr" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -9444,16 +9672,6 @@ }, /turf/open/floor/iron/smooth, /area/station/cargo/drone_bay) -"dDi" = ( -/obj/machinery/door/airlock/maintenance{ - name = "Maintenance" - }, -/obj/effect/mapping_helpers/airlock/access/any/service/maintenance, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/plating, -/area/station/maintenance/port/greater) "dDk" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/chapel{ @@ -9519,6 +9737,12 @@ /obj/item/radio/intercom/directional/north, /turf/open/floor/iron, /area/station/engineering/atmos) +"dEp" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/camera/autoname/directional/west, +/obj/machinery/firealarm/directional/west, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "dEq" = ( /obj/effect/turf_decal/siding/thinplating_new/light, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -9552,19 +9776,18 @@ dir = 1 }, /area/station/science/ordnance/testlab) -"dEQ" = ( -/obj/structure/cable, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/plating, -/area/station/maintenance/port/greater) "dEY" = ( /obj/effect/turf_decal/siding/thinplating_new/light{ dir = 5 }, /turf/open/floor/iron/white/small, /area/station/service/hydroponics) +"dFn" = ( +/obj/structure/table/wood, +/obj/item/flashlight/lamp, +/obj/item/radio/intercom/directional/west, +/turf/open/floor/wood, +/area/station/command/heads_quarters/qm) "dFA" = ( /obj/effect/turf_decal/tile/brown/opposingcorners, /obj/machinery/atmospherics/pipe/smart/simple/cyan/hidden{ @@ -9667,6 +9890,12 @@ }, /turf/open/floor/iron/dark/small, /area/station/ai_monitored/security/armory) +"dIw" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/light/small/directional/west, +/turf/open/floor/iron/dark, +/area/station/engineering/atmospherics_engine) "dIQ" = ( /obj/effect/turf_decal/weather/dirt, /obj/structure/flora/bush/flowers_yw/style_3, @@ -9782,6 +10011,11 @@ }, /turf/open/floor/engine/n2o, /area/station/engineering/atmos) +"dLl" = ( +/obj/effect/spawner/structure/window, +/obj/structure/curtain/bounty/start_closed, +/turf/open/floor/plating, +/area/station/maintenance/port/greater) "dLn" = ( /obj/structure/chair/office, /turf/open/floor/iron/dark/herringbone, @@ -9846,6 +10080,13 @@ /obj/machinery/camera/autoname/directional/east, /turf/open/floor/plating, /area/station/construction/mining/aux_base) +"dMC" = ( +/obj/structure/window/reinforced/spawner/directional/north, +/obj/structure/window/reinforced/spawner/directional/south, +/obj/structure/grille, +/obj/structure/window/reinforced/spawner/directional/west, +/turf/open/floor/plating, +/area/station/hallway/primary/central/fore) "dMM" = ( /obj/effect/spawner/random/engineering/tracking_beacon, /turf/open/floor/iron, @@ -9925,6 +10166,19 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/commons/storage/tools) +"dOH" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "dOP" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible/layer2{ dir = 1 @@ -10046,17 +10300,10 @@ /obj/effect/turf_decal/siding/wood/end, /turf/open/floor/stone, /area/station/service/chapel) -"dRD" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 9 - }, -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) +"dRz" = ( +/obj/docking_port/stationary/syndicate/northeast, +/turf/open/space/basic, +/area/space) "dRT" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -10145,6 +10392,22 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/iron, /area/station/hallway/primary/central/aft) +"dTi" = ( +/obj/machinery/light/cold/directional/west, +/obj/machinery/atmospherics/components/unary/thermomachine/freezer/layer2{ + dir = 4 + }, +/turf/open/floor/iron/dark, +/area/station/science/ordnance) +"dTj" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable, +/obj/effect/mapping_helpers/airlock/access/all/supply/general, +/obj/machinery/door/airlock{ + name = "Cargo Maintenance" + }, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "dTo" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, /obj/effect/turf_decal/stripes/line{ @@ -10174,11 +10437,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) -"dTQ" = ( -/obj/structure/disposalpipe/segment, -/obj/structure/cable, -/turf/open/floor/wood, -/area/station/service/chapel/office) "dTW" = ( /obj/effect/turf_decal/tile/brown/opposingcorners, /obj/machinery/computer/shuttle/mining{ @@ -10342,6 +10600,14 @@ /obj/machinery/door/firedoor, /turf/open/floor/catwalk_floor/iron, /area/station/science/lower) +"dXu" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/chair/stool/directional/south, +/turf/open/floor/iron, +/area/station/cargo/sorting) "dXO" = ( /obj/effect/spawner/structure/window/reinforced/tinted, /obj/structure/disposalpipe/segment{ @@ -10462,13 +10728,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) -"dZm" = ( -/obj/structure/chair{ - dir = 8 - }, -/obj/machinery/light/small/directional/south, -/turf/open/floor/iron, -/area/station/maintenance/port/fore) "dZn" = ( /obj/machinery/ai_slipper{ uses = 10 @@ -10569,6 +10828,11 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/wood/tile, /area/station/service/bar) +"ebn" = ( +/obj/structure/closet/emcloset, +/obj/effect/turf_decal/tile/blue, +/turf/open/floor/iron/dark/side, +/area/station/hallway/primary/central/fore) "ebE" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -10586,6 +10850,19 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/herringbone, /area/station/commons/dorms) +"ebM" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/sorting) "ebU" = ( /obj/structure/table/reinforced, /obj/structure/reagent_dispensers/servingdish, @@ -10665,6 +10942,19 @@ }, /turf/open/floor/iron, /area/station/service/hydroponics) +"edA" = ( +/obj/machinery/conveyor_switch/oneway{ + dir = 8; + id = "QMLoad"; + name = "Loading Conveyor"; + pixel_x = -13; + pixel_y = 19 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "edD" = ( /obj/machinery/light/small/directional/west, /obj/item/kirbyplants/random, @@ -10758,10 +11048,6 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/iron, /area/station/hallway/primary/central/aft) -"efn" = ( -/obj/effect/spawner/random/structure/crate_loot, -/turf/open/floor/plating, -/area/station/maintenance/department/electrical) "efy" = ( /obj/item/kirbyplants/organic/plant21, /obj/machinery/status_display/ai/directional/west, @@ -10817,11 +11103,22 @@ }, /turf/open/floor/iron, /area/station/service/hydroponics) +"egg" = ( +/obj/structure/water_source/puddle, +/turf/open/misc/asteroid, +/area/station/maintenance/starboard/greater) "egr" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt, /turf/open/floor/catwalk_floor/iron_dark, /area/station/science/xenobiology) +"egA" = ( +/obj/machinery/vending/autodrobe, +/obj/effect/turf_decal/siding/wideplating/dark{ + dir = 8 + }, +/turf/open/floor/iron/small, +/area/station/commons/fitness/locker_room) "egC" = ( /obj/machinery/atmospherics/pipe/smart/simple/purple/visible{ dir = 4 @@ -10861,6 +11158,18 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/chapel, /area/station/maintenance/starboard/greater) +"egW" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/item/radio/intercom/directional/south, +/obj/machinery/light/cold/directional/south, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "ehd" = ( /obj/item/stack/cable_coil, /obj/item/electronics/airlock, @@ -10898,6 +11207,19 @@ /obj/effect/spawner/structure/window/reinforced/tinted, /turf/open/floor/plating, /area/station/maintenance/fore/lesser) +"ehu" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/button/door/directional/east{ + id = "qm_warehouse_aft"; + name = "Warehouse Door Control"; + pixel_x = -24; + pixel_y = -23; + req_access = list("cargo") + }, +/obj/machinery/light/small/dim/directional/west, +/obj/effect/turf_decal/loading_area, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "ehT" = ( /obj/machinery/door/airlock{ id_tag = "commiss2"; @@ -10928,6 +11250,16 @@ /obj/structure/broken_flooring/singular/directional/south, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) +"eib" = ( +/obj/machinery/conveyor_switch/oneway{ + id = "QMLoad2"; + name = "Unloading Conveyor"; + pixel_x = -13; + pixel_y = 3 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/iron, +/area/station/cargo/storage) "eip" = ( /obj/machinery/power/port_gen/pacman, /obj/machinery/power/terminal{ @@ -11197,14 +11529,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) -"elN" = ( -/obj/effect/landmark/start/hangover, -/obj/machinery/light/small/directional/north, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/hallway/primary/central/aft) "elR" = ( /obj/structure/table, /obj/structure/window/spawner/directional/south, @@ -11234,6 +11558,9 @@ /obj/machinery/holopad, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/rd) +"emz" = ( +/turf/closed/wall/r_wall/rust, +/area/station/maintenance/department/electrical) "emB" = ( /obj/machinery/door/airlock/maintenance{ name = "Maintenance" @@ -11297,6 +11624,16 @@ "enG" = ( /turf/open/floor/iron/dark, /area/station/science/ordnance) +"enI" = ( +/obj/machinery/door/airlock/maintenance{ + name = "Atmospherics Maintenance" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/mapping_helpers/airlock/access/all/engineering/atmos, +/turf/open/floor/plating, +/area/station/maintenance/disposal/incinerator) "enV" = ( /obj/structure/closet/secure_closet/research_director, /obj/item/radio/intercom/directional/north, @@ -11322,13 +11659,6 @@ /obj/machinery/power/apc/auto_name/directional/north, /turf/open/floor/iron, /area/station/security/brig/entrance) -"eog" = ( -/obj/machinery/atmospherics/components/unary/thermomachine/freezer/layer2{ - dir = 4 - }, -/obj/machinery/light/cold/directional/west, -/turf/open/floor/iron/dark, -/area/station/science/ordnance) "eok" = ( /obj/machinery/air_sensor/nitrogen_tank, /obj/machinery/atmospherics/pipe/smart/simple/yellow/visible, @@ -11544,6 +11874,15 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/port/greater) +"eti" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/stripes/white/line{ + dir = 8 + }, +/turf/open/floor/iron/dark/side{ + dir = 8 + }, +/area/station/cargo/storage) "etl" = ( /obj/machinery/atmospherics/pipe/smart/simple/cyan/hidden{ dir = 5 @@ -11565,6 +11904,10 @@ /obj/effect/spawner/random/maintenance, /turf/open/floor/circuit, /area/station/maintenance/port/aft) +"etJ" = ( +/obj/machinery/light/small/directional/south, +/turf/open/floor/stone, +/area/station/service/chapel) "etZ" = ( /obj/effect/turf_decal/tile/dark_red/half/contrasted, /obj/effect/turf_decal/siding/wideplating/dark/corner{ @@ -11756,6 +12099,26 @@ /obj/structure/sink/directional/east, /turf/open/floor/iron/white, /area/station/medical/virology) +"eyx" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/stripes/red/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/red/line{ + dir = 8 + }, +/obj/structure/sign/directions/supply/directional/west{ + pixel_x = 0; + pixel_y = 39 + }, +/obj/structure/sign/directions/vault/directional/west{ + dir = 2; + pixel_x = 0; + pixel_y = 30 + }, +/turf/open/floor/iron/small, +/area/station/hallway/primary/central/fore) "eyB" = ( /obj/structure/cable, /obj/machinery/door/firedoor, @@ -11954,17 +12317,6 @@ }, /turf/open/floor/iron, /area/station/commons/storage/art) -"eBC" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/item/radio/intercom/directional/south, -/turf/open/floor/iron, -/area/station/hallway/primary/central/fore) "eBH" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -12014,6 +12366,23 @@ }, /turf/open/floor/iron/small, /area/station/engineering/main) +"eCO" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/power/apc/auto_name/directional/east, +/obj/effect/turf_decal/siding/wood, +/turf/open/floor/iron/smooth, +/area/station/command/heads_quarters/qm) +"eCV" = ( +/obj/effect/turf_decal/tile/brown/anticorner/contrasted, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/sorting) "eDh" = ( /obj/effect/spawner/structure/window/survival_pod, /turf/open/floor/engine, @@ -12034,6 +12403,7 @@ /obj/machinery/door/airlock/engineering/glass{ name = "Engineering Foyer" }, +/obj/effect/mapping_helpers/airlock/access/any/engineering/general, /turf/open/floor/catwalk_floor, /area/station/engineering/break_room) "eDr" = ( @@ -12149,6 +12519,13 @@ /obj/machinery/camera/directional/west, /turf/open/floor/iron/smooth, /area/station/commons/storage/tools) +"eEG" = ( +/obj/structure/hedge, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/floor/iron/smooth, +/area/station/cargo/storage) "eEL" = ( /obj/machinery/portable_atmospherics/canister/air, /turf/open/floor/plating, @@ -12342,18 +12719,6 @@ /obj/machinery/light/cold/directional/north, /turf/open/floor/iron, /area/station/security/prison/workout) -"eHv" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/obj/structure/chair/comfy/brown{ - buildstackamount = 0; - color = "#c45c57"; - dir = 8 - }, -/turf/open/floor/iron/grimy, -/area/station/service/library) "eHy" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -12383,13 +12748,14 @@ /obj/machinery/light/floor, /turf/open/floor/iron/dark/textured, /area/station/ai_monitored/turret_protected/ai) -"eIF" = ( -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/obj/structure/table, +"eII" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/tile/neutral, +/obj/machinery/status_display/evac/directional/east, +/obj/machinery/camera/autoname/directional/east, /turf/open/floor/iron, -/area/station/cargo/sorting) +/area/station/hallway/primary/central/fore) "eIM" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/disposalpipe/sorting/mail/flip{ @@ -12436,6 +12802,20 @@ /obj/effect/turf_decal/tile/dark_red/opposingcorners, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) +"eJi" = ( +/obj/structure/table/wood, +/obj/item/hand_labeler_refill{ + pixel_x = -4; + pixel_y = 26 + }, +/obj/structure/sign/poster/official/random/directional/south, +/obj/machinery/fax{ + fax_name = "Quartermaster's Office"; + name = "Quartermaster's Fax Machine"; + pixel_y = 7 + }, +/turf/open/floor/wood, +/area/station/command/heads_quarters/qm) "eJm" = ( /obj/machinery/disposal/bin, /obj/effect/turf_decal/bot, @@ -12461,14 +12841,6 @@ /obj/effect/turf_decal/stripes/asteroid/end, /turf/open/floor/circuit/green, /area/station/science/robotics/mechbay) -"eKd" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden, -/obj/machinery/light/small/directional/west, -/obj/machinery/airlock_sensor/incinerator_atmos{ - pixel_y = -20 - }, -/turf/open/floor/engine, -/area/station/maintenance/disposal/incinerator) "eKf" = ( /obj/structure/table, /obj/item/storage/box/donkpockets/donkpocketpizza, @@ -12497,6 +12869,11 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"eKV" = ( +/obj/machinery/atmospherics/pipe/smart/simple/dark/visible, +/obj/machinery/portable_atmospherics/pump, +/turf/open/floor/iron/dark, +/area/station/science/ordnance) "eKW" = ( /obj/machinery/door/airlock/maintenance{ name = "Bathroom" @@ -12577,6 +12954,19 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/circuit/red, /area/station/ai_monitored/turret_protected/ai) +"eNa" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/white/line{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "eNl" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -12687,6 +13077,12 @@ }, /turf/open/floor/iron, /area/station/cargo/miningfoundry) +"ePr" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/sorting) "ePt" = ( /obj/structure/flora/grass/jungle/a/style_4, /turf/open/floor/grass, @@ -12754,6 +13150,17 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/commons/dorms) +"eQI" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/firealarm/directional/east, +/obj/effect/turf_decal/stripes/corner, +/obj/effect/turf_decal/stripes/white/corner, +/obj/machinery/camera/autoname/directional/east, +/turf/open/floor/iron/smooth, +/area/station/cargo/warehouse) "eQQ" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -12802,6 +13209,16 @@ /obj/machinery/door/firedoor, /turf/open/floor/catwalk_floor/iron, /area/station/science/lower) +"eSA" = ( +/obj/machinery/disposal/bin, +/obj/effect/turf_decal/bot, +/obj/structure/disposalpipe/trunk{ + dir = 2 + }, +/turf/open/floor/iron/dark/side{ + dir = 1 + }, +/area/station/hallway/primary/central/fore) "eSV" = ( /obj/structure/bed/maint, /turf/open/floor/iron/small, @@ -12855,6 +13272,12 @@ /obj/effect/turf_decal/siding/wood/corner, /turf/open/floor/wood/tile, /area/station/service/bar) +"eTL" = ( +/obj/structure/cable, +/turf/open/floor/iron/stairs{ + dir = 1 + }, +/area/station/cargo/lobby) "eTT" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -13061,6 +13484,11 @@ /obj/machinery/light/cold/directional/west, /turf/open/floor/iron/white, /area/station/medical/medbay/aft) +"eXl" = ( +/obj/effect/spawner/structure/window/reinforced/plasma, +/obj/machinery/atmospherics/pipe/smart/simple/orange/visible, +/turf/open/floor/plating, +/area/station/engineering/supermatter/room) "eXo" = ( /turf/closed/wall/r_wall, /area/station/tcommsat/server) @@ -13158,6 +13586,10 @@ }, /turf/open/misc/sandy_dirt, /area/station/maintenance/port/lesser) +"eZd" = ( +/obj/effect/spawner/random/structure/crate_loot, +/turf/open/floor/plating, +/area/station/maintenance/department/electrical) "eZi" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -13473,6 +13905,10 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark/small, /area/station/security/brig) +"fgo" = ( +/obj/item/pickaxe, +/turf/open/floor/plating, +/area/station/maintenance/department/electrical) "fgp" = ( /turf/open/floor/iron/dark/side, /area/station/security/execution/transfer) @@ -13608,6 +14044,10 @@ /obj/item/plate, /turf/open/floor/iron/cafeteria, /area/station/security/prison/mess) +"fiE" = ( +/obj/effect/turf_decal/siding/red, +/turf/open/floor/iron, +/area/station/cargo/storage) "fiK" = ( /obj/structure/cable, /obj/structure/disposalpipe/sorting/mail/flip{ @@ -13677,12 +14117,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) -"fkd" = ( -/obj/structure/chair/stool/directional/south, -/obj/machinery/holopad, -/obj/effect/landmark/start/cargo_technician, -/turf/open/floor/iron, -/area/station/cargo/sorting) "fkj" = ( /obj/machinery/porta_turret/ai{ dir = 4 @@ -13804,6 +14238,13 @@ /obj/item/flashlight/lantern, /turf/open/floor/plating/rust, /area/station/maintenance/starboard/greater) +"fma" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/effect/landmark/start/cargo_technician, +/turf/open/floor/iron, +/area/station/cargo/storage) "fme" = ( /obj/effect/turf_decal/weather/dirt{ dir = 1 @@ -14077,6 +14518,13 @@ /obj/machinery/door/window/brigdoor/right/directional/north, /turf/open/floor/iron/textured_large, /area/station/security/checkpoint/customs) +"frY" = ( +/obj/structure/closet/secure_closet/security/cargo, +/obj/effect/turf_decal/tile/red/anticorner/contrasted{ + dir = 1 + }, +/turf/open/floor/iron/smooth, +/area/station/security/checkpoint/supply) "frZ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -14154,18 +14602,6 @@ }, /turf/open/floor/wood/tile, /area/station/maintenance/aft) -"fts" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/computer/order_console/bitrunning{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/end{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "ftv" = ( /obj/effect/turf_decal/tile/dark_red/opposingcorners, /obj/structure/table/reinforced, @@ -14199,6 +14635,18 @@ }, /turf/open/floor/wood, /area/station/service/chapel) +"ftI" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/lobby) "ftT" = ( /obj/machinery/atmospherics/pipe/smart/simple/orange/hidden, /obj/machinery/camera/directional/west{ @@ -14334,6 +14782,15 @@ }, /turf/open/floor/iron/dark, /area/station/security/processing) +"fvX" = ( +/obj/structure/table, +/obj/item/restraints/handcuffs/cable/red{ + pixel_x = 1; + pixel_y = 6 + }, +/obj/item/storage/toolbox/mechanical, +/turf/open/floor/iron, +/area/station/cargo/sorting) "fwc" = ( /obj/structure/cable, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -14409,14 +14866,14 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/maintenance/department/medical/central) +"fxc" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/smooth, +/area/station/cargo/warehouse) "fxi" = ( /turf/open/floor/iron/dark/small, /area/station/science/xenobiology) -"fxp" = ( -/obj/effect/spawner/structure/window/reinforced/plasma, -/obj/machinery/atmospherics/pipe/smart/simple/orange/visible, -/turf/open/floor/plating, -/area/station/engineering/supermatter/room) "fxF" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -14428,6 +14885,14 @@ /obj/structure/table, /turf/open/floor/iron/kitchen/small, /area/station/maintenance/aft) +"fxO" = ( +/obj/effect/turf_decal/stripes/white/line{ + dir = 4 + }, +/turf/open/floor/iron/dark/side{ + dir = 4 + }, +/area/station/cargo/storage) "fxW" = ( /obj/machinery/restaurant_portal/restaurant, /obj/effect/turf_decal/siding/wood{ @@ -14570,6 +15035,13 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/central/aft) +"fAn" = ( +/obj/effect/spawner/structure/window, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "fAr" = ( /obj/structure/window/reinforced/spawner/directional/south, /obj/structure/barricade/wooden/crude, @@ -14693,9 +15165,6 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/construction) -"fCd" = ( -/turf/open/floor/wood, -/area/station/cargo/miningfoundry) "fCf" = ( /obj/effect/turf_decal/caution{ dir = 4 @@ -14725,6 +15194,16 @@ }, /turf/open/floor/iron/dark, /area/station/medical/chemistry) +"fCK" = ( +/obj/machinery/door/airlock/mining{ + name = "Mining Office" + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/mapping_helpers/airlock/access/all/supply, +/turf/open/floor/iron/smooth, +/area/station/cargo/warehouse) "fCS" = ( /obj/structure/window/reinforced/spawner/directional/east, /obj/machinery/airalarm/directional/east, @@ -15092,6 +15571,14 @@ /obj/machinery/vending/wardrobe/science_wardrobe, /turf/open/floor/iron/white, /area/station/science/research) +"fHX" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/iron/stairs{ + dir = 8 + }, +/area/station/cargo/storage) "fIe" = ( /obj/machinery/atmospherics/pipe/smart/simple/cyan/hidden{ dir = 6 @@ -15116,6 +15603,13 @@ /obj/machinery/light/floor, /turf/open/floor/stone, /area/station/service/bar) +"fIq" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/spawner/structure/window, +/turf/open/floor/plating, +/area/station/cargo/office) "fIw" = ( /obj/effect/landmark/navigate_destination/dockescpod, /turf/open/floor/plating, @@ -15313,22 +15807,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/fore) -"fLF" = ( -/obj/machinery/navbeacon{ - codes_txt = "delivery;dir=8"; - location = "QM #2" - }, -/obj/effect/turf_decal/delivery, -/obj/machinery/camera/autoname/directional/south, -/obj/machinery/light/small/directional/south, -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/cargo/storage) "fLI" = ( /obj/effect/spawner/random/structure/crate, /turf/open/floor/iron/dark/small, @@ -15365,6 +15843,15 @@ /obj/structure/disposalpipe/segment, /turf/closed/wall, /area/station/commons/fitness/recreation/entertainment) +"fMf" = ( +/obj/machinery/disposal/bin, +/obj/effect/turf_decal/bot, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/obj/machinery/power/apc/auto_name/directional/south, +/turf/open/floor/iron, +/area/station/hallway/primary/port) "fMg" = ( /obj/structure/chair/stool/directional/north, /turf/open/floor/iron/smooth, @@ -15643,6 +16130,14 @@ /obj/machinery/light/small/directional/west, /turf/open/floor/iron/small, /area/station/service/janitor) +"fQv" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "fQA" = ( /obj/effect/spawner/random/structure/chair_maintenance{ dir = 8 @@ -15739,9 +16234,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/wood/parquet, /area/station/service/library) -"fSe" = ( -/turf/closed/wall/rust, -/area/station/cargo/miningfoundry) "fSf" = ( /obj/structure/cable, /obj/effect/spawner/structure/window/reinforced, @@ -15978,6 +16470,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/commons/fitness/locker_room) +"fWj" = ( +/obj/structure/cable, +/obj/machinery/airalarm/directional/north, +/obj/item/kirbyplants/random, +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/office) "fWr" = ( /obj/structure/closet/crate, /obj/structure/barricade/wooden/crude, @@ -16522,10 +17023,12 @@ /obj/machinery/camera/autoname/directional/west, /turf/open/floor/iron, /area/station/hallway/primary/aft) -"ggr" = ( -/obj/item/pickaxe, -/turf/open/floor/plating, -/area/station/maintenance/department/electrical) +"ggn" = ( +/obj/effect/decal/cleanable/oil, +/obj/machinery/byteforge, +/obj/effect/turf_decal/box, +/turf/open/floor/iron/dark/smooth_large, +/area/station/cargo/bitrunning/den) "ggw" = ( /obj/effect/turf_decal/stripes/white/end{ dir = 1 @@ -16554,6 +17057,14 @@ }, /turf/open/floor/wood, /area/station/engineering/atmospherics_engine) +"ggK" = ( +/obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/machinery/pdapainter/supply, +/turf/open/floor/iron/smooth, +/area/station/command/heads_quarters/qm) "ggN" = ( /obj/effect/turf_decal/stripes/white/line{ dir = 9 @@ -16682,6 +17193,12 @@ /obj/machinery/nuclearbomb/beer, /turf/open/floor/iron/freezer, /area/station/command/corporate_suite) +"giA" = ( +/obj/effect/turf_decal/siding/wood/end{ + dir = 4 + }, +/turf/open/floor/carpet/red, +/area/station/command/heads_quarters/qm) "giU" = ( /obj/effect/turf_decal/siding/thinplating_new/terracotta{ dir = 1 @@ -16801,11 +17318,6 @@ /obj/machinery/suit_storage_unit/atmos, /turf/open/floor/iron/dark, /area/station/engineering/atmos/office) -"gls" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/catwalk_floor/iron_dark, -/area/station/maintenance/central/greater) "glM" = ( /obj/effect/turf_decal/trimline/neutral/line, /obj/effect/turf_decal/trimline/neutral/line{ @@ -16919,6 +17431,15 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central/aft) +"gnO" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/office) "gnQ" = ( /obj/machinery/atmospherics/pipe/layer_manifold/scrubbers/hidden, /obj/effect/spawner/structure/window, @@ -17087,6 +17608,12 @@ /obj/structure/spider/stickyweb, /turf/open/floor/iron/dark, /area/station/maintenance/department/engine/atmos) +"gqw" = ( +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/office) "gqS" = ( /obj/machinery/atmospherics/pipe/smart/simple/purple/visible, /obj/effect/turf_decal/siding/wideplating, @@ -17204,6 +17731,20 @@ }, /turf/open/floor/iron/white/corner, /area/station/hallway/secondary/exit/departure_lounge) +"guq" = ( +/obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/effect/spawner/random/structure/steam_vent, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) +"gus" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron/smooth, +/area/station/cargo/warehouse) "guz" = ( /obj/structure/cable, /obj/item/kirbyplants/random, @@ -17379,15 +17920,6 @@ /obj/machinery/light/floor, /turf/open/floor/iron/dark/small, /area/station/tcommsat/server) -"gxr" = ( -/obj/machinery/door/airlock/mining{ - name = "Mining Office" - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/smooth, -/area/station/cargo/miningfoundry) "gxs" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/research/glass{ @@ -17424,10 +17956,6 @@ /obj/item/hfr_box/core, /turf/open/floor/iron/dark, /area/station/engineering/atmospherics_engine) -"gxL" = ( -/obj/machinery/firealarm/directional/south, -/turf/open/floor/iron, -/area/station/cargo/storage) "gxP" = ( /obj/structure/flora/bush/large/style_random, /obj/structure/window/spawner/directional/east, @@ -17662,6 +18190,12 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron/small, /area/station/hallway/primary/fore) +"gBs" = ( +/obj/effect/spawner/structure/window, +/obj/structure/cable, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plating, +/area/station/command/heads_quarters/qm) "gBu" = ( /turf/closed/wall/r_wall, /area/station/security/prison/mess) @@ -17854,6 +18388,37 @@ /obj/structure/closet/firecloset, /turf/open/floor/plating, /area/station/maintenance/port/fore) +"gEa" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/office) +"gEb" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/table/wood, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/obj/item/folder/yellow{ + pixel_x = 7; + pixel_y = 6 + }, +/obj/item/storage/dice{ + pixel_x = -10; + pixel_y = 11 + }, +/obj/item/pen{ + pixel_x = -2; + pixel_y = 4 + }, +/turf/open/floor/carpet, +/area/station/maintenance/hallway/abandoned_recreation) "gEc" = ( /obj/structure/closet/emcloset, /turf/open/floor/plating, @@ -17880,16 +18445,6 @@ "gEH" = ( /turf/closed/wall/r_wall, /area/station/security/evidence) -"gEJ" = ( -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/obj/machinery/airalarm/directional/south, -/turf/open/floor/iron, -/area/station/cargo/office) "gEM" = ( /obj/structure/chair/sofa/bench/right{ dir = 4 @@ -17911,6 +18466,25 @@ }, /turf/open/floor/iron/smooth, /area/station/command/bridge) +"gFi" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/button/door/directional/east{ + id = "qm_warehouse"; + name = "Warehouse Door Control"; + pixel_x = -24; + pixel_y = 24; + req_access = list("cargo") + }, +/obj/effect/turf_decal/loading_area{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "gFm" = ( /obj/machinery/light/dim/directional/south, /obj/effect/turf_decal/tile/neutral, @@ -18004,12 +18578,6 @@ }, /turf/open/floor/carpet/executive, /area/station/command/heads_quarters/captain/private) -"gGw" = ( -/obj/machinery/airalarm/directional/north, -/obj/machinery/newscaster/directional/west, -/obj/structure/chair, -/turf/open/floor/wood, -/area/station/cargo/miningfoundry) "gGx" = ( /obj/effect/turf_decal/siding/wood{ dir = 5 @@ -18026,6 +18594,14 @@ /obj/structure/lattice, /turf/open/space/basic, /area/space/nearstation) +"gGA" = ( +/obj/effect/turf_decal/stripes/white/line{ + dir = 1 + }, +/turf/open/floor/iron/dark/side{ + dir = 1 + }, +/area/station/cargo/storage) "gGB" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -18114,6 +18690,25 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/catwalk_floor/iron_smooth, /area/station/command/gateway) +"gIr" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 4 + }, +/obj/machinery/conveyor_switch/oneway{ + id = "packageSort2"; + name = "Sort and Deliver"; + pixel_x = 8; + pixel_y = 12 + }, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/sorting) "gIs" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -18187,6 +18782,26 @@ /obj/machinery/camera/autoname/directional/south, /turf/open/floor/iron, /area/station/security) +"gJb" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/conveyor{ + dir = 1; + id = "packageSort2" + }, +/obj/machinery/door/window/left/directional/west{ + name = "Crate Security Door"; + req_access = list("shipping") + }, +/turf/open/floor/plating, +/area/station/cargo/sorting) "gJo" = ( /turf/open/floor/iron/stairs{ dir = 8 @@ -18259,18 +18874,6 @@ /obj/structure/reagent_dispensers/fueltank, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) -"gKK" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/machinery/door/airlock/maintenance{ - name = "Maintenance" - }, -/obj/effect/mapping_helpers/airlock/unres{ - dir = 1 - }, -/obj/effect/mapping_helpers/airlock/access/any/supply/maintenance, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "gKL" = ( /turf/closed/wall/r_wall, /area/station/engineering/break_room) @@ -18350,6 +18953,15 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central/aft) +"gLS" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/landmark/navigate_destination/chapel, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/iron, +/area/station/hallway/primary/port) "gLV" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -18489,13 +19101,6 @@ }, /turf/open/floor/iron/small, /area/station/engineering/break_room) -"gNC" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/mapping_helpers/broken_floor, -/obj/structure/cable, -/turf/open/floor/wood, -/area/station/command/heads_quarters/qm) "gNH" = ( /obj/effect/turf_decal/stripes/white/line{ dir = 6 @@ -18513,12 +19118,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/hallway/primary/port) -"gNV" = ( -/obj/structure/disposalpipe/segment, -/turf/open/floor/iron/stairs{ - dir = 1 - }, -/area/station/cargo/office) "gNX" = ( /obj/machinery/light/floor, /turf/open/floor/iron/white/small, @@ -18557,6 +19156,13 @@ }, /turf/open/floor/iron, /area/station/science/xenobiology) +"gOS" = ( +/obj/machinery/rnd/production/techfab/department/cargo, +/obj/effect/turf_decal/delivery/white, +/obj/machinery/light_switch/directional/south, +/obj/machinery/light/warm/directional/south, +/turf/open/floor/iron/smooth, +/area/station/cargo/sorting) "gOX" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 8 @@ -18595,11 +19201,24 @@ /obj/structure/fermenting_barrel, /turf/open/floor/plating, /area/station/maintenance/port/fore) -"gPT" = ( -/obj/effect/spawner/random/structure/grille, -/obj/effect/spawner/random/structure/girder, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) +"gPO" = ( +/obj/structure/disposalpipe/trunk{ + dir = 2 + }, +/obj/machinery/disposal/delivery_chute{ + name = "Service Deliveries" + }, +/obj/structure/sign/departments/botany/directional/north, +/obj/effect/turf_decal/tile/green/fourcorners, +/obj/structure/plasticflaps{ + name = "Service Deliveries" + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/obj/effect/turf_decal/delivery/white, +/turf/open/floor/iron/dark/side, +/area/station/cargo/sorting) "gPY" = ( /obj/structure/window/reinforced/spawner/directional/west, /obj/effect/turf_decal/stripes/white/line{ @@ -18614,14 +19233,6 @@ /obj/structure/sign/warning/chem_diamond, /turf/closed/wall, /area/station/medical/chemistry) -"gQm" = ( -/obj/structure/window/spawner/directional/east, -/obj/item/kirbyplants/random, -/obj/effect/turf_decal/bot_white, -/obj/machinery/light/small/directional/north, -/obj/structure/sign/warning/no_smoking/circle/directional/north, -/turf/open/floor/iron/smooth, -/area/station/commons/storage/tools) "gQy" = ( /obj/effect/mapping_helpers/broken_floor, /obj/structure/cable, @@ -18629,29 +19240,6 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/plating, /area/station/maintenance/disposal/incinerator) -"gQG" = ( -/obj/structure/window/spawner/directional/east, -/obj/structure/closet/crate, -/obj/effect/turf_decal/bot_white, -/obj/item/clothing/gloves/color/fyellow, -/obj/item/stack/package_wrap{ - pixel_y = 5 - }, -/obj/item/stack/package_wrap{ - pixel_y = 2 - }, -/obj/item/storage/box{ - desc = "It smells of monkey business..."; - name = "Empty Gorillacube Box" - }, -/obj/item/weldingtool, -/obj/item/radio{ - pixel_y = 3; - pixel_x = -6 - }, -/obj/item/assembly/signaler, -/turf/open/floor/iron/smooth, -/area/station/commons/storage/tools) "gRm" = ( /obj/structure/flora/bush/flowers_br, /obj/structure/flora/bush/flowers_pp/style_random, @@ -18737,19 +19325,19 @@ /obj/item/stack/sheet/mineral/titanium, /turf/open/floor/tram, /area/station/maintenance/department/medical/central) +"gSA" = ( +/obj/machinery/vending/wardrobe/cargo_wardrobe, +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/office) "gSD" = ( /obj/machinery/mass_driver/chapelgun{ dir = 8 }, /turf/open/floor/plating, /area/station/service/chapel/funeral) -"gSX" = ( -/obj/machinery/computer/piratepad_control/civilian{ - dir = 1 - }, -/obj/structure/sign/departments/cargo/directional/west, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/central/fore) "gTb" = ( /turf/open/floor/iron/dark/side{ dir = 8 @@ -18779,6 +19367,15 @@ }, /turf/open/floor/carpet/executive, /area/station/command/meeting_room) +"gTj" = ( +/obj/structure/cable, +/turf/closed/wall, +/area/station/maintenance/port/greater) +"gTw" = ( +/obj/machinery/light/small/dim/directional/north, +/obj/effect/spawner/random/structure/crate, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "gTH" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -18890,12 +19487,6 @@ /obj/machinery/atmospherics/pipe/smart/simple/green/visible, /turf/open/floor/engine/o2, /area/station/engineering/atmos) -"gUQ" = ( -/obj/machinery/atmospherics/pipe/layer_manifold/supply/visible{ - dir = 4 - }, -/turf/closed/wall/r_wall, -/area/station/maintenance/department/engine/atmos) "gUV" = ( /obj/structure/cable, /obj/structure/chair/stool/directional/south{ @@ -18991,6 +19582,18 @@ /obj/machinery/status_display/ai/directional/north, /turf/open/floor/iron/cafeteria, /area/station/science/breakroom) +"gXB" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 4 + }, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/lobby) "gXL" = ( /obj/structure/cable, /obj/machinery/door/airlock{ @@ -19077,6 +19680,16 @@ dir = 4 }, /area/station/hallway/secondary/entry) +"gZR" = ( +/obj/structure/sign/poster/random/directional/south, +/obj/machinery/conveyor{ + id = "mining"; + dir = 10 + }, +/obj/machinery/bouldertech/refinery, +/obj/structure/sign/poster/random/directional/east, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "gZS" = ( /obj/structure/cable, /obj/machinery/power/apc/auto_name/directional/west, @@ -19106,19 +19719,18 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/commons/dorms) -"had" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/junction/flip{ - dir = 4 - }, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "hal" = ( /obj/effect/turf_decal/stripes/line{ dir = 6 }, /turf/open/floor/engine, /area/station/engineering/atmospherics_engine) +"hao" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/lobby) "haq" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -19570,16 +20182,6 @@ /obj/structure/lattice, /turf/open/misc/asteroid/airless, /area/space/nearstation) -"hfC" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/corner, -/obj/effect/decal/cleanable/dirt, -/obj/effect/spawner/random/trash, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "hfI" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -19589,22 +20191,6 @@ }, /turf/open/floor/wood/tile, /area/station/tcommsat/server) -"hfZ" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/turf/open/floor/iron/dark/side{ - dir = 4 - }, -/area/station/commons/storage/tools) -"hgd" = ( -/obj/structure/table, -/obj/item/screwdriver{ - pixel_y = -6 - }, -/obj/item/storage/toolbox/mechanical{ - pixel_y = 7 - }, -/turf/open/floor/iron/dark, -/area/station/commons/storage/tools) "hgf" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/tile/green{ @@ -19628,6 +20214,16 @@ }, /turf/open/floor/iron/smooth, /area/station/maintenance/solars/starboard/aft) +"hgp" = ( +/obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/office) "hgu" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -19708,12 +20304,13 @@ /obj/effect/mapping_helpers/airlock/access/all/security/general, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"hhr" = ( -/obj/machinery/atmospherics/pipe/layer_manifold/scrubbers/hidden{ +"hhy" = ( +/obj/machinery/atmospherics/pipe/smart/simple/yellow/visible{ dir = 4 }, -/turf/closed/wall/r_wall, -/area/station/maintenance/department/engine/atmos) +/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible, +/turf/open/floor/iron, +/area/station/engineering/atmos) "hhL" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -19800,6 +20397,21 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark/small, /area/station/medical/morgue) +"hjA" = ( +/obj/structure/table, +/obj/machinery/status_display/supply{ + pixel_x = 1; + pixel_y = 32 + }, +/obj/machinery/fax/auto_name{ + pixel_x = -1; + pixel_y = 6 + }, +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/office) "hjQ" = ( /obj/structure/disposalpipe/segment, /obj/effect/turf_decal/tile/neutral{ @@ -19807,6 +20419,19 @@ }, /turf/open/floor/iron, /area/station/engineering/lobby) +"hjS" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/structure/table, +/obj/effect/turf_decal/delivery/white, +/obj/effect/spawner/random/food_or_drink/donkpockets{ + pixel_x = -9; + pixel_y = 3 + }, +/obj/structure/cable, +/turf/open/floor/iron/smooth, +/area/station/cargo/sorting) "hkd" = ( /obj/effect/turf_decal/siding/wideplating{ dir = 8 @@ -19927,6 +20552,18 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron/dark, /area/station/science/ordnance/storage) +"hlP" = ( +/obj/structure/table/wood, +/obj/effect/decal/cleanable/dirt, +/obj/item/stack/wrapping_paper{ + pixel_x = -3; + pixel_y = 5 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/turf/open/floor/carpet/orange, +/area/station/command/heads_quarters/qm) "hlX" = ( /obj/machinery/door/airlock/public/glass{ name = "Old Command Hallway" @@ -19950,27 +20587,6 @@ /obj/effect/spawner/random/structure/girder, /turf/open/floor/tram, /area/station/security/tram) -"hmh" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/dark/side{ - dir = 4 - }, -/area/station/commons/storage/tools) -"hmj" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/table, -/obj/effect/decal/cleanable/dirt, -/obj/item/tank/internals/emergency_oxygen{ - pixel_x = 5; - pixel_y = 3 - }, -/obj/item/gps{ - pixel_y = 5; - pixel_x = 13 - }, -/obj/item/storage/toolbox/emergency/old, -/turf/open/floor/iron/dark, -/area/station/commons/storage/tools) "hmk" = ( /obj/structure/chair/stool/directional/east, /turf/open/floor/iron/smooth, @@ -20016,26 +20632,12 @@ dir = 1 }, /area/station/service/bar/backroom) -"hmQ" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/table, -/obj/effect/decal/cleanable/dirt, -/obj/item/crowbar/large{ - pixel_y = 18 - }, -/obj/item/clothing/head/costume/pirate{ - pixel_x = 15; - pixel_y = -3 - }, -/obj/item/clothing/suit/hazardvest{ - pixel_x = -3; - pixel_y = -2 - }, -/obj/item/wrench{ - pixel_y = 15 +"hmR" = ( +/obj/structure/disposalpipe/segment{ + dir = 6 }, -/turf/open/floor/iron/dark, -/area/station/commons/storage/tools) +/turf/open/floor/iron, +/area/station/cargo/storage) "hnf" = ( /obj/item/bikehorn/rubberducky{ pixel_x = -6; @@ -20137,16 +20739,13 @@ /obj/structure/flora/bush/flowers_pp/style_random, /turf/open/misc/sandy_dirt, /area/station/medical/medbay/lobby) -"hoV" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable, -/obj/structure/railing/corner/end{ - dir = 4 +"hpb" = ( +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 8 }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/wood, -/area/station/cargo/miningfoundry) +/obj/machinery/vending/cigarette, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "hpe" = ( /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/iron, @@ -20196,11 +20795,6 @@ dir = 8 }, /area/station/science/lobby) -"hqH" = ( -/obj/item/reagent_containers/cup/watering_can/wood, -/obj/structure/table, -/turf/open/floor/plating, -/area/station/maintenance/starboard/greater) "hqM" = ( /obj/structure/toiletbong{ dir = 1 @@ -20415,12 +21009,10 @@ }, /obj/effect/turf_decal/delivery/white, /obj/structure/rack, -/obj/item/hand_labeler, /obj/item/stack/cable_coil/five, /obj/item/pickaxe, /obj/item/wrench, /obj/item/radio/off, -/obj/structure/sign/poster/official/random/directional/west, /turf/open/floor/iron/smooth, /area/station/commons/storage/tools) "huj" = ( @@ -20630,13 +21222,6 @@ /obj/machinery/status_display/evac/directional/west, /turf/open/floor/iron/diagonal, /area/station/engineering/lobby) -"hyb" = ( -/obj/structure/cable, -/obj/machinery/power/apc/auto_name/directional/north, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/smooth, -/area/station/cargo/warehouse) "hyi" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -20660,12 +21245,25 @@ "hyE" = ( /turf/closed/wall, /area/station/maintenance/starboard/aft) -"hyO" = ( +"hyS" = ( +/obj/effect/turf_decal/tile/brown/opposingcorners, +/obj/machinery/atmospherics/pipe/smart/simple/orange/hidden{ + dir = 4 + }, +/obj/machinery/door/airlock/engineering{ + name = "Engineering Office" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ + cycle_id = "atmos_airlock_1" + }, /obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/structure/steam_vent, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) +/obj/machinery/door/firedoor, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/effect/mapping_helpers/airlock/access/all/engineering/atmos, +/turf/open/floor/iron, +/area/station/engineering/atmos/office) "hyW" = ( /obj/effect/turf_decal/weather/dirt{ dir = 10 @@ -20691,9 +21289,6 @@ }, /turf/open/floor/iron/dark/herringbone, /area/station/ai_monitored/command/nuke_storage) -"hzm" = ( -/turf/closed/wall/rust, -/area/station/cargo/miningoffice) "hzp" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/trimline/neutral/line, @@ -20707,6 +21302,16 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/port) +"hzr" = ( +/obj/structure/closet/secure_closet/detective, +/obj/machinery/requests_console/directional/north{ + department = "Detective's Office"; + name = "Detective Requests Console" + }, +/obj/machinery/light/small/directional/west, +/obj/structure/detectiveboard/directional/west, +/turf/open/floor/wood, +/area/station/security/detectives_office) "hzK" = ( /obj/structure/disposalpipe/segment, /turf/open/floor/plating, @@ -20765,6 +21370,19 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark, /area/station/maintenance/department/engine/atmos) +"hAO" = ( +/obj/machinery/computer/piratepad_control/civilian{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 1 + }, +/obj/machinery/camera/autoname/directional/south, +/obj/machinery/status_display/supply{ + pixel_y = -32 + }, +/turf/open/floor/iron/dark/side, +/area/station/cargo/lobby) "hAW" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -20998,17 +21616,6 @@ /obj/machinery/light/cold/directional/north, /turf/open/floor/iron, /area/station/hallway/primary/port) -"hEi" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 4 - }, -/obj/machinery/firealarm/directional/east, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/turf/open/floor/iron, -/area/station/cargo/sorting) "hEl" = ( /obj/structure/table/rolling, /obj/effect/turf_decal/siding/yellow, @@ -21113,12 +21720,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden, /turf/closed/wall/r_wall, /area/station/maintenance/disposal/incinerator) -"hGa" = ( -/obj/machinery/camera/directional/east{ - c_tag = "Atmospherics Tank - Mix" - }, -/turf/open/floor/engine/vacuum, -/area/station/engineering/atmos) "hGb" = ( /turf/closed/wall/r_wall, /area/station/science/ordnance/storage) @@ -21144,6 +21745,11 @@ }, /turf/open/floor/iron/white, /area/station/medical/medbay/aft) +"hGA" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/obj/effect/landmark/start/cargo_technician, +/turf/open/floor/iron, +/area/station/cargo/sorting) "hGE" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -21192,6 +21798,16 @@ }, /turf/open/space/basic, /area/space/nearstation) +"hHX" = ( +/obj/structure/chair/office/light{ + dir = 4 + }, +/obj/effect/landmark/start/quartermaster, +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/turf/open/floor/carpet/orange, +/area/station/command/heads_quarters/qm) "hIi" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -21312,14 +21928,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark/small, /area/station/security/detectives_office) -"hKV" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/landmark/start/hangover, -/turf/open/floor/iron, -/area/station/hallway/primary/central/fore) "hKX" = ( /turf/closed/mineral/random/stationside, /area/station/hallway/primary/fore) @@ -21342,10 +21950,6 @@ "hLc" = ( /turf/open/floor/plating, /area/station/science/xenobiology) -"hLm" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron/smooth, -/area/station/cargo/office) "hLx" = ( /obj/machinery/atmospherics/pipe/smart/simple/green/visible{ dir = 4 @@ -21562,13 +22166,6 @@ /obj/effect/spawner/random/maintenance, /turf/open/floor/plating, /area/station/maintenance/central/greater) -"hPd" = ( -/obj/structure/hedge, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/turf/open/floor/iron/dark/side, -/area/station/cargo/office) "hPi" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -21733,6 +22330,17 @@ }, /turf/open/misc/sandy_dirt, /area/station/security/tram) +"hSn" = ( +/obj/item/kirbyplants/random, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/effect/turf_decal/tile/neutral, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "hSK" = ( /obj/structure/cable, /obj/effect/turf_decal/siding/white{ @@ -21924,13 +22532,6 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/iron/dark, /area/station/science/genetics) -"hWa" = ( -/obj/machinery/atmospherics/pipe/smart/simple/yellow/visible{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible, -/turf/open/floor/iron, -/area/station/engineering/atmos) "hWk" = ( /obj/machinery/vending/coffee, /obj/structure/extinguisher_cabinet/directional/south, @@ -22024,6 +22625,14 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos/project) +"hXM" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/landmark/start/depsec/supply, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, +/turf/open/floor/iron/smooth, +/area/station/security/checkpoint/supply) "hXU" = ( /turf/closed/wall, /area/station/security/execution/education) @@ -22082,6 +22691,21 @@ dir = 8 }, /area/station/science/lab) +"hYQ" = ( +/obj/structure/disposalpipe/trunk{ + dir = 2 + }, +/obj/machinery/disposal/delivery_chute{ + name = "Security Deliveries" + }, +/obj/structure/sign/departments/security/directional/north, +/obj/effect/turf_decal/tile/red/fourcorners, +/obj/structure/plasticflaps{ + name = "Security Deliveries" + }, +/obj/effect/turf_decal/delivery/white, +/turf/open/floor/iron/dark/side, +/area/station/cargo/sorting) "hYS" = ( /obj/effect/turf_decal/tile/yellow/diagonal_centre, /obj/structure/railing, @@ -22122,18 +22746,6 @@ }, /turf/open/floor/iron/dark/smooth_large, /area/station/command/meeting_room) -"hZe" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/mapping_helpers/broken_floor, -/obj/structure/sign/poster/random/directional/east, -/obj/machinery/conveyor{ - id = "mining" - }, -/obj/machinery/brm, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) "hZP" = ( /obj/structure/cable, /obj/structure/sign/poster/official/random/directional/north, @@ -22419,6 +23031,11 @@ /obj/structure/broken_flooring/singular/directional/east, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) +"idB" = ( +/obj/structure/cable, +/obj/machinery/airalarm/directional/south, +/turf/open/floor/plating, +/area/station/maintenance/disposal/incinerator) "idF" = ( /obj/effect/turf_decal/siding/wood{ dir = 10 @@ -22456,6 +23073,22 @@ /obj/machinery/telecomms/message_server/preset, /turf/open/floor/circuit, /area/station/tcommsat/server) +"iek" = ( +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/obj/machinery/disposal/delivery_chute{ + name = "Engineering Deliveries" + }, +/obj/structure/sign/departments/engineering/directional/north, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/obj/structure/plasticflaps{ + name = "Engineering Deliveries" + }, +/obj/effect/turf_decal/delivery/white, +/obj/machinery/light/warm/directional/north, +/turf/open/floor/iron/dark/side, +/area/station/cargo/sorting) "ieY" = ( /obj/structure/disposalpipe/segment, /obj/effect/mapping_helpers/broken_floor, @@ -22702,6 +23335,24 @@ }, /turf/open/floor/iron, /area/station/commons/vacant_room/commissary) +"iiR" = ( +/obj/structure/railing{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/machinery/conveyor_switch/oneway{ + pixel_x = 4; + pixel_y = 10; + id = "mining" + }, +/obj/effect/turf_decal/siding/thinplating_new{ + dir = 6 + }, +/turf/open/floor/iron/smooth, +/area/station/cargo/miningfoundry) "iiW" = ( /obj/structure/cable, /turf/open/floor/catwalk_floor/iron_dark, @@ -22941,15 +23592,6 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/engine, /area/station/engineering/supermatter/room) -"ina" = ( -/obj/structure/table, -/turf/open/floor/plating, -/area/station/maintenance/port/greater) -"ind" = ( -/obj/machinery/light/floor, -/obj/structure/flora/bush/flowers_br, -/turf/open/floor/grass, -/area/station/hallway/primary/central/fore) "inh" = ( /obj/structure/disposalpipe/segment, /obj/effect/turf_decal/trimline/neutral/line{ @@ -23005,6 +23647,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/commons/dorms) +"ioJ" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/obj/effect/spawner/random/engineering/tracking_beacon, +/turf/open/floor/iron, +/area/station/cargo/lobby) "ioQ" = ( /obj/machinery/portable_atmospherics/scrubber, /obj/machinery/atmospherics/components/unary/portables_connector/visible/layer2{ @@ -23049,17 +23698,6 @@ /mob/living/basic/pet/dog/pug/mcgriff, /turf/open/floor/iron, /area/station/security/warden) -"ipd" = ( -/obj/effect/turf_decal/stripes/line, -/obj/machinery/button/door/directional/east{ - id = "qm_warehouse"; - name = "Warehouse Door Control"; - pixel_x = -24; - pixel_y = -24; - req_access = list("cargo") - }, -/turf/open/floor/iron/smooth, -/area/station/cargo/warehouse) "ipf" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -23177,13 +23815,6 @@ }, /turf/open/floor/stone, /area/station/service/abandoned_gambling_den) -"iqj" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/turf/open/floor/iron/stairs{ - dir = 1 - }, -/area/station/maintenance/port/fore) "iqp" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -23193,10 +23824,6 @@ /obj/machinery/holopad, /turf/open/floor/iron/smooth, /area/station/command/bridge) -"iqq" = ( -/obj/structure/closet, -/turf/open/floor/iron/smooth, -/area/station/cargo/office) "iqB" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -23228,6 +23855,14 @@ /obj/machinery/airalarm/directional/west, /turf/open/floor/iron/dark, /area/station/security/interrogation) +"iqM" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "ira" = ( /obj/structure/tank_dispenser/oxygen, /obj/machinery/light/small/directional/south, @@ -23361,13 +23996,14 @@ "itb" = ( /turf/closed/wall/r_wall/rust, /area/station/ai_monitored/turret_protected/aisat/maint) -"itr" = ( -/obj/machinery/atmospherics/pipe/bridge_pipe/yellow/visible{ - dir = 4 +"itf" = ( +/obj/structure/disposalpipe/segment, +/obj/item/kirbyplants/random, +/obj/effect/turf_decal/siding/wood{ + dir = 9 }, -/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible, -/turf/open/floor/iron, -/area/station/engineering/atmos) +/turf/open/floor/carpet/red, +/area/station/command/heads_quarters/qm) "itw" = ( /obj/structure/disposalpipe/segment{ dir = 9 @@ -23537,6 +24173,16 @@ /obj/structure/extinguisher_cabinet/directional/east, /turf/open/floor/iron/dark, /area/station/science/robotics/lab) +"ivC" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/lobby) "ivY" = ( /obj/structure/table/reinforced, /obj/effect/spawner/random/techstorage/tcomms_all, @@ -23729,6 +24375,7 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/cable, /obj/structure/disposalpipe/segment, +/obj/effect/mapping_helpers/airlock/access/any/engineering/general, /turf/open/floor/catwalk_floor, /area/station/engineering/atmos/storage/gas) "izF" = ( @@ -23756,6 +24403,11 @@ /obj/machinery/field/generator, /turf/open/floor/iron/dark/small, /area/station/engineering/storage_shared) +"iAt" = ( +/obj/effect/mapping_helpers/broken_floor, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/wood, +/area/station/maintenance/hallway/abandoned_recreation) "iAu" = ( /obj/structure/bed{ dir = 4 @@ -23814,6 +24466,15 @@ /obj/machinery/airalarm/directional/west, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"iAL" = ( +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/office) "iAM" = ( /obj/effect/turf_decal/siding/wideplating/dark/corner{ dir = 1 @@ -23850,14 +24511,6 @@ }, /turf/open/floor/iron/white, /area/station/security/medical) -"iBo" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/power/apc/auto_name/directional/north, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "iBt" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/disposalpipe/segment, @@ -23976,6 +24629,16 @@ }, /turf/open/floor/wood/tile, /area/station/command/meeting_room) +"iDm" = ( +/obj/structure/cable, +/obj/structure/railing/corner/end{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/siding/thinplating_new, +/turf/open/floor/iron/smooth, +/area/station/cargo/miningfoundry) "iDt" = ( /obj/effect/mapping_helpers/airlock/access/any/security/general, /obj/machinery/door/airlock/security{ @@ -24031,20 +24694,13 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/engineering/atmos) -"iEi" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 1 - }, -/obj/effect/turf_decal/siding/wood, -/obj/machinery/door/airlock/public/glass{ - name = "Chapel Office" +"iEc" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 }, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/all/service/chapel_office, -/obj/structure/disposalpipe/segment, /obj/structure/cable, -/turf/open/floor/iron/textured_half, -/area/station/service/chapel/office) +/turf/open/floor/iron/small, +/area/station/engineering/break_room) "iEk" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, @@ -24134,10 +24790,42 @@ }, /turf/open/floor/plating, /area/station/maintenance/fore/lesser) +"iFG" = ( +/obj/item/radio/intercom/directional/south, +/obj/effect/turf_decal/siding/wood, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 4 + }, +/obj/structure/cable, +/turf/open/floor/iron/grimy, +/area/station/service/library/private) "iFP" = ( /obj/item/kirbyplants/random/fullysynthetic, /turf/open/floor/plating/rust, /area/station/maintenance/hallway/abandoned_command) +"iGb" = ( +/obj/structure/window/spawner/directional/east, +/obj/structure/closet/crate, +/obj/effect/turf_decal/bot_white, +/obj/item/clothing/gloves/color/fyellow, +/obj/item/stack/package_wrap{ + pixel_y = 5 + }, +/obj/item/stack/package_wrap{ + pixel_y = 2 + }, +/obj/item/storage/box{ + desc = "It smells of monkey business..."; + name = "Empty Gorillacube Box" + }, +/obj/item/weldingtool, +/obj/item/radio{ + pixel_y = 3; + pixel_x = -6 + }, +/obj/item/assembly/signaler, +/turf/open/floor/iron/smooth, +/area/station/commons/storage/tools) "iGl" = ( /turf/open/floor/plating, /area/station/maintenance/hallway/abandoned_command) @@ -24212,6 +24900,14 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/commons/vacant_room/commissary) +"iGW" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 1 + }, +/obj/effect/landmark/start/hangover, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/turf/open/floor/iron, +/area/station/cargo/lobby) "iHa" = ( /obj/machinery/atmospherics/components/binary/pump/on{ name = "Gas to Cold Loop"; @@ -24322,6 +25018,20 @@ }, /turf/open/floor/iron/dark/textured_edge, /area/station/command/heads_quarters/hop) +"iIG" = ( +/obj/structure/rack, +/obj/item/clothing/gloves/cargo_gauntlet{ + pixel_y = -3 + }, +/obj/item/clothing/gloves/cargo_gauntlet, +/obj/item/clothing/gloves/cargo_gauntlet{ + pixel_y = 3 + }, +/obj/machinery/airalarm/directional/south, +/turf/open/floor/iron/dark/textured_half{ + dir = 1 + }, +/area/station/cargo/storage) "iIK" = ( /obj/effect/turf_decal/bot, /obj/structure/rack, @@ -24412,12 +25122,18 @@ /mob/living/basic/pet/dog/corgi/ian, /turf/open/floor/iron/dark/textured_edge, /area/station/command/heads_quarters/hop) -"iJh" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/railing, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/wood, -/area/station/cargo/miningfoundry) +"iJp" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 1 + }, +/obj/effect/turf_decal/stripes, +/obj/effect/turf_decal/trimline/brown/line, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, +/obj/effect/landmark/start/bitrunner, +/turf/open/floor/iron/dark/smooth_half, +/area/station/cargo/bitrunning/den) "iJq" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -24455,6 +25171,9 @@ /obj/structure/sign/poster/official/random/directional/north, /turf/open/floor/iron/white, /area/station/medical/medbay/central) +"iJH" = ( +/turf/closed/wall, +/area/station/security/checkpoint/supply) "iJI" = ( /obj/structure/table/glass, /obj/item/folder/blue, @@ -24511,6 +25230,14 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/security/brig/entrance) +"iKn" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/junction{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "iKo" = ( /obj/structure/broken_flooring/corner/directional/south, /obj/effect/spawner/random/trash/graffiti{ @@ -24566,16 +25293,6 @@ }, /turf/open/floor/iron/diagonal, /area/station/command/heads_quarters/hop) -"iLF" = ( -/obj/item/kirbyplants/organic/applebush, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 4 - }, -/obj/machinery/light/small/directional/north, -/turf/open/floor/iron/dark/side{ - dir = 8 - }, -/area/station/hallway/primary/central/fore) "iLH" = ( /obj/effect/mapping_helpers/airlock/access/any/service/maintenance, /obj/machinery/door/airlock/maintenance{ @@ -24915,6 +25632,22 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating/elevatorshaft, /area/station/commons/dorms) +"iQM" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/trimline/purple/filled/line{ + dir = 1 + }, +/obj/effect/turf_decal/arrows{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown/half/contrasted, +/turf/open/floor/iron/dark/side{ + dir = 1 + }, +/area/station/cargo/sorting) "iQT" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/disposalpipe/segment{ @@ -25053,10 +25786,6 @@ }, /turf/open/floor/iron/dark/herringbone, /area/station/ai_monitored/command/nuke_storage) -"iTv" = ( -/obj/item/kirbyplants/random, -/turf/open/floor/wood/parquet, -/area/station/service/library) "iTy" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -25133,6 +25862,15 @@ }, /turf/open/floor/circuit, /area/station/tcommsat/server) +"iUA" = ( +/obj/machinery/conveyor{ + id = "mining" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "iUH" = ( /obj/effect/turf_decal/tile/neutral, /obj/machinery/camera/autoname/directional/south, @@ -25141,6 +25879,14 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/port) +"iUI" = ( +/obj/structure/railing, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/effect/turf_decal/siding/thinplating_new, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/smooth, +/area/station/cargo/miningfoundry) "iUK" = ( /obj/effect/turf_decal/stripes/white/line{ dir = 8 @@ -25259,16 +26005,6 @@ }, /turf/open/floor/iron/smooth, /area/station/maintenance/port/aft) -"iWb" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/sorting) "iWe" = ( /obj/structure/cable, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, @@ -25489,6 +26225,11 @@ /obj/machinery/light/small/directional/west, /turf/open/floor/iron/dark/smooth_large, /area/station/maintenance/central/lesser) +"iZx" = ( +/obj/structure/cable, +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "iZy" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -25574,6 +26315,10 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/port) +"jab" = ( +/obj/structure/reagent_dispensers/fueltank, +/turf/open/floor/plating, +/area/station/maintenance/port/greater) "jar" = ( /obj/machinery/drone_dispenser, /turf/open/misc/asteroid, @@ -25620,15 +26365,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/security) -"jaN" = ( -/obj/structure/hedge, -/obj/effect/decal/cleanable/cobweb, -/obj/machinery/status_display/supply{ - pixel_y = 32 - }, -/obj/machinery/light/small/directional/north, -/turf/open/floor/plating, -/area/station/cargo/storage) "jaP" = ( /obj/effect/mob_spawn/corpse/human/clown, /turf/open/floor/plating/airless, @@ -25880,6 +26616,11 @@ /obj/machinery/light/dim/directional/north, /turf/open/floor/iron/smooth, /area/station/security/evidence) +"jfP" = ( +/turf/open/floor/iron/stairs{ + dir = 8 + }, +/area/station/cargo/storage) "jfT" = ( /obj/effect/turf_decal/siding/thinplating_new/light{ dir = 1 @@ -25896,6 +26637,20 @@ /obj/structure/cable, /turf/open/floor/iron/smooth, /area/station/service/greenroom) +"jgj" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/button/door/directional/east{ + id = "qm_warehouse"; + name = "Warehouse Door Control"; + pixel_x = -24; + pixel_y = -24; + req_access = list("cargo") + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron/smooth, +/area/station/cargo/warehouse) "jgq" = ( /obj/effect/turf_decal/weather/dirt{ dir = 8 @@ -25935,13 +26690,6 @@ "jhm" = ( /turf/open/floor/wood, /area/station/service/abandoned_gambling_den) -"jhs" = ( -/obj/structure/disposalpipe/segment, -/obj/structure/cable, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/obj/machinery/airalarm/directional/west, -/turf/open/floor/iron, -/area/station/maintenance/port/fore) "jhB" = ( /obj/structure/sign/warning/electric_shock, /turf/closed/wall/r_wall, @@ -26112,13 +26860,6 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) -"jkS" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/cargo/storage) "jkT" = ( /obj/structure/table/wood, /obj/machinery/fax/auto_name, @@ -26133,6 +26874,19 @@ /obj/structure/cable, /turf/open/floor/plating/rust, /area/station/engineering/supermatter/room) +"jln" = ( +/obj/structure/chair/office{ + dir = 1 + }, +/obj/effect/landmark/start/cargo_technician, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/office) "jlt" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -26144,14 +26898,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/security) -"jlv" = ( -/obj/structure/disposalpipe/segment, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/cargo/storage) "jlz" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -26236,6 +26982,13 @@ /obj/machinery/light/small/directional/west, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) +"jmC" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/tile/neutral, +/obj/structure/sign/departments/holy/directional/south, +/obj/machinery/light/cold/directional/south, +/turf/open/floor/iron, +/area/station/hallway/primary/port) "jmF" = ( /obj/effect/spawner/random/structure/crate, /obj/effect/turf_decal/stripes/line{ @@ -26243,12 +26996,6 @@ }, /turf/open/floor/plating, /area/station/construction/mining/aux_base) -"jmK" = ( -/obj/structure/disposalpipe/segment{ - dir = 9 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "jmN" = ( /obj/structure/table, /obj/item/stack/rods/fifty, @@ -26269,6 +27016,17 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) +"jmX" = ( +/obj/structure/table/wood, +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/obj/item/pen{ + pixel_x = -2; + pixel_y = 4 + }, +/turf/open/floor/carpet, +/area/station/maintenance/hallway/abandoned_recreation) "jmY" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -26419,14 +27177,6 @@ }, /turf/open/floor/iron/smooth, /area/station/security/evidence) -"jpR" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/rack, -/obj/effect/spawner/random/maintenance/three, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "jpW" = ( /obj/structure/cable, /obj/structure/table/wood, @@ -26452,39 +27202,6 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron, /area/station/hallway/secondary/recreation) -"jqu" = ( -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/sorting) -"jqA" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/conveyor{ - dir = 1; - id = "packageSort2" - }, -/obj/machinery/door/window/left/directional/west{ - name = "Crate Security Door"; - req_access = list("shipping") - }, -/obj/machinery/camera/autoname/directional/east, -/turf/open/floor/plating, -/area/station/cargo/sorting) "jqD" = ( /obj/effect/turf_decal/siding/yellow, /obj/effect/turf_decal/tile/yellow/diagonal_centre, @@ -26523,6 +27240,14 @@ }, /turf/open/floor/iron/dark, /area/station/medical/chemistry) +"jro" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/obj/machinery/camera/autoname/directional/west, +/turf/open/floor/iron, +/area/station/cargo/sorting) "jrs" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -26537,6 +27262,12 @@ }, /turf/open/floor/engine, /area/station/engineering/supermatter/room) +"jry" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/catwalk_floor/iron_white, +/area/station/cargo/storage) "jrD" = ( /obj/effect/turf_decal/siding/wideplating{ dir = 4 @@ -26573,11 +27304,6 @@ }, /turf/open/floor/circuit, /area/station/tcommsat/server) -"jrX" = ( -/turf/open/floor/iron/stairs{ - dir = 1 - }, -/area/station/cargo/office) "jsa" = ( /obj/item/radio/intercom/directional/west, /turf/open/floor/iron/white/side{ @@ -26636,13 +27362,6 @@ /obj/structure/steam_vent, /turf/open/floor/plating, /area/station/maintenance/aft) -"jtd" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/neutral, -/obj/machinery/status_display/evac/directional/east, -/turf/open/floor/iron, -/area/station/hallway/primary/central/fore) "jte" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 1 @@ -26663,6 +27382,10 @@ /obj/machinery/airalarm/directional/east, /turf/open/floor/iron/diagonal, /area/station/command/heads_quarters/hop) +"jtB" = ( +/obj/effect/turf_decal/stripes/white/corner, +/turf/open/floor/iron/dark/corner, +/area/station/cargo/storage) "jtD" = ( /obj/structure/closet/emcloset, /turf/open/floor/iron/showroomfloor, @@ -26691,30 +27414,11 @@ /obj/machinery/status_display/ai/directional/east, /turf/open/floor/iron, /area/station/hallway/primary/fore) -"jug" = ( -/obj/machinery/door/airlock/hatch{ - name = "Tool Supply Corridor" - }, -/obj/effect/mapping_helpers/airlock/access/all/supply/general, -/turf/open/floor/catwalk_floor/iron_dark, -/area/station/commons/storage/tools) -"juJ" = ( -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/structure/table, +"juo" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /obj/effect/decal/cleanable/dirt, -/obj/item/stack/package_wrap{ - pixel_y = 5 - }, -/obj/item/storage/box/matches, -/turf/open/floor/iron, -/area/station/cargo/sorting) -"juP" = ( -/obj/machinery/light/small/directional/south, -/obj/machinery/status_display/evac/directional/south, -/turf/open/floor/stone, -/area/station/service/chapel) +/turf/open/floor/iron/smooth, +/area/station/cargo/miningfoundry) "juS" = ( /obj/structure/bed, /obj/item/bedsheet/hop, @@ -26722,6 +27426,14 @@ /obj/machinery/firealarm/directional/south, /turf/open/floor/iron/grimy, /area/station/command/heads_quarters/hop) +"juU" = ( +/obj/machinery/atmospherics/pipe/smart/simple/purple/visible, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light_switch/directional/west, +/obj/effect/landmark/event_spawn, +/obj/machinery/portable_atmospherics/pump/lil_pump, +/turf/open/floor/iron/dark, +/area/station/science/ordnance) "jvd" = ( /obj/effect/turf_decal/siding/thinplating{ dir = 1 @@ -26737,17 +27449,6 @@ /obj/structure/cable, /turf/open/floor/iron/dark/small, /area/station/command/heads_quarters/captain/private) -"jvm" = ( -/obj/machinery/door/airlock/engineering/glass/critical{ - heat_proof = 1; - name = "Supermatter Chamber" - }, -/obj/effect/mapping_helpers/airlock/access/any/engineering/general, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, -/turf/open/floor/engine, -/area/station/engineering/supermatter) "jvB" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -26887,14 +27588,6 @@ "jxD" = ( /turf/open/floor/iron, /area/station/maintenance/starboard/greater) -"jxJ" = ( -/obj/structure/hedge, -/obj/machinery/status_display/supply{ - pixel_y = -32 - }, -/obj/machinery/light/small/directional/south, -/turf/open/floor/plating, -/area/station/cargo/storage) "jxU" = ( /obj/effect/turf_decal/siding/blue{ dir = 9 @@ -27090,6 +27783,16 @@ /obj/machinery/light/small/dim/directional/south, /turf/open/floor/iron/dark, /area/station/engineering/lobby) +"jAN" = ( +/obj/machinery/computer/cargo{ + dir = 1 + }, +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/office) "jAR" = ( /obj/effect/turf_decal/tile/dark_red/opposingcorners, /obj/machinery/airalarm/directional/east, @@ -27136,6 +27839,42 @@ /obj/machinery/flasher/directional/north, /turf/open/floor/circuit/red, /area/station/ai_monitored/turret_protected/ai) +"jBJ" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/window/left/directional/west{ + name = "Cargo Desk"; + req_access = list("shipping") + }, +/obj/structure/desk_bell{ + pixel_x = 7 + }, +/obj/item/paper_bin{ + pixel_x = -7; + pixel_y = 6 + }, +/obj/effect/turf_decal/siding/white{ + dir = 4 + }, +/obj/item/pen{ + pixel_x = 8; + pixel_y = 8 + }, +/obj/machinery/door/firedoor, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/cargo/office) +"jBN" = ( +/obj/machinery/piratepad/civilian, +/obj/effect/turf_decal/bot_white, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 1 + }, +/obj/machinery/light/cold/dim/directional/south, +/obj/machinery/airalarm/directional/south, +/turf/open/floor/iron/dark/side, +/area/station/cargo/lobby) "jBQ" = ( /obj/effect/turf_decal/tile/dark_red/fourcorners, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -27143,12 +27882,6 @@ }, /turf/open/floor/iron, /area/station/security/execution/transfer) -"jCi" = ( -/obj/structure/cable, -/obj/machinery/door/airlock/maintenance, -/obj/effect/mapping_helpers/airlock/access/all/supply/general, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "jCm" = ( /obj/effect/landmark/start/hangover, /turf/open/misc/dirt/station, @@ -27163,13 +27896,6 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/engine, /area/station/engineering/supermatter/room) -"jCP" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron/smooth, -/area/station/cargo/warehouse) "jCZ" = ( /obj/machinery/door/window/brigdoor/left/directional/west{ id = "Cell 1"; @@ -27191,16 +27917,6 @@ "jDi" = ( /turf/open/floor/iron/dark, /area/station/engineering/atmospherics_engine) -"jDm" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/office) "jDt" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable, @@ -27319,27 +28035,6 @@ }, /turf/closed/wall, /area/station/hallway/secondary/entry) -"jEK" = ( -/obj/effect/turf_decal/siding/white{ - dir = 1 - }, -/obj/structure/table, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/obj/machinery/fax{ - fax_name = "Cargo Office"; - name = "Cargo Office Fax Machine"; - pixel_y = 4 - }, -/obj/structure/railing{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/office) "jEQ" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -27356,6 +28051,19 @@ /obj/structure/sign/poster/official/random/directional/north, /turf/open/floor/iron/smooth, /area/station/hallway/secondary/command) +"jFg" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/paperplane{ + pixel_x = 7; + pixel_y = 7 + }, +/obj/item/paperplane{ + pixel_x = -1; + pixel_y = 1 + }, +/obj/structure/cable, +/turf/open/floor/wood, +/area/station/command/heads_quarters/qm) "jFh" = ( /obj/item/kirbyplants/random, /turf/open/floor/iron, @@ -27440,6 +28148,15 @@ dir = 1 }, /area/station/hallway/secondary/entry) +"jGC" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/stripes/white/corner{ + dir = 8 + }, +/turf/open/floor/iron/dark/corner{ + dir = 8 + }, +/area/station/cargo/storage) "jGK" = ( /obj/structure/chair/wood, /obj/structure/cable, @@ -27533,6 +28250,11 @@ /mob/living/basic/sloth/citrus, /turf/open/floor/iron, /area/station/cargo/storage) +"jHC" = ( +/obj/effect/spawner/random/structure/crate, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "jHI" = ( /obj/effect/turf_decal/stripes/white/line{ dir = 5 @@ -27551,6 +28273,21 @@ /obj/structure/chair/stool/directional/north, /turf/open/floor/plating, /area/station/maintenance/disposal/incinerator) +"jHN" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/maintenance/department/electrical) +"jHS" = ( +/obj/machinery/door/airlock/engineering/glass{ + name = "Engineering Storage" + }, +/obj/effect/mapping_helpers/airlock/access/all/engineering/engine_equipment, +/turf/open/floor/iron/smooth_half{ + dir = 8 + }, +/area/station/engineering/main) "jHU" = ( /obj/structure/chair/sofa/bench/left{ dir = 8 @@ -27574,14 +28311,6 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron/cafeteria, /area/station/science/circuits) -"jIh" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "jIj" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 8 @@ -27600,6 +28329,12 @@ /obj/structure/window/spawner/directional/south, /turf/open/floor/plating, /area/station/maintenance/starboard/greater) +"jIn" = ( +/obj/item/radio/intercom/directional/north, +/obj/machinery/firealarm/directional/west, +/obj/machinery/vending/cytopro, +/turf/open/floor/iron/white, +/area/station/science/cytology) "jIy" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -27621,73 +28356,48 @@ /obj/effect/mapping_helpers/airlock/access/all/medical/cmo, /turf/open/floor/iron, /area/station/maintenance/department/medical/central) -"jIH" = ( +"jJg" = ( +/obj/effect/turf_decal/siding/wideplating, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/disposalpipe/segment{ dir = 6 }, -/obj/structure/railing{ - dir = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/wood, -/area/station/cargo/miningfoundry) -"jIN" = ( -/obj/structure/disposalpipe/segment{ +/area/station/engineering/main) +"jJw" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/stripes/white/line{ dir = 4 }, -/obj/effect/turf_decal/tile/brown{ +/turf/open/floor/iron/dark/side{ dir = 4 }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/obj/item/radio/intercom/directional/west, -/turf/open/floor/iron, -/area/station/cargo/office) -"jIY" = ( +/area/station/cargo/storage) +"jJB" = ( /obj/structure/disposalpipe/segment{ - dir = 10 - }, -/obj/effect/turf_decal/tile/brown{ dir = 4 }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ +/obj/effect/turf_decal/stripes/line{ dir = 4 }, -/turf/open/floor/iron, -/area/station/cargo/office) -"jJc" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/brown{ +/obj/effect/turf_decal/tile/brown/half/contrasted{ dir = 4 }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/office) -"jJd" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/tile/green/opposingcorners, -/obj/effect/turf_decal/tile/blue/opposingcorners{ - dir = 8 - }, -/obj/machinery/hydroponics/constructable, +/obj/structure/cable, /turf/open/floor/iron, -/area/station/service/hydroponics) -"jJg" = ( -/obj/effect/turf_decal/siding/wideplating, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/area/station/cargo/sorting) +"jJO" = ( /obj/structure/disposalpipe/segment{ - dir = 6 + dir = 5 }, +/obj/structure/chair/stool/directional/east, +/obj/effect/mapping_helpers/broken_floor, +/obj/machinery/newscaster/directional/west, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood, -/area/station/engineering/main) +/area/station/maintenance/hallway/abandoned_recreation) "jJP" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -27727,6 +28437,14 @@ dir = 1 }, /area/station/science/xenobiology) +"jKl" = ( +/obj/effect/landmark/start/cargo_technician, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/obj/structure/cable, +/turf/open/floor/iron/smooth, +/area/station/cargo/warehouse) "jKq" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -27737,21 +28455,6 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/iron, /area/station/science/xenobiology) -"jKu" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/door/airlock/mining/glass{ - name = "Cargo Office" - }, -/obj/effect/mapping_helpers/airlock/access/all/supply/general, -/obj/machinery/door/firedoor, -/turf/open/floor/iron/stairs{ - dir = 4 - }, -/area/station/cargo/office) "jKJ" = ( /obj/machinery/door/window/right/directional/north, /turf/open/floor/iron, @@ -27778,20 +28481,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/maintenance/starboard/greater) -"jLr" = ( -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/trimline/neutral/line{ +"jLt" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 }, -/obj/effect/turf_decal/trimline/neutral/line{ - dir = 4 - }, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/hallway/primary/central/fore) +/obj/item/kirbyplants/random, +/turf/open/floor/iron/white, +/area/station/science/cytology) "jLv" = ( /obj/effect/turf_decal/bot{ dir = 1 @@ -27850,12 +28546,6 @@ }, /turf/open/floor/circuit, /area/station/tcommsat/server) -"jMb" = ( -/obj/effect/turf_decal/bot_white, -/obj/structure/reagent_dispensers/fueltank, -/obj/machinery/light/small/directional/west, -/turf/open/floor/iron/smooth_large, -/area/station/cargo/warehouse) "jMp" = ( /obj/machinery/atmospherics/pipe/smart/manifold/yellow/visible{ dir = 8 @@ -27881,15 +28571,6 @@ /obj/structure/spider/stickyweb, /turf/open/floor/iron/small, /area/station/maintenance/department/engine/atmos) -"jMQ" = ( -/obj/machinery/atmospherics/components/binary/pump/off{ - name = "O2 To Pure" - }, -/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/engineering/atmos) "jMX" = ( /obj/structure/disposalpipe/segment{ dir = 9 @@ -27951,6 +28632,13 @@ /obj/machinery/status_display/evac/directional/west, /turf/open/misc/sandy_dirt, /area/station/hallway/primary/central/fore) +"jNV" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/smart/simple/orange/visible, +/turf/open/floor/engine, +/area/station/engineering/supermatter/room) "jOb" = ( /obj/machinery/firealarm/directional/east, /obj/effect/turf_decal/siding/wideplating/dark{ @@ -28033,6 +28721,10 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/fore/greater) +"jPl" = ( +/obj/machinery/button/ignition/incinerator/atmos, +/turf/closed/wall/r_wall, +/area/station/maintenance/disposal/incinerator) "jPo" = ( /obj/structure/cable, /obj/machinery/door/airlock/maintenance{ @@ -28082,6 +28774,14 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron/small, /area/station/commons/fitness/locker_room) +"jQG" = ( +/obj/machinery/holopad, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/structure/chair/stool/directional/south, +/turf/open/floor/iron, +/area/station/cargo/sorting) "jQW" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/public/glass{ @@ -28420,11 +29120,6 @@ /obj/effect/mapping_helpers/airlock/access/all/security/general, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"jVx" = ( -/obj/structure/closet/emcloset, -/obj/effect/turf_decal/tile/blue, -/turf/open/floor/iron/dark/side, -/area/station/maintenance/central/greater) "jVJ" = ( /obj/structure/table, /obj/item/bikehorn/rubberducky{ @@ -28530,19 +29225,6 @@ dir = 8 }, /area/station/hallway/secondary/dock) -"jWZ" = ( -/obj/machinery/mineral/ore_redemption{ - dir = 4; - input_dir = 8; - output_dir = 4 - }, -/obj/machinery/door/window/right/directional/east{ - name = "Ore Redemtion Window" - }, -/obj/effect/turf_decal/bot, -/obj/machinery/firealarm/directional/south, -/turf/open/floor/iron/textured_large, -/area/station/cargo/office) "jXc" = ( /obj/structure/disposalpipe/segment{ dir = 9 @@ -28706,21 +29388,9 @@ /obj/effect/mapping_helpers/airlock/access/all/command/teleporter, /turf/open/floor/iron/dark/textured_half, /area/station/command/teleporter) -"jZc" = ( -/obj/effect/turf_decal/siding/wood, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron/smooth, -/area/station/command/heads_quarters/qm) "jZl" = ( /turf/closed/wall/r_wall, /area/station/engineering/atmospherics_engine) -"jZn" = ( -/obj/machinery/disposal/bin, -/obj/effect/turf_decal/bot, -/turf/open/floor/iron/dark/side{ - dir = 1 - }, -/area/station/hallway/primary/central/fore) "jZJ" = ( /obj/effect/spawner/structure/window/reinforced, /obj/effect/turf_decal/stripes/corner{ @@ -28929,16 +29599,6 @@ /obj/machinery/light_switch/directional/west, /turf/open/floor/iron/white/small, /area/station/science/server) -"kee" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, -/obj/item/food/grown/pineapple{ - pixel_x = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "kel" = ( /obj/machinery/light/cold/directional/south, /obj/machinery/modular_computer/preset/id{ @@ -28973,22 +29633,6 @@ /obj/item/kirbyplants/random, /turf/open/floor/iron, /area/station/science/lower) -"keQ" = ( -/obj/effect/turf_decal/weather/dirt, -/obj/effect/turf_decal/weather/dirt{ - dir = 1 - }, -/obj/structure/flora/bush/flowers_yw, -/turf/open/floor/grass, -/area/station/service/chapel) -"kft" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/turf/open/floor/iron/dark/side, -/area/station/cargo/office) "kfv" = ( /obj/effect/turf_decal/stripes/red/line, /obj/machinery/power/apc/auto_name/directional/east, @@ -29061,6 +29705,16 @@ dir = 1 }, /area/station/hallway/primary/aft) +"kgp" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/lobby) "kgu" = ( /obj/structure/lattice/catwalk, /obj/machinery/atmospherics/components/unary/passive_vent, @@ -29113,6 +29767,24 @@ /obj/structure/tram, /turf/open/floor/tram, /area/station/security/tram) +"khw" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 1 + }, +/obj/effect/turf_decal/arrows{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown/half/contrasted, +/obj/machinery/power/apc/auto_name/directional/east, +/obj/structure/cable, +/turf/open/floor/iron/dark/side{ + dir = 1 + }, +/area/station/cargo/sorting) "khD" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/reagent_dispensers/watertank, @@ -29152,18 +29824,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) -"khZ" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/dark, -/area/station/cargo/office) -"kia" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/smooth, -/area/station/cargo/warehouse) "kii" = ( /obj/structure/flora/bush/flowers_yw/style_3{ pixel_y = -3 @@ -29183,6 +29843,12 @@ }, /turf/open/floor/grass/Airless, /area/station/hallway/primary/central/aft) +"kik" = ( +/obj/structure/chair/stool/directional/east, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/wood, +/area/station/maintenance/hallway/abandoned_recreation) "kit" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -29239,10 +29905,24 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/iron, /area/station/construction/mining/aux_base) +"kiW" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/sorting) "kiY" = ( /obj/structure/flora/tree/jungle/style_6, /turf/open/floor/grass, /area/station/service/chapel) +"kjb" = ( +/obj/structure/hedge, +/obj/structure/sign/poster/contraband/random/directional/east, +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/turf/open/floor/wood, +/area/station/command/heads_quarters/qm) "kjg" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -29346,6 +30026,33 @@ /obj/machinery/light/small/dim/directional/east, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) +"kkD" = ( +/obj/effect/turf_decal/siding/white{ + dir = 5 + }, +/obj/structure/table, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/structure/railing{ + dir = 5 + }, +/obj/effect/turf_decal/tile/brown/half/contrasted, +/obj/item/stack/package_wrap{ + pixel_y = 2 + }, +/obj/item/stack/package_wrap{ + pixel_y = 6; + pixel_x = -1 + }, +/obj/item/paper/crumpled{ + pixel_x = 5; + pixel_y = 0 + }, +/turf/open/floor/iron/dark/side{ + dir = 1 + }, +/area/station/cargo/lobby) "kkK" = ( /obj/effect/spawner/random/structure/closet_maintenance, /obj/effect/spawner/random/maintenance, @@ -29401,6 +30108,13 @@ dir = 1 }, /area/station/engineering/atmos) +"klA" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4; + name = "Plasma to Pure" + }, +/turf/open/floor/iron, +/area/station/engineering/atmos) "klF" = ( /obj/effect/turf_decal/tile/neutral/half/contrasted{ dir = 4 @@ -29565,6 +30279,10 @@ "knv" = ( /turf/closed/wall, /area/station/maintenance/department/engine/atmos) +"knw" = ( +/obj/machinery/light/small/directional/west, +/turf/open/floor/iron/smooth_large, +/area/station/engineering/supermatter/room) "knB" = ( /obj/machinery/door/airlock{ id_tag = "Toilet2"; @@ -29582,12 +30300,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/maintenance/port/aft) -"knL" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/iron/dark, -/area/station/cargo/storage) "knO" = ( /obj/structure/disposalpipe/segment, /obj/machinery/airalarm/directional/east, @@ -29596,6 +30308,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/white/small, /area/station/commons/toilet/restrooms) +"knR" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/landmark/start/hangover, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "knV" = ( /obj/structure/closet/l3closet, /obj/effect/turf_decal/stripes/line{ @@ -29638,19 +30355,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) -"kpT" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/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/effect/turf_decal/tile/brown/anticorner/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/sorting) "kpU" = ( /obj/effect/turf_decal/tile/blue/anticorner/contrasted, /turf/open/floor/iron/white, @@ -29706,16 +30410,6 @@ }, /turf/open/floor/plating, /area/station/medical/surgery/theatre) -"kqL" = ( -/obj/structure/disposalpipe/junction/flip{ - dir = 1 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/brown/half/contrasted, -/turf/open/floor/iron, -/area/station/cargo/sorting) "kqM" = ( /obj/structure/cable, /obj/item/reagent_containers/cup/bucket, @@ -29742,38 +30436,11 @@ /obj/structure/cable, /turf/open/floor/iron/small, /area/station/medical/morgue) -"kqQ" = ( -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/brown/anticorner/contrasted, -/turf/open/floor/iron, -/area/station/cargo/sorting) "kqU" = ( /obj/effect/decal/cleanable/dirt, /obj/item/radio/intercom/directional/north, /turf/open/floor/carpet/lone, /area/station/service/abandoned_gambling_den) -"kqW" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/door/airlock/mining/glass{ - name = "Delivery Office" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ - cycle_id = "sci-entrance" - }, -/obj/effect/mapping_helpers/airlock/access/all/supply/general, -/obj/machinery/door/firedoor, -/turf/open/floor/iron, -/area/station/cargo/sorting) "kqX" = ( /turf/closed/wall, /area/station/ai_monitored/aisat/exterior) @@ -29889,15 +30556,12 @@ /obj/effect/turf_decal/siding/wood, /turf/open/floor/iron/dark/diagonal, /area/station/service/bar) -"kso" = ( -/obj/structure/disposalpipe/junction{ - dir = 8 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/maintenance/port/fore) +"ksq" = ( +/obj/structure/chair/stool/directional/south, +/obj/machinery/light/small/directional/north, +/obj/structure/mirror/directional/north, +/turf/open/floor/iron/grimy, +/area/station/cargo/boutique) "ksv" = ( /obj/effect/turf_decal/stripes/white/line{ dir = 8 @@ -29905,33 +30569,6 @@ /obj/effect/spawner/random/structure/girder, /turf/open/floor/tram, /area/station/maintenance/department/medical/central) -"ksx" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/door/airlock/mining/glass{ - name = "Cargo Office" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ - cycle_id = "sci-entrance" - }, -/obj/effect/mapping_helpers/airlock/access/all/supply/general, -/obj/machinery/door/firedoor, -/turf/open/floor/iron, -/area/station/maintenance/port/fore) -"ksA" = ( -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/power/apc/auto_name/directional/north, -/turf/open/floor/iron/dark, -/area/station/cargo/office) "ksB" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -29943,6 +30580,10 @@ }, /turf/open/floor/catwalk_floor/iron, /area/station/engineering/gravity_generator) +"ksE" = ( +/obj/effect/landmark/event_spawn, +/turf/open/floor/wood, +/area/station/command/heads_quarters/qm) "ksJ" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -30023,11 +30664,6 @@ }, /turf/open/floor/engine/plasma, /area/station/engineering/atmos) -"ktM" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/dark, -/area/station/cargo/office) "ktT" = ( /obj/effect/turf_decal/tile/blue{ dir = 4 @@ -30044,28 +30680,6 @@ /obj/item/radio/intercom/prison/directional/west, /turf/open/floor/iron/cafeteria, /area/station/security/prison) -"kua" = ( -/obj/structure/table, -/obj/item/disk/cargo{ - pixel_x = 6 - }, -/obj/item/paper/crumpled{ - pixel_x = -7; - pixel_y = 8 - }, -/obj/item/pen{ - pixel_x = -5 - }, -/obj/item/storage/fancy/cigarettes/cigpack_robust{ - pixel_x = 7; - pixel_y = 15 - }, -/turf/open/floor/iron/dark, -/area/station/cargo/office) -"kuq" = ( -/obj/machinery/computer/cargo/request, -/turf/open/floor/plating, -/area/station/hallway/primary/central/fore) "kut" = ( /obj/machinery/door/airlock/engineering{ name = "Engine Airlock" @@ -30213,6 +30827,20 @@ /obj/structure/window/spawner/directional/north, /turf/open/space/basic, /area/space/nearstation) +"kxa" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/machinery/door/airlock/mining{ + name = "Mining Office" + }, +/obj/effect/mapping_helpers/airlock/access/all/supply/mining, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/unres{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "kxb" = ( /obj/structure/table/reinforced/titaniumglass, /obj/effect/turf_decal/bot, @@ -30244,6 +30872,10 @@ /obj/machinery/firealarm/directional/north, /turf/open/floor/iron/white, /area/station/hallway/primary/starboard) +"kxu" = ( +/obj/machinery/door/firedoor, +/turf/open/floor/iron/small, +/area/station/cargo/lobby) "kxE" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/door/airlock/research/glass{ @@ -30302,16 +30934,6 @@ /obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/wood, /area/station/service/chapel/funeral) -"kyE" = ( -/obj/machinery/disposal/bin, -/obj/effect/turf_decal/bot, -/obj/structure/disposalpipe/trunk{ - dir = 1 - }, -/obj/machinery/power/apc/auto_name/directional/south, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/hallway/primary/port) "kyN" = ( /obj/structure/reagent_dispensers/watertank, /turf/open/floor/iron/small, @@ -30592,15 +31214,6 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) -"kFg" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/siding/wood, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/obj/structure/cable, -/turf/open/floor/iron/smooth, -/area/station/command/heads_quarters/qm) "kFq" = ( /obj/structure/disposalpipe/trunk{ dir = 8 @@ -30635,22 +31248,6 @@ /obj/machinery/airalarm/directional/south, /turf/open/floor/iron/smooth, /area/station/cargo/sorting) -"kFI" = ( -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/obj/structure/table, -/obj/effect/turf_decal/delivery/white, -/obj/effect/spawner/random/food_or_drink/donkpockets{ - pixel_x = -9; - pixel_y = 3 - }, -/obj/item/reagent_containers/cup/glass/waterbottle/large{ - pixel_x = 5; - pixel_y = 20 - }, -/turf/open/floor/iron/smooth, -/area/station/cargo/sorting) "kFJ" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, @@ -30660,10 +31257,6 @@ /obj/machinery/atmospherics/pipe/smart/simple/yellow/visible, /turf/open/floor/engine/n2o, /area/station/engineering/atmos) -"kFU" = ( -/obj/item/kirbyplants/random, -/turf/open/floor/iron, -/area/station/maintenance/port/fore) "kFY" = ( /turf/closed/wall/r_wall, /area/station/medical/morgue) @@ -30826,32 +31419,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/medbay/central) -"kIO" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/table/reinforced, -/obj/machinery/door/window/left/directional/west{ - name = "Cargo Desk"; - req_access = list("shipping") - }, -/obj/structure/desk_bell{ - pixel_x = 7 - }, -/obj/item/paper_bin{ - pixel_x = -7; - pixel_y = 6 - }, -/obj/effect/turf_decal/siding/white{ - dir = 4 - }, -/obj/item/pen{ - pixel_x = 8; - pixel_y = 8 - }, -/obj/machinery/door/firedoor, -/turf/open/floor/iron/dark/textured_large, -/area/station/cargo/office) "kIQ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -30874,17 +31441,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/greater) -"kJb" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 4 - }, -/turf/open/floor/iron/dark/side{ - dir = 8 - }, -/area/station/hallway/primary/central/fore) "kJj" = ( /obj/structure/disposalpipe/segment, /obj/structure/disposalpipe/segment{ @@ -30908,6 +31464,14 @@ /obj/effect/decal/cleanable/cobweb/cobweb2, /turf/open/floor/plating, /area/station/ai_monitored/security/armory) +"kJu" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/effect/landmark/start/cargo_technician, +/obj/structure/chair/stool/directional/south, +/turf/open/floor/iron, +/area/station/cargo/sorting) "kJJ" = ( /obj/structure/cable, /obj/effect/mapping_helpers/broken_floor, @@ -30997,6 +31561,27 @@ "kMe" = ( /turf/open/floor/iron/smooth_large, /area/station/engineering/supermatter/room) +"kMg" = ( +/obj/effect/turf_decal/tile/brown/opposingcorners, +/obj/machinery/atmospherics/pipe/smart/simple/cyan/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/door/airlock/engineering{ + name = "Engineering Office" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ + cycle_id = "atmos_airlock_1" + }, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/all/engineering/atmos, +/turf/open/floor/iron, +/area/station/engineering/atmos/office) "kMm" = ( /obj/structure/chair/sofa/right/brown{ dir = 1 @@ -31021,6 +31606,31 @@ /obj/machinery/holopad, /turf/open/floor/iron/smooth, /area/station/security/checkpoint/customs) +"kMY" = ( +/obj/effect/turf_decal/stripes{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes{ + dir = 8 + }, +/obj/machinery/door/airlock/mining{ + name = "Bitrunning Den" + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/mapping_helpers/airlock/access/any/supply/bit_den, +/obj/machinery/door/firedoor, +/turf/open/floor/iron/dark/smooth_half{ + dir = 1 + }, +/area/station/cargo/bitrunning/den) "kNf" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -31039,10 +31649,6 @@ /obj/structure/closet/firecloset, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"kNv" = ( -/obj/machinery/air_sensor/mix_tank, -/turf/open/floor/engine/vacuum, -/area/station/engineering/atmos) "kNx" = ( /turf/open/floor/engine/o2, /area/station/engineering/atmos) @@ -31099,6 +31705,15 @@ /obj/structure/cable, /turf/closed/wall/r_wall, /area/station/maintenance/solars/port/aft) +"kOA" = ( +/obj/effect/mapping_helpers/broken_floor, +/obj/structure/sign/poster/random/directional/east, +/obj/machinery/conveyor{ + id = "mining" + }, +/obj/machinery/brm, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "kOG" = ( /obj/structure/cable, /obj/machinery/door/airlock/external{ @@ -31146,21 +31761,20 @@ /obj/machinery/light/cold/directional/south, /turf/open/floor/iron/white/small, /area/station/security/warden) +"kPh" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/structure/sign/poster/official/random/directional/north, +/obj/machinery/light/small/directional/north, +/turf/open/floor/iron, +/area/station/hallway/primary/central/aft) "kPk" = ( /obj/structure/chair/sofa/bench{ dir = 1 }, /turf/open/floor/iron/dark/side, /area/station/security/execution/transfer) -"kPo" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/plating, -/area/station/maintenance/port/greater) "kPv" = ( /obj/structure/table, /obj/item/paper_bin{ @@ -31205,6 +31819,15 @@ }, /turf/open/floor/iron, /area/station/cargo/storage) +"kQj" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "kQk" = ( /obj/effect/turf_decal/siding/wood{ dir = 5 @@ -31219,6 +31842,9 @@ /obj/machinery/holopad, /turf/open/floor/iron, /area/station/cargo/storage) +"kRb" = ( +/turf/open/floor/iron, +/area/station/cargo/sorting) "kRi" = ( /obj/machinery/atmospherics/pipe/smart/simple/purple/visible{ dir = 4 @@ -31252,14 +31878,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) -"kRJ" = ( -/obj/structure/disposalpipe/segment, -/obj/item/banner/cargo, -/obj/effect/mapping_helpers/broken_floor, -/obj/machinery/airalarm/directional/west, -/obj/structure/cable, -/turf/open/floor/wood, -/area/station/command/heads_quarters/qm) "kRN" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark/smooth_corner{ @@ -31295,11 +31913,6 @@ /obj/machinery/firealarm/directional/north, /turf/open/floor/iron/dark/smooth_large, /area/station/ai_monitored/turret_protected/ai_upload) -"kSf" = ( -/obj/effect/mapping_helpers/broken_floor, -/obj/machinery/holopad, -/turf/open/floor/wood, -/area/station/command/heads_quarters/qm) "kSj" = ( /obj/structure/chair/plastic{ dir = 8 @@ -31327,14 +31940,6 @@ /obj/effect/spawner/random/maintenance, /turf/open/floor/iron, /area/station/maintenance/hallway/abandoned_command) -"kSO" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/power/apc/auto_name/directional/east, -/obj/machinery/photocopier, -/turf/open/floor/wood, -/area/station/command/heads_quarters/qm) "kTm" = ( /obj/machinery/door/firedoor, /obj/effect/turf_decal/siding/wood{ @@ -31449,20 +32054,6 @@ /obj/structure/chair/sofa/bench/left, /turf/open/floor/stone, /area/station/service/chapel) -"kVn" = ( -/obj/structure/disposalpipe/segment, -/obj/structure/table/reinforced, -/obj/effect/turf_decal/tile/red/fourcorners, -/obj/machinery/recharger{ - pixel_x = 5; - pixel_y = 4 - }, -/obj/item/radio/off{ - pixel_x = -6 - }, -/obj/machinery/light/small/directional/south, -/turf/open/floor/iron/smooth, -/area/station/security/checkpoint/supply) "kVx" = ( /obj/effect/spawner/random/structure/closet_maintenance, /obj/effect/spawner/random/maintenance, @@ -31565,25 +32156,11 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/cafeteria, /area/station/science/circuits) -"kXR" = ( -/obj/machinery/vending/cigarette, -/turf/open/floor/iron, -/area/station/maintenance/port/fore) "kXS" = ( /obj/structure/closet/emcloset, /obj/structure/sign/poster/official/random/directional/north, /turf/open/floor/plating, /area/station/hallway/secondary/dock) -"kYa" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/brown/fourcorners, -/obj/effect/landmark/navigate_destination/cargo, -/turf/open/floor/iron, -/area/station/hallway/primary/central/fore) "kYs" = ( /obj/machinery/mech_bay_recharge_port{ dir = 2 @@ -31599,10 +32176,6 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/engine, /area/station/science/explab) -"kYG" = ( -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/maintenance/port/fore) "kYI" = ( /obj/effect/turf_decal/sand/plating, /obj/structure/chair/plastic{ @@ -31632,11 +32205,6 @@ }, /turf/open/floor/iron, /area/station/science/cytology) -"kYZ" = ( -/obj/structure/window/spawner/directional/east, -/obj/structure/window/spawner/directional/south, -/turf/open/floor/grass, -/area/station/cargo/storage) "kZh" = ( /obj/structure/table/glass, /obj/effect/turf_decal/siding/thinplating_new/light{ @@ -31681,15 +32249,6 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron/showroomfloor, /area/station/medical/surgery/theatre) -"kZB" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable, -/obj/structure/extinguisher_cabinet/directional/north, -/obj/machinery/light/cold/directional/north, -/turf/open/floor/iron, -/area/station/cargo/storage) "kZC" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -31732,9 +32291,6 @@ }, /turf/open/floor/iron/small, /area/station/hallway/primary/central/aft) -"laD" = ( -/turf/open/floor/iron/dark, -/area/station/hallway/primary/central/fore) "laF" = ( /obj/structure/table, /obj/effect/turf_decal/siding/thinplating_new/terracotta{ @@ -31763,15 +32319,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) -"laL" = ( -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 4 - }, -/obj/effect/turf_decal/loading_area/white, -/turf/open/floor/iron/dark/side{ - dir = 8 - }, -/area/station/hallway/primary/central/fore) "laU" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -31788,35 +32335,10 @@ /obj/machinery/airalarm/directional/west, /turf/open/floor/iron/smooth, /area/station/maintenance/solars/port/aft) -"lbi" = ( -/obj/structure/flora/bush/flowers_br, -/obj/structure/flora/bush/flowers_yw, -/obj/machinery/light/floor, -/turf/open/floor/grass, -/area/station/hallway/primary/central/fore) -"lbl" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 9 - }, -/obj/item/storage/fancy/candle_box, -/obj/structure/rack/skeletal, -/obj/machinery/camera/autoname/directional/west, +"lbe" = ( /obj/structure/sign/poster/official/random/directional/north, -/turf/open/floor/iron/grimy, -/area/station/service/library) -"lbF" = ( -/obj/effect/turf_decal/siding/thinplating_new/dark{ - dir = 1 - }, -/obj/effect/turf_decal/stripes, -/obj/effect/turf_decal/trimline/brown/line, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 8 - }, -/obj/machinery/light/small/directional/east, -/obj/effect/landmark/start/bitrunner, -/turf/open/floor/iron/dark/smooth_half, -/area/station/cargo/bitrunning/den) +/turf/open/floor/iron/dark, +/area/station/cargo/lobby) "lbG" = ( /obj/effect/turf_decal/stripes/white/line{ dir = 1 @@ -31911,14 +32433,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/station/maintenance/department/engine) -"ldl" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/neutral, -/obj/structure/sign/departments/holy/directional/south, -/obj/machinery/light/cold/directional/south, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/hallway/primary/port) "ldq" = ( /turf/closed/wall, /area/station/maintenance/department/science/xenobiology) @@ -32235,10 +32749,6 @@ /obj/item/camera, /turf/open/floor/iron, /area/station/security/prison/workout) -"lhd" = ( -/obj/structure/water_source/puddle, -/turf/open/floor/grass, -/area/station/security/prison/garden) "lhi" = ( /obj/machinery/airalarm/directional/north, /obj/machinery/button/door/directional/north{ @@ -32541,19 +33051,22 @@ /obj/item/pen, /turf/open/floor/iron, /area/station/security/prison/rec) -"lkI" = ( -/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/stripes/corner{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "lkJ" = ( /obj/structure/flora/rock/pile/jungle/style_4, /turf/open/floor/grass, /area/station/service/chapel) +"lkL" = ( +/obj/structure/table, +/obj/item/paper_bin{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/pen{ + pixel_x = -2; + pixel_y = 3 + }, +/turf/open/floor/iron, +/area/station/cargo/sorting) "lkN" = ( /obj/effect/turf_decal/siding/wideplating{ dir = 1 @@ -32574,10 +33087,6 @@ "lkV" = ( /turf/closed/wall/r_wall, /area/station/science/ordnance) -"llg" = ( -/obj/effect/turf_decal/stripes/white/line, -/turf/open/floor/iron/dark, -/area/station/cargo/storage) "llC" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/trimline/blue/filled/line{ @@ -32591,19 +33100,6 @@ }, /turf/open/floor/iron/dark/small, /area/station/tcommsat/server) -"llN" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/sorting) "llP" = ( /obj/structure/cable, /obj/structure/bed/medical{ @@ -32645,10 +33141,6 @@ /obj/effect/mapping_helpers/airlock/access/all/science/xenobio, /turf/open/floor/plating, /area/station/maintenance/department/science/xenobiology) -"lme" = ( -/obj/effect/landmark/event_spawn, -/turf/open/floor/carpet/donk, -/area/station/command/heads_quarters/qm) "lmm" = ( /mob/living/basic/frog, /obj/effect/turf_decal/weather/dirt{ @@ -32665,28 +33157,30 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) -"lmv" = ( -/obj/structure/disposalpipe/segment, -/obj/item/kirbyplants/random, -/turf/open/floor/iron/grimy, -/area/station/command/heads_quarters/qm) +"lmp" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/chair/stool/directional/west, +/obj/machinery/airalarm/directional/east, +/obj/machinery/light/small/directional/east, +/turf/open/floor/wood, +/area/station/maintenance/hallway/abandoned_recreation) "lmz" = ( /turf/open/floor/iron, /area/station/hallway/primary/central/fore) "lmJ" = ( /turf/open/floor/iron, /area/station/engineering/atmos/project) -"lmR" = ( -/obj/structure/dresser, -/obj/structure/sign/poster/contraband/random/directional/east, -/turf/open/floor/iron/grimy, -/area/station/command/heads_quarters/qm) -"lmS" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 +"lmZ" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 8 }, -/turf/open/floor/iron/dark, -/area/station/cargo/office) +/obj/effect/landmark/navigate_destination/bar, +/obj/machinery/camera/autoname/directional/west, +/obj/machinery/light/small/directional/west, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "lnu" = ( /obj/machinery/holopad, /turf/open/floor/iron/dark, @@ -32737,6 +33231,17 @@ /obj/structure/ore_box, /turf/open/floor/plating, /area/station/maintenance/starboard/greater) +"lnL" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/obj/structure/chair{ + dir = 4; + pixel_y = -2 + }, +/obj/effect/turf_decal/tile/neutral, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "lnM" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/door/window/brigdoor/right/directional/north{ @@ -32790,16 +33295,6 @@ }, /turf/open/floor/iron/dark, /area/station/security/processing) -"loj" = ( -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 4 - }, -/obj/machinery/piratepad/civilian, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/iron/dark/side{ - dir = 8 - }, -/area/station/hallway/primary/central/fore) "lom" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -32924,14 +33419,6 @@ "lql" = ( /turf/open/floor/wood/parquet, /area/station/service/library) -"lqq" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/landmark/navigate_destination/chapel, -/turf/open/floor/iron, -/area/station/hallway/primary/port) "lqt" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -32974,6 +33461,12 @@ /obj/effect/landmark/start/assistant, /turf/open/floor/iron, /area/station/hallway/secondary/recreation) +"lrN" = ( +/obj/machinery/camera/directional/east{ + c_tag = "Atmospherics Tank - Mix" + }, +/turf/open/floor/engine/vacuum, +/area/station/engineering/atmos) "lrP" = ( /obj/machinery/computer/security{ dir = 8 @@ -33008,6 +33501,10 @@ /obj/structure/closet/emcloset, /turf/open/floor/plating, /area/station/engineering/supermatter/room) +"lsH" = ( +/obj/structure/cable, +/turf/open/floor/wood, +/area/station/command/heads_quarters/qm) "lsO" = ( /obj/machinery/status_display/evac/directional/south, /turf/open/floor/iron/white/side{ @@ -33096,6 +33593,13 @@ }, /turf/open/floor/iron/showroomfloor, /area/station/commons/dorms) +"lud" = ( +/obj/effect/mapping_helpers/broken_floor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/light_switch/directional/south, +/obj/machinery/light/small/directional/south, +/turf/open/floor/wood, +/area/station/maintenance/hallway/abandoned_recreation) "lun" = ( /obj/machinery/door/firedoor, /obj/effect/mapping_helpers/airlock/access/all/command/general, @@ -33162,24 +33666,6 @@ /obj/structure/lattice, /turf/open/space/basic, /area/space/nearstation) -"lvr" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/landmark/navigate_destination/bar, -/obj/machinery/camera/autoname/directional/west, -/turf/open/floor/iron, -/area/station/hallway/primary/central/fore) -"lvu" = ( -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/obj/effect/landmark/event_spawn, -/turf/open/floor/iron, -/area/station/cargo/office) "lvv" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 4 @@ -33227,6 +33713,13 @@ /obj/effect/landmark/blobstart, /turf/open/floor/iron/small, /area/station/maintenance/department/engine/atmos) +"lvN" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/sorting) "lvS" = ( /obj/machinery/porta_turret/ai{ dir = 4 @@ -33275,15 +33768,6 @@ }, /turf/open/floor/iron/dark, /area/station/science/ordnance) -"lwC" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/generic_maintenance_landmark, -/obj/structure/table, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/plating, -/area/station/maintenance/port/greater) "lwI" = ( /obj/effect/turf_decal/tile/brown/opposingcorners, /obj/machinery/computer/security/mining{ @@ -33342,17 +33826,10 @@ dir = 1 }, /area/station/commons/fitness/locker_room) -"lxy" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/obj/machinery/door/airlock/mining{ - name = "Mining Office" - }, -/obj/effect/mapping_helpers/airlock/access/all/supply/mining, -/obj/machinery/door/firedoor, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) +"lxE" = ( +/obj/effect/spawner/random/structure/closet_empty/crate, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "lxI" = ( /obj/effect/turf_decal/siding/wood/end, /obj/effect/spawner/random/engineering/atmospherics_portable, @@ -33457,13 +33934,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/cargo/storage) -"lzA" = ( -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/effect/landmark/event_spawn, -/turf/open/floor/iron, -/area/station/cargo/storage) "lzB" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -33494,51 +33964,10 @@ dir = 1 }, /area/station/command/bridge) -"lzU" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/window/spawner/directional/west, -/obj/structure/window/spawner/directional/north, -/turf/open/floor/grass, -/area/station/cargo/storage) -"lzW" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 1 - }, -/obj/structure/table/glass, -/obj/item/paper_bin{ - pixel_x = -3; - pixel_y = 7 - }, -/obj/item/pen/invisible{ - pixel_x = -2; - pixel_y = 7 - }, -/obj/machinery/newscaster/directional/north, -/obj/item/storage/photo_album/library, -/turf/open/floor/iron/grimy, -/area/station/service/library) -"lAk" = ( -/obj/effect/turf_decal/siding/white{ - dir = 9 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/obj/structure/table, -/obj/item/paper_bin{ - pixel_x = 2; - pixel_y = 1 - }, -/obj/structure/railing{ - dir = 9 - }, -/turf/open/floor/iron, -/area/station/cargo/office) +"lAM" = ( +/obj/effect/spawner/random/structure/girder, +/turf/open/floor/plating, +/area/station/maintenance/department/electrical) "lAO" = ( /obj/effect/mapping_helpers/broken_floor, /obj/effect/decal/cleanable/dirt, @@ -33595,31 +34024,6 @@ }, /turf/open/floor/iron/dark, /area/station/engineering/lobby) -"lBn" = ( -/obj/effect/turf_decal/siding/white{ - dir = 5 - }, -/obj/structure/table, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/obj/item/radio, -/obj/structure/railing{ - dir = 5 - }, -/obj/item/stamp{ - pixel_x = -12; - pixel_y = 3 - }, -/obj/item/stamp/denied{ - pixel_x = -12; - pixel_y = -2 - }, -/turf/open/floor/iron, -/area/station/cargo/office) "lBp" = ( /obj/structure/lattice, /obj/machinery/atmospherics/pipe/heat_exchanging/simple{ @@ -33681,14 +34085,6 @@ }, /turf/open/floor/engine, /area/station/engineering/supermatter/room) -"lCg" = ( -/obj/structure/chair{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown/fourcorners, -/obj/effect/landmark/start/hangover, -/turf/open/floor/iron, -/area/station/hallway/primary/central/fore) "lCh" = ( /obj/effect/turf_decal/tile/purple/opposingcorners, /obj/effect/turf_decal/siding/green, @@ -33810,16 +34206,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) -"lEm" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/chair/office{ - dir = 1 - }, -/obj/effect/landmark/start/cargo_technician, -/turf/open/floor/iron/dark, -/area/station/cargo/office) "lEs" = ( /obj/structure/extinguisher_cabinet/directional/east, /obj/effect/turf_decal/tile/neutral/opposingcorners{ @@ -33870,26 +34256,16 @@ }, /turf/open/floor/wood/tile, /area/station/maintenance/aft) -"lEO" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 5 - }, -/obj/structure/table/glass, -/obj/item/flashlight/lamp/green{ - pixel_x = 2; - pixel_y = 9 - }, -/obj/item/taperecorder{ - pixel_x = -15; - pixel_y = 3 - }, -/obj/effect/decal/cleanable/cobweb/cobweb2, -/obj/machinery/light_switch/directional/north, -/turf/open/floor/iron/grimy, -/area/station/service/library) "lER" = ( /turf/open/floor/iron/dark, /area/station/maintenance/department/engine/atmos) +"lFb" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "lFg" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -33911,13 +34287,6 @@ /obj/machinery/exodrone_launcher, /turf/open/floor/iron/smooth, /area/station/cargo/drone_bay) -"lFG" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/siding/red, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/cargo/storage) "lGd" = ( /obj/structure/disposalpipe/segment, /obj/effect/decal/cleanable/dirt, @@ -33930,10 +34299,6 @@ /obj/machinery/shower/directional/south, /turf/open/floor/iron/white, /area/station/medical/medbay/central) -"lGk" = ( -/obj/machinery/pdapainter/supply, -/turf/open/floor/wood, -/area/station/command/heads_quarters/qm) "lGo" = ( /obj/structure/window/reinforced/spawner/directional/east, /obj/structure/window/reinforced/spawner/directional/north, @@ -33971,16 +34336,6 @@ /obj/machinery/light/cold/directional/north, /turf/open/floor/iron, /area/station/science/lower) -"lGO" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/security/prison/garden) -"lGT" = ( -/obj/structure/chair/stool/directional/south, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/carpet/donk, -/area/station/command/heads_quarters/qm) "lHb" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/machinery/computer/robotics, @@ -34005,10 +34360,6 @@ }, /turf/open/floor/engine, /area/station/engineering/supermatter/room) -"lHe" = ( -/obj/structure/chair/stool/directional/south, -/turf/open/floor/carpet/donk, -/area/station/command/heads_quarters/qm) "lHk" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -34081,12 +34432,6 @@ /obj/machinery/airalarm/directional/north, /turf/open/floor/wood/large, /area/station/command/heads_quarters/captain/private) -"lHZ" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/turf/closed/wall, -/area/station/hallway/primary/central/aft) "lIa" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -34111,13 +34456,6 @@ /obj/effect/mapping_helpers/airlock/access/all/medical/general, /turf/open/floor/iron/white/small, /area/station/medical/medbay/lobby) -"lIf" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/turf/open/floor/iron/grimy, -/area/station/command/heads_quarters/qm) "lIh" = ( /obj/structure/cable, /obj/structure/disposalpipe/junction/flip{ @@ -34127,27 +34465,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/medical/medbay/central) -"lIn" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/chair/stool/directional/east, -/obj/effect/landmark/start/quartermaster, -/obj/structure/cable, -/turf/open/floor/iron/grimy, -/area/station/command/heads_quarters/qm) -"lIq" = ( -/obj/structure/table/wood/fancy/green, -/obj/item/paperplane{ - pixel_x = 7; - pixel_y = 7 - }, -/obj/item/paperplane{ - pixel_x = -1; - pixel_y = 1 - }, -/obj/structure/cable, -/turf/open/floor/iron/grimy, -/area/station/command/heads_quarters/qm) "lIt" = ( /obj/effect/turf_decal/siding/thinplating_new/terracotta{ dir = 6 @@ -34155,12 +34472,6 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/iron/dark/small, /area/station/maintenance/department/engine/atmos) -"lIw" = ( -/obj/structure/chair/stool/directional/west, -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable, -/turf/open/floor/iron/grimy, -/area/station/command/heads_quarters/qm) "lIL" = ( /obj/machinery/atmospherics/pipe/smart/simple/general/visible, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -34202,18 +34513,18 @@ /obj/item/radio/intercom/directional/north, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai_upload_foyer) -"lJV" = ( -/obj/structure/bed, -/obj/effect/decal/cleanable/dirt, -/obj/item/bedsheet/qm, -/obj/item/reagent_containers/cup/glass/bottle/tequila{ - pixel_x = -5; - pixel_y = 2 +"lKf" = ( +/obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 6 }, -/obj/structure/sign/poster/contraband/random/directional/east, -/obj/machinery/camera/autoname/directional/east, -/turf/open/floor/iron/grimy, -/area/station/command/heads_quarters/qm) +/obj/machinery/power/apc/auto_name/directional/west, +/obj/machinery/camera/autoname/directional/west, +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/office) "lKg" = ( /obj/machinery/firealarm/directional/east, /turf/open/floor/wood, @@ -34259,20 +34570,6 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) -"lKH" = ( -/obj/effect/turf_decal/siding/thinplating_new/dark{ - dir = 1 - }, -/obj/effect/turf_decal/trimline/brown/line, -/obj/effect/turf_decal/stripes, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 4 - }, -/obj/machinery/airalarm/directional/west, -/obj/effect/decal/cleanable/dirt/dust, -/obj/effect/landmark/start/bitrunner, -/turf/open/floor/iron/dark/smooth_half, -/area/station/cargo/bitrunning/den) "lKV" = ( /turf/open/floor/iron/smooth, /area/station/commons/storage/tools) @@ -34304,13 +34601,6 @@ /obj/machinery/door/firedoor, /turf/open/floor/plating, /area/station/cargo/drone_bay) -"lLq" = ( -/obj/machinery/firealarm/directional/east, -/obj/effect/decal/cleanable/oil, -/obj/machinery/byteforge, -/obj/effect/turf_decal/box, -/turf/open/floor/iron/dark/smooth_large, -/area/station/cargo/bitrunning/den) "lLr" = ( /obj/machinery/porta_turret/ai{ dir = 4 @@ -34386,14 +34676,6 @@ /obj/structure/holosign/barrier/atmos/tram, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) -"lMH" = ( -/obj/item/radio/intercom/directional/south, -/obj/effect/turf_decal/siding/wood, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/turf/open/floor/iron/grimy, -/area/station/service/library) "lNf" = ( /obj/effect/turf_decal/siding/blue, /turf/open/floor/iron/white/small, @@ -34459,15 +34741,6 @@ /obj/item/radio/intercom/directional/south, /turf/open/floor/iron/diagonal, /area/station/engineering/lobby) -"lNN" = ( -/obj/structure/table, -/obj/item/toy/foamblade, -/obj/item/analyzer{ - pixel_y = 8; - pixel_x = -9 - }, -/turf/open/floor/iron/dark/small, -/area/station/commons/fitness/locker_room) "lNQ" = ( /obj/effect/turf_decal/bot_white/right, /obj/machinery/firealarm/directional/north, @@ -34482,6 +34755,11 @@ /obj/effect/landmark/navigate_destination/court, /turf/open/floor/iron, /area/station/hallway/primary/starboard) +"lOg" = ( +/obj/effect/spawner/random/structure/grille, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "lOi" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -34535,6 +34813,30 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"lPv" = ( +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/table, +/obj/item/folder/red{ + pixel_y = 3 + }, +/obj/item/food/monkeycube/bee{ + name = "monkey cube"; + pixel_y = 17 + }, +/obj/item/food/monkeycube/chicken{ + pixel_y = 15; + pixel_x = 6; + name = "monkey cube"; + desc = "A new Nanotrasen classic, the monkey cube. Tastes like everything!" + }, +/obj/item/wirecutters{ + pixel_y = 6 + }, +/turf/open/floor/iron/dark, +/area/station/commons/storage/tools) "lPC" = ( /obj/structure/bookcase/random, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -34551,12 +34853,6 @@ /obj/machinery/announcement_system, /turf/open/floor/iron/grimy, /area/station/tcommsat/server) -"lPK" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/broken_floor, -/obj/structure/reagent_dispensers/fueltank, -/turf/open/floor/plating, -/area/station/maintenance/port/greater) "lPO" = ( /obj/structure/table, /obj/item/surgery_tray/full{ @@ -34619,12 +34915,6 @@ /obj/structure/broken_flooring/singular/directional/east, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) -"lRc" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/station/cargo/storage) "lRh" = ( /obj/effect/landmark/start/scientist, /obj/machinery/light/small/directional/north, @@ -34766,14 +35056,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/security/execution/transfer) -"lTv" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/stripes/white/line{ - dir = 6 - }, -/turf/open/floor/iron/dark, -/area/station/cargo/storage) "lTy" = ( /obj/effect/turf_decal/siding/wood/corner{ dir = 8 @@ -34792,14 +35074,6 @@ /obj/structure/chair/stool/directional/west, /turf/open/floor/iron/small, /area/station/maintenance/port/lesser) -"lTN" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/stripes/white/line{ - dir = 1 - }, -/turf/open/floor/iron/dark, -/area/station/cargo/storage) "lTU" = ( /obj/effect/turf_decal/stripes/white/line{ dir = 10 @@ -34822,17 +35096,6 @@ "lUo" = ( /turf/open/floor/iron, /area/station/science/lobby) -"lUz" = ( -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/stripes/white/line{ - dir = 10 - }, -/turf/open/floor/iron/dark, -/area/station/cargo/storage) "lUE" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -34876,15 +35139,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) -"lVv" = ( -/obj/structure/chair/stool/directional/south, -/obj/effect/turf_decal/siding/yellow{ - dir = 1 - }, -/obj/effect/landmark/start/atmospheric_technician, -/obj/structure/cable, -/turf/open/floor/wood, -/area/station/engineering/break_room) "lVy" = ( /obj/effect/turf_decal/tile/green/anticorner/contrasted{ dir = 8 @@ -34942,40 +35196,21 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) -"lWF" = ( -/obj/structure/disposalpipe/segment, +"lWE" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/siding/red{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) -"lWR" = ( -/obj/structure/table/wood, -/obj/effect/decal/cleanable/dirt, -/obj/item/stack/wrapping_paper{ - pixel_x = -3; - pixel_y = 5 - }, -/turf/open/floor/carpet/donk, -/area/station/command/heads_quarters/qm) -"lWU" = ( -/obj/structure/table/wood, +/obj/structure/table, /obj/effect/decal/cleanable/dirt, -/obj/item/folder/yellow{ - pixel_x = 3; - pixel_y = 6 +/obj/item/tank/internals/emergency_oxygen{ + pixel_x = 5; + pixel_y = 3 }, -/obj/item/dest_tagger{ - pixel_x = -11; - pixel_y = 4 +/obj/item/gps{ + pixel_y = 5; + pixel_x = 13 }, -/turf/open/floor/carpet/donk, -/area/station/command/heads_quarters/qm) +/obj/item/storage/toolbox/emergency/old, +/turf/open/floor/iron/dark, +/area/station/commons/storage/tools) "lWV" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -34993,10 +35228,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/catwalk_floor/iron_smooth, /area/station/security/checkpoint/supply) -"lXf" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/wood, -/area/station/command/heads_quarters/qm) "lXg" = ( /obj/effect/turf_decal/tile/neutral/half/contrasted{ dir = 4 @@ -35011,12 +35242,6 @@ dir = 4 }, /area/station/science/xenobiology) -"lXn" = ( -/obj/structure/disposalpipe/segment, -/obj/structure/closet/secure_closet/quartermaster, -/obj/machinery/light_switch/directional/south, -/turf/open/floor/iron/grimy, -/area/station/command/heads_quarters/qm) "lXw" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable, @@ -35045,6 +35270,15 @@ }, /turf/open/floor/wood/tile, /area/station/science/lower) +"lXM" = ( +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/obj/machinery/disposal/bin, +/obj/machinery/light/small/directional/south, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/carpet/lone, +/area/station/service/chapel/office) "lXR" = ( /obj/structure/disposalpipe/junction, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -35075,14 +35309,17 @@ /obj/machinery/light/warm/directional/north, /turf/open/floor/iron, /area/station/commons/dorms) -"lXY" = ( -/obj/machinery/airalarm/directional/south, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ +"lYe" = ( +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/obj/structure/window/spawner/directional/west, +/obj/effect/turf_decal/stripes/end, +/obj/structure/disposaloutlet{ dir = 1 }, -/obj/item/banner/cargo, -/turf/open/floor/iron/grimy, -/area/station/command/heads_quarters/qm) +/turf/open/floor/plating, +/area/station/cargo/sorting) "lYf" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -35107,28 +35344,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) -"lYt" = ( -/obj/structure/table/wood/fancy/green, -/obj/item/storage/wallet{ - pixel_x = -3; - pixel_y = 10 - }, -/obj/item/cigarette/cigar{ - pixel_x = -1; - pixel_y = -2 - }, -/obj/item/lighter{ - pixel_x = 11; - pixel_y = -7 - }, -/obj/machinery/light/directional/south, -/turf/open/floor/iron/grimy, -/area/station/command/heads_quarters/qm) -"lYw" = ( -/obj/structure/hedge, -/obj/item/radio/intercom/directional/south, -/turf/open/floor/iron/grimy, -/area/station/command/heads_quarters/qm) "lYF" = ( /obj/effect/turf_decal/siding/yellow{ dir = 9 @@ -35269,17 +35484,6 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/hallway/secondary/dock) -"lZP" = ( -/obj/structure/table, -/obj/item/toy/eightball{ - pixel_x = -4 - }, -/obj/item/wirecutters{ - pixel_y = 17; - pixel_x = 4 - }, -/turf/open/floor/iron/dark/small, -/area/station/commons/fitness/locker_room) "lZR" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/duct, @@ -35292,6 +35496,12 @@ }, /turf/open/floor/grass, /area/station/service/chapel) +"mac" = ( +/obj/structure/hedge, +/obj/item/radio/intercom/directional/south, +/obj/effect/turf_decal/siding/wood, +/turf/open/floor/wood, +/area/station/command/heads_quarters/qm) "mae" = ( /obj/structure/cable, /turf/closed/wall, @@ -35469,6 +35679,10 @@ /obj/effect/landmark/start/chief_medical_officer, /turf/open/floor/wood/parquet, /area/station/command/heads_quarters/cmo) +"mdp" = ( +/obj/structure/water_source/puddle, +/turf/open/floor/grass, +/area/station/security/prison/garden) "mdr" = ( /obj/effect/spawner/random/structure/girder, /turf/open/floor/tram, @@ -35484,14 +35698,6 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/iron/showroomfloor, /area/station/commons/toilet/auxiliary) -"mdX" = ( -/obj/machinery/light/small/directional/north, -/obj/machinery/conveyor_switch{ - id = "mining"; - pixel_x = -10 - }, -/turf/open/floor/wood, -/area/station/cargo/miningfoundry) "meh" = ( /obj/structure/railing{ dir = 4 @@ -35503,6 +35709,14 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/commons/fitness/recreation/entertainment) +"mek" = ( +/obj/effect/turf_decal/siding/wood, +/obj/machinery/holopad, +/mob/living/basic/chick/permanent{ + name = "Morgan" + }, +/turf/open/floor/iron/smooth, +/area/station/command/heads_quarters/qm) "meu" = ( /turf/closed/wall, /area/station/command/heads_quarters/captain) @@ -35708,6 +35922,20 @@ /obj/item/clothing/under/costume/skeleton, /turf/open/floor/eighties, /area/station/service/abandoned_gambling_den/gaming) +"mjh" = ( +/obj/structure/railing{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/machinery/holopad, +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/cable, +/turf/open/floor/iron/small, +/area/station/engineering/break_room) "mjr" = ( /obj/machinery/vending/dinnerware, /obj/machinery/requests_console/auto_name/directional/south, @@ -35754,13 +35982,6 @@ }, /turf/open/floor/iron, /area/station/cargo/storage) -"mjX" = ( -/obj/structure/closet/secure_closet/security/cargo, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 8 - }, -/turf/open/floor/iron/smooth, -/area/station/security/checkpoint/supply) "mka" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -35800,28 +36021,11 @@ /obj/machinery/power/apc/auto_name/directional/north, /turf/open/floor/iron/white/textured_large, /area/station/command/heads_quarters/cmo) -"mkF" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/landmark/start/depsec/supply, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 1 - }, -/turf/open/floor/iron/smooth, -/area/station/security/checkpoint/supply) "mkN" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/maintenance/fore/greater) -"mkO" = ( -/obj/structure/filingcabinet, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 4 - }, -/obj/machinery/firealarm/directional/east, -/turf/open/floor/iron/smooth, -/area/station/security/checkpoint/supply) "mkZ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/siding/wood{ @@ -35844,6 +36048,14 @@ /obj/structure/alien/weeds, /turf/open/floor/iron, /area/station/maintenance/starboard/greater) +"mln" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden, +/obj/machinery/light/small/directional/west, +/obj/machinery/airlock_sensor/incinerator_atmos{ + pixel_y = -20 + }, +/turf/open/floor/engine, +/area/station/maintenance/disposal/incinerator) "mlp" = ( /obj/structure/chair/stool/bar/directional/south, /obj/effect/turf_decal/siding/wood{ @@ -35851,13 +36063,6 @@ }, /turf/open/floor/wood, /area/station/service/abandoned_gambling_den) -"mlr" = ( -/obj/structure/chair/office/light{ - dir = 4 - }, -/obj/effect/landmark/start/quartermaster, -/turf/open/floor/carpet/donk, -/area/station/command/heads_quarters/qm) "mls" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -35955,6 +36160,10 @@ }, /turf/open/floor/iron/smooth, /area/station/maintenance/department/electrical) +"mmZ" = ( +/obj/effect/spawner/random/trash, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "mnb" = ( /obj/effect/turf_decal/stripes/white/corner{ dir = 4 @@ -36037,12 +36246,18 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/iron/dark/smooth_large, /area/station/command/meeting_room) -"mnZ" = ( -/obj/machinery/computer/cargo{ - dir = 4 +"mnU" = ( +/obj/structure/hedge, +/obj/structure/disposalpipe/segment{ + dir = 10 }, -/turf/open/floor/plating, -/area/station/cargo/storage) +/obj/machinery/light_switch/directional/east, +/obj/machinery/light/warm/directional/east, +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/office) "mog" = ( /obj/machinery/oven/range, /obj/machinery/airalarm/directional/north, @@ -36074,6 +36289,23 @@ /obj/machinery/door/firedoor, /turf/open/floor/catwalk_floor/iron_white, /area/station/science/research) +"moq" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/trimline/green/filled/line{ + dir = 1 + }, +/obj/effect/turf_decal/arrows{ + dir = 1 + }, +/obj/item/radio/intercom/directional/west, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown/half/contrasted, +/turf/open/floor/iron/dark/side{ + dir = 1 + }, +/area/station/cargo/sorting) "mos" = ( /obj/machinery/light/small/directional/east, /turf/open/floor/iron/smooth, @@ -36119,6 +36351,26 @@ }, /turf/open/floor/wood/parquet, /area/station/medical/psychology) +"mpL" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/item/crowbar/large{ + pixel_y = 18 + }, +/obj/item/clothing/head/costume/pirate{ + pixel_x = 15; + pixel_y = -3 + }, +/obj/item/clothing/suit/hazardvest{ + pixel_x = -3; + pixel_y = -2 + }, +/obj/item/wrench{ + pixel_y = 15 + }, +/turf/open/floor/iron/dark, +/area/station/commons/storage/tools) "mpQ" = ( /obj/structure/bed{ dir = 4 @@ -36147,13 +36399,6 @@ }, /turf/open/floor/iron, /area/station/maintenance/hallway/abandoned_command) -"mqz" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 10 - }, -/obj/machinery/vending/wardrobe/curator_wardrobe, -/turf/open/floor/iron/grimy, -/area/station/service/library) "mqH" = ( /obj/structure/cable, /obj/effect/landmark/generic_maintenance_landmark, @@ -36180,48 +36425,20 @@ }, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) -"mrn" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/plating, -/area/station/maintenance/port/greater) "mrt" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/light/small/directional/north, /turf/open/floor/iron, /area/station/hallway/secondary/dock) -"mrP" = ( -/obj/structure/disposalpipe/segment{ +"mrY" = ( +/obj/effect/turf_decal/siding/wood{ dir = 6 }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/table, -/obj/item/folder/red{ - pixel_y = 3 - }, -/obj/item/food/monkeycube/bee{ - name = "monkey cube"; - pixel_y = 17 - }, -/obj/item/food/monkeycube/chicken{ - pixel_y = 15; - pixel_x = 6; - name = "monkey cube"; - desc = "A new Nanotrasen classic, the monkey cube. Tastes like everything!" - }, -/obj/item/wirecutters{ - pixel_y = 6 - }, -/turf/open/floor/iron/dark, -/area/station/commons/storage/tools) +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron/grimy, +/area/station/service/library/private) "msg" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -36241,12 +36458,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central/aft) -"msq" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/central/fore) "mss" = ( /obj/machinery/atmospherics/components/binary/pump{ dir = 8; @@ -36256,17 +36467,15 @@ /obj/structure/cable, /turf/open/floor/engine, /area/station/engineering/supermatter/room) -"msy" = ( -/obj/machinery/door/airlock/mining/glass{ - name = "Cargo Bay" - }, -/obj/effect/mapping_helpers/airlock/access/all/supply/general, -/obj/machinery/door/firedoor, -/turf/open/floor/iron, -/area/station/cargo/storage) "msJ" = ( /turf/open/floor/iron, /area/station/hallway/secondary/dock) +"mta" = ( +/obj/structure/dresser, +/obj/structure/sign/poster/contraband/random/directional/east, +/obj/effect/turf_decal/siding/wood, +/turf/open/floor/wood, +/area/station/command/heads_quarters/qm) "mtc" = ( /obj/structure/table/wood, /obj/effect/decal/cleanable/dirt, @@ -36441,15 +36650,6 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/engine, /area/station/science/xenobiology) -"mwK" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/neutral, -/obj/structure/disposalpipe/junction/flip{ - dir = 8 - }, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/hallway/primary/port) "mwN" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/tile/neutral{ @@ -36477,6 +36677,15 @@ /obj/effect/turf_decal/tile/dark_red/opposingcorners, /turf/open/floor/iron, /area/station/security/warden) +"mxh" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/lobby) "mxp" = ( /obj/structure/table, /obj/structure/railing/corner{ @@ -36623,10 +36832,6 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) -"mzv" = ( -/obj/docking_port/stationary/syndicate/northeast, -/turf/open/space/basic, -/area/space) "mzx" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -36728,6 +36933,21 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/department/engine) +"mCV" = ( +/obj/machinery/portable_atmospherics/scrubber, +/turf/open/floor/plating, +/area/station/maintenance/port/greater) +"mCW" = ( +/obj/machinery/airalarm/directional/south, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, +/obj/item/banner/cargo, +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/turf/open/floor/carpet/red, +/area/station/command/heads_quarters/qm) "mDf" = ( /obj/structure/chair/wood{ dir = 8 @@ -36743,6 +36963,13 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/port/lesser) +"mDk" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "mDl" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -36848,6 +37075,15 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/iron/showroomfloor, /area/station/security/prison/shower) +"mFd" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/landmark/navigate_destination/chapel, +/obj/structure/extinguisher_cabinet/directional/north, +/turf/open/floor/iron, +/area/station/hallway/primary/port) "mFh" = ( /obj/effect/decal/cleanable/glass, /obj/structure/table/reinforced/rglass, @@ -36905,6 +37141,13 @@ /obj/structure/cable, /turf/open/floor/eighties, /area/station/service/abandoned_gambling_den/gaming) +"mFQ" = ( +/obj/structure/cable, +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/office) "mGg" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -36972,6 +37215,12 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos/project) +"mGI" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/closed/wall, +/area/station/cargo/lobby) "mGM" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/broken_flooring/singular/directional/south, @@ -37063,6 +37312,20 @@ dir = 1 }, /area/station/science/lower) +"mIp" = ( +/obj/effect/turf_decal/trimline/neutral/line{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/neutral/line{ + dir = 4 + }, +/obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "mIA" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -37093,13 +37356,6 @@ /obj/structure/sign/poster/official/random/directional/north, /turf/open/floor/wood/tile, /area/station/command/corporate_showroom) -"mIE" = ( -/obj/machinery/door/airlock/public/glass{ - name = "Public Shrine" - }, -/obj/machinery/door/firedoor, -/turf/open/floor/stone, -/area/station/hallway/primary/port) "mIP" = ( /obj/structure/chair{ dir = 8 @@ -37238,15 +37494,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/station/hallway/primary/port) -"mKB" = ( -/obj/machinery/navbeacon{ - codes_txt = "delivery;dir=8"; - location = "QM #1" - }, -/obj/effect/turf_decal/delivery, -/mob/living/simple_animal/bot/mulebot, -/turf/open/floor/iron, -/area/station/cargo/storage) "mKD" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/tile/red{ @@ -37254,6 +37501,14 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/exit/departure_lounge) +"mKR" = ( +/obj/effect/turf_decal/stripes/corner, +/obj/machinery/camera/autoname/directional/south, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron/smooth, +/area/station/cargo/warehouse) "mKY" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, @@ -37282,6 +37537,11 @@ }, /turf/open/floor/iron, /area/station/security/processing) +"mLz" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/cargo/storage) "mLA" = ( /obj/structure/cable, /obj/machinery/power/apc/auto_name/directional/west, @@ -37411,6 +37671,14 @@ }, /turf/open/floor/wood/tile, /area/station/command/meeting_room) +"mOc" = ( +/obj/machinery/door/airlock/engineering{ + name = "Engine Airlock" + }, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/any/engineering/general, +/turf/open/floor/plating, +/area/station/engineering/supermatter/room) "mOk" = ( /obj/structure/table/glass, /obj/item/folder/blue{ @@ -37520,16 +37788,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/smooth, /area/station/command/bridge) -"mQh" = ( -/obj/effect/turf_decal/stripes/line, -/obj/machinery/conveyor_switch/oneway{ - id = "QMLoad2"; - name = "Unloading Conveyor"; - pixel_x = -13; - pixel_y = 3 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "mQz" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/structure/chair/office{ @@ -37581,6 +37839,12 @@ /obj/machinery/camera/autoname/directional/west, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"mRQ" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/cargo/storage) "mSa" = ( /turf/open/floor/iron, /area/station/commons/fitness/locker_room) @@ -37635,11 +37899,6 @@ /obj/item/clothing/head/costume/foilhat, /turf/open/floor/plating, /area/station/cargo/boutique) -"mTe" = ( -/obj/structure/disposalpipe/segment, -/obj/structure/chair/stool/directional/north, -/turf/open/floor/iron, -/area/station/cargo/sorting) "mTl" = ( /turf/closed/wall, /area/station/cargo/sorting) @@ -37733,16 +37992,6 @@ }, /turf/open/floor/wood/parquet, /area/station/service/library) -"mUm" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/machinery/status_display/ai/directional/west, -/obj/structure/disposalpipe/segment, -/obj/machinery/light/cold/directional/west, -/turf/open/floor/iron, -/area/station/hallway/primary/central/fore) "mUn" = ( /obj/structure/cable, /obj/machinery/door/airlock{ @@ -37753,13 +38002,6 @@ /obj/structure/alien/weeds, /turf/open/floor/plating, /area/station/maintenance/starboard/greater) -"mUt" = ( -/obj/structure/chair/stool/directional/south, -/obj/structure/mirror/directional/north, -/obj/machinery/light/small/directional/north, -/obj/effect/decal/cleanable/cobweb/cobweb2, -/turf/open/floor/iron/grimy, -/area/station/cargo/boutique) "mUO" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, @@ -37871,6 +38113,17 @@ }, /turf/open/floor/iron/white/small, /area/station/service/hydroponics) +"mWU" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/structure/chair{ + dir = 4; + pixel_y = -2 + }, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "mWY" = ( /obj/effect/turf_decal/tile/dark_red/opposingcorners, /obj/structure/chair/sofa/bench/left{ @@ -37879,6 +38132,13 @@ /obj/machinery/airalarm/directional/west, /turf/open/floor/iron, /area/station/security/processing) +"mXb" = ( +/obj/effect/turf_decal/weather/dirt{ + dir = 10 + }, +/obj/structure/flora/tree/jungle/style_2, +/turf/open/floor/grass, +/area/station/service/chapel) "mXk" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/broken_flooring/singular/directional/east, @@ -37961,6 +38221,15 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"mYE" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/item/kirbyplants/random, +/obj/machinery/firealarm/directional/south, +/obj/item/storage/belt/utility, +/turf/open/floor/iron/smooth, +/area/station/commons/storage/tools) "mYP" = ( /obj/structure/table, /obj/item/storage/bag/tray/cafeteria{ @@ -38021,16 +38290,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) -"mZg" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/hallway/primary/central/fore) "mZA" = ( /obj/effect/mapping_helpers/airlock/abandoned, /obj/machinery/door/airlock/public/glass{ @@ -38066,6 +38325,9 @@ /obj/machinery/igniter/incinerator_ordmix, /turf/open/floor/engine/vacuum, /area/station/science/ordnance/burnchamber) +"naB" = ( +/turf/closed/wall/rust, +/area/station/cargo/lobby) "naC" = ( /obj/structure/cable, /obj/structure/broken_flooring/singular/directional/south, @@ -38085,6 +38347,15 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/station/security/brig/entrance) +"naK" = ( +/obj/machinery/door/airlock/engineering{ + name = "Engineering Office" + }, +/obj/effect/mapping_helpers/airlock/access/all/engineering/engine_equipment, +/turf/open/floor/iron/smooth_half{ + dir = 8 + }, +/area/station/maintenance/department/engine/atmos) "naN" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/door/airlock{ @@ -38111,10 +38382,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/port/lesser) -"nbN" = ( -/obj/effect/spawner/random/structure/girder, -/turf/open/floor/plating, -/area/station/maintenance/department/electrical) "ncb" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/table/wood, @@ -38293,6 +38560,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/security/prison) +"nhk" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, +/turf/open/floor/wood, +/area/station/command/heads_quarters/qm) "nhl" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -38471,6 +38744,16 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/fore/greater) +"njv" = ( +/obj/structure/reagent_dispensers/wall/peppertank/directional/west, +/obj/machinery/computer/records/security{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 8 + }, +/turf/open/floor/iron/smooth, +/area/station/security/checkpoint/supply) "njA" = ( /obj/machinery/photocopier, /obj/structure/sign/poster/official/random/directional/north, @@ -38526,6 +38809,14 @@ /obj/structure/barricade/wooden/crude, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) +"nku" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, +/obj/structure/cable, +/turf/open/floor/iron/smooth, +/area/station/cargo/warehouse) "nkw" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/trimline/blue/filled/corner{ @@ -38649,26 +38940,29 @@ }, /turf/open/floor/iron/dark/textured_large, /area/station/service/kitchen) +"nmE" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/wood, +/area/station/command/heads_quarters/qm) "nmH" = ( /obj/structure/railing, /obj/effect/turf_decal/siding/wideplating, /turf/open/floor/wood, /area/station/engineering/main) -"nmX" = ( -/obj/machinery/power/apc/auto_name/directional/north, +"nmV" = ( /obj/structure/cable, -/turf/open/floor/mineral/titanium, -/area/station/command/heads_quarters/ce) -"nnc" = ( +/obj/effect/decal/cleanable/dirt, /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) +"nmX" = ( +/obj/machinery/power/apc/auto_name/directional/north, /obj/structure/cable, -/turf/open/floor/iron/smooth, -/area/station/command/heads_quarters/qm) +/turf/open/floor/mineral/titanium, +/area/station/command/heads_quarters/ce) "nnd" = ( /obj/effect/turf_decal/tile/dark_red/half/contrasted{ dir = 1 @@ -38818,21 +39112,6 @@ /obj/structure/sign/departments/court/directional/north, /turf/open/floor/iron, /area/station/hallway/primary/starboard) -"nqa" = ( -/obj/machinery/door/airlock/grunge{ - name = "Janitorial Closet" - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/effect/mapping_helpers/airlock/access/any/service/janitor, -/turf/open/floor/iron/textured_half{ - dir = 8 - }, -/area/station/service/janitor) "nqd" = ( /obj/machinery/shower/directional/east, /obj/effect/turf_decal/trimline/blue/end{ @@ -38918,20 +39197,6 @@ }, /turf/open/floor/wood, /area/station/service/chapel) -"nry" = ( -/obj/effect/turf_decal/tile/red/anticorner/contrasted{ - dir = 8 - }, -/obj/structure/reagent_dispensers/wall/peppertank/directional/west, -/obj/machinery/computer/records/security{ - dir = 4 - }, -/obj/machinery/requests_console/directional/south{ - department = "Security"; - name = "Security Requests Console" - }, -/turf/open/floor/iron/smooth, -/area/station/security/checkpoint/supply) "nsc" = ( /obj/structure/cable, /obj/item/kirbyplants/organic/applebush, @@ -38983,17 +39248,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/port) -"nsL" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/obj/effect/landmark/start/depsec/supply, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/turf/open/floor/iron/smooth, -/area/station/security/checkpoint/supply) "nsO" = ( /obj/item/kirbyplants/random, /obj/machinery/firealarm/directional/south, @@ -39009,11 +39263,6 @@ /obj/item/kirbyplants/random, /turf/open/floor/iron, /area/station/hallway/secondary/dock) -"nsX" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/turf/open/floor/wood, -/area/station/cargo/miningfoundry) "nte" = ( /obj/structure/table/glass, /obj/machinery/recharger, @@ -39059,10 +39308,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/starboard) -"ntJ" = ( -/obj/structure/disposalpipe/segment, -/turf/open/floor/plating, -/area/station/maintenance/port/greater) "ntK" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -39095,15 +39340,6 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron/textured_half, /area/station/commons/fitness/recreation/entertainment) -"nua" = ( -/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/stripes/line{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "num" = ( /obj/effect/turf_decal/sand/plating, /turf/closed/wall, @@ -39221,6 +39457,23 @@ }, /turf/open/floor/iron/recharge_floor, /area/station/maintenance/port/aft) +"nwb" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/office) +"nwf" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/firealarm/directional/west, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "nwj" = ( /obj/effect/turf_decal/tile/blue{ dir = 4 @@ -39255,14 +39508,6 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/entry) -"nxo" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/stripes/white/line{ - dir = 8 - }, -/turf/open/floor/iron/dark, -/area/station/cargo/storage) "nxD" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -39292,15 +39537,6 @@ /obj/machinery/keycard_auth/wall_mounted/directional/south, /turf/open/floor/wood, /area/station/command/heads_quarters/qm) -"nxX" = ( -/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/stripes/white/line{ - dir = 4 - }, -/turf/open/floor/iron/dark, -/area/station/cargo/storage) "nyd" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -39360,14 +39596,6 @@ dir = 4 }, /area/station/science/lower) -"nyE" = ( -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/cargo/storage) "nyH" = ( /turf/closed/wall, /area/station/hallway/primary/aft) @@ -39376,22 +39604,6 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron, /area/station/construction/mining/aux_base) -"nyS" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/door/airlock/command/glass{ - name = "Quartermaster's Office" - }, -/obj/effect/mapping_helpers/airlock/access/all/supply/qm, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/obj/machinery/door/firedoor, -/turf/open/floor/catwalk_floor/iron_smooth, -/area/station/command/heads_quarters/qm) "nyT" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -39412,6 +39624,18 @@ /obj/machinery/light_switch/directional/west, /turf/open/floor/iron/dark, /area/station/medical/pharmacy) +"nzd" = ( +/obj/structure/filingcabinet, +/obj/machinery/firealarm/directional/east, +/obj/effect/turf_decal/tile/red/anticorner/contrasted{ + dir = 4 + }, +/turf/open/floor/iron/smooth, +/area/station/security/checkpoint/supply) +"nzy" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted, +/turf/open/floor/iron, +/area/station/cargo/sorting) "nzA" = ( /obj/effect/turf_decal/tile/dark_red/opposingcorners, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -39428,6 +39652,44 @@ "nzL" = ( /turf/closed/wall, /area/station/science/ordnance/testlab) +"nzO" = ( +/obj/structure/table, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/item/stamp/denied{ + pixel_x = -1; + pixel_y = 8 + }, +/obj/item/stamp{ + pixel_x = -7; + pixel_y = 0 + }, +/obj/item/radio{ + pixel_x = 9; + pixel_y = 4 + }, +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/office) +"nzS" = ( +/obj/machinery/atmospherics/components/trinary/filter/flipped/layer2{ + dir = 4 + }, +/obj/machinery/light/small/directional/north, +/obj/machinery/button/door/incinerator_vent_atmos_aux{ + pixel_x = 8; + pixel_y = 24 + }, +/obj/machinery/button/door/incinerator_vent_atmos_main{ + pixel_x = 8; + pixel_y = 36 + }, +/turf/open/floor/plating, +/area/station/maintenance/disposal/incinerator) "nzU" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -39798,12 +40060,6 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/grass, /area/station/medical/virology) -"nGu" = ( -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/turf/open/floor/plating, -/area/station/maintenance/port/greater) "nGA" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -39827,6 +40083,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/smooth, /area/station/engineering/main) +"nHb" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/obj/machinery/vending/wardrobe/curator_wardrobe, +/obj/structure/cable, +/obj/machinery/power/apc/auto_name/directional/west, +/turf/open/floor/iron/grimy, +/area/station/service/library/private) "nHd" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -39835,37 +40100,6 @@ /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/plating, /area/station/maintenance/department/engine/atmos) -"nHp" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/sign/poster/official/random/directional/north, -/obj/item/radio{ - desc = "An old handheld radio. You could use it, if you really wanted to."; - icon_state = "radio"; - name = "old radio"; - pixel_x = -6; - pixel_y = 10 - }, -/turf/open/floor/iron/dark, -/area/station/cargo/office) -"nHq" = ( -/obj/structure/table/reinforced, -/obj/item/folder/yellow{ - pixel_x = 13; - pixel_y = 1 - }, -/obj/item/flashlight/lamp{ - pixel_x = -4; - pixel_y = 4 - }, -/obj/item/clothing/ears/earmuffs{ - pixel_x = 15; - pixel_y = 7 - }, -/obj/structure/cable, -/turf/open/floor/wood, -/area/station/engineering/break_room) "nHu" = ( /obj/effect/spawner/random/structure/closet_maintenance, /turf/open/floor/plating, @@ -40008,6 +40242,17 @@ }, /turf/open/floor/plating, /area/station/command/meeting_room) +"nJK" = ( +/obj/structure/reagent_dispensers/watertank/high, +/obj/effect/turf_decal/siding/thinplating_new/light{ + dir = 9 + }, +/obj/machinery/light/small/dim/directional/north, +/obj/effect/turf_decal/delivery/white{ + color = "#52B4E9" + }, +/turf/open/floor/iron/white/small, +/area/station/service/hydroponics) "nJU" = ( /obj/machinery/conveyor{ dir = 4; @@ -40027,13 +40272,6 @@ /obj/machinery/light_switch/directional/east, /turf/open/floor/iron/white, /area/station/medical/treatment_center) -"nKe" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, -/obj/machinery/atmospherics/pipe/smart/simple/orange/visible, -/turf/open/floor/engine, -/area/station/engineering/supermatter/room) "nKj" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -40048,6 +40286,14 @@ /obj/machinery/light/floor, /turf/open/floor/iron/smooth, /area/station/hallway/secondary/command) +"nLi" = ( +/obj/structure/cable, +/obj/effect/turf_decal/siding/thinplating_new{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/smooth, +/area/station/cargo/miningfoundry) "nLk" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -40062,12 +40308,6 @@ }, /turf/open/floor/catwalk_floor/iron_white, /area/station/command/heads_quarters/rd) -"nLH" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/smooth, -/area/station/cargo/warehouse) "nLJ" = ( /obj/machinery/portable_atmospherics/canister, /obj/effect/turf_decal/bot{ @@ -40091,6 +40331,23 @@ }, /turf/open/floor/iron, /area/station/engineering/storage/tech) +"nLQ" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/cell_charger{ + pixel_x = -1; + pixel_y = 4 + }, +/obj/item/stock_parts/power_store/cell/high{ + pixel_x = -1; + pixel_y = 4 + }, +/obj/item/assembly/timer{ + pixel_x = 14; + pixel_y = 6 + }, +/turf/open/floor/iron/dark, +/area/station/commons/storage/tools) "nMk" = ( /obj/machinery/power/emitter/welded{ dir = 1 @@ -40119,13 +40376,6 @@ /obj/effect/mapping_helpers/airlock/access/any/engineering/construction, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) -"nMV" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "nMW" = ( /obj/machinery/door/firedoor, /obj/effect/turf_decal/stripes/red/line{ @@ -40222,19 +40472,17 @@ /obj/effect/turf_decal/tile/dark_red/fourcorners, /turf/open/floor/iron, /area/station/security/brig/entrance) +"nPg" = ( +/obj/effect/spawner/random/trash, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "nPl" = ( /obj/machinery/power/supermatter_crystal/engine, /turf/open/floor/engine, /area/station/engineering/supermatter) -"nPt" = ( -/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/stripes/corner{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "nPu" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/dark_red/opposingcorners, @@ -40364,20 +40612,6 @@ /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/iron/smooth, /area/station/engineering/break_room) -"nQE" = ( -/obj/structure/railing{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/machinery/holopad, -/obj/effect/decal/cleanable/dirt/dust, -/obj/structure/cable, -/turf/open/floor/iron/small, -/area/station/engineering/break_room) "nQH" = ( /obj/structure/closet{ name = "Paramedic Supplies" @@ -40401,12 +40635,6 @@ /obj/machinery/holopad, /turf/open/floor/iron/smooth, /area/station/security/checkpoint/escape) -"nRa" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/neutral, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/hallway/primary/port) "nRd" = ( /obj/structure/cable, /obj/effect/spawner/structure/window, @@ -40474,12 +40702,6 @@ "nST" = ( /turf/open/floor/iron/small, /area/station/maintenance/department/engine) -"nSY" = ( -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/turf/open/floor/iron/dark, -/area/station/cargo/office) "nTa" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -40489,22 +40711,6 @@ }, /turf/open/floor/iron/textured_half, /area/station/hallway/primary/central/fore) -"nTi" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/button/door/directional/east{ - id = "qm_warehouse"; - name = "Warehouse Door Control"; - pixel_x = -24; - pixel_y = 24; - req_access = list("cargo") - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "nTt" = ( /obj/effect/mapping_helpers/broken_floor, /obj/machinery/computer/shuttle/mining/common{ @@ -40571,13 +40777,6 @@ }, /turf/open/floor/iron/cafeteria, /area/station/science/circuits) -"nUx" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/turf/open/floor/iron/smooth, -/area/station/cargo/warehouse) "nUK" = ( /obj/effect/turf_decal/siding/wood, /obj/structure/barricade/wooden/crude, @@ -40792,12 +40991,6 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/iron/smooth, /area/station/maintenance/solars/port/aft) -"nYQ" = ( -/obj/machinery/vending/wardrobe/cargo_wardrobe, -/obj/machinery/camera/autoname/directional/south, -/obj/machinery/light/small/directional/south, -/turf/open/floor/iron/dark, -/area/station/cargo/office) "nZh" = ( /obj/structure/table, /obj/item/stock_parts/scanning_module{ @@ -40906,6 +41099,23 @@ /obj/item/stock_parts/power_store/cell/high, /turf/open/floor/iron/dark, /area/station/science/robotics/lab) +"oba" = ( +/obj/structure/table/reinforced, +/obj/item/folder/yellow{ + pixel_x = 13; + pixel_y = 1 + }, +/obj/item/flashlight/lamp{ + pixel_x = -4; + pixel_y = 4 + }, +/obj/item/clothing/ears/earmuffs{ + pixel_x = 15; + pixel_y = 7 + }, +/obj/structure/cable, +/turf/open/floor/wood, +/area/station/engineering/break_room) "obb" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -40926,6 +41136,10 @@ }, /turf/open/floor/iron/smooth, /area/station/engineering/break_room) +"obk" = ( +/obj/structure/cable, +/turf/open/floor/iron/smooth, +/area/station/cargo/warehouse) "obq" = ( /obj/structure/cable, /obj/structure/lattice/catwalk, @@ -40939,13 +41153,6 @@ /obj/machinery/power/apc/auto_name/directional/east, /turf/open/floor/iron/white/small, /area/station/science/ordnance/storage) -"obH" = ( -/obj/structure/disposalpipe/segment{ - dir = 9 - }, -/obj/structure/chair/stool/directional/south, -/turf/open/floor/iron, -/area/station/cargo/sorting) "obN" = ( /obj/structure/cable, /obj/effect/spawner/random/maintenance, @@ -40984,16 +41191,6 @@ /obj/machinery/computer/records/security, /turf/open/floor/iron, /area/station/security/brig/entrance) -"ocZ" = ( -/obj/machinery/portable_atmospherics/canister/air, -/obj/effect/turf_decal/bot{ - dir = 1 - }, -/obj/machinery/power/apc/auto_name/directional/west, -/obj/structure/cable, -/obj/machinery/light/small/directional/west, -/turf/open/floor/iron/dark, -/area/station/engineering/atmos/storage) "odh" = ( /obj/effect/landmark/atmospheric_sanity/ignore_area, /turf/open/floor/plating, @@ -41030,12 +41227,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/cargo/storage) -"oem" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 8 - }, -/turf/open/floor/iron/dark, -/area/station/cargo/storage) "oer" = ( /obj/machinery/atmospherics/components/binary/pump{ dir = 4; @@ -41118,6 +41309,15 @@ /obj/structure/cable, /turf/open/floor/iron/dark/small, /area/station/command/heads_quarters/captain/private) +"ogq" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/light/cold/directional/west, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "ogr" = ( /obj/effect/turf_decal/tile/blue{ dir = 1 @@ -41186,15 +41386,6 @@ dir = 1 }, /area/station/hallway/secondary/entry) -"ohb" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/item/reagent_containers/pill, -/obj/item/reagent_containers/pill/maintenance, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "ohf" = ( /obj/structure/reagent_dispensers/fueltank/large, /obj/effect/turf_decal/bot{ @@ -41202,13 +41393,6 @@ }, /turf/open/floor/iron/dark, /area/station/engineering/atmos/storage) -"ohj" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/white/line{ - dir = 4 - }, -/turf/open/floor/iron/dark, -/area/station/cargo/storage) "ohk" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -41278,12 +41462,6 @@ /obj/machinery/light/cold/directional/east, /turf/open/floor/iron/dark/small, /area/station/security/checkpoint/customs) -"ohN" = ( -/obj/item/radio/intercom/directional/north, -/obj/machinery/firealarm/directional/west, -/obj/machinery/vending/cytopro, -/turf/open/floor/iron/white, -/area/station/science/cytology) "oig" = ( /obj/effect/spawner/structure/window/reinforced, /obj/effect/turf_decal/stripes/corner{ @@ -41299,6 +41477,13 @@ /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/plating, /area/station/maintenance/department/electrical) +"oim" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 4 + }, +/obj/structure/sign/warning/no_smoking/directional/east, +/turf/open/floor/iron, +/area/station/cargo/lobby) "ois" = ( /obj/effect/turf_decal/siding/white{ dir = 6 @@ -41308,16 +41493,6 @@ /obj/item/storage/bag/xeno, /turf/open/floor/iron/dark/small, /area/station/science/xenobiology) -"oiw" = ( -/obj/structure/disposalpipe/trunk{ - dir = 1 - }, -/obj/machinery/disposal/bin, -/obj/effect/turf_decal/bot, -/obj/structure/sign/poster/official/random/directional/south, -/obj/structure/extinguisher_cabinet/directional/west, -/turf/open/floor/iron/dark, -/area/station/cargo/office) "oix" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, @@ -41332,13 +41507,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/maintenance/department/medical/central) -"oiL" = ( -/obj/machinery/computer/cargo{ - dir = 1 - }, -/obj/machinery/light_switch/directional/south, -/turf/open/floor/plating, -/area/station/cargo/office) "oiP" = ( /obj/effect/turf_decal/tile/yellow/half/contrasted{ dir = 1 @@ -41836,13 +42004,6 @@ }, /turf/open/floor/iron/cafeteria, /area/station/science/circuits) -"otG" = ( -/obj/structure/filingcabinet/filingcabinet, -/obj/machinery/status_display/supply{ - pixel_y = -32 - }, -/turf/open/floor/iron/dark, -/area/station/cargo/office) "otJ" = ( /obj/structure/disposalpipe/segment, /obj/effect/turf_decal/trimline/neutral/line{ @@ -41976,13 +42137,6 @@ dir = 1 }, /area/station/command/gateway) -"owl" = ( -/obj/effect/turf_decal/stripes/line, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "owm" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -42020,13 +42174,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/aft) -"owM" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 5 - }, -/obj/effect/landmark/event_spawn, -/turf/open/floor/iron/dark, -/area/station/cargo/storage) "owP" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/effect/turf_decal/delivery/white, @@ -42086,13 +42233,20 @@ }, /turf/open/floor/wood/parquet, /area/station/service/library) -"oxw" = ( +"oxt" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 4 + }, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/white/line{ - dir = 9 +/obj/structure/disposalpipe/segment{ + dir = 4 }, -/turf/open/floor/iron/dark, -/area/station/cargo/storage) +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/sorting) "oyn" = ( /obj/structure/disposalpipe/segment, /obj/machinery/door/airlock/public/glass{ @@ -42100,18 +42254,15 @@ }, /turf/open/floor/iron/textured_half, /area/station/maintenance/hallway/abandoned_command) -"oyp" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/machinery/firealarm/directional/west, -/turf/open/floor/iron, -/area/station/hallway/primary/central/fore) "oyq" = ( /obj/machinery/light/warm/directional/south, /turf/open/floor/iron, /area/station/commons/fitness/locker_room) +"oyv" = ( +/obj/machinery/light/small/directional/north, +/obj/effect/landmark/start/cargo_technician, +/turf/open/floor/iron/smooth, +/area/station/cargo/lobby) "oyz" = ( /obj/structure/flora/grass/jungle/b/style_3, /obj/effect/turf_decal/weather/dirt{ @@ -42120,6 +42271,13 @@ /obj/structure/cable, /turf/open/floor/grass, /area/station/service/chapel) +"oyH" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/siding/red, +/obj/structure/disposalpipe/segment, +/turf/open/floor/iron, +/area/station/cargo/storage) "oyQ" = ( /turf/closed/wall, /area/station/science/auxlab/firing_range) @@ -42139,10 +42297,6 @@ /obj/machinery/camera/autoname/directional/west, /turf/open/floor/circuit, /area/station/tcommsat/server) -"oyZ" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron/grimy, -/area/station/command/heads_quarters/qm) "ozn" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -42245,6 +42399,20 @@ }, /turf/open/floor/engine, /area/station/engineering/atmospherics_engine) +"oBO" = ( +/obj/machinery/door/airlock/public/glass/incinerator/atmos_interior, +/obj/effect/mapping_helpers/airlock/locked, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/visible/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible, +/obj/machinery/airlock_controller/incinerator_atmos{ + pixel_x = -40; + pixel_y = -8 + }, +/turf/open/floor/engine, +/area/station/maintenance/disposal/incinerator) "oBP" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -42320,9 +42488,6 @@ /obj/machinery/air_sensor/helium_tank, /turf/open/floor/engine/helium, /area/station/ai_monitored/turret_protected/ai) -"oCG" = ( -/turf/closed/wall/rust, -/area/station/cargo/bitrunning/den) "oCM" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/broken_flooring/pile/directional/east, @@ -42418,6 +42583,15 @@ }, /turf/open/floor/iron/white, /area/station/medical/medbay/central) +"oEL" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/cargo/storage) "oFc" = ( /obj/effect/spawner/random/trash, /obj/machinery/light/small/directional/west, @@ -42433,23 +42607,6 @@ dir = 4 }, /area/station/maintenance/starboard/greater) -"oFi" = ( -/obj/structure/disposalpipe/segment{ - dir = 9 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/conveyor{ - dir = 1; - id = "packageSort2" - }, -/obj/structure/window/spawner/directional/west, -/turf/open/floor/plating, -/area/station/cargo/sorting) "oFu" = ( /turf/closed/wall, /area/station/security/office) @@ -42740,10 +42897,6 @@ }, /turf/open/floor/circuit, /area/station/tcommsat/server) -"oJR" = ( -/obj/structure/disposalpipe/segment, -/turf/open/floor/iron/dark, -/area/station/cargo/office) "oKb" = ( /obj/effect/turf_decal/tile/yellow/half/contrasted{ dir = 8 @@ -42812,6 +42965,12 @@ }, /turf/open/floor/iron/white/small, /area/station/commons/toilet/restrooms) +"oLE" = ( +/obj/structure/chair/stool/directional/west, +/obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/structure/sign/poster/official/random/directional/north, +/turf/open/floor/wood, +/area/station/maintenance/hallway/abandoned_recreation) "oLV" = ( /obj/machinery/camera/autoname/directional/south, /obj/structure/cable, @@ -42871,13 +43030,11 @@ dir = 8 }, /area/station/science/research) -"oNW" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/structure/sign/poster/official/random/directional/north, -/turf/open/floor/iron, -/area/station/hallway/primary/central/aft) +"oNQ" = ( +/obj/item/kirbyplants/random, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/wood, +/area/station/service/chapel/office) "oNX" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -42893,6 +43050,13 @@ /obj/effect/spawner/random/engineering/atmospherics_portable, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) +"oOf" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "oOg" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/light/small/directional/north, @@ -42915,6 +43079,14 @@ }, /turf/open/floor/plating, /area/station/construction/mining/aux_base) +"oOm" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/chair/stool/directional/east, +/obj/effect/decal/cleanable/cobweb, +/obj/structure/sign/poster/official/random/directional/north, +/obj/machinery/light/small/directional/west, +/turf/open/floor/wood, +/area/station/maintenance/hallway/abandoned_recreation) "oOp" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/light/cold/directional/east, @@ -43004,34 +43176,9 @@ /obj/structure/cable, /turf/open/floor/iron/small, /area/station/hallway/secondary/service) -"oPi" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/button/door/directional/east{ - id = "qm_warehouse_aft"; - name = "Warehouse Door Control"; - pixel_x = -24; - pixel_y = -23; - req_access = list("cargo") - }, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "oPj" = ( /turf/open/floor/engine/plasma, /area/station/engineering/atmos) -"oPo" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "oPy" = ( /obj/structure/bookcase/random, /obj/structure/sign/painting/library{ @@ -43112,6 +43259,16 @@ /obj/effect/turf_decal/siding/wideplating, /turf/open/floor/wood, /area/station/engineering/atmos/pumproom) +"oQP" = ( +/obj/effect/turf_decal/trimline/neutral/line{ + dir = 8 + }, +/obj/structure/cable, +/obj/effect/turf_decal/trimline/neutral/line{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "oRj" = ( /obj/effect/turf_decal/siding/yellow{ dir = 8 @@ -43224,16 +43381,6 @@ }, /turf/open/floor/iron, /area/station/cargo/storage) -"oSg" = ( -/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/siding/red/corner, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "oSv" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/machinery/computer/rdconsole{ @@ -43241,12 +43388,12 @@ }, /turf/open/floor/iron/smooth, /area/station/command/bridge) -"oSx" = ( -/obj/effect/turf_decal/siding/red, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/cargo/storage) +"oSB" = ( +/obj/machinery/vending/wardrobe/chap_wardrobe, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/camera/autoname/directional/south, +/turf/open/floor/carpet/lone, +/area/station/service/chapel/office) "oTf" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -43514,10 +43661,6 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/entry) -"oYf" = ( -/obj/machinery/button/ignition/incinerator/atmos, -/turf/closed/wall/r_wall, -/area/station/maintenance/disposal/incinerator) "oYi" = ( /obj/effect/turf_decal/trimline/neutral/line, /obj/effect/turf_decal/trimline/neutral/line{ @@ -43623,6 +43766,18 @@ /obj/machinery/airalarm/directional/north, /turf/open/floor/iron, /area/station/maintenance/department/medical/central) +"oZZ" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/landmark/start/depsec/supply, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 1 + }, +/turf/open/floor/iron/smooth, +/area/station/security/checkpoint/supply) "pan" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -43741,6 +43896,12 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"pbV" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/lobby) "pca" = ( /obj/machinery/door/firedoor, /obj/effect/turf_decal/stripes/red/line{ @@ -43880,17 +44041,10 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/department/engine) -"pep" = ( -/obj/structure/cable, -/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ - cycle_id = "sci-entrance" - }, -/obj/machinery/door/airlock/maintenance{ - name = "Maintenance" - }, -/obj/effect/mapping_helpers/airlock/access/any/supply/maintenance, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) +"peE" = ( +/obj/structure/closet, +/turf/open/floor/iron/smooth, +/area/station/cargo/lobby) "peN" = ( /obj/structure/lattice, /obj/machinery/camera/motion/directional/north{ @@ -44098,21 +44252,6 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/iron/showroomfloor, /area/station/command/corporate_showroom) -"pih" = ( -/obj/structure/disposalpipe/trunk{ - dir = 8 - }, -/obj/structure/window/spawner/directional/west, -/obj/effect/turf_decal/stripes/end, -/obj/structure/disposaloutlet{ - dir = 1 - }, -/obj/machinery/status_display/supply{ - pixel_x = 32 - }, -/obj/machinery/light/cold/directional/east, -/turf/open/floor/plating, -/area/station/cargo/sorting) "pil" = ( /obj/structure/disposalpipe/segment, /obj/machinery/door/airlock{ @@ -44196,23 +44335,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) -"pjG" = ( -/obj/machinery/light_switch/directional/north, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) -"pjL" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/trimline/blue/filled/line{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/obj/effect/turf_decal/arrows{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/sorting) "pjT" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -44363,6 +44485,12 @@ }, /turf/open/floor/iron/smooth_large, /area/station/science/auxlab/firing_range) +"pmD" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/light/small/directional/south, +/obj/effect/turf_decal/tile/red/half/contrasted, +/turf/open/floor/iron/smooth, +/area/station/security/checkpoint/supply) "pmE" = ( /obj/effect/turf_decal/tile/yellow/diagonal_centre, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -44427,11 +44555,6 @@ /obj/structure/flora/bush/jungle/c/style_random, /turf/open/floor/grass, /area/station/service/chapel) -"pnO" = ( -/obj/structure/cable, -/obj/machinery/airalarm/directional/south, -/turf/open/floor/plating, -/area/station/maintenance/disposal/incinerator) "pnQ" = ( /obj/effect/turf_decal/stripes/white/line{ dir = 6 @@ -44514,19 +44637,6 @@ }, /turf/open/floor/iron/dark/small, /area/station/hallway/primary/fore) -"poM" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/conveyor_switch/oneway{ - dir = 8; - id = "QMLoad"; - name = "Loading Conveyor"; - pixel_x = -13; - pixel_y = 19 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "poU" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -44588,6 +44698,16 @@ /obj/effect/spawner/random/engineering/atmospherics_portable, /turf/open/floor/plating, /area/station/maintenance/department/science/xenobiology) +"ppP" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/effect/turf_decal/tile/neutral, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "ppQ" = ( /obj/effect/turf_decal/stripes/box, /obj/machinery/portable_atmospherics/canister/carbon_dioxide, @@ -44619,15 +44739,6 @@ }, /turf/open/floor/iron/dark, /area/station/engineering/atmos/storage) -"pqv" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/spawner/random/trash, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "pqK" = ( /obj/structure/cable, /obj/machinery/door/window/left/directional/south, @@ -44656,10 +44767,6 @@ /obj/item/kirbyplants/random, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) -"prd" = ( -/obj/machinery/light/small/directional/west, -/turf/open/floor/iron/smooth_large, -/area/station/engineering/supermatter/room) "prf" = ( /obj/structure/cable, /obj/effect/spawner/structure/window/reinforced, @@ -44821,6 +44928,10 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/central/greater) +"puk" = ( +/obj/effect/spawner/structure/window, +/turf/open/floor/plating, +/area/station/cargo/lobby) "pus" = ( /obj/effect/turf_decal/box/red/corners, /obj/effect/turf_decal/stripes/white/line{ @@ -44878,16 +44989,6 @@ }, /turf/open/floor/iron/white/side, /area/station/science/research) -"pwJ" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/light/small/directional/north, -/turf/open/floor/iron/smooth, -/area/station/command/heads_quarters/qm) "pwN" = ( /turf/open/floor/iron/dark/small, /area/station/service/chapel/storage) @@ -44959,13 +45060,6 @@ /obj/machinery/light/floor, /turf/open/floor/grass, /area/station/service/chapel) -"pyA" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/plating, -/area/station/maintenance/port/greater) "pyF" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -44983,6 +45077,13 @@ "pzd" = ( /turf/closed/wall, /area/station/commons/fitness/recreation/entertainment) +"pzk" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/landmark/start/hangover, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "pzy" = ( /obj/structure/table, /obj/item/storage/box/prisoner{ @@ -45094,6 +45195,22 @@ /obj/machinery/light/small/directional/west, /turf/open/floor/iron/dark, /area/station/security/interrogation) +"pBo" = ( +/obj/structure/table/wood, +/obj/item/folder/white{ + pixel_x = -3; + pixel_y = 0 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/obj/item/pen{ + pixel_x = -2; + pixel_y = 4 + }, +/obj/structure/sign/poster/official/random/directional/north, +/turf/open/floor/carpet, +/area/station/maintenance/hallway/abandoned_recreation) "pBu" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/tile/neutral{ @@ -45448,28 +45565,11 @@ /obj/structure/alien/weeds, /turf/open/floor/plating, /area/station/maintenance/starboard/greater) -"pHo" = ( -/obj/structure/rack, -/obj/item/storage/medkit/regular, -/turf/open/floor/plating, -/area/station/cargo/storage) "pHq" = ( /obj/machinery/camera/autoname/directional/south, /obj/machinery/firealarm/directional/south, /turf/open/floor/iron, /area/station/hallway/secondary/entry) -"pHs" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/siding/red{ - dir = 4 - }, -/obj/structure/disposalpipe/segment{ - dir = 9 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "pHw" = ( /obj/structure/table, /obj/effect/decal/cleanable/dirt, @@ -45548,30 +45648,16 @@ }, /turf/open/floor/iron/dark/small, /area/station/commons/fitness/locker_room) -"pIi" = ( -/obj/effect/mapping_helpers/broken_floor, -/obj/structure/rack, -/obj/item/clothing/ears/earmuffs{ - pixel_x = -3; - pixel_y = -2 - }, -/obj/item/clothing/ears/earmuffs{ - pixel_x = -8; - pixel_y = 11 - }, -/obj/item/clothing/ears/earmuffs{ - pixel_x = 4; - pixel_y = 6 - }, -/obj/item/pickaxe, -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/white/corner{ - dir = 8 +"pIg" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/disposalpipe/segment{ + dir = 4 }, -/turf/open/floor/plating, -/area/station/cargo/miningfoundry) +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/cargo/storage) "pIn" = ( /obj/structure/disposalpipe/segment{ dir = 5 @@ -45581,6 +45667,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/maintenance/hallway/abandoned_command) +"pIo" = ( +/obj/machinery/computer/order_console/bitrunning{ + dir = 8 + }, +/turf/open/floor/iron/dark/smooth_large, +/area/station/cargo/bitrunning/den) "pIp" = ( /obj/machinery/light/small/directional/west, /obj/effect/turf_decal/stripes/white/line{ @@ -45627,12 +45719,6 @@ /obj/effect/landmark/start/cargo_technician, /turf/open/floor/iron, /area/station/cargo/storage) -"pJn" = ( -/obj/machinery/light/small/directional/south, -/turf/open/floor/iron/stairs{ - dir = 8 - }, -/area/station/cargo/storage) "pJr" = ( /obj/machinery/portable_atmospherics/canister, /turf/open/floor/plating, @@ -45667,13 +45753,6 @@ /obj/machinery/firealarm/directional/west, /turf/open/floor/iron/showroomfloor, /area/station/commons/toilet/auxiliary) -"pJQ" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/effect/mapping_helpers/broken_floor, -/obj/structure/steam_vent, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "pKi" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/security{ @@ -45845,6 +45924,26 @@ }, /turf/open/floor/plating, /area/station/engineering/gravity_generator) +"pMX" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/wood, +/area/station/service/chapel/office) +"pNa" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 1 + }, +/obj/effect/turf_decal/arrows{ + dir = 1 + }, +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown/half/contrasted, +/turf/open/floor/iron/dark/side{ + dir = 1 + }, +/area/station/cargo/sorting) "pNh" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -45892,18 +45991,6 @@ }, /turf/closed/wall, /area/station/commons/fitness/locker_room) -"pOg" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/obj/machinery/holopad, -/turf/open/floor/iron, -/area/station/cargo/office) "pOi" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -46021,16 +46108,6 @@ /obj/effect/spawner/random/engineering/tracking_beacon, /turf/open/floor/engine, /area/station/science/xenobiology) -"pPx" = ( -/obj/structure/disposalpipe/trunk{ - dir = 1 - }, -/obj/machinery/disposal/bin, -/obj/machinery/light/small/directional/south, -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable, -/turf/open/floor/carpet/lone, -/area/station/service/chapel/office) "pPK" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -46143,6 +46220,10 @@ /obj/effect/mapping_helpers/airlock/access/any/security/general, /turf/open/floor/iron/textured_half, /area/station/security/checkpoint/customs/auxiliary) +"pRO" = ( +/obj/structure/filingcabinet/chestdrawer, +/turf/open/floor/iron/smooth, +/area/station/cargo/lobby) "pRQ" = ( /obj/effect/turf_decal/tile/blue/half/contrasted, /turf/open/floor/iron/white, @@ -46190,15 +46271,6 @@ }, /turf/open/floor/plating, /area/station/science/ordnance/testlab) -"pSI" = ( -/obj/machinery/door/morgue{ - name = "Private Study"; - req_access = list("library") - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/catwalk_floor/iron_dark, -/area/station/maintenance/central/greater) "pSN" = ( /obj/item/radio/intercom/directional/south, /obj/machinery/holopad, @@ -46260,6 +46332,12 @@ /obj/effect/decal/cleanable/cobweb/cobweb2, /turf/open/floor/iron, /area/station/commons/fitness/recreation/entertainment) +"pTK" = ( +/obj/machinery/atmospherics/pipe/layer_manifold/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/station/maintenance/department/engine/atmos) "pTZ" = ( /obj/effect/turf_decal/siding/wideplating/dark{ dir = 8 @@ -46282,6 +46360,7 @@ /obj/machinery/door/airlock/engineering/glass{ name = "Engineering Foyer" }, +/obj/effect/mapping_helpers/airlock/access/any/engineering/general, /turf/open/floor/catwalk_floor, /area/station/engineering/break_room) "pUx" = ( @@ -46397,6 +46476,12 @@ }, /turf/open/floor/iron/dark/side, /area/station/science/xenobiology) +"pVV" = ( +/obj/machinery/camera/autoname/directional/west, +/turf/open/floor/iron/stairs{ + dir = 1 + }, +/area/station/cargo/lobby) "pWl" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -46633,10 +46718,11 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) -"pZu" = ( -/obj/structure/hedge, -/turf/open/floor/plating, -/area/station/cargo/storage) +"pZt" = ( +/obj/structure/chair/stool/directional/west, +/obj/structure/cable, +/turf/open/floor/wood, +/area/station/command/heads_quarters/qm) "pZv" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/tile/neutral{ @@ -46647,18 +46733,22 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) -"pZz" = ( -/obj/structure/rack, -/obj/item/clothing/gloves/cargo_gauntlet{ - pixel_y = -3 +"pZC" = ( +/obj/structure/table/wood, +/obj/item/folder{ + pixel_x = 1; + pixel_y = 4 }, -/obj/item/clothing/gloves/cargo_gauntlet, -/obj/item/clothing/gloves/cargo_gauntlet{ - pixel_y = 3 +/obj/effect/turf_decal/siding/wood{ + dir = 9 }, -/obj/machinery/airalarm/directional/south, -/turf/open/floor/plating, -/area/station/cargo/storage) +/obj/item/pen{ + pixel_x = -2; + pixel_y = 4 + }, +/obj/structure/sign/poster/official/tactical_game_cards/directional/north, +/turf/open/floor/carpet, +/area/station/maintenance/hallway/abandoned_recreation) "pZK" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -47034,15 +47124,17 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/white/small, /area/station/commons/toilet/restrooms) -"qgK" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 +"qgX" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 }, -/obj/item/kirbyplants/random, -/obj/machinery/firealarm/directional/south, -/obj/item/storage/belt/utility, -/turf/open/floor/iron/smooth, -/area/station/commons/storage/tools) +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) +"qgZ" = ( +/turf/open/floor/carpet/lone, +/area/station/service/chapel/office) "qhh" = ( /obj/structure/cable, /obj/structure/table/glass, @@ -47061,16 +47153,6 @@ /obj/machinery/power/apc/auto_name/directional/north, /turf/open/floor/iron/white, /area/station/science/cytology) -"qht" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 1; - name = "CO2 to Pure" - }, -/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/engineering/atmos) "qhD" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -47100,6 +47182,15 @@ }, /turf/open/floor/iron/dark/diagonal, /area/station/service/bar) +"qhU" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/structure/cable, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/effect/turf_decal/siding/wood/corner, +/turf/open/floor/carpet/red, +/area/station/command/heads_quarters/qm) "qhV" = ( /obj/structure/table, /obj/machinery/fax{ @@ -47199,11 +47290,6 @@ }, /turf/open/floor/iron/cafeteria, /area/station/hallway/secondary/exit/departure_lounge) -"qjn" = ( -/obj/effect/mapping_helpers/broken_floor, -/obj/structure/table, -/turf/open/floor/plating, -/area/station/maintenance/port/greater) "qjp" = ( /obj/machinery/power/apc/auto_name/directional/north, /obj/structure/cable, @@ -47293,6 +47379,13 @@ /obj/machinery/power/terminal, /turf/open/floor/iron/smooth_large, /area/station/engineering/supermatter/room) +"qkC" = ( +/obj/item/kirbyplants/random, +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/office) "qkK" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -47368,7 +47461,7 @@ /obj/machinery/door/airlock/maintenance{ name = "Atmospherics Maintenance" }, -/obj/effect/mapping_helpers/airlock/access/any/engineering/construction, +/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance, /turf/open/floor/plating, /area/station/maintenance/department/engine/atmos) "qmz" = ( @@ -47443,6 +47536,16 @@ /obj/machinery/airalarm/directional/east, /turf/open/floor/iron/white/small, /area/station/science/ordnance/storage) +"qnU" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/turf/open/floor/carpet/red, +/area/station/command/heads_quarters/qm) "qoj" = ( /obj/structure/disposalpipe/segment, /obj/machinery/door/window/right/directional/west{ @@ -47527,6 +47630,19 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/department/science/xenobiology) +"qqB" = ( +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=8"; + location = "QM #2" + }, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/storage) "qqC" = ( /obj/structure/chair/comfy/carp{ dir = 1 @@ -47565,6 +47681,15 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/science/xenobiology) +"qrJ" = ( +/obj/structure/cable, +/turf/open/floor/iron/smooth, +/area/station/cargo/miningfoundry) +"qrW" = ( +/obj/machinery/portable_atmospherics/canister/plasma, +/obj/machinery/atmospherics/pipe/smart/simple/yellow/visible, +/turf/open/floor/engine/plasma, +/area/station/engineering/atmos) "qsg" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/power/terminal, @@ -47620,15 +47745,6 @@ "qtd" = ( /turf/open/floor/wood/tile, /area/station/command/corporate_showroom) -"qto" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 8 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, -/obj/structure/extinguisher_cabinet/directional/west, -/turf/open/floor/iron, -/area/station/cargo/sorting) "qtE" = ( /obj/structure/bed{ dir = 4 @@ -47653,18 +47769,16 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/fore/lesser) -"qul" = ( -/obj/machinery/light/small/directional/east, -/obj/machinery/light_switch/directional/east, -/obj/effect/mapping_helpers/turn_off_lights_with_lightswitch, -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/white/corner{ - dir = 4 +"qtW" = ( +/obj/machinery/door/morgue{ + name = "Private Study"; + req_access = list("library") }, -/turf/open/floor/iron/smooth, -/area/station/cargo/warehouse) +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/maintenance/central/greater) "quq" = ( /obj/effect/turf_decal/stripes/line, /obj/structure/closet/crate/cardboard, @@ -47830,15 +47944,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/tcommsat/server) -"qxF" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable, -/turf/open/floor/plating/elevatorshaft, -/area/station/engineering/break_room) "qxN" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -48168,6 +48273,34 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/iron/dark, /area/station/science/xenobiology) +"qCG" = ( +/obj/effect/turf_decal/siding/white{ + dir = 9 + }, +/obj/structure/table, +/obj/structure/railing{ + dir = 9 + }, +/obj/effect/turf_decal/tile/brown/half/contrasted, +/obj/item/radio{ + desc = "An old handheld radio. You could use it, if you really wanted to."; + icon_state = "radio"; + name = "old radio"; + pixel_x = -4; + pixel_y = 10 + }, +/obj/item/reagent_containers/cup/glass/coffee{ + pixel_x = 15; + pixel_y = 8 + }, +/obj/effect/spawner/random/food_or_drink/donuts{ + pixel_x = 8; + pixel_y = 0 + }, +/turf/open/floor/iron/dark/side{ + dir = 1 + }, +/area/station/cargo/lobby) "qCJ" = ( /obj/structure/cable, /obj/effect/turf_decal/siding/wood{ @@ -48320,11 +48453,6 @@ }, /turf/open/misc/sandy_dirt, /area/station/security/tram) -"qDP" = ( -/obj/structure/chair/stool/directional/north, -/obj/effect/landmark/event_spawn, -/turf/open/floor/iron, -/area/station/cargo/sorting) "qEe" = ( /turf/open/floor/iron/white/side{ dir = 8 @@ -48752,24 +48880,32 @@ /obj/machinery/camera/autoname/directional/north, /turf/open/floor/iron, /area/station/security/courtroom) -"qMw" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/landmark/navigate_destination/chapel, -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/hallway/primary/port) "qMG" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/structure/cable, /turf/open/floor/iron/small, /area/station/maintenance/department/electrical) +"qMI" = ( +/obj/effect/landmark/event_spawn, +/obj/effect/turf_decal/stripes/white/corner{ + dir = 4 + }, +/turf/open/floor/iron/dark/corner{ + dir = 4 + }, +/area/station/cargo/storage) "qMK" = ( /turf/closed/wall, /area/station/command/bridge) +"qMM" = ( +/obj/machinery/firealarm/directional/south, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/cargo/storage) "qMP" = ( /obj/structure/closet/firecloset, /obj/structure/sign/poster/official/random/directional/north, @@ -48940,13 +49076,6 @@ dir = 1 }, /area/station/science/lower) -"qQP" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "qQR" = ( /obj/structure/table/wood, /obj/machinery/light/small/directional/south, @@ -48978,9 +49107,6 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron, /area/station/hallway/secondary/dock) -"qRq" = ( -/turf/closed/wall/rust, -/area/station/security/checkpoint/supply) "qRs" = ( /obj/structure/chair/stool/directional/north, /obj/machinery/light/small/directional/south, @@ -49061,27 +49187,17 @@ /obj/machinery/portable_atmospherics/canister/nitrogen, /turf/open/floor/iron/smooth_large, /area/station/science/ordnance/storage) +"qSF" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable, +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "qSH" = ( /obj/effect/turf_decal/bot_white, /obj/effect/spawner/random/structure/crate, /turf/open/floor/iron/smooth_large, /area/station/cargo/warehouse) -"qSS" = ( -/obj/structure/table/reinforced, -/obj/effect/turf_decal/tile/red/fourcorners, -/obj/item/paper_bin{ - pixel_x = 1; - pixel_y = 9 - }, -/obj/item/pen{ - pixel_x = 1; - pixel_y = 9 - }, -/obj/item/book/manual/wiki/security_space_law, -/obj/item/radio/intercom/directional/east, -/obj/machinery/camera/autoname/directional/south, -/turf/open/floor/iron/smooth, -/area/station/security/checkpoint/supply) "qSZ" = ( /obj/structure/hedge, /obj/machinery/light/cold/directional/west, @@ -49153,6 +49269,11 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/wood, /area/station/cargo/boutique) +"qTS" = ( +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/loading_area, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "qUa" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -49519,6 +49640,17 @@ /obj/effect/mapping_helpers/airlock/cyclelink_helper, /turf/open/floor/iron/dark/small, /area/station/security/tram) +"qYq" = ( +/obj/machinery/door/airlock/wood{ + desc = "Sessions held every Friday."; + name = "The Sunfinder Society" + }, +/obj/effect/mapping_helpers/airlock/access/any/service/maintenance, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/plating, +/area/station/maintenance/port/greater) "qYr" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -49568,6 +49700,12 @@ /obj/structure/cable, /turf/open/floor/iron/smooth, /area/station/engineering/main) +"qYG" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "qYK" = ( /obj/structure/disposalpipe/trunk, /obj/structure/window/reinforced/spawner/directional/west, @@ -49660,6 +49798,26 @@ }, /turf/open/floor/iron/smooth_large, /area/station/science/ordnance/storage) +"qZX" = ( +/obj/effect/decal/cleanable/molten_object, +/obj/effect/landmark/event_spawn, +/obj/structure/table, +/obj/item/reagent_containers/cup/bottle/welding_fuel{ + pixel_y = -3; + pixel_x = 13 + }, +/obj/item/stack/sheet/iron/ten{ + pixel_y = -6; + pixel_x = -2 + }, +/obj/item/hand_labeler{ + pixel_y = -15 + }, +/obj/item/reagent_containers/cup/watering_can{ + pixel_y = 12 + }, +/turf/open/floor/iron/dark, +/area/station/commons/storage/tools) "raf" = ( /obj/structure/reagent_dispensers/water_cooler, /obj/effect/turf_decal/tile/dark_red/opposingcorners, @@ -49764,6 +49922,14 @@ }, /turf/open/floor/iron/white, /area/station/medical/treatment_center) +"rbT" = ( +/obj/effect/landmark/navigate_destination/cargo, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "rbW" = ( /obj/machinery/door/airlock{ name = "Maintenance" @@ -49923,6 +50089,24 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/recreation) +"rev" = ( +/obj/machinery/requests_console/directional/south{ + department = "Security"; + name = "Security Requests Console" + }, +/obj/effect/turf_decal/tile/red/anticorner/contrasted{ + dir = 8 + }, +/obj/structure/table/reinforced, +/obj/item/radio/off{ + pixel_x = -6 + }, +/obj/machinery/recharger{ + pixel_x = 5; + pixel_y = 4 + }, +/turf/open/floor/iron/smooth, +/area/station/security/checkpoint/supply) "rex" = ( /obj/effect/turf_decal/tile/neutral/full, /obj/effect/decal/cleanable/dirt, @@ -50022,6 +50206,11 @@ /obj/item/radio/intercom/directional/west, /turf/open/floor/glass, /area/station/command/heads_quarters/rd) +"rfP" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/cargo/storage) "rfT" = ( /obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible{ dir = 5 @@ -50125,6 +50314,12 @@ /obj/structure/chair/office, /turf/open/floor/iron/smooth, /area/station/cargo/drone_bay) +"rhF" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/lobby) "rhH" = ( /obj/effect/turf_decal/tile/blue, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -50140,15 +50335,6 @@ /obj/machinery/power/apc/auto_name/directional/north, /turf/open/floor/iron/grimy, /area/station/commons/vacant_room/office) -"rie" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/start/cargo_technician, -/turf/open/floor/iron/smooth, -/area/station/cargo/warehouse) -"rif" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron/smooth, -/area/station/cargo/warehouse) "rig" = ( /obj/machinery/door/poddoor/massdriver_chapel, /turf/open/floor/plating, @@ -50329,6 +50515,14 @@ /obj/machinery/camera/autoname/directional/north, /turf/open/floor/iron/dark, /area/station/science/ordnance/testlab) +"rmc" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted, +/obj/structure/disposalpipe/segment, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/cargo/sorting) "rmk" = ( /obj/effect/turf_decal/weather/dirt, /obj/structure/flora/bush/jungle/c/style_3{ @@ -50391,13 +50585,6 @@ /obj/structure/thermoplastic/light, /turf/open/floor/tram, /area/station/maintenance/port/aft) -"roi" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "roq" = ( /obj/effect/turf_decal/sand/plating, /turf/open/floor/wood/tile, @@ -50504,9 +50691,6 @@ }, /turf/open/floor/iron/dark, /area/station/security/office) -"rqq" = ( -/turf/open/floor/catwalk_floor/iron_dark, -/area/station/cargo/office) "rqt" = ( /obj/machinery/airalarm/directional/north, /obj/effect/decal/cleanable/dirt, @@ -50552,10 +50736,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/commons/fitness/locker_room) -"rrq" = ( -/obj/structure/closet, -/turf/open/floor/plating, -/area/station/cargo/office) "rrt" = ( /obj/effect/spawner/structure/window/reinforced/tinted, /turf/open/floor/plating, @@ -50569,6 +50749,12 @@ }, /turf/open/floor/iron/small, /area/station/engineering/atmos/pumproom) +"rrJ" = ( +/obj/structure/filingcabinet/filingcabinet, +/obj/machinery/power/apc/auto_name/directional/west, +/obj/structure/cable, +/turf/open/floor/wood, +/area/station/maintenance/hallway/abandoned_recreation) "rrQ" = ( /obj/item/kirbyplants/random/fullysynthetic, /obj/effect/turf_decal/tile/dark_red/half/contrasted, @@ -50679,6 +50865,17 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron/small, /area/station/ai_monitored/command/storage/eva) +"rtH" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/stripes/white/line{ + dir = 8 + }, +/turf/open/floor/iron/dark/side{ + dir = 8 + }, +/area/station/cargo/storage) "rtI" = ( /turf/open/floor/iron/white/corner{ dir = 8 @@ -50761,14 +50958,6 @@ "ruD" = ( /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) -"ruR" = ( -/obj/machinery/door/airlock/engineering{ - name = "Engine Airlock" - }, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/any/engineering/general, -/turf/open/floor/plating, -/area/station/engineering/supermatter/room) "ruS" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -51040,6 +51229,16 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/iron, /area/station/hallway/primary/central/aft) +"ryX" = ( +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=8"; + location = "QM #1" + }, +/obj/effect/turf_decal/delivery, +/mob/living/simple_animal/bot/mulebot, +/obj/machinery/camera/autoname/directional/south, +/turf/open/floor/iron, +/area/station/cargo/storage) "rza" = ( /obj/structure/disposalpipe/junction{ dir = 1 @@ -51089,15 +51288,17 @@ dir = 1 }, /area/station/hallway/secondary/entry) -"rzL" = ( -/obj/structure/sign/poster/random/directional/south, -/obj/machinery/conveyor{ - id = "mining"; - dir = 10 +"rzX" = ( +/obj/structure/hedge, +/obj/machinery/status_display/supply{ + pixel_y = -32 }, -/obj/machinery/bouldertech/refinery, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) +/obj/machinery/light/small/directional/south, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/floor/iron/smooth, +/area/station/cargo/storage) "rzZ" = ( /obj/effect/spawner/random/structure/crate, /obj/effect/spawner/random/maintenance, @@ -51168,10 +51369,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/science/ordnance/testlab) -"rBh" = ( -/obj/effect/turf_decal/tile/brown/fourcorners, -/turf/open/floor/iron, -/area/station/hallway/primary/central/fore) "rBq" = ( /obj/structure/cable, /obj/structure/table/reinforced, @@ -51256,18 +51453,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/carpet/lone, /area/station/service/abandoned_gambling_den) -"rDc" = ( -/obj/structure/table/reinforced, -/obj/effect/turf_decal/siding/yellow{ - dir = 4 - }, -/obj/effect/spawner/random/food_or_drink/donkpockets{ - pixel_y = 6 - }, -/obj/structure/disposalpipe/segment, -/obj/structure/cable, -/turf/open/floor/wood, -/area/station/engineering/break_room) "rDj" = ( /obj/structure/chair/sofa/bench/left{ dir = 8 @@ -51278,6 +51463,14 @@ dir = 4 }, /area/station/hallway/secondary/entry) +"rDs" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "Filing Room" + }, +/obj/effect/mapping_helpers/airlock/access/all/supply/general, +/obj/structure/cable, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/cargo/lobby) "rDv" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/light/cold/directional/west, @@ -51357,6 +51550,11 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"rEV" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/security/prison/garden) "rEW" = ( /obj/effect/turf_decal/tile/neutral{ dir = 4 @@ -51377,25 +51575,6 @@ dir = 1 }, /area/station/command/heads_quarters/hop) -"rFa" = ( -/obj/structure/disposalpipe/trunk{ - dir = 2 - }, -/obj/machinery/disposal/delivery_chute{ - name = "Service Deliveries" - }, -/obj/structure/sign/departments/botany/directional/north, -/obj/effect/turf_decal/tile/green/fourcorners, -/obj/structure/plasticflaps{ - name = "Service Deliveries" - }, -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, -/obj/effect/turf_decal/delivery/white, -/obj/effect/decal/cleanable/cobweb, -/turf/open/floor/iron, -/area/station/cargo/sorting) "rFb" = ( /obj/machinery/atmospherics/pipe/smart/simple/orange/hidden, /obj/effect/turf_decal/tile/yellow, @@ -51408,6 +51587,12 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"rFm" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "rFn" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/tile/neutral, @@ -51425,6 +51610,17 @@ dir = 4 }, /area/station/science/ordnance/testlab) +"rFv" = ( +/obj/structure/railing{ + dir = 1 + }, +/obj/structure/railing, +/obj/structure/hedge, +/obj/effect/turf_decal/siding/thinplating_new/end{ + dir = 4 + }, +/turf/open/floor/iron/dark, +/area/station/cargo/storage) "rFy" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/trimline/blue/filled/line{ @@ -51456,41 +51652,16 @@ dir = 6 }, /area/station/science/research) -"rFP" = ( -/obj/structure/disposalpipe/trunk{ - dir = 2 - }, -/obj/machinery/disposal/delivery_chute{ - name = "Security Deliveries" - }, -/obj/structure/sign/departments/security/directional/north, -/obj/effect/turf_decal/tile/red/fourcorners, -/obj/structure/plasticflaps{ - name = "Security Deliveries" - }, -/obj/effect/turf_decal/delivery/white, -/turf/open/floor/iron, -/area/station/cargo/sorting) +"rFU" = ( +/obj/structure/table/wood, +/obj/item/paper_bin, +/obj/item/pen, +/turf/open/floor/carpet/lone, +/area/station/service/chapel/office) "rFV" = ( /obj/effect/turf_decal/trimline/blue/filled/corner, /turf/open/floor/iron/white, /area/station/medical/treatment_center) -"rFW" = ( -/obj/structure/disposalpipe/trunk{ - dir = 1 - }, -/obj/machinery/disposal/delivery_chute{ - name = "Engineering Deliveries" - }, -/obj/structure/sign/departments/engineering/directional/north, -/obj/effect/turf_decal/tile/yellow/fourcorners, -/obj/structure/plasticflaps{ - name = "Engineering Deliveries" - }, -/obj/effect/turf_decal/delivery/white, -/obj/machinery/light/cold/directional/north, -/turf/open/floor/iron, -/area/station/cargo/sorting) "rGp" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -51501,19 +51672,6 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron/white/small, /area/station/science/ordnance/storage) -"rGq" = ( -/obj/structure/disposalpipe/trunk, -/obj/machinery/disposal/delivery_chute{ - name = "Science Deliveries" - }, -/obj/structure/sign/departments/science/directional/north, -/obj/effect/turf_decal/tile/purple/fourcorners, -/obj/structure/plasticflaps{ - name = "Science Deliveries" - }, -/obj/effect/turf_decal/delivery/white, -/turf/open/floor/iron, -/area/station/cargo/sorting) "rGB" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -51530,10 +51688,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/virology) -"rGN" = ( -/obj/effect/spawner/random/structure/crate, -/turf/open/floor/plating, -/area/station/maintenance/port/greater) "rGO" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt, @@ -51661,6 +51815,30 @@ }, /turf/open/floor/grass, /area/station/science/xenobiology) +"rJB" = ( +/obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/photocopier, +/turf/open/floor/iron/smooth, +/area/station/command/heads_quarters/qm) +"rJL" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/cargo/sorting) +"rJQ" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/storage) "rJW" = ( /obj/machinery/suit_storage_unit/hos, /obj/effect/decal/cleanable/dirt, @@ -51674,6 +51852,11 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"rKn" = ( +/obj/structure/cable, +/obj/item/banner/cargo, +/turf/open/floor/iron/smooth, +/area/station/command/heads_quarters/qm) "rKv" = ( /obj/structure/broken_flooring/singular/directional/east, /turf/open/floor/iron, @@ -51719,6 +51902,13 @@ }, /turf/open/floor/engine, /area/station/science/explab) +"rLp" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "rLr" = ( /obj/machinery/door/poddoor/incinerator_ordmix, /turf/open/floor/engine/vacuum, @@ -51974,6 +52164,15 @@ }, /turf/open/floor/plating, /area/station/maintenance/port/lesser) +"rPM" = ( +/obj/effect/landmark/start/cargo_technician, +/obj/effect/turf_decal/stripes/white/line{ + dir = 4 + }, +/turf/open/floor/iron/dark/side{ + dir = 4 + }, +/area/station/cargo/storage) "rPT" = ( /obj/structure/chair/stool/bar/directional/east, /obj/effect/turf_decal/siding/red/corner{ @@ -52071,6 +52270,17 @@ dir = 1 }, /area/station/security/courtroom) +"rRl" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/chair/stool/directional/east, +/obj/effect/landmark/start/quartermaster, +/obj/structure/cable, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/floor/carpet/red, +/area/station/command/heads_quarters/qm) "rRq" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/dark_red/opposingcorners, @@ -52149,6 +52359,15 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/wood/tile, /area/station/command/corporate_showroom) +"rSM" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/plating, +/area/station/maintenance/port/greater) "rST" = ( /turf/closed/wall, /area/station/cargo/storage) @@ -52191,20 +52410,6 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/recreation) -"rTD" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/trimline/green/filled/line{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/obj/effect/turf_decal/arrows{ - dir = 1 - }, -/obj/item/radio/intercom/directional/west, -/turf/open/floor/iron, -/area/station/cargo/sorting) "rTJ" = ( /obj/effect/turf_decal/trimline/blue/filled/corner{ dir = 4 @@ -52216,17 +52421,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/treatment_center) -"rTU" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/trimline/red/filled/line{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/arrows{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/sorting) "rUb" = ( /obj/structure/hedge, /obj/machinery/status_display/evac/directional/east, @@ -52250,17 +52444,6 @@ /obj/item/assembly/mousetrap/armed, /turf/open/floor/stone, /area/station/service/abandoned_gambling_den) -"rUt" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/trimline/purple/filled/line{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/arrows{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/sorting) "rUI" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -52356,15 +52539,6 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) -"rVQ" = ( -/obj/structure/disposalpipe/trunk, -/obj/structure/window/spawner/directional/west, -/obj/effect/turf_decal/stripes/end{ - dir = 1 - }, -/obj/machinery/disposal/delivery_chute, -/turf/open/floor/plating, -/area/station/cargo/sorting) "rVT" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -52372,6 +52546,11 @@ }, /turf/open/floor/iron/dark, /area/station/security/processing) +"rWa" = ( +/obj/structure/closet, +/obj/machinery/camera/autoname/directional/east, +/turf/open/floor/iron/smooth, +/area/station/cargo/lobby) "rWm" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -52419,6 +52598,13 @@ /obj/item/radio/intercom/directional/south, /turf/open/floor/iron/grimy, /area/station/command/heads_quarters/ce) +"rWK" = ( +/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/siding/red/corner, +/turf/open/floor/iron, +/area/station/cargo/storage) "rWM" = ( /obj/structure/table, /obj/item/exodrone{ @@ -52453,6 +52639,19 @@ dir = 1 }, /area/station/cargo/bitrunning/den) +"rWR" = ( +/obj/structure/disposalpipe/trunk, +/obj/machinery/disposal/delivery_chute{ + name = "Science Deliveries" + }, +/obj/structure/sign/departments/science/directional/north, +/obj/effect/turf_decal/tile/purple/fourcorners, +/obj/structure/plasticflaps{ + name = "Science Deliveries" + }, +/obj/effect/turf_decal/delivery/white, +/turf/open/floor/iron/dark/side, +/area/station/cargo/sorting) "rWU" = ( /obj/structure/rack, /obj/effect/spawner/random/maintenance, @@ -52526,13 +52725,6 @@ /obj/structure/flora/bush/flowers_yw/style_3, /turf/open/floor/grass, /area/station/service/chapel) -"rYt" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/obj/item/kirbyplants/random, -/turf/open/floor/iron/white, -/area/station/science/cytology) "rYx" = ( /obj/effect/turf_decal/siding/wideplating/dark, /obj/structure/cable, @@ -52572,10 +52764,6 @@ }, /turf/open/floor/iron, /area/station/medical/chemistry) -"rZe" = ( -/obj/structure/railing/corner/end/flip, -/turf/open/floor/plating, -/area/station/cargo/miningfoundry) "rZi" = ( /obj/structure/cable, /obj/machinery/power/solar{ @@ -52654,15 +52842,6 @@ }, /turf/open/floor/engine/plasma, /area/station/engineering/atmos) -"sar" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/machinery/camera/autoname/directional/west, -/obj/machinery/firealarm/directional/west, -/turf/open/floor/iron, -/area/station/hallway/primary/central/fore) "sas" = ( /obj/effect/turf_decal/siding/wood, /turf/open/floor/carpet/blue, @@ -52919,6 +53098,14 @@ dir = 8 }, /area/station/engineering/main) +"sfL" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 8 + }, +/obj/structure/extinguisher_cabinet/directional/west, +/turf/open/floor/iron, +/area/station/cargo/sorting) "sge" = ( /obj/structure/reagent_dispensers/beerkeg, /obj/item/clothing/head/costume/festive, @@ -52936,42 +53123,12 @@ /obj/machinery/light/small/directional/west, /turf/open/floor/iron/showroomfloor, /area/station/commons/toilet/auxiliary) -"sgC" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) -"sgL" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/door/airlock/mining/glass{ - name = "Cargo Bay" - }, -/obj/effect/mapping_helpers/airlock/access/all/supply/general, -/obj/machinery/door/firedoor, -/turf/open/floor/iron, -/area/station/cargo/storage) "sgO" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark/smooth_edge{ dir = 1 }, /area/station/maintenance/starboard/greater) -"sgR" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/sorting) "sgY" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, @@ -53047,6 +53204,18 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white/corner, /area/station/science/xenobiology) +"sjn" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/structure/chair/comfy/brown{ + buildstackamount = 0; + color = "#c45c57"; + dir = 8 + }, +/turf/open/floor/iron/grimy, +/area/station/service/library/private) "sjp" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt, @@ -53092,6 +53261,11 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"sjX" = ( +/obj/item/radio/intercom/directional/east, +/obj/machinery/light/warm/directional/east, +/turf/open/floor/iron, +/area/station/cargo/storage) "sjY" = ( /obj/machinery/atmospherics/pipe/layer_manifold/purple/visible{ dir = 4 @@ -53173,13 +53347,6 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/station/science/genetics) -"skW" = ( -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/effect/spawner/random/structure/crate, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "slp" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -53233,16 +53400,6 @@ "slY" = ( /turf/closed/wall, /area/station/maintenance/port/fore) -"slZ" = ( -/obj/structure/closet/secure_closet/detective, -/obj/machinery/requests_console/directional/north{ - department = "Detective's Office"; - name = "Detective Requests Console" - }, -/obj/machinery/light/small/directional/west, -/obj/structure/detectiveboard/directional/west, -/turf/open/floor/wood, -/area/station/security/detectives_office) "smf" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -53429,14 +53586,6 @@ }, /turf/open/floor/grass, /area/station/service/chapel) -"spo" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/structure/extinguisher_cabinet/directional/north, -/turf/open/floor/iron, -/area/station/hallway/primary/port) "spx" = ( /obj/machinery/portable_atmospherics/canister/anesthetic_mix, /obj/machinery/atmospherics/components/unary/portables_connector/visible, @@ -53444,6 +53593,23 @@ /obj/machinery/airalarm/directional/north, /turf/open/floor/iron/white/small, /area/station/medical/cryo) +"spA" = ( +/obj/structure/table, +/obj/machinery/light/warm/directional/south, +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/obj/effect/spawner/random/food_or_drink/snack/lizard{ + pixel_x = 9; + pixel_y = 3 + }, +/obj/effect/spawner/random/food_or_drink/refreshing_beverage{ + pixel_x = -5; + pixel_y = 7 + }, +/obj/structure/sign/poster/official/random/directional/south, +/turf/open/floor/iron, +/area/station/cargo/office) "spH" = ( /obj/machinery/door/firedoor, /turf/open/floor/iron/small, @@ -53554,9 +53720,6 @@ /obj/structure/disposalpipe/segment, /turf/closed/wall, /area/station/maintenance/port/greater) -"srw" = ( -/turf/closed/wall/r_wall/rust, -/area/station/maintenance/department/electrical) "srx" = ( /obj/machinery/power/port_gen/pacman, /obj/effect/turf_decal/bot{ @@ -53923,17 +54086,6 @@ /obj/machinery/camera/directional/north, /turf/open/floor/grass, /area/station/service/chapel) -"swO" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/window/spawner/directional/east, -/obj/structure/window/spawner/directional/north, -/mob/living/basic/chick/permanent{ - name = "Morgan" - }, -/turf/open/floor/grass, -/area/station/cargo/storage) "swT" = ( /obj/machinery/door/airlock/maintenance_hatch{ name = "Engineering Maintenance" @@ -53948,21 +54100,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/department/engine) -"swV" = ( -/obj/effect/mapping_helpers/broken_floor, -/obj/structure/table/wood, -/obj/item/hand_labeler_refill{ - pixel_x = -4; - pixel_y = 26 - }, -/obj/structure/sign/poster/official/random/directional/south, -/obj/machinery/fax{ - fax_name = "Quartermaster's Office"; - name = "Quartermaster's Fax Machine"; - pixel_y = 7 - }, -/turf/open/floor/wood, -/area/station/command/heads_quarters/qm) "swW" = ( /obj/effect/turf_decal/siding/wood, /obj/effect/turf_decal/siding/wood{ @@ -54014,6 +54151,16 @@ /obj/structure/lattice, /turf/open/space/basic, /area/space/nearstation) +"sxQ" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/holopad, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/lobby) "sxT" = ( /obj/structure/cable, /obj/structure/lattice/catwalk, @@ -54064,15 +54211,6 @@ "syk" = ( /turf/closed/wall, /area/station/security/warden) -"syx" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "syA" = ( /obj/machinery/door/airlock/public/glass{ name = "Dorms" @@ -54116,23 +54254,37 @@ }, /turf/open/floor/wood, /area/station/service/chapel) -"sBf" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 4 +"sAy" = ( +/obj/structure/railing{ + dir = 1 }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/spawner/random/structure/steam_vent, -/turf/open/floor/plating, -/area/station/maintenance/port/greater) +/obj/structure/railing, +/obj/structure/hedge, +/obj/effect/turf_decal/siding/thinplating{ + dir = 8 + }, +/obj/effect/turf_decal/siding/thinplating_new/end{ + dir = 8 + }, +/turf/open/floor/iron/dark, +/area/station/cargo/storage) "sBm" = ( /obj/structure/transport/linear/tram, /obj/structure/fluff/tram_rail/floor, /obj/structure/thermoplastic/light, /turf/open/floor/tram, /area/station/maintenance/port/aft) +"sBn" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 4 + }, +/obj/machinery/firealarm/directional/east, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/sorting) "sBq" = ( /obj/effect/turf_decal/siding/wood, /obj/structure/closet/l3closet/janitor, @@ -54319,6 +54471,12 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"sEd" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/smooth, +/area/station/cargo/warehouse) "sEn" = ( /obj/item/clothing/head/cone, /obj/item/clothing/head/cone{ @@ -54484,6 +54642,9 @@ /obj/structure/reagent_dispensers/watertank, /turf/open/floor/plating, /area/station/maintenance/starboard/central) +"sHW" = ( +/turf/closed/wall, +/area/station/maintenance/hallway/abandoned_recreation) "sHX" = ( /obj/effect/turf_decal/stripes/red/line{ dir = 6 @@ -54523,10 +54684,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/grimy, /area/station/commons/vacant_room/office) -"sJf" = ( -/obj/structure/water_source/puddle, -/turf/open/misc/asteroid, -/area/station/maintenance/starboard/greater) "sJg" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/general/hidden, /obj/machinery/door/airlock/command{ @@ -54602,6 +54759,18 @@ }, /turf/open/floor/iron, /area/station/service/hydroponics) +"sKh" = ( +/obj/effect/landmark/start/librarian, +/turf/open/floor/iron/grimy, +/area/station/service/library/private) +"sKj" = ( +/obj/machinery/light/warm/directional/east, +/obj/effect/turf_decal/tile/brown/anticorner{ + dir = 4 + }, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/lobby) "sKk" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -54655,6 +54824,24 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron/white/small, /area/station/security/warden) +"sKO" = ( +/obj/structure/table, +/obj/item/disk/cargo{ + pixel_x = 6 + }, +/obj/item/storage/fancy/cigarettes/cigpack_robust{ + pixel_x = -3; + pixel_y = 11 + }, +/obj/item/pen{ + pixel_x = -9; + pixel_y = 0 + }, +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/office) "sKS" = ( /obj/structure/sign/poster/official/pda_ad/directional/north, /obj/structure/tank_holder/extinguisher, @@ -54888,15 +55075,6 @@ /obj/machinery/camera/autoname/directional/west, /turf/open/floor/iron/showroomfloor, /area/station/medical/virology) -"sOP" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/turf/open/floor/iron/dark, -/area/station/cargo/office) "sOR" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/door/airlock/public/glass{ @@ -55064,6 +55242,10 @@ dir = 8 }, /area/station/science/lobby) +"sRs" = ( +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/storage) "sRD" = ( /obj/machinery/shower/directional/west, /obj/effect/turf_decal/siding/thinplating/dark{ @@ -55083,15 +55265,6 @@ "sRL" = ( /turf/closed/wall, /area/station/service/janitor) -"sRR" = ( -/obj/structure/disposalpipe/segment, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/cargo/storage) "sRT" = ( /obj/machinery/disposal/bin, /obj/effect/turf_decal/siding/thinplating{ @@ -55126,26 +55299,6 @@ /obj/effect/turf_decal/tile/blue, /turf/open/floor/iron/white, /area/station/medical/medbay/aft) -"sSx" = ( -/obj/structure/table, -/obj/item/restraints/handcuffs/cable{ - pixel_x = -1 - }, -/obj/item/paper/crumpled{ - pixel_x = 9; - pixel_y = -5 - }, -/obj/item/dest_tagger{ - pixel_x = 19; - pixel_y = 6 - }, -/turf/open/floor/iron, -/area/station/cargo/sorting) -"sSA" = ( -/obj/structure/table, -/obj/item/folder/yellow, -/turf/open/floor/iron, -/area/station/cargo/sorting) "sSB" = ( /turf/open/floor/catwalk_floor, /area/station/engineering/break_room) @@ -55160,24 +55313,6 @@ /obj/effect/turf_decal/tile/yellow/opposingcorners, /turf/open/floor/iron, /area/station/hallway/secondary/construction) -"sSU" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 4 - }, -/obj/machinery/conveyor_switch/oneway{ - id = "packageSort2"; - name = "Sort and Deliver"; - pixel_x = 8; - pixel_y = 12 - }, -/turf/open/floor/iron, -/area/station/cargo/sorting) "sSW" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -55231,6 +55366,16 @@ /obj/machinery/telecomms/bus/preset_one, /turf/open/floor/circuit, /area/station/tcommsat/server) +"sTN" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/structure/sign/poster/official/random/directional/west, +/obj/structure/destructible/cult/item_dispenser/archives/library, +/obj/item/book/codex_gigas, +/obj/machinery/light/small/dim/directional/west, +/turf/open/floor/iron/grimy, +/area/station/service/library/private) "sTR" = ( /obj/structure/cable, /obj/effect/mapping_helpers/airlock/access/all/medical/general, @@ -55358,13 +55503,20 @@ "sVN" = ( /turf/closed/wall/r_wall, /area/station/security/prison/workout) -"sVO" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/spawner/directional/south, -/obj/structure/window/reinforced/spawner/directional/north, -/obj/structure/window/reinforced/spawner/directional/west, -/turf/open/floor/plating, -/area/station/hallway/primary/central/fore) +"sVQ" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/siding/red{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/light/small/directional/south, +/turf/open/floor/iron, +/area/station/cargo/storage) "sWc" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/chem_master, @@ -55399,6 +55551,10 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/white, /area/station/science/cytology) +"sXj" = ( +/obj/machinery/air_sensor/mix_tank, +/turf/open/floor/engine/vacuum, +/area/station/engineering/atmos) "sXm" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -55787,9 +55943,6 @@ }, /turf/open/floor/iron/dark, /area/station/science/genetics) -"tca" = ( -/turf/open/floor/carpet/donk, -/area/station/command/heads_quarters/qm) "tcz" = ( /obj/effect/turf_decal/trimline/blue/filled/corner, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, @@ -55843,16 +55996,6 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/station/security/lockers) -"tdD" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/firealarm/directional/east, -/obj/effect/turf_decal/stripes/corner, -/obj/effect/turf_decal/stripes/white/corner, -/turf/open/floor/iron/smooth, -/area/station/cargo/warehouse) "tdE" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -56004,6 +56147,13 @@ /obj/structure/table/wood, /turf/open/floor/iron/grimy, /area/station/hallway/secondary/entry) +"tfj" = ( +/obj/effect/turf_decal/bot_white, +/obj/structure/reagent_dispensers/fueltank, +/obj/machinery/light/small/directional/west, +/obj/structure/sign/poster/official/random/directional/west, +/turf/open/floor/iron/smooth_large, +/area/station/cargo/warehouse) "tfy" = ( /obj/structure/closet/firecloset, /obj/effect/turf_decal/tile/red{ @@ -56039,13 +56189,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/port) -"tfX" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/turf/open/floor/iron/dark/side, -/area/station/cargo/office) "tgl" = ( /turf/closed/wall, /area/station/service/greenroom) @@ -56213,6 +56356,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/commons/fitness/locker_room) +"tjg" = ( +/obj/machinery/atmospherics/components/binary/pump/off{ + name = "O2 To Pure" + }, +/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/engineering/atmos) "tjj" = ( /turf/closed/wall/r_wall, /area/station/ai_monitored/turret_protected/ai_upload) @@ -56243,6 +56395,12 @@ /obj/item/kirbyplants/random, /turf/open/floor/iron, /area/station/maintenance/port/fore) +"tki" = ( +/obj/structure/cable, +/obj/machinery/door/airlock/maintenance, +/obj/effect/mapping_helpers/airlock/access/all/supply/general, +/turf/open/floor/plating, +/area/station/cargo/warehouse) "tkm" = ( /obj/structure/window/spawner/directional/west, /obj/structure/flora/bush/large/style_random{ @@ -56287,12 +56445,6 @@ /obj/structure/sign/warning/cold_temp/directional/north, /turf/open/floor/plating, /area/station/medical/coldroom) -"tll" = ( -/obj/structure/cable, -/obj/machinery/power/apc/auto_name/directional/south, -/obj/effect/landmark/start/quartermaster, -/turf/open/floor/iron, -/area/station/cargo/storage) "tlt" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -56300,6 +56452,9 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"tlG" = ( +/turf/closed/wall, +/area/station/cargo/lobby) "tlI" = ( /obj/structure/flora/bush/fullgrass/style_random, /obj/structure/flora/rock/pile/jungle/style_random, @@ -56410,16 +56565,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/engine, /area/station/science/explab) -"tnu" = ( -/obj/structure/table, -/obj/item/folder/yellow, -/obj/item/pen, -/obj/item/reagent_containers/cup/glass/mug/coco{ - pixel_x = 10; - pixel_y = 14 - }, -/turf/open/floor/iron, -/area/station/cargo/sorting) "tnx" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -56484,13 +56629,6 @@ }, /turf/open/floor/tram, /area/station/maintenance/port/aft) -"tov" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/light/cold/directional/north, -/turf/open/floor/iron/dark, -/area/station/cargo/office) "toC" = ( /obj/effect/turf_decal/tile/yellow/half/contrasted{ dir = 4 @@ -56638,12 +56776,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/wood, /area/station/commons/fitness/recreation) -"tqn" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/light/small/directional/west, -/turf/open/floor/iron/dark, -/area/station/engineering/atmospherics_engine) "tqo" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, @@ -56691,10 +56823,12 @@ dir = 1 }, /area/station/hallway/secondary/dock) -"tro" = ( -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/iron/smooth, -/area/station/cargo/warehouse) +"tri" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/wood, +/area/station/maintenance/hallway/abandoned_recreation) "trp" = ( /turf/closed/wall, /area/station/maintenance/port/aft) @@ -56738,6 +56872,28 @@ /obj/structure/sign/departments/aiupload/directional/south, /turf/open/floor/iron/white, /area/station/hallway/primary/starboard) +"tsk" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/cargo/sorting) +"tsl" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/effect/turf_decal/siding/wood, +/obj/machinery/door/airlock/public/glass{ + name = "Chapel Office" + }, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/all/service/chapel_office, +/obj/structure/disposalpipe/segment, +/turf/open/floor/iron/textured_half, +/area/station/service/chapel/office) "tst" = ( /obj/machinery/atmospherics/pipe/smart/simple/general/visible{ dir = 4 @@ -56844,6 +57000,14 @@ /obj/item/stack/sheet/glass/fifty, /turf/open/floor/iron/dark, /area/station/engineering/atmospherics_engine) +"tuw" = ( +/obj/structure/cable, +/obj/structure/disposalpipe/junction/flip{ + dir = 4 + }, +/obj/effect/spawner/random/structure/steam_vent, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "tux" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -57345,6 +57509,15 @@ }, /turf/open/floor/iron, /area/station/security/prison/workout) +"tBE" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/obj/machinery/power/apc/auto_name/directional/north, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "tCh" = ( /obj/structure/chair/stool/directional/north, /obj/effect/turf_decal/siding/red, @@ -57606,6 +57779,13 @@ /mob/living/carbon/human/species/monkey/punpun, /turf/open/floor/stone, /area/station/service/abandoned_gambling_den) +"tHo" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/cable, +/turf/open/floor/iron/smooth_large, +/area/station/engineering/supermatter/room) "tHp" = ( /obj/effect/turf_decal/tile/dark_red/opposingcorners, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, @@ -57720,6 +57900,20 @@ "tJX" = ( /turf/open/floor/plating, /area/station/maintenance/aft) +"tJY" = ( +/obj/machinery/door/firedoor, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/status_display/supply{ + pixel_x = 0; + pixel_y = 32 + }, +/obj/structure/cable, +/turf/open/floor/iron/small, +/area/station/cargo/lobby) "tKa" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -57728,10 +57922,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/port/lesser) -"tKf" = ( -/obj/structure/closet/emcloset, -/turf/open/floor/plating, -/area/station/maintenance/port/greater) "tKl" = ( /obj/effect/landmark/start/assistant, /obj/effect/turf_decal/tile/neutral{ @@ -57994,6 +58184,12 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/starboard) +"tOu" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/mapping_helpers/broken_floor, +/obj/structure/closet/firecloset, +/turf/open/floor/plating, +/area/station/maintenance/port/greater) "tOw" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -58024,27 +58220,10 @@ }, /turf/open/floor/iron/white, /area/station/hallway/primary/starboard) -"tPa" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/white/line{ - dir = 8 - }, -/turf/open/floor/wood, -/area/station/cargo/miningfoundry) "tPf" = ( /obj/machinery/light/small/directional/east, /turf/open/floor/iron/dark, /area/station/security/interrogation) -"tPg" = ( -/obj/structure/chair/stool/directional/north, -/obj/effect/landmark/start/cargo_technician, -/turf/open/floor/iron, -/area/station/cargo/sorting) "tPm" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/sign/poster/official/random/directional/north, @@ -58112,6 +58291,11 @@ /obj/structure/cable, /turf/open/floor/catwalk_floor/iron_dark, /area/station/cargo/bitrunning/den) +"tQn" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/sign/poster/official/no_erp/directional/south, +/turf/open/floor/wood, +/area/station/maintenance/hallway/abandoned_recreation) "tQr" = ( /obj/effect/turf_decal/tile/purple/opposingcorners, /obj/effect/turf_decal/siding/green{ @@ -58176,6 +58360,16 @@ /obj/structure/extinguisher_cabinet/directional/east, /turf/open/floor/iron, /area/station/security/courtroom) +"tRm" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 1; + name = "Plasma to Pure" + }, +/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/engineering/atmos) "tRw" = ( /obj/structure/disposalpipe/trunk{ dir = 8 @@ -58226,14 +58420,6 @@ /obj/machinery/light/small/broken/directional/west, /turf/open/floor/eighties, /area/station/service/abandoned_gambling_den/gaming) -"tSA" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/structure/sign/departments/cargo/directional/west, -/turf/open/floor/iron, -/area/station/hallway/primary/central/fore) "tSB" = ( /obj/structure/cable, /obj/structure/table/reinforced, @@ -58429,12 +58615,6 @@ }, /turf/open/floor/plating, /area/station/science/robotics/lab) -"tVR" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "tWm" = ( /obj/structure/flora/bush/jungle/c/style_3, /obj/effect/turf_decal/weather/dirt, @@ -58806,9 +58986,6 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos/project) -"uct" = ( -/turf/open/floor/engine/vacuum, -/area/station/engineering/atmos) "ucy" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/siding/red{ @@ -58833,6 +59010,13 @@ }, /turf/open/floor/wood, /area/station/service/chapel/funeral) +"ucO" = ( +/obj/machinery/light/floor, +/obj/structure/flora/bush/flowers_br/style_3, +/obj/structure/flora/bush/flowers_yw, +/obj/structure/flora/bush/flowers_pp, +/turf/open/floor/grass, +/area/station/hallway/primary/central/fore) "ucR" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/door/airlock{ @@ -59007,6 +59191,20 @@ }, /turf/open/floor/iron/textured_large, /area/station/command/heads_quarters/hop) +"ueL" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/brown/line, +/obj/effect/turf_decal/stripes, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/obj/machinery/airalarm/directional/west, +/obj/effect/landmark/start/bitrunner, +/obj/machinery/camera/autoname/directional/west, +/turf/open/floor/iron/dark/smooth_half, +/area/station/cargo/bitrunning/den) "ueP" = ( /obj/machinery/camera/directional/east{ c_tag = "Atmospherics Tank - Air" @@ -59114,13 +59312,6 @@ }, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/rd) -"ugt" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable, -/turf/open/floor/iron/small, -/area/station/engineering/break_room) "ugA" = ( /obj/effect/turf_decal/siding/yellow{ dir = 1 @@ -59286,6 +59477,31 @@ }, /turf/open/floor/iron/white/small, /area/station/science/lobby) +"uiK" = ( +/obj/machinery/atmospherics/pipe/layer_manifold/supply/visible{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/station/maintenance/department/engine/atmos) +"uiO" = ( +/obj/effect/mapping_helpers/broken_floor, +/obj/structure/table/wood, +/obj/item/paper_bin{ + pixel_x = -2; + pixel_y = 4 + }, +/obj/item/pen{ + pixel_x = -2; + pixel_y = 4 + }, +/obj/item/pen{ + pixel_x = -2; + pixel_y = 10 + }, +/obj/structure/sign/poster/official/the_owl/directional/west, +/obj/item/radio/intercom/directional/south, +/turf/open/floor/wood, +/area/station/maintenance/hallway/abandoned_recreation) "uiS" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -59294,6 +59510,13 @@ dir = 1 }, /area/station/science/research) +"uiU" = ( +/obj/effect/spawner/structure/window, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/plating, +/area/station/cargo/office) "uiY" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -59539,6 +59762,14 @@ /obj/effect/spawner/random/maintenance, /turf/open/floor/plating, /area/station/maintenance/port/aft) +"umL" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable, +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/office) "unc" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -59554,6 +59785,12 @@ }, /turf/open/floor/iron/smooth, /area/station/security/checkpoint/customs/auxiliary) +"unG" = ( +/obj/machinery/power/apc/auto_name/directional/north, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/smooth, +/area/station/cargo/miningfoundry) "unK" = ( /obj/structure/reagent_dispensers/fueltank, /turf/open/floor/plating, @@ -59642,6 +59879,17 @@ /obj/effect/spawner/structure/window, /turf/open/floor/plating, /area/station/hallway/primary/starboard) +"upF" = ( +/obj/structure/table, +/obj/item/toy/eightball{ + pixel_x = -4 + }, +/obj/item/wirecutters{ + pixel_y = 17; + pixel_x = 4 + }, +/turf/open/floor/iron/dark/small, +/area/station/commons/fitness/locker_room) "upG" = ( /obj/structure/railing, /obj/structure/cable, @@ -59651,6 +59899,12 @@ dir = 4 }, /area/station/command/heads_quarters/ce) +"upM" = ( +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/iron, +/area/station/cargo/sorting) "upP" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -59703,15 +59957,6 @@ "uqw" = ( /turf/closed/wall/r_wall, /area/station/commons/fitness/recreation) -"uqE" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/sorting) "uqF" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/tile/neutral, @@ -59913,15 +60158,6 @@ /obj/effect/spawner/random/trash, /turf/open/floor/plating, /area/station/maintenance/fore/greater) -"usg" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/turf/open/floor/iron/smooth, -/area/station/command/heads_quarters/qm) "usF" = ( /obj/effect/mapping_helpers/broken_floor, /obj/structure/easel, @@ -59975,23 +60211,6 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/command/meeting_room) -"utH" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/door/airlock/command/glass{ - name = "Quartermaster's Office" - }, -/obj/effect/mapping_helpers/airlock/access/all/supply/qm, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, -/obj/machinery/door/firedoor, -/turf/open/floor/catwalk_floor/iron_smooth, -/area/station/command/heads_quarters/qm) "utP" = ( /obj/structure/table/reinforced/plastitaniumglass, /obj/item/paper_bin/carbon{ @@ -60010,6 +60229,25 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"uur" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/storage/wallet{ + pixel_x = -3; + pixel_y = 10 + }, +/obj/item/cigarette/cigar{ + pixel_x = -1; + pixel_y = -2 + }, +/obj/item/lighter{ + pixel_x = 11; + pixel_y = -7 + }, +/obj/machinery/light/directional/south, +/obj/structure/sign/poster/official/random/directional/south, +/obj/effect/turf_decal/siding/wood, +/turf/open/floor/wood, +/area/station/command/heads_quarters/qm) "uuz" = ( /obj/structure/rack, /obj/effect/turf_decal/tile/brown/opposingcorners{ @@ -60020,25 +60258,15 @@ /obj/machinery/camera/directional/west, /turf/open/floor/iron, /area/station/commons/vacant_room/commissary) -"uuN" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 +"uuA" = ( +/obj/structure/chair/stool/directional/south, +/obj/effect/turf_decal/siding/yellow{ + dir = 1 }, +/obj/effect/landmark/start/atmospheric_technician, /obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/brown/half/contrasted, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/cargo/sorting) -"uuR" = ( -/obj/machinery/door/airlock/wood{ - desc = "Sessions held every Friday."; - name = "The Sunfinder Society" - }, -/obj/effect/mapping_helpers/airlock/abandoned, -/turf/open/floor/plating, -/area/station/cargo/miningfoundry) +/turf/open/floor/wood, +/area/station/engineering/break_room) "uuS" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/siding/blue{ @@ -60111,15 +60339,14 @@ /obj/effect/landmark/transport/nav_beacon/tram/nav/immovable_rod, /turf/open/floor/iron, /area/station/hallway/secondary/entry) -"uxd" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 +"uwO" = ( +/obj/machinery/door/airlock/hatch{ + name = "Tool Supply Corridor" }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/maintenance/port/fore) +/obj/effect/mapping_helpers/airlock/access/any/service/maintenance, +/obj/effect/mapping_helpers/airlock/unres, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/commons/storage/tools) "uxJ" = ( /obj/machinery/smartfridge/chemistry/preloaded, /obj/machinery/door/firedoor, @@ -60135,12 +60362,6 @@ /obj/structure/trap/stun, /turf/open/floor/plating, /area/station/maintenance/starboard/greater) -"uxY" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/chair/stool/bamboo, -/obj/structure/cable, -/turf/open/floor/carpet/lone, -/area/station/service/chapel/office) "uya" = ( /obj/structure/cable, /obj/effect/spawner/structure/window/reinforced, @@ -60748,6 +60969,23 @@ /obj/item/assault_pod/mining, /turf/open/floor/iron, /area/station/construction/mining/aux_base) +"uHE" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/door/airlock/mining/glass{ + name = "Delivery Office" + }, +/obj/effect/mapping_helpers/airlock/access/all/supply/general, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/unres{ + dir = 8 + }, +/turf/open/floor/iron/small, +/area/station/cargo/sorting) "uHF" = ( /obj/machinery/atmospherics/pipe/layer_manifold/supply/visible, /obj/machinery/door/airlock{ @@ -60800,17 +61038,6 @@ }, /turf/open/floor/iron/dark, /area/station/engineering/atmos/office) -"uIv" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/hallway/primary/central/fore) "uIy" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, @@ -60821,6 +61048,16 @@ }, /turf/open/floor/iron/white/small, /area/station/service/hydroponics) +"uIG" = ( +/obj/machinery/computer/cargo/request{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 1 + }, +/obj/structure/extinguisher_cabinet/directional/south, +/turf/open/floor/iron/dark/side, +/area/station/cargo/lobby) "uIP" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -60874,6 +61111,27 @@ /obj/machinery/shieldgen, /turf/open/floor/iron/dark/small, /area/station/engineering/storage_shared) +"uJI" = ( +/obj/machinery/power/apc/auto_name/directional/south, +/obj/effect/landmark/start/quartermaster, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/cargo/storage) +"uJV" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/office) "uKh" = ( /obj/structure/closet/emcloset, /obj/effect/turf_decal/bot, @@ -60925,14 +61183,6 @@ /obj/machinery/camera/autoname/directional/east, /turf/open/floor/iron, /area/station/hallway/secondary/entry) -"uKP" = ( -/obj/effect/mapping_helpers/broken_floor, -/obj/structure/table/wood, -/obj/item/flashlight/lamp, -/obj/effect/decal/cleanable/dirt, -/obj/item/radio/intercom/directional/west, -/turf/open/floor/wood, -/area/station/command/heads_quarters/qm) "uLj" = ( /turf/closed/wall, /area/station/commons/toilet/auxiliary) @@ -60947,6 +61197,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating/rust, /area/station/engineering/main) +"uLz" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/maintenance/port/greater) "uLD" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -61128,6 +61387,18 @@ /obj/machinery/airalarm/directional/north, /turf/open/floor/wood/tile, /area/station/command/meeting_room) +"uPf" = ( +/obj/structure/cable, +/obj/structure/disposalpipe/segment, +/obj/machinery/door/airlock/maintenance{ + name = "Maintenance" + }, +/obj/effect/mapping_helpers/airlock/unres{ + dir = 1 + }, +/obj/effect/mapping_helpers/airlock/access/any/service/maintenance, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "uPr" = ( /obj/structure/weightmachine/weightlifter, /obj/effect/turf_decal/bot, @@ -61200,6 +61471,17 @@ "uQo" = ( /turf/open/floor/engine/air, /area/station/engineering/atmos) +"uQt" = ( +/obj/machinery/door/airlock/command/glass{ + name = "Quartermaster's Office" + }, +/obj/effect/mapping_helpers/airlock/access/all/supply/qm, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/dark/textured_half{ + dir = 1 + }, +/area/station/command/heads_quarters/qm) "uQu" = ( /obj/structure/window/reinforced/spawner/directional/west, /obj/machinery/status_display/door_timer{ @@ -61333,14 +61615,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/commons/dorms) -"uSt" = ( -/obj/effect/turf_decal/siding/wood, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 1 - }, -/turf/open/floor/iron/smooth, -/area/station/command/heads_quarters/qm) "uSB" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -61350,17 +61624,14 @@ /obj/effect/landmark/navigate_destination/tcomms, /turf/open/floor/iron, /area/station/science/lower) -"uSG" = ( -/obj/structure/cable, +"uSM" = ( +/obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/siding/wood, -/turf/open/floor/iron/smooth, -/area/station/command/heads_quarters/qm) -"uSI" = ( -/obj/machinery/light/small/directional/east, -/turf/open/floor/wood, -/area/station/cargo/boutique) +/obj/effect/spawner/random/structure/closet_empty/crate, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/iron/smooth_large, +/area/station/cargo/warehouse) "uSN" = ( /obj/effect/spawner/random/vending/snackvend, /obj/effect/turf_decal/tile/neutral/half/contrasted{ @@ -61438,19 +61709,6 @@ }, /turf/open/floor/iron/dark/small, /area/station/science/xenobiology) -"uUb" = ( -/obj/structure/disposalpipe/segment{ - dir = 9 - }, -/obj/structure/cable, -/obj/structure/table, -/obj/effect/turf_decal/delivery/white, -/obj/machinery/microwave{ - pixel_y = 6 - }, -/obj/machinery/power/apc/auto_name/directional/south, -/turf/open/floor/iron/smooth, -/area/station/cargo/sorting) "uUe" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/closed/wall/r_wall, @@ -61468,6 +61726,36 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/hallway/primary/starboard) +"uUq" = ( +/obj/structure/table/wood, +/obj/item/folder/yellow{ + pixel_x = 3; + pixel_y = 6 + }, +/obj/item/dest_tagger{ + pixel_x = -11; + pixel_y = 4 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/floor/carpet/orange, +/area/station/command/heads_quarters/qm) +"uUz" = ( +/obj/machinery/light/small/directional/east, +/obj/machinery/light_switch/directional/east, +/obj/effect/mapping_helpers/turn_off_lights_with_lightswitch, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/white/corner{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/iron/smooth_large, +/area/station/cargo/warehouse) "uUA" = ( /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/plating, @@ -61511,6 +61799,17 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"uVB" = ( +/obj/item/kirbyplants/organic/plant17, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/sign/calendar{ + pixel_x = 0; + pixel_y = -26 + }, +/obj/machinery/light/small/directional/south, +/turf/open/floor/wood, +/area/station/maintenance/hallway/abandoned_recreation) "uVD" = ( /obj/effect/mapping_helpers/broken_floor, /obj/machinery/airalarm/directional/east, @@ -61904,21 +62203,6 @@ dir = 1 }, /area/station/command/heads_quarters/hop) -"vdl" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/button/door/directional/east{ - id = "qm_warehouse_aft"; - name = "Warehouse Door Control"; - pixel_x = -24; - pixel_y = -23; - req_access = list("cargo") - }, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "vdt" = ( /obj/item/kirbyplants/random, /obj/effect/turf_decal/stripes/line{ @@ -61951,13 +62235,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/medbay/central) -"vdL" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/spawner/random/structure/steam_vent, -/turf/open/floor/plating, -/area/station/maintenance/port/greater) "vdX" = ( /obj/structure/table/reinforced, /obj/effect/turf_decal/tile/blue/fourcorners, @@ -62181,6 +62458,15 @@ /obj/effect/mapping_helpers/airlock/access/any/science/maintenance, /turf/open/floor/plating, /area/station/maintenance/department/science/xenobiology) +"vgL" = ( +/obj/effect/turf_decal/tile/brown/opposingcorners, +/obj/effect/turf_decal/tile/brown/opposingcorners, +/obj/machinery/atmospherics/components/binary/volume_pump, +/obj/structure/railing{ + dir = 1 + }, +/turf/open/floor/iron/small, +/area/station/engineering/atmos/office) "vgN" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/yellow/opposingcorners, @@ -62208,10 +62494,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/department/science/xenobiology) -"vhe" = ( -/obj/structure/filingcabinet/chestdrawer, -/turf/open/floor/iron/smooth, -/area/station/cargo/office) "vhr" = ( /obj/structure/sink/directional/west, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -62348,6 +62630,15 @@ /obj/structure/alien/weeds, /turf/open/floor/plating, /area/station/maintenance/starboard/greater) +"vjs" = ( +/obj/structure/disposalpipe/segment, +/obj/item/food/grown/pineapple{ + pixel_x = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/cargo/storage) "vjI" = ( /obj/machinery/door/airlock{ name = "Bathrooms" @@ -62423,6 +62714,17 @@ /obj/effect/spawner/structure/window, /turf/open/floor/plating, /area/station/command/heads_quarters/qm) +"vkR" = ( +/obj/machinery/door/airlock/engineering/glass/critical{ + heat_proof = 1; + name = "Supermatter Chamber" + }, +/obj/effect/mapping_helpers/airlock/access/any/engineering/general, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/turf/open/floor/engine, +/area/station/engineering/supermatter) "vkS" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -62769,13 +63071,6 @@ /obj/structure/sign/nanotrasen, /turf/closed/wall/r_wall, /area/station/command/teleporter) -"vpb" = ( -/obj/machinery/door/airlock/hatch{ - name = "Tool Supply Corridor" - }, -/obj/effect/mapping_helpers/airlock/access/all/supply/general, -/turf/open/floor/catwalk_floor/iron_dark, -/area/station/cargo/office) "vpk" = ( /obj/structure/cable, /turf/open/floor/iron/smooth, @@ -62976,6 +63271,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark/herringbone, /area/station/security/courtroom) +"vse" = ( +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "vsf" = ( /obj/structure/closet/crate{ name = "Materials Crate" @@ -63149,25 +63449,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) -"vuH" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/power/apc/auto_name/directional/west, -/obj/structure/cable, -/obj/effect/turf_decal/delivery, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) -"vuJ" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/sorting) "vuR" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -63250,13 +63531,14 @@ /turf/open/floor/iron, /area/station/hallway/secondary/construction) "vvC" = ( -/obj/machinery/door/airlock/engineering{ - name = "Engine Airlock" - }, /obj/machinery/door/firedoor, /obj/effect/mapping_helpers/airlock/access/any/engineering/construction, /obj/structure/cable, /obj/effect/landmark/navigate_destination, +/obj/machinery/door/airlock/engineering{ + name = "Main Engineering" + }, +/obj/effect/mapping_helpers/airlock/access/any/engineering/general, /turf/open/floor/catwalk_floor, /area/station/engineering/break_room) "vvK" = ( @@ -63518,6 +63800,10 @@ /obj/structure/cable, /turf/open/floor/iron/cafeteria, /area/station/security/prison/mess) +"vzD" = ( +/obj/effect/turf_decal/stripes/white/line, +/turf/open/floor/iron/dark/side, +/area/station/cargo/storage) "vzE" = ( /obj/structure/window/spawner/directional/east, /obj/structure/window/spawner/directional/west, @@ -63768,12 +64054,6 @@ /obj/effect/turf_decal/tile/dark_red/opposingcorners, /turf/open/floor/iron, /area/station/security/lockers) -"vDS" = ( -/obj/structure/closet/secure_closet/engineering_personal, -/obj/item/clothing/suit/hooded/wintercoat/engineering, -/obj/structure/cable, -/turf/open/floor/iron/small, -/area/station/engineering/break_room) "vDV" = ( /turf/closed/wall/r_wall, /area/station/command/heads_quarters/cmo) @@ -64022,15 +64302,6 @@ /obj/machinery/light/cold/directional/east, /turf/open/floor/engine, /area/station/science/xenobiology) -"vHU" = ( -/obj/machinery/door/airlock/engineering{ - name = "Engineering Office" - }, -/obj/effect/mapping_helpers/airlock/access/all/engineering/engine_equipment, -/turf/open/floor/iron/smooth_half{ - dir = 8 - }, -/area/station/maintenance/department/engine/atmos) "vHV" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -64132,6 +64403,13 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"vJE" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Public Shrine" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/iron/textured_half, +/area/station/hallway/primary/port) "vJG" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/tile/brown/opposingcorners, @@ -64302,11 +64580,6 @@ }, /turf/open/floor/iron, /area/station/security/brig/entrance) -"vLD" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/obj/structure/cable, -/turf/open/floor/iron/grimy, -/area/station/command/heads_quarters/qm) "vLF" = ( /obj/structure/closet/secure_closet/courtroom, /obj/item/gavelblock, @@ -64325,9 +64598,6 @@ /obj/effect/mapping_helpers/airlock/access/all/science/robotics, /turf/open/floor/catwalk_floor/iron_white, /area/station/science/robotics/augments) -"vLP" = ( -/turf/closed/wall/rust, -/area/station/command/heads_quarters/qm) "vLQ" = ( /obj/structure/disposalpipe/trunk{ dir = 8 @@ -64441,14 +64711,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/maintenance/starboard/greater) -"vNv" = ( -/obj/effect/turf_decal/stripes/corner, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/obj/machinery/camera/autoname/directional/south, -/turf/open/floor/iron/smooth, -/area/station/cargo/warehouse) "vNM" = ( /obj/machinery/door/airlock{ name = "Hydroponics Maintenance" @@ -64606,6 +64868,10 @@ /obj/structure/sign/poster/official/random/directional/east, /turf/open/floor/eighties/red, /area/station/hallway/primary/central/fore) +"vRc" = ( +/obj/effect/turf_decal/loading_area/white, +/turf/open/floor/iron, +/area/station/cargo/lobby) "vRd" = ( /obj/structure/table, /obj/effect/turf_decal/tile/dark_red, @@ -64626,11 +64892,6 @@ dir = 1 }, /area/station/science/research) -"vRn" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/turf/closed/wall, -/area/station/maintenance/port/greater) "vRt" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -64661,6 +64922,17 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/aft) +"vSn" = ( +/obj/structure/hedge, +/obj/machinery/status_display/supply{ + pixel_y = 32 + }, +/obj/machinery/light/small/directional/north, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/floor/iron/smooth, +/area/station/cargo/storage) "vSt" = ( /obj/effect/turf_decal/siding/wideplating{ dir = 4 @@ -65009,6 +65281,14 @@ }, /turf/open/floor/iron/small, /area/station/hallway/primary/central/fore) +"vWy" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/sign/departments/cargo/directional/west, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "vWA" = ( /obj/effect/turf_decal/tile/brown/opposingcorners, /obj/machinery/firealarm/directional/south, @@ -65089,6 +65369,15 @@ /obj/machinery/power/apc/auto_name/directional/west, /turf/open/floor/iron, /area/station/security/prison/rec) +"vXv" = ( +/obj/structure/table, +/obj/item/toy/foamblade, +/obj/item/analyzer{ + pixel_y = 8; + pixel_x = -9 + }, +/turf/open/floor/iron/dark/small, +/area/station/commons/fitness/locker_room) "vXy" = ( /obj/effect/turf_decal/stripes/corner, /turf/open/floor/iron/white/corner{ @@ -65240,6 +65529,11 @@ }, /turf/open/floor/stone, /area/station/service/abandoned_gambling_den) +"vZS" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/turf/open/floor/iron/smooth, +/area/station/cargo/lobby) "vZW" = ( /obj/structure/chair/sofa/bench/right{ dir = 4 @@ -65349,6 +65643,15 @@ dir = 1 }, /area/station/science/lower) +"wbt" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/closet/secure_closet/quartermaster, +/obj/machinery/light_switch/directional/south, +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/turf/open/floor/carpet/red, +/area/station/command/heads_quarters/qm) "wbH" = ( /obj/machinery/holopad, /obj/effect/decal/cleanable/dirt, @@ -65400,11 +65703,6 @@ }, /turf/open/floor/iron, /area/station/security/execution/transfer) -"wcz" = ( -/obj/structure/disposalpipe/segment, -/obj/structure/chair/stool/directional/south, -/turf/open/floor/iron, -/area/station/cargo/sorting) "wcF" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/visible/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible, @@ -65648,6 +65946,13 @@ }, /turf/open/floor/iron, /area/station/security/execution/transfer) +"whg" = ( +/obj/effect/landmark/start/hangover, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/hallway/primary/central/aft) "whl" = ( /obj/machinery/portable_atmospherics/canister/oxygen, /obj/effect/turf_decal/stripes/line{ @@ -65740,6 +66045,14 @@ /obj/structure/cable, /turf/open/floor/engine, /area/station/engineering/supermatter/room) +"wie" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 1 + }, +/obj/effect/spawner/random/vending/colavend, +/obj/machinery/firealarm/directional/south, +/turf/open/floor/iron/dark/side, +/area/station/cargo/lobby) "win" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -65783,13 +66096,6 @@ /obj/structure/tank_holder/extinguisher, /turf/open/floor/iron/white, /area/station/medical/medbay/central) -"wjw" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/structure/cable, -/turf/open/floor/iron/smooth_large, -/area/station/engineering/supermatter/room) "wjG" = ( /obj/structure/filingcabinet, /turf/open/floor/iron/dark/small, @@ -65845,16 +66151,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"wkK" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/plating, -/area/station/maintenance/port/greater) "wla" = ( /obj/effect/landmark/generic_maintenance_landmark, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -65962,6 +66258,15 @@ /obj/effect/spawner/structure/window, /turf/open/floor/plating, /area/station/cargo/office) +"wnf" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/turf/open/floor/plating/elevatorshaft, +/area/station/engineering/break_room) "wnw" = ( /obj/machinery/pdapainter/engineering, /obj/effect/turf_decal/bot, @@ -66085,6 +66390,15 @@ }, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) +"woY" = ( +/obj/structure/chair/stool/directional/south, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/turf/open/floor/carpet/orange, +/area/station/command/heads_quarters/qm) "wpa" = ( /turf/open/floor/plating, /area/station/ai_monitored/turret_protected/aisat/maint) @@ -66128,6 +66442,15 @@ "wqj" = ( /turf/closed/wall, /area/station/commons/toilet/restrooms) +"wqx" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "wqz" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/yellow/visible, /turf/open/floor/engine, @@ -66137,20 +66460,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/maintenance/port/aft) -"wqI" = ( -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/office) "wqM" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable, @@ -66328,6 +66637,14 @@ }, /turf/open/floor/iron/dark/side, /area/station/science/xenobiology) +"wtd" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/door/poddoor/shutters{ + id = "qm_warehouse_aft"; + name = "Warehouse Shutters" + }, +/turf/open/floor/plating, +/area/station/cargo/warehouse) "wte" = ( /obj/effect/turf_decal/stripes/white/line{ dir = 1 @@ -66547,6 +66864,13 @@ /obj/structure/hedge, /turf/open/floor/iron/grimy, /area/station/science/cubicle) +"wvF" = ( +/obj/structure/filingcabinet/filingcabinet, +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/office) "wvM" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -66604,16 +66928,6 @@ dir = 1 }, /area/station/science/lower) -"wwJ" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/brown/half/contrasted, -/turf/open/floor/iron, -/area/station/cargo/sorting) "wwQ" = ( /obj/structure/chair/office{ dir = 4 @@ -66648,6 +66962,17 @@ /obj/machinery/light/small/dim/directional/north, /turf/open/floor/iron/dark, /area/station/maintenance/department/engine/atmos) +"wxJ" = ( +/obj/machinery/door/airlock/engineering/glass/critical{ + heat_proof = 1; + name = "Supermatter Chamber" + }, +/obj/effect/mapping_helpers/airlock/access/any/engineering/general, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/turf/open/floor/engine, +/area/station/engineering/supermatter) "wxR" = ( /obj/structure/rack, /obj/effect/spawner/random/maintenance, @@ -66734,6 +67059,12 @@ /obj/machinery/light/warm/directional/east, /turf/open/floor/iron/dark, /area/station/science/genetics) +"wyG" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/turf/open/floor/carpet/orange, +/area/station/command/heads_quarters/qm) "wyH" = ( /obj/machinery/door/airlock/maintenance{ name = "Maintenance" @@ -66769,14 +67100,13 @@ }, /turf/open/floor/engine/air, /area/station/engineering/atmos) -"wzo" = ( -/obj/machinery/light/small/directional/north, -/obj/effect/landmark/start/cargo_technician, -/turf/open/floor/iron/smooth, -/area/station/cargo/office) "wzv" = ( /turf/open/floor/plating, /area/station/maintenance/department/electrical) +"wzz" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/iron, +/area/station/cargo/sorting) "wzF" = ( /obj/effect/turf_decal/stripes/corner{ dir = 4 @@ -66821,6 +67151,16 @@ }, /turf/open/floor/plating, /area/station/maintenance/department/engine) +"wAh" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/status_display/supply{ + pixel_x = -2; + pixel_y = 32 + }, +/turf/open/floor/catwalk_floor/iron_white, +/area/station/cargo/storage) "wAj" = ( /obj/structure/table/wood, /obj/machinery/computer/records/medical/laptop{ @@ -67019,6 +67359,15 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/station/maintenance/department/engine/atmos) +"wDQ" = ( +/obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/effect/spawner/random/structure/steam_vent, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "wEf" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/neutral{ @@ -67728,14 +68077,6 @@ /obj/effect/landmark/start/depsec/medical, /turf/open/floor/iron/smooth, /area/station/security/checkpoint/customs/auxiliary) -"wOM" = ( -/obj/structure/disposalpipe/segment{ - dir = 9 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/spawner/random/trash, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "wOS" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -67745,26 +68086,6 @@ /obj/effect/landmark/navigate_destination/disposals, /turf/open/floor/iron, /area/station/maintenance/hallway/abandoned_command) -"wOZ" = ( -/obj/effect/decal/cleanable/molten_object, -/obj/effect/landmark/event_spawn, -/obj/structure/table, -/obj/item/reagent_containers/cup/bottle/welding_fuel{ - pixel_y = -3; - pixel_x = 13 - }, -/obj/item/stack/sheet/iron/ten{ - pixel_y = -6; - pixel_x = -2 - }, -/obj/item/hand_labeler{ - pixel_y = -15 - }, -/obj/item/reagent_containers/cup/watering_can{ - pixel_y = 12 - }, -/turf/open/floor/iron/dark, -/area/station/commons/storage/tools) "wPd" = ( /turf/closed/wall/r_wall, /area/station/maintenance/starboard/lesser) @@ -67820,16 +68141,6 @@ }, /turf/open/floor/iron/smooth, /area/station/engineering/main) -"wPO" = ( -/obj/machinery/atmospherics/components/binary/pump/on{ - name = "O2 to Airmix" - }, -/obj/machinery/light/no_nightlight/directional/north, -/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/engineering/atmos) "wPP" = ( /obj/effect/turf_decal/tile/yellow/anticorner/contrasted{ dir = 1 @@ -68042,11 +68353,6 @@ /obj/machinery/smartfridge/organ, /turf/open/floor/plating, /area/station/medical/morgue) -"wSf" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable, -/turf/open/floor/iron/grimy, -/area/station/command/heads_quarters/qm) "wSg" = ( /obj/effect/turf_decal/tile/blue{ dir = 4 @@ -68056,12 +68362,6 @@ }, /turf/open/floor/iron/white/corner, /area/station/hallway/primary/aft) -"wSi" = ( -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/turf/open/floor/iron/dark, -/area/station/cargo/office) "wSF" = ( /obj/effect/turf_decal/tile/blue/anticorner/contrasted{ dir = 8 @@ -68248,6 +68548,12 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron, /area/station/science/ordnance/testlab) +"wVr" = ( +/obj/structure/filingcabinet/chestdrawer, +/obj/structure/cable, +/obj/machinery/power/apc/auto_name/directional/west, +/turf/open/floor/iron/smooth, +/area/station/cargo/lobby) "wVI" = ( /obj/machinery/biogenerator, /obj/machinery/light/small/dim/directional/north, @@ -68482,14 +68788,6 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/maintenance/starboard/central) -"wZD" = ( -/obj/effect/turf_decal/weather/dirt, -/obj/structure/flora/bush/large/style_random{ - pixel_x = -20; - pixel_y = 3 - }, -/turf/open/floor/grass, -/area/station/service/chapel) "wZF" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -68575,15 +68873,6 @@ /obj/machinery/status_display/ai/directional/north, /turf/open/floor/plating, /area/station/engineering/storage/tech) -"xaZ" = ( -/obj/structure/chair{ - dir = 8 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/maintenance/port/fore) "xba" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -68656,6 +68945,13 @@ "xck" = ( /turf/closed/wall/r_wall, /area/station/engineering/atmos/office) +"xco" = ( +/obj/effect/landmark/event_spawn, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "xcq" = ( /obj/effect/turf_decal/stripes/white/line{ dir = 8 @@ -68678,6 +68974,22 @@ /obj/structure/window/spawner/directional/north, /turf/open/floor/grass, /area/station/service/hydroponics) +"xcA" = ( +/obj/structure/table/reinforced, +/obj/item/paper_bin{ + pixel_x = 1; + pixel_y = 9 + }, +/obj/item/pen{ + pixel_x = 1; + pixel_y = 9 + }, +/obj/item/book/manual/wiki/security_space_law, +/obj/item/radio/intercom/directional/east, +/obj/machinery/camera/autoname/directional/south, +/obj/effect/turf_decal/tile/red/anticorner/contrasted, +/turf/open/floor/iron/smooth, +/area/station/security/checkpoint/supply) "xcF" = ( /turf/open/floor/iron, /area/station/commons/dorms) @@ -68865,6 +69177,18 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron/white/textured_large, /area/station/science/research) +"xeZ" = ( +/obj/machinery/light/small/directional/south, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/stairs{ + dir = 8 + }, +/area/station/cargo/storage) "xfa" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, @@ -69016,6 +69340,21 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/port) +"xgK" = ( +/obj/effect/turf_decal/trimline/yellow/filled/line{ + dir = 1 + }, +/obj/effect/turf_decal/arrows{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown/half/contrasted, +/turf/open/floor/iron/dark/side{ + dir = 1 + }, +/area/station/cargo/sorting) "xhk" = ( /obj/machinery/door/airlock/public/glass{ name = "Public Shrine" @@ -69026,16 +69365,15 @@ dir = 8 }, /area/station/hallway/primary/central/fore) -"xht" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/item/radio/intercom/directional/south, -/obj/effect/turf_decal/tile/neutral, +"xhC" = ( /obj/structure/disposalpipe/segment{ - dir = 5 + dir = 4 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/cable, /turf/open/floor/iron, -/area/station/hallway/primary/port) +/area/station/cargo/lobby) "xhD" = ( /obj/structure/table, /obj/item/clothing/shoes/ducky_shoes{ @@ -69154,6 +69492,20 @@ dir = 5 }, /area/station/science/lower) +"xjc" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "Cargo Office" + }, +/obj/effect/mapping_helpers/airlock/access/all/supply/general, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/mapping_helpers/airlock/unres{ + dir = 8 + }, +/obj/structure/cable, +/turf/open/floor/iron/small, +/area/station/cargo/office) "xjg" = ( /turf/open/floor/iron/dark, /area/station/security/interrogation) @@ -69360,10 +69712,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) -"xmI" = ( -/obj/structure/closet/firecloset, -/turf/open/floor/plating, -/area/station/maintenance/port/greater) "xmL" = ( /obj/effect/turf_decal/tile/dark_red/opposingcorners, /obj/effect/landmark/start/security_officer, @@ -69381,20 +69729,6 @@ /obj/effect/mapping_helpers/requests_console/supplies, /turf/open/floor/iron/white/small, /area/station/service/hydroponics) -"xng" = ( -/obj/structure/disposalpipe/trunk, -/obj/machinery/disposal/delivery_chute{ - name = "Medical Deliveries" - }, -/obj/structure/sign/departments/exam_room/directional/north, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/effect/turf_decal/stripes/corner, -/obj/structure/plasticflaps{ - name = "Medical Deliveries" - }, -/obj/effect/turf_decal/delivery/white, -/turf/open/floor/iron, -/area/station/cargo/sorting) "xnk" = ( /obj/structure/cable, /obj/effect/turf_decal/siding/wood, @@ -69669,6 +70003,17 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/catwalk_floor/iron_white, /area/station/science/robotics/augments) +"xrt" = ( +/obj/structure/chair/sofa/bench/left{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/landmark/start/hangover, +/obj/effect/turf_decal/tile/neutral/half/contrasted{ + dir = 1 + }, +/turf/open/floor/iron/dark/side, +/area/station/hallway/primary/central/fore) "xru" = ( /obj/item/kirbyplants/random/fullysynthetic, /obj/machinery/airalarm/directional/east, @@ -69844,6 +70189,20 @@ dir = 4 }, /area/station/science/lobby) +"xsP" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 4 + }, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/sorting) "xsT" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -70057,12 +70416,6 @@ "xvF" = ( /turf/open/floor/catwalk_floor/iron_dark, /area/station/science/xenobiology) -"xvJ" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/closed/wall, -/area/station/cargo/miningfoundry) "xvK" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -70079,6 +70432,17 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/hallway/secondary/recreation) +"xvR" = ( +/obj/machinery/firealarm/directional/east, +/obj/effect/turf_decal/stripes, +/obj/effect/turf_decal/trimline/brown/line, +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 1 + }, +/obj/machinery/light/small/directional/east, +/obj/structure/sign/poster/official/random/directional/north, +/turf/open/floor/iron/dark/smooth_half, +/area/station/cargo/bitrunning/den) "xvT" = ( /turf/closed/wall/r_wall, /area/station/ai_monitored/turret_protected/aisat/maint) @@ -70121,11 +70485,6 @@ /obj/structure/bed/maint, /turf/open/floor/light/colour_cycle/dancefloor_b, /area/station/maintenance/starboard/central) -"xwn" = ( -/obj/machinery/atmospherics/pipe/smart/simple/dark/visible, -/obj/machinery/portable_atmospherics/pump, -/turf/open/floor/iron/dark, -/area/station/science/ordnance) "xwr" = ( /obj/effect/turf_decal/siding/thinplating_new/light, /obj/machinery/recharge_station, @@ -70240,14 +70599,17 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/command/heads_quarters/hos) -"xxT" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +"xyb" = ( +/obj/structure/window/spawner/directional/west, +/obj/effect/turf_decal/stripes/end{ + dir = 1 + }, +/obj/machinery/disposal/delivery_chute, +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, /turf/open/floor/plating, -/area/station/maintenance/port/greater) +/area/station/cargo/sorting) "xyh" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -70407,17 +70769,6 @@ /obj/effect/spawner/random/trash, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) -"xAx" = ( -/obj/machinery/door/airlock/engineering/glass/critical{ - heat_proof = 1; - name = "Supermatter Chamber" - }, -/obj/effect/mapping_helpers/airlock/access/any/engineering/general, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/turf/open/floor/engine, -/area/station/engineering/supermatter) "xAA" = ( /obj/effect/turf_decal/tile/green/half/contrasted{ dir = 1 @@ -70440,24 +70791,21 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai_upload) +"xAO" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/junction/flip{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/cargo/sorting) "xAR" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"xAV" = ( -/obj/structure/chair/sofa/bench/left{ - dir = 1 - }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/landmark/start/hangover, -/obj/effect/turf_decal/tile/neutral/half/contrasted{ - dir = 1 - }, -/obj/machinery/light/cold/directional/south, -/turf/open/floor/iron/dark/side, -/area/station/hallway/primary/central/fore) "xBd" = ( /obj/effect/turf_decal/plaque{ icon_state = "L7"; @@ -70584,6 +70932,21 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/port/lesser) +"xDl" = ( +/obj/structure/bed, +/obj/effect/decal/cleanable/dirt, +/obj/item/bedsheet/qm, +/obj/item/reagent_containers/cup/glass/bottle/tequila{ + pixel_x = -5; + pixel_y = 2 + }, +/obj/structure/sign/poster/contraband/random/directional/east, +/obj/machinery/camera/autoname/directional/east, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/floor/wood, +/area/station/command/heads_quarters/qm) "xDs" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/door/firedoor, @@ -70613,21 +70976,6 @@ /obj/machinery/portable_atmospherics/canister/air, /turf/open/floor/plating, /area/station/maintenance/starboard/central) -"xEl" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/spawner/random/structure/twelve_percent_spirit_board, -/turf/open/floor/wood, -/area/station/service/chapel/office) -"xEm" = ( -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/obj/machinery/photocopier, -/turf/open/floor/iron, -/area/station/cargo/office) "xEn" = ( /obj/machinery/atmospherics/pipe/layer_manifold/supply/hidden{ dir = 4 @@ -70918,6 +71266,13 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/catwalk_floor/iron, /area/station/science/lobby) +"xIl" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/landmark/start/hangover, +/turf/open/floor/iron, +/area/station/cargo/lobby) "xIu" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/trimline/blue/filled/line{ @@ -71049,6 +71404,16 @@ /obj/machinery/light_switch/directional/north, /turf/open/floor/iron/cafeteria, /area/station/science/circuits) +"xKn" = ( +/obj/machinery/door/airlock/hatch{ + name = "Tool Supply Corridor" + }, +/obj/effect/mapping_helpers/airlock/access/any/service/maintenance, +/obj/effect/mapping_helpers/airlock/unres{ + dir = 1 + }, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/cargo/lobby) "xKq" = ( /obj/machinery/rnd/production/circuit_imprinter/department/science, /obj/effect/turf_decal/bot, @@ -71063,6 +71428,12 @@ "xKG" = ( /turf/open/floor/iron, /area/station/hallway/primary/port) +"xKI" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "xKQ" = ( /obj/effect/turf_decal/tile/dark_red/fourcorners, /obj/machinery/firealarm/directional/north, @@ -71114,6 +71485,15 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/maintenance/port/lesser) +"xLw" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/lobby) "xLy" = ( /obj/effect/turf_decal/sand/plating, /obj/effect/decal/cleanable/dirt/dust, @@ -71198,10 +71578,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/starboard) -"xMu" = ( -/obj/effect/turf_decal/siding/wood, -/turf/closed/wall, -/area/station/service/library) "xMv" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -71261,14 +71637,6 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) -"xOm" = ( -/obj/effect/turf_decal/delivery, -/obj/machinery/door/poddoor/shutters{ - id = "qm_warehouse_aft"; - name = "Warehouse Shutters" - }, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "xOq" = ( /obj/effect/turf_decal/tile/dark_red/opposingcorners, /turf/open/floor/iron, @@ -71398,9 +71766,6 @@ /obj/item/kirbyplants/random/fullysynthetic, /turf/open/floor/wood/parquet, /area/station/medical/psychology) -"xPX" = ( -/turf/closed/wall/rust, -/area/station/cargo/office) "xPY" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -71540,6 +71905,14 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/iron/white, /area/station/hallway/primary/starboard) +"xRC" = ( +/obj/structure/cable, +/obj/effect/mapping_helpers/airlock/access/all/supply/general, +/obj/machinery/door/airlock{ + name = "Cargo Maintenance" + }, +/turf/open/floor/plating, +/area/station/maintenance/port/greater) "xRH" = ( /turf/closed/wall, /area/station/maintenance/fore/lesser) @@ -71633,6 +72006,20 @@ }, /turf/open/floor/iron/white/textured_large, /area/station/medical/medbay/lobby) +"xSY" = ( +/obj/structure/disposalpipe/trunk, +/obj/machinery/disposal/delivery_chute{ + name = "Medical Deliveries" + }, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/effect/turf_decal/stripes/corner, +/obj/structure/plasticflaps{ + name = "Medical Deliveries" + }, +/obj/effect/turf_decal/delivery/white, +/obj/structure/sign/departments/med/directional/north, +/turf/open/floor/iron/dark/side, +/area/station/cargo/sorting) "xSZ" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -72075,6 +72462,9 @@ }, /turf/open/floor/iron, /area/station/engineering/gravity_generator) +"xYo" = ( +/turf/open/floor/iron, +/area/station/cargo/lobby) "xYu" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, @@ -72113,11 +72503,6 @@ "xYO" = ( /turf/closed/wall/r_wall, /area/station/maintenance/department/bridge) -"xZd" = ( -/obj/machinery/portable_atmospherics/canister/air, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/maintenance/port/greater) "xZe" = ( /obj/effect/landmark/start/chaplain, /obj/effect/turf_decal/siding/wood/end{ @@ -72131,12 +72516,6 @@ /obj/effect/landmark/navigate_destination/det, /turf/open/floor/iron, /area/station/hallway/primary/port) -"xZh" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/closed/wall, -/area/station/maintenance/port/fore) "xZs" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt, @@ -72438,16 +72817,6 @@ "yeh" = ( /turf/closed/wall, /area/station/hallway/primary/starboard) -"yei" = ( -/obj/machinery/door/airlock/maintenance{ - name = "Atmospherics Maintenance" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/mapping_helpers/airlock/access/all/engineering/atmos, -/turf/open/floor/plating, -/area/station/maintenance/disposal/incinerator) "yel" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 @@ -72577,13 +72946,6 @@ "yfD" = ( /turf/closed/wall, /area/station/medical/surgery/theatre) -"yfF" = ( -/obj/machinery/vending/autodrobe, -/obj/effect/turf_decal/siding/wideplating/dark{ - dir = 8 - }, -/turf/open/floor/iron/small, -/area/station/commons/fitness/locker_room) "yfJ" = ( /obj/effect/spawner/random/structure/closet_maintenance, /obj/effect/decal/cleanable/dirt, @@ -72827,12 +73189,6 @@ /obj/machinery/light/no_nightlight/directional/south, /turf/open/floor/iron, /area/station/engineering/atmos) -"yjc" = ( -/obj/machinery/rnd/production/techfab/department/cargo, -/obj/effect/turf_decal/delivery/white, -/obj/machinery/light_switch/directional/south, -/turf/open/floor/iron/smooth, -/area/station/cargo/sorting) "yjd" = ( /turf/open/floor/iron/dark, /area/station/security/lockers) @@ -72843,6 +73199,35 @@ /obj/machinery/newscaster/directional/west, /turf/open/floor/iron/white/small, /area/station/science/cubicle) +"yjy" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/table/wood, +/obj/item/folder/red{ + pixel_x = -4; + pixel_y = -1 + }, +/obj/item/folder/blue{ + pixel_x = 3; + pixel_y = -30 + }, +/obj/effect/spawner/random/entertainment/toy_figure{ + pixel_x = 4; + pixel_y = 11 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, +/obj/item/pen{ + pixel_x = -2; + pixel_y = 4 + }, +/turf/open/floor/carpet, +/area/station/maintenance/hallway/abandoned_recreation) "yjE" = ( /turf/closed/wall/r_wall, /area/station/maintenance/department/engine) @@ -79478,7 +79863,7 @@ ybp qBK jMp cor -wPO +bDi wLw udH gbh @@ -79719,7 +80104,7 @@ rDU hYC bLp wGx -qht +cdp nrn lCT trX @@ -79735,7 +80120,7 @@ kNx tyc dJn nrn -jMQ +tjg wmL civ gbh @@ -81521,7 +81906,7 @@ fAD jWm ybO kVB -dzH +qrW rPg nrn trY @@ -81764,7 +82149,7 @@ wWm mPB pit wWm -pnO +idB pCn teV dix @@ -81775,7 +82160,7 @@ ykk hYC egC nlt -ckR +tRm nrn ktJ saq @@ -82017,7 +82402,7 @@ wBo sRf wBo hFO -oYf +jPl mPB wWm nlR @@ -82273,9 +82658,9 @@ wBo fgX uFS wBo -eKd +mln wBo -aeH +nzS dOP pit dHx @@ -82531,7 +82916,7 @@ bTI jnI gya qBM -ael +oBO wcF eqr mUe @@ -82545,7 +82930,7 @@ pjk pjk pjk qfK -fAD +klA hLx klg lRy @@ -82846,7 +83231,7 @@ gZi gZi gZi hrV -hzm +lOj dDB dDB dDB @@ -83105,7 +83490,7 @@ iVK jhC lOj hLT -hzm +lOj hLT lOj dDB @@ -83354,7 +83739,7 @@ haO slY kwY kPW -ueX +slY ikr iVK iVK @@ -83366,7 +83751,7 @@ kkV ipr lOj lOj -hzm +lOj lOj kdH kdH @@ -83572,8 +83957,8 @@ oVm fjf sRW fjf -itr -hWa +cHD +hhy wFK ybO qOr @@ -83625,7 +84010,7 @@ lOj dTW lwI lOj -jaN +vSn kdH kmo ouN @@ -83633,8 +84018,8 @@ rST ouN oQr kdH -pZu -jxJ +eEG +rzX slw dDd vuj @@ -83882,7 +84267,7 @@ bTE cob vWA lOj -mnZ +aNE kdH nJU kEA @@ -83890,8 +84275,8 @@ kQe ouR oRr kdH -pHo -pZz +dfM +iIG slw qtJ qdu @@ -84077,7 +84462,7 @@ pWm pRw pnl pxz -yei +enI ybO ybO qKA @@ -84348,7 +84733,7 @@ wmq vMI pKW kiP -tqn +dIw dYv jZl feu @@ -84358,7 +84743,7 @@ bGX jhj cGV tkU -ocZ +bst pqr tkU kUN @@ -84397,16 +84782,16 @@ jvR jir lPi uzJ -mQh -nJU +eib +knk ppk uzJ ovQ -oRr -poM +oSb +edA uzJ -mKB -aLm +ryX +slw slw lLi slw @@ -84595,7 +84980,7 @@ fjh wzv pnl dpH -kNv +sXj gAy jZl bKK @@ -84642,31 +85027,31 @@ ohl slY slY slY -ueX slY -ueX +slY +slY +nFo nFo -oCG nFo nFo nFo nFo -lxy -hzm +kxa +lOj jTA -ovQ -knk -ppk +qYG +pZK +xKI kQM -owl -oSb -ppk +kQj +pZK +xKI mjQ -fLF +qqB ahr nFX nFX -cdC +ozn pSP mhk mhk @@ -84851,9 +85236,9 @@ pWm uEH dfd pnl -uct -uct -uct +bjt +bjt +bjt jZl bEG rCk @@ -84900,31 +85285,31 @@ slY gOK slY hfc -kPW +bEv iNE nFo ach -lKH +ueL ylH nEl ejq tvN -lRc moz -kee -nua -nPt +moz +vjs +odX odX -lkI -oSg -lWF +odX +odX +odX +rWK mjV -pHs +sVQ mhk ihb ozt -dEQ sqz +bHw mhk iSD pbw @@ -85108,9 +85493,9 @@ wzv yil wzv pnl -uct -hGa -uct +bjt +lrN +bjt jZl oqq tmK @@ -85158,30 +85543,30 @@ gPN gZk iNE kPW -kPW +lxE nFo tPZ rPx cvP rWP -bCh +kMY jWA -lTv -oem -oem -nxo -oem -oem -owM -oSx +uzJ +jtB +jJw +fxO +rPM +fxO +qMI +rfP +fiE qby qby qby +iJH +iJH mhk -mhk -mhk -xxT -mhk +bHw mhk pGS sUN @@ -85363,12 +85748,12 @@ kNn yil xnL yil -bXb +jHN pnl pnl pnl pnl -srw +emz tXF qaU yew @@ -85413,32 +85798,32 @@ xpl slY gPN slY -jCo -kPW +kwY +bEv hfc nFo hNv -lbF -lLq +iJp +ggn nyf ejq -jkS -lTN -mRD +oEL +uzJ +vzD +amq mRD -knL kEH mRD -llg -oSx +gGA +rfP +fiE qby -mjX +frY mLh -nry -qRq -mhk -vdL +njv +rev mhk +bHw mhk cXb sry @@ -85620,10 +86005,10 @@ rjo pWm pWm pWm -bXb -bXb -bXb -bXb +jHN +jHN +jHN +jHN yil fTJ qpp @@ -85639,7 +86024,7 @@ ttL glo dPW vCp -moN +vgL kWY mzx dcK @@ -85667,34 +86052,34 @@ dDB mEB gDH mFA -ueX slY slY -jCo +slY +bEv slY slY nFo nFo +xvR +pIo nFo nFo -nFo -nFo -kZB -lUz -ohj -ohj -nxX -ohj -ohj -oxw -lFG +boG +hmR +jGC +rtH +eti +eti +eti +dvP +odX +oyH lWY -mkF +oZZ mLk -nsL -kVn +hXM +pmD srn -iHT pRc mhk pbw @@ -85877,7 +86262,7 @@ mmT vtJ acg pWm -efn +eZd wzv wzv wzv @@ -85926,32 +86311,32 @@ gEc gIx sjq sjq -hyO -roi -jCi +guq +jCo +tki nPX ouT -jMb -kzI -kzI +jjq +jjq +jjq rST iUN -jlv -sRR -odX -fts -nyE +pIg +rLp +moz +iqM uzJ -axj uzJ -azK +sjX +uzJ +mLz +cNw qby -mkO +nzd mMt dVW -qSS +xcA mhk -tKf kwy mhk bBh @@ -85965,7 +86350,7 @@ iSD rnr aCz wAW -spo +wXk xiF gEx yea @@ -86136,8 +86521,8 @@ bOa pWm bvt bvt -nbN -ggr +lAM +fgo oii pnl gmv @@ -86180,35 +86565,35 @@ dDB dDB slY slY -slY hTr slY slY -iBo -slY +qgX +mmZ +jjq jiu -jCP -kia -kia -kia +obk +tfj +kzI +gus oGl iVx lzp jFB -tll +mRQ +uJI wuM -nyS pBD wuM pBD +uQt wuM -vLP wuM -vLP +wuM +mhk mhk mhk mhk -xmI ivh mhk fme @@ -86228,7 +86613,7 @@ uAk yea vmX vij -xEl +oNQ wyl fEC fEC @@ -86403,14 +86788,14 @@ jDi jDi jDi pnl -srw +emz pnl pnl jZl xck -cag +hyS xck -bJH +kMg xck cGV bNq @@ -86418,9 +86803,9 @@ bNq ecq bNq bNq -hhr +pTK bNq -gUQ +uiK bNq bNq bNq @@ -86435,37 +86820,37 @@ blb blb blb blb -blb slY hLD hTD oOK slY -hfC +lFb slY jjq -hyb +jjq +dcu jNc qSH -vNv +mKR rST iVI -jmK +fma jHB -gxL +sRs +qMM wuM -bKz -kFg -kRJ -bvV -lGk -uKP +rKn +bdi +lsH +nmE +dFn wCI -swV +eJi mhk nFY mhk -mhk +mCV mze iLH oyz @@ -86692,32 +87077,32 @@ dDB blb dDB dDB -dDB slY tjY siG nEA slY -oPi -xOm +tBE +ehu +wtd pAU -nLH -nUx -rie -ipd +fxc +nku +jKl +jgj rTA -nTi -lzA +gFi +xco lUI -tVR -pBD -nnc -jZc +rJQ +iKn +gBs +ggK +mek kSb -tca -lGT -lWR -mlr +cjc +hlP +hHX nxJ mhk xYJ @@ -86829,7 +87214,7 @@ aWt sis sis sis -lhd +mdp xjz blb dDB @@ -86949,35 +87334,35 @@ dDB blb dDB dDB -dDB slY rhm cis slY slY -oPo -xOm -tdD +lFb +qTS +wtd +eQI vrW -qul -rif -tro +uUz +uSM +sEd rTA -sgC +csj eDy uzJ -uzJ +sRs +lzp pBD -usg -uSt -kSf -lme -lHe -lWU -tca +rJB +cUV +ksE +woY +uUq +wyG urF mhk -xZd +cEp mhk sNW mze @@ -86995,14 +87380,14 @@ cdB wAW rpB jzr -qMw -iEi -dTQ -cVO -uxY -czu -dny -doi +gLS +tsl +pMX +cDQ +buc +rFU +qgZ +oSB fEC kJJ qVP @@ -87081,7 +87466,7 @@ eua izh xAG jWd -lGO +rEV cZA hyX tBm @@ -87171,7 +87556,7 @@ kNn pnl pnl pnl -srw +emz pnl tOc oCE @@ -87206,37 +87591,37 @@ dDB tYT aJq dDB -dDB -ueX +slY +slY mEB slY +vse +mFA slY -nMV -dRD -xwz -xwz -gxr -fSe +jjq +jjq +fCK +jjq ibe ipP rST eeb -lzU -dfN -pJn +fHX +sAy +jfP +xeZ wuM -pwJ -uSG -kSO -gNC +cbq +eCO +bIu lHk -lXf +nhk lKg efS mhk -qTJ mhk -rGN +mhk +mhk mze mhk feL @@ -87252,14 +87637,14 @@ iSD wBm wXk pEO -nRa +xOS rQC von pvC aLS wzS wzS -pPx +lXM fEC rui qVP @@ -87466,33 +87851,33 @@ dDB dDB dDB blb -dDB slY -ohb +bUq xwz -fSe -pIi -tPa xwz +cyQ +cuZ +eNa xwz mTl +mTl rST -sgL -swO -kYZ -msy -vLP -utH -pBD +wAh +jry +rFv +dwy +bbV +wuM +wuM wuM vkN lHT vkN -mhk -mhk -mhk -mhk -mhk +wuM +wuM +sHW +rrJ +uiO mhk mze mhk @@ -87506,10 +87891,10 @@ lFm kzV uaa eYB -mIE +vJE wXk glM -ldl +jmC yea vrf von @@ -87723,33 +88108,33 @@ dDB dDB dDB blb -dDB -ueX -ohl +slY +vse xwz -gGw -nsX -hoV -vuH +cky +juo +iDm +biV xwz -rFa -rTD -iWb +gPO +moq +jro +jnn jnn bDN bDN -qto -kpT +ebM +sfL kFD kTp -lmv -lIf -lXn -srn -ntJ -nGu -xYJ -ina +itf +qnU +wbt +kTp +oOm +jJO +kik +uVB mhk gLV mhk @@ -87762,11 +88147,11 @@ tBk miF miF miF -juP +etJ wAW -lqq +mFd ckP -xht +amX yea yea vJn @@ -87980,36 +88365,36 @@ dDB dDB dDB blb -dDB slY -mFA +vse xwz -mdX -fCd -iJh +unG +qrJ +iUI jwU xwz -rFP -rTU -sgR -obH -sSx -tnu -tPg -uuN +hYQ +pNa +wzz +dXu +ahI +lkL +hGA +tsk +nzy btG pBD -vLD -lIn -lXY -mhk -ina -pyA -ina -xYJ -xYJ +qhU +rRl +mCW +wuM +pZC +yjy +jmX +tri +qYq xsD -srn +mhk xxj cSb nDj @@ -88020,11 +88405,11 @@ cxz cZs cZs eYB -mIE +vJE wXk uQK -mwK -kyE +bfS +fMf yea vJA vKa @@ -88237,33 +88622,33 @@ dDB dDB dDB blb -dDB slY -ohl -uuR -rZe -jIH -bbK +vse +and +nLi +cNl +iiR ePn uki -rFW -bCZ -uqE -fkd -sSA +iek +xgK +upM +jQG +abv wcP -qDP -wwJ -yjc -vLP -oyZ -lIq -lYt -mhk -xYJ -lwC -tYL -mhk +kRb +rJL +nzy +gOS +wuM +giA +jFg +uur +wuM +pBo +gEb +dgy +lud mhk fpN mhk @@ -88452,7 +88837,7 @@ kMe nDJ lWV cYt -wjw +tHo gAV tDu ccA @@ -88467,14 +88852,14 @@ oYv jJg bsG wqW -cQV +jHS tdb tdb tdb tdb qyr mLZ -vHU +naK lER hRO knv @@ -88494,36 +88879,36 @@ blb blb slY mEB -ueX slY -ohl +iZx +xwz xwz -pjG -hZe -bOY -rzL +kOA +iUA +gZR xwz -rGq -rUt -sgR -wcz -eIF -juJ -mTe -kqL -kFI +rWR +iQM +lvN +kJu +fvX +cOs +kiW +xAO +rmc +hjS pBD -wSf -lIw -lYw -mhk -qjn -uiw -ina +lsH +pZt +mac +wuM +oLE +lmp +iAt +tQn mhk -ozt -mrn -vRn +mSA +gTj ani bKv jCm @@ -88753,32 +89138,32 @@ ueX hNo wZF wZF -had -xwz -xwz -xvJ -xwz -fSe -xwz -xng -pjL -llN -jqu -sSU -vuJ -hEi -kqQ -uUb +tuw +slY +slY +fAn +slY +slY +xSY +khw +xsP +oxt +gIr +jJB +sBn +ePr +eCV +bjf wuM -lmR -lJV -cYT -mhk -mhk -dDi -mhk +mta +xDl +kjb +wuM +dLl +twm +dLl +dLl mhk -sNW jQv mhk oOC @@ -88797,7 +89182,7 @@ beN oRw xle xle -slZ +hzr iIU wAj xle @@ -88957,7 +89342,7 @@ ayK ayK ayK lQU -ruR +mOc lQU ayK lQU @@ -88965,7 +89350,7 @@ lQU lQU ayK lQU -ruR +mOc lQU ayK rDV @@ -89009,28 +89394,28 @@ mEB gDH mFA gKi -gPT -qQP -pJQ -wZF -pqv -wZF -vdl +lOg +ohl slY -ueX -rVQ -oFi -jqA +gTw +nPg +gDH +slY +slY +slY +xyb +gJb lUT -pih +lYe mTl -kqW kFJ -slY -slY -mhk -mhk -mhk +uHE +kFJ +wuM +wuM +wuM +wuM +wuM rZb jXc xYJ @@ -89267,30 +89652,30 @@ gEc mFA slY slY +oOf +qSF +rFm +fQv +wZF +wZF +wDQ slY slY -slY -xZh -slY -qQP -roi -slY -slY -slY -xZh -xZh -slY -slY -uxd -kFU -kXR -slY -rXw +uiU +bLG +diN +xat +gSA +nwb +qkC +wvF +mhk +qTJ lYT mhk uiw mhk -mhk +sNW mhk mhk ete @@ -89523,25 +89908,25 @@ slY slY mFA slY -aus -voz -sRg -hmb -huh slY slY -qQP -iqj -sjq -sjq -syx -jIh -csA -jhs -kso -kYG -kYG -pep +slY +slY +bmO +slY +slY +qgX +kAn +slY +fWj +hgp +hgp +lKf +cCC +aBQ +mFQ +mFQ +xRC nJo avY oHk @@ -89553,7 +89938,7 @@ vMP eRy mhk iSD -keQ +bqA cxz vUS miF @@ -89724,8 +90109,8 @@ uqe uLW blb aKm -fxp -nKe +eXl +jNV guh cBl fJe @@ -89778,27 +90163,27 @@ blb blb blb ueX -gIx -gKK -vOm -tOw -hVk -gpP -iJq -ivm +nmV slY -kPW -slY -slY -skW -wOM -jpR -ueX -aae -uxd -xaZ -dZm +aus +voz +sRg +hmb +huh +ivm slY +brO +wZF +dTj +umL +uJV +uJV +gnO +gqw +gEa +iAL +spA +mhk ilo tYL mhk @@ -89810,7 +90195,7 @@ mhk oTH mhk lji -wZD +qzP nDj sRF miF @@ -90035,27 +90420,27 @@ dDB dDB dDB slY -atx -ueX -gQm -hbw -hfZ -hmh -pGE +aBt +uPf +vOm +tOw +hVk +gpP +iJq qfV slY -kPW -kAn -slY -xZh -slY -xZh +apP +jHC slY -slY -ksx -mEB -slY -ueX +hjA +mnU +nzO +jln +jAN +gEa +bzW +sKO +mhk jQv sNW mhk @@ -90296,22 +90681,22 @@ slY slY eVc hbw -wOZ -hmj +qZX +lWE arL sRg slY slY slY slY -nHp -jrX -jIN -xEm -xPX -ksA -oJR -oiw +wnd +xat +fIq +jBJ +wnd +xjc +aMI +xat mhk jQv sqz @@ -90511,7 +90896,7 @@ szg tpW pUM kMe -prd +knw fGf ayK izf @@ -90551,24 +90936,24 @@ sRg cJT eEq sRg -gQG +iGb hbw -aGI -hmQ +nLQ +mpL pGE -jug -rqq -rqq -rqq -vpb -lmS -lAk -jIY -jDm -tfX -khZ -nSY -nYQ +uwO +bRA +bRA +bRA +xKn +dmO +pVV +axP +ivC +kgp +ftI +hao +uIG mhk ifl mhk @@ -90810,25 +91195,25 @@ mGY hXf xGf jLb -hgd -mrP +cOa +lPv xrZ sRg -xat -xat -xat -xat -tov -jEK -jJc -pOg -kft -ktM -sOP -otG +tlG +tlG +tlG +tlG +lbe +qCG +pbV +sxQ +day +mxh +vRc +jBN mhk oEn -lPK +tOu mhk mTN wTO @@ -90839,7 +91224,7 @@ oUJ wCR oOC iRE -rya +mXb kZI oUb yhX @@ -91028,10 +91413,10 @@ gAV qkq wRy urz -vDS -ugt -lVv -nHq +dkD +iEc +uuA +oba exQ fib cca @@ -91071,21 +91456,21 @@ hgn jEQ gRL hcl -xat -vhe -vhe -wnd -lmS -lBn -jJc -lvu -hPd -kua -lEm -oiL +tlG +pRO +wVr +puk +dmO +kkD +iGW +xhC +ioJ +xIl +xYo +hAO mhk -kPo -wkK +uLz +pRc mhk wCR wCR @@ -91274,7 +91659,7 @@ dyI dyI ozQ ozQ -xAx +wxJ brA brA dyI @@ -91288,7 +91673,7 @@ ayK swK jTf nCC -rDc +bwW qQi sVu wfn @@ -91327,26 +91712,26 @@ hgZ hgZ kaz eOk -qgK -xPX -wzo -hLm -bGU -wSi -gNV -wqI -gEJ -xat -wnd -kIO -wnd -mhk +mYE +naB +oyv +vZS +rDs +dAZ +eTL +sKj +gXB +rhF +xLw +oim +wie mhk -sBf +jab +rSM mhk -mUt +ksq wTO -uSI +qVR scY rJo bHU @@ -91545,7 +91930,7 @@ ayK nXC nmi cED -nQE +mjh rLj gNt iIK @@ -91585,21 +91970,21 @@ qiz fgt pHC qiz -xat -rrq -iqq -xPX -wnd -wnd -jKu -jWZ -xRV -kuq -msq -laD -gSX +tlG +rWa +peE +tlG +puk +puk +tlG +tJY +kxu +cjf +mGI +tlG mhk -jQv +rXw +rSM mhk wCR wCR @@ -91788,7 +92173,7 @@ cBd cBd dyI ozQ -jvm +vkR brA dyI oer @@ -91802,7 +92187,7 @@ ayK wfn wfn osT -qxF +wnf wap wfn gKL @@ -91846,15 +92231,15 @@ xRV xRV xRV xRV -lCg -lCg -kYa -rBh -xRV -iLF -kJb -laL -loj +ccO +mWU +lnL +dOH +rbT +ppP +hSn +hpb +mhk mhk jby mhk @@ -92101,20 +92486,20 @@ nxI sxZ qGc pfw -sar -tSA -frI -frI -uIv -frI -aDJ -hKV -mZg +dEp +vWy frI +aJD +aJD +wqx +aJD +knR +mDk frI -oyp +dBn +nwf mXZ -mUm +ogq mAR qWG fkS @@ -92362,8 +92747,8 @@ uAo iIv uAo jsG -jLr -aHS +oQP +mIp fHN jpu pWM @@ -92617,9 +93002,9 @@ nTa tlt eIM yjZ -yjZ -yjZ -jtd +pzk +pzk +eII xSw kfw yeD @@ -92878,7 +93263,7 @@ xZS xZS xRV xRV -vIJ +eyx kux wGz yaL @@ -93405,7 +93790,7 @@ cKt jVM hIm azq -iTv +api wMg lql vtr @@ -93670,7 +94055,7 @@ mmL qDC btY mUi -xMu +xeO qmM vSi hEJ @@ -94166,11 +94551,11 @@ xZS vET ncL qwz -jVM -jVM -jVM -jVM -jVM +yaL +yaL +yaL +yaL +yaL jVM eAm jVM @@ -94423,7 +94808,7 @@ uVT vET ncL wQB -jVx +ebn jVM rXy bFO @@ -94947,7 +95332,7 @@ ptX hsH srg jVM -ayT +nJK sZo yfC lnN @@ -95200,7 +95585,7 @@ jVM jVM jVM jVM -pSI +qtW jVM xlU jRK @@ -95453,11 +95838,11 @@ kvT wQB cZi jVM -lbl -bwy -mqz +dgt +sTN +nHb jVM -gls +cMH jVM lzB jVM @@ -95710,11 +96095,11 @@ kyO wQB drC jVM -lzW -dbJ -lMH +dqF +sKh +iFG jVM -gls +cMH jVM uZY jVM @@ -95967,11 +96352,11 @@ ncL wQB ydz jVM -lEO -eHv -bes -pSI -gls +bgl +sjn +mrY +qtW +cMH jVM joR jVM @@ -96494,7 +96879,7 @@ mgW yfC edG wBc -jJd +qiC qiC ghj qiC @@ -97506,7 +97891,7 @@ opn jYY ndJ rJZ -eBC +egW xRV xRV xRV @@ -97528,7 +97913,7 @@ xmt hrl xmt xmt -lHZ +xli eNP qFc cEo @@ -97765,8 +98150,8 @@ dCu eXR wQB rHl -sVO -lbi +dMC +ucO jVM jTn xXe @@ -98021,7 +98406,7 @@ psc dCu rJZ wQB -xAV +xrt txW nCX jVM @@ -98537,7 +98922,7 @@ rJZ wQB eIO xND -ind +czh jVM oZy jVM @@ -100356,7 +100741,7 @@ xkV ecC cvV spH -elN +whg dPp sFs fZZ @@ -100870,7 +101255,7 @@ gyy xkV swW vkh -oNW +kPh cSy bpY sMt @@ -101891,7 +102276,7 @@ rZq ycX pBu khY -lvr +lmZ aGq khY khY @@ -102386,7 +102771,7 @@ cCD gcz jyM uoB -jZn +eSA baJ rji vAw @@ -105222,7 +105607,7 @@ sRL bCP dqB pIf -lZP +upF jgF wqj rEa @@ -105734,7 +106119,7 @@ nVa fuD xVV eWP -lNN +vXv lWp xhD heN @@ -106767,7 +107152,7 @@ jvQ eul eeJ egJ -yfF +egA gMq duT gtk @@ -107529,7 +107914,7 @@ rqw sRL sRL sRL -nqa +ceD sRL sRL eeJ @@ -114219,7 +114604,7 @@ xQJ bfE rIo xQJ -ohN +jIn oUC oPM sDj @@ -114992,7 +115377,7 @@ noB xQJ avN oPM -rYt +jLt wBI sEr dQQ @@ -118775,7 +119160,7 @@ dDB dDB dDB dDB -mzv +dRz dDB dDB dDB @@ -121442,7 +121827,7 @@ xok xok xok xok -eog +dTi tbI xok qNO @@ -122217,7 +122602,7 @@ lkV iJL rci vTv -dpz +juU boY agI kQt @@ -122988,7 +123373,7 @@ nWh xnR aLC wLZ -xwn +eKV cns vwJ kQt @@ -129173,10 +129558,10 @@ uxL lhl jxD ylD -hqH +cWC vzv brz -sJf +egg ylD wyj dYR diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 70090fc32fcee..64fe3288fba40 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -285,9 +285,6 @@ "agd" = ( /obj/effect/turf_decal/tile/red/fourcorners, /obj/structure/closet/secure_closet/security/cargo, -/obj/machinery/power/apc/auto_name/directional/west, -/obj/structure/extinguisher_cabinet/directional/east, -/obj/machinery/newscaster/directional/east, /turf/open/floor/iron/dark, /area/station/security/checkpoint/supply) "agi" = ( @@ -470,6 +467,8 @@ /obj/machinery/light/small/directional/west, /obj/machinery/firealarm/directional/west, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/power/apc/auto_name/directional/south, +/obj/structure/cable, /turf/open/floor/iron/dark, /area/station/security/checkpoint/supply) "aja" = ( @@ -5799,10 +5798,8 @@ /area/station/security/courtroom) "cap" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 1 - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, /turf/open/floor/iron, /area/station/cargo/sorting) "caO" = ( @@ -11741,8 +11738,6 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/decal/cleanable/wrapping, /obj/item/sales_tagger{ pixel_x = -5; @@ -12659,7 +12654,7 @@ /obj/effect/turf_decal/trimline/yellow/filled/line, /obj/effect/turf_decal/trimline/brown/filled/warning, /obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, /turf/open/floor/iron, /area/station/cargo/sorting) "exC" = ( @@ -13236,7 +13231,6 @@ /turf/open/floor/iron, /area/station/service/hydroponics) "eKG" = ( -/obj/structure/cable, /obj/structure/disposalpipe/segment{ dir = 4 }, @@ -15706,8 +15700,6 @@ /turf/open/floor/circuit/red, /area/station/ai_monitored/turret_protected/ai_upload) "fEV" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/tile/brown/fourcorners, /obj/machinery/door/airlock/security/glass{ name = "Security Post - Cargo" @@ -16799,7 +16791,6 @@ /area/station/science/ordnance/storage) "gav" = ( /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/brown/opposingcorners, /obj/structure/table, /obj/machinery/photocopier{ pixel_y = 9 @@ -19019,7 +19010,6 @@ /turf/open/floor/iron/dark, /area/station/medical/morgue) "gPw" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/security/checkpoint/supply) "gPA" = ( @@ -19206,9 +19196,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 1 - }, /obj/structure/fake_stairs/directional/north, /turf/open/floor/iron, /area/station/cargo/storage) @@ -19493,8 +19480,8 @@ }, /obj/structure/chair/office/light, /obj/effect/landmark/start/depsec/supply, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, /turf/open/floor/iron/dark, /area/station/security/checkpoint/supply) "gZu" = ( @@ -19536,10 +19523,10 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 1 }, -/obj/effect/turf_decal/tile/brown/opposingcorners, /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, /turf/open/floor/iron, /area/station/cargo/sorting) "hav" = ( @@ -20653,6 +20640,7 @@ "hvB" = ( /obj/effect/turf_decal/trimline/green/filled/line, /obj/effect/turf_decal/trimline/brown/filled/warning, +/obj/structure/cable, /turf/open/floor/iron, /area/station/cargo/sorting) "hvI" = ( @@ -21110,7 +21098,10 @@ /obj/structure/disposalpipe/segment{ dir = 6 }, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown/opposingcorners, /turf/open/floor/iron, /area/station/cargo/sorting) "hCl" = ( @@ -21510,6 +21501,7 @@ /obj/effect/turf_decal/arrows/red{ dir = 4 }, +/obj/effect/spawner/random/structure/crate, /turf/open/floor/iron, /area/station/cargo/storage) "hKV" = ( @@ -21667,6 +21659,7 @@ /obj/effect/turf_decal/trimline/red/filled/line, /obj/effect/turf_decal/trimline/brown/filled/warning, /obj/structure/disposalpipe/segment, +/obj/structure/cable, /turf/open/floor/iron, /area/station/cargo/sorting) "hOp" = ( @@ -22147,9 +22140,6 @@ /area/station/command/teleporter) "hWC" = ( /obj/structure/cable, -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 1 - }, /obj/structure/fake_stairs/directional/north, /turf/open/floor/iron, /area/station/cargo/storage) @@ -23112,7 +23102,9 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, /turf/open/floor/iron/dark, /area/station/security/checkpoint/supply) "imU" = ( @@ -24767,7 +24759,9 @@ pixel_x = 9 }, /obj/machinery/recharger, -/obj/machinery/digital_clock/directional/east, +/obj/effect/mapping_helpers/requests_console/assistance, +/obj/effect/mapping_helpers/requests_console/supplies, +/obj/machinery/requests_console/auto_name/directional/east, /turf/open/floor/iron/dark, /area/station/security/checkpoint/supply) "iQd" = ( @@ -27359,6 +27353,8 @@ dir = 4 }, /obj/effect/landmark/start/cargo_technician, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/tile/brown/opposingcorners, /turf/open/floor/iron, /area/station/cargo/sorting) "jHQ" = ( @@ -28165,11 +28161,11 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/structure/cable, /obj/machinery/door/firedoor, /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable, /turf/open/floor/iron, /area/station/cargo/lobby) "jUu" = ( @@ -30344,9 +30340,6 @@ dir = 8 }, /obj/machinery/camera/directional/west, -/obj/machinery/requests_console/directional/west, -/obj/effect/mapping_helpers/requests_console/assistance, -/obj/effect/mapping_helpers/requests_console/supplies, /obj/item/dest_tagger{ pixel_x = -9; pixel_y = 12 @@ -30355,6 +30348,9 @@ pixel_x = -11; pixel_y = -3 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, /turf/open/floor/iron/dark, /area/station/security/checkpoint/supply) "kJx" = ( @@ -31766,10 +31762,10 @@ /turf/open/floor/iron, /area/station/cargo/storage) "liX" = ( -/obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/door/firedoor, +/obj/structure/cable, /turf/open/floor/iron, /area/station/cargo/lobby) "lje" = ( @@ -42830,10 +42826,10 @@ /obj/effect/turf_decal/trimline/brown/warning{ dir = 8 }, -/obj/structure/extinguisher_cabinet/directional/north, /obj/machinery/light/small/directional/north, /obj/structure/disposalpipe/segment, -/obj/effect/spawner/random/structure/crate, +/obj/structure/tank_holder/extinguisher, +/obj/structure/sign/clock/directional/north, /turf/open/floor/iron, /area/station/cargo/sorting) "pke" = ( @@ -44583,11 +44579,9 @@ /obj/effect/turf_decal/trimline/brown/filled/corner{ dir = 1 }, -/obj/effect/turf_decal/trimline/brown/filled/corner{ - dir = 4 - }, /obj/effect/decal/cleanable/wrapping, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, /turf/open/floor/iron, /area/station/cargo/sorting) "pPp" = ( @@ -47317,9 +47311,9 @@ /area/station/security/prison) "qNL" = ( /obj/effect/turf_decal/tile/red/half/contrasted, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, /turf/open/floor/iron/dark, /area/station/security/checkpoint/supply) "qNO" = ( @@ -49648,6 +49642,9 @@ /obj/effect/turf_decal/tile/red/anticorner/contrasted{ dir = 1 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, /turf/open/floor/iron/dark, /area/station/security/checkpoint/supply) "rBU" = ( @@ -49880,9 +49877,7 @@ /turf/open/floor/carpet, /area/station/command/heads_quarters/hop) "rGk" = ( -/obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/power/apc/auto_name/directional/north, /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 1 }, @@ -49890,6 +49885,7 @@ /obj/machinery/airalarm/directional/north, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/modular_computer/preset/cargochat/cargo, +/obj/structure/cable, /turf/open/floor/iron, /area/station/cargo/sorting) "rGm" = ( @@ -50316,7 +50312,6 @@ /area/station/ai_monitored/turret_protected/aisat_interior) "rNA" = ( /obj/structure/disposalpipe/segment, -/obj/effect/spawner/random/structure/crate, /turf/open/floor/iron, /area/station/cargo/sorting) "rNI" = ( @@ -50652,8 +50647,8 @@ /turf/open/floor/iron, /area/station/commons/locker) "rUd" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/power/apc/auto_name/directional/east, +/obj/structure/cable, /turf/open/floor/iron, /area/station/cargo/sorting) "rUo" = ( @@ -52823,6 +52818,7 @@ "sHX" = ( /obj/effect/turf_decal/tile/brown/opposingcorners, /obj/effect/decal/cleanable/oil/slippery, +/obj/structure/cable, /turf/open/floor/iron, /area/station/cargo/sorting) "sIe" = ( @@ -53903,12 +53899,6 @@ dir = 1 }, /area/station/hallway/secondary/entry) -"sZT" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/plating, -/area/station/security/checkpoint/supply) "sZU" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -55003,12 +54993,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/aft/lesser) -"tvv" = ( -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 8 - }, -/turf/closed/wall, -/area/station/command/heads_quarters/qm) "tvE" = ( /turf/closed/wall/r_wall, /area/station/command/gateway) @@ -57902,7 +57886,6 @@ /turf/open/floor/iron, /area/station/security/mechbay) "uuW" = ( -/obj/effect/turf_decal/tile/brown/opposingcorners, /obj/structure/table, /obj/machinery/fax{ fax_name = "Cargo Office"; @@ -57912,7 +57895,7 @@ pixel_x = 8; pixel_y = 8 }, -/turf/open/floor/plating, +/turf/open/floor/iron, /area/station/cargo/sorting) "uvw" = ( /obj/machinery/status_display/supply{ @@ -58065,6 +58048,7 @@ "uyh" = ( /obj/effect/turf_decal/tile/brown/opposingcorners, /obj/machinery/holopad, +/obj/structure/cable, /turf/open/floor/iron, /area/station/cargo/sorting) "uyi" = ( @@ -58105,8 +58089,6 @@ /obj/structure/disposalpipe/segment{ dir = 9 }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/item/stamp/granted{ pixel_x = -7; pixel_y = 4 @@ -58434,6 +58416,7 @@ /obj/effect/turf_decal/arrows/red{ dir = 4 }, +/obj/effect/spawner/random/structure/crate, /turf/open/floor/iron, /area/station/cargo/storage) "uET" = ( @@ -62979,7 +62962,6 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/effect/turf_decal/tile/brown/opposingcorners, /turf/open/floor/iron, /area/station/cargo/sorting) "wcf" = ( @@ -63533,6 +63515,9 @@ /obj/machinery/door/airlock/security/glass{ name = "Security Post - Cargo" }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, /turf/open/floor/plating, /area/station/security/checkpoint/supply) "wmf" = ( @@ -67539,16 +67524,18 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/structure/tank_holder/extinguisher{ + pixel_x = -9 + }, /turf/open/floor/iron/dark, /area/station/security/checkpoint/supply) "xJv" = ( /obj/machinery/light/directional/north, /turf/open/floor/iron/recharge_floor, /area/station/security/mechbay) -"xJy" = ( -/obj/effect/turf_decal/tile/brown/opposingcorners, -/turf/closed/wall, -/area/station/security/checkpoint/supply) "xJA" = ( /obj/structure/sign/warning/docking, /turf/closed/wall, @@ -68789,7 +68776,7 @@ "ygk" = ( /obj/effect/turf_decal/trimline/purple/filled/line, /obj/effect/turf_decal/trimline/brown/filled/warning, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, /turf/open/floor/iron, /area/station/cargo/sorting) "ygp" = ( @@ -88975,10 +88962,10 @@ gfa eOl vjg mLp -tvv +kQP xTe xTe -tvv +kQP kQP wdM asT @@ -90014,11 +90001,11 @@ fhB hxd rtG oor -xJy +oor wme oor xbu -sZT +oor oor oor pNk @@ -90277,7 +90264,7 @@ kJk xJj gZq aiy -afW +oor mnP tEr iOc diff --git a/_maps/map_files/wawastation/wawastation.dmm b/_maps/map_files/wawastation/wawastation.dmm index 096cf003ac4eb..8eca8d06b6112 100644 --- a/_maps/map_files/wawastation/wawastation.dmm +++ b/_maps/map_files/wawastation/wawastation.dmm @@ -4937,9 +4937,9 @@ /turf/open/floor/iron/dark, /area/station/security/courtroom) "bLI" = ( -/obj/machinery/processor/slime, /obj/effect/turf_decal/bot_red, /obj/effect/turf_decal/stripes/line, +/obj/machinery/processor/slime, /turf/open/floor/iron/white/textured_large, /area/station/science/xenobiology) "bLS" = ( @@ -17542,10 +17542,8 @@ /area/space/nearstation) "gkj" = ( /obj/effect/turf_decal/tile/blue/fourcorners, -/obj/machinery/camera/autoname/directional/north{ - network = list("ss13","medbay") - }, /obj/machinery/iv_drip, +/obj/machinery/light/cold/dim/directional/north, /turf/open/floor/iron/white, /area/station/medical/treatment_center) "gkt" = ( @@ -22068,6 +22066,7 @@ /obj/effect/turf_decal/tile/blue/fourcorners, /obj/machinery/light_switch/directional/west, /obj/item/wrench/medical, +/obj/machinery/light/cold/dim/directional/west, /turf/open/floor/iron/white, /area/station/medical/treatment_center) "hPs" = ( @@ -26151,6 +26150,7 @@ }, /obj/structure/closet/secure_closet/captains, /obj/machinery/firealarm/directional/north, +/obj/item/storage/lockbox/medal, /turf/open/floor/carpet/royalblue, /area/station/command/heads_quarters/captain/private) "jpe" = ( @@ -38292,7 +38292,7 @@ }, /obj/structure/cable, /obj/effect/mapping_helpers/apc/cell_5k, -/turf/open/floor/circuit/green, +/turf/open/floor/circuit/green/telecomms/mainframe, /area/station/ai_monitored/turret_protected/ai) "nAa" = ( /obj/machinery/door/firedoor/border_only{ @@ -41519,7 +41519,7 @@ name = "AI Core Shutters" }, /obj/structure/cable, -/turf/open/floor/circuit/green, +/turf/open/floor/circuit/green/telecomms/mainframe, /area/station/ai_monitored/turret_protected/ai) "oOb" = ( /obj/effect/turf_decal/tile/neutral{ @@ -46862,6 +46862,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/item/stack/sheet/mineral/plasma, /turf/open/floor/iron/white/textured_large, /area/station/science/xenobiology) "qGN" = ( @@ -47527,11 +47528,11 @@ /turf/open/floor/plating, /area/station/maintenance/department/engine) "qUi" = ( -/obj/machinery/processor/slime, /obj/effect/turf_decal/bot_red, /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/machinery/processor/slime, /turf/open/floor/iron/white/textured_large, /area/station/science/xenobiology) "qUl" = ( @@ -48756,6 +48757,7 @@ pixel_y = 8 }, /obj/effect/turf_decal/stripes/line, +/obj/item/stack/sheet/mineral/plasma, /turf/open/floor/iron/white/textured_large, /area/station/science/xenobiology) "rms" = ( @@ -65509,10 +65511,12 @@ /turf/open/floor/iron/dark, /area/station/command/bridge) "xcC" = ( -/obj/machinery/light/cold/dim/directional/north, /obj/item/radio/intercom/directional/east, /obj/machinery/vending/drugs, /obj/effect/turf_decal/tile/blue/fourcorners, +/obj/machinery/camera/autoname/directional/north{ + network = list("ss13","medbay") + }, /turf/open/floor/iron/white, /area/station/medical/treatment_center) "xdf" = ( diff --git a/_maps/mining_configs/iceland.json b/_maps/mining_configs/iceland.json index 1726e53d63f85..428247a4d9b5f 100644 --- a/_maps/mining_configs/iceland.json +++ b/_maps/mining_configs/iceland.json @@ -8,7 +8,6 @@ "planetary": 1, "traits": [ { - "Up": true, "Mining": true, "No Parallax": true, "Ice Ruins Underground": true, @@ -18,8 +17,6 @@ "Linkage": null }, { - "Up": true, - "Down": true, "Mining": true, "No Parallax": true, "Ice Ruins Underground": true, @@ -28,8 +25,6 @@ "Linkage": null }, { - "Down": true, - "Mining": true, "No Parallax": true, "Weather_Snowstorm": true, "Ice Ruins": true, diff --git a/_maps/multiz_debug.json b/_maps/multiz_debug.json index e83101d74d733..af3ffa3521293 100644 --- a/_maps/multiz_debug.json +++ b/_maps/multiz_debug.json @@ -11,17 +11,13 @@ ], "traits": [ { - "Up": true, "Linkage": "Cross" }, { - "Up": true, - "Down": true, "Baseturf": "/turf/open/openspace", "Linkage": "Cross" }, { - "Down": true, "Baseturf": "/turf/open/openspace", "Linkage": "Cross" } diff --git a/_maps/northstar.json b/_maps/northstar.json index bd1a53c562272..fdae8ac42f387 100644 --- a/_maps/northstar.json +++ b/_maps/northstar.json @@ -14,23 +14,17 @@ "space_empty_levels": 2, "traits": [ { - "Up": true, "Linkage": "Cross" }, { - "Up": true, - "Down": true, "Baseturf": "/turf/open/openspace", "Linkage": "Cross" }, { - "Up": true, - "Down": true, "Baseturf": "/turf/open/openspace", "Linkage": "Cross" }, { - "Down": true, "Baseturf": "/turf/open/openspace", "Linkage": "Cross" } diff --git a/_maps/shuttles/pirate_ex_interdyne.dmm b/_maps/shuttles/pirate_ex_interdyne.dmm index 3896e755f85d9..4dd64e4cdbe04 100644 --- a/_maps/shuttles/pirate_ex_interdyne.dmm +++ b/_maps/shuttles/pirate_ex_interdyne.dmm @@ -291,9 +291,9 @@ /area/shuttle/pirate) "aS" = ( /obj/effect/turf_decal/tile/dark_blue/opposingcorners, -/obj/structure/closet/crate/freezer/blood/interdyne, /obj/machinery/light/small/blacklight/directional/south, /obj/machinery/iv_drip, +/obj/structure/closet/crate/secure/freezer/interdyne/blood, /turf/open/floor/iron/dark, /area/shuttle/pirate) "aW" = ( diff --git a/_maps/templates/battlecruiser_starfury.dmm b/_maps/templates/battlecruiser_starfury.dmm index 15d7485c99bf3..410cad31a81c7 100644 --- a/_maps/templates/battlecruiser_starfury.dmm +++ b/_maps/templates/battlecruiser_starfury.dmm @@ -2364,11 +2364,11 @@ /obj/structure/rack{ dir = 8 }, -/obj/item/gun/ballistic/revolver/syndicate{ +/obj/item/gun/ballistic/revolver/badass{ pixel_x = 2; pixel_y = 5 }, -/obj/item/gun/ballistic/revolver/syndicate{ +/obj/item/gun/ballistic/revolver/badass{ pixel_x = -1; pixel_y = 2 }, diff --git a/_maps/tramstation.json b/_maps/tramstation.json index 7336decb3d7f5..5f5825dce68fe 100644 --- a/_maps/tramstation.json +++ b/_maps/tramstation.json @@ -11,12 +11,10 @@ }, "traits": [ { - "Up": true, "Baseturf": "/turf/open/misc/asteroid/airless", "Linkage": "Cross" }, { - "Down": true, "Baseturf": "/turf/open/openspace", "Linkage": "Cross" } diff --git a/_maps/wawastation.json b/_maps/wawastation.json index 71d716a56e07e..71c818bc6bd61 100644 --- a/_maps/wawastation.json +++ b/_maps/wawastation.json @@ -11,12 +11,10 @@ }, "traits": [ { - "Up": true, "Baseturf": "/turf/open/misc/asteroid/airless", "Linkage": "Cross" }, { - "Down": true, "Baseturf": "/turf/open/openspace", "Linkage": "Cross" } diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm index 74eefa2dc858c..36e6f74a1988c 100644 --- a/code/__DEFINES/DNA.dm +++ b/code/__DEFINES/DNA.dm @@ -60,8 +60,9 @@ #define DNA_MOTH_MARKINGS_BLOCK 13 #define DNA_MUSHROOM_CAPS_BLOCK 14 #define DNA_POD_HAIR_BLOCK 15 +#define DNA_FISH_TAIL_BLOCK 16 /// DOPPLER SHIFT ADDITION BEGIN -#define DNA_BREASTS_BLOCK 16 +#define DNA_BREASTS_BLOCK 17 /// DOPPLER SHIFT ADDITION END // Hey! Listen up if you're here because you're adding a species feature! @@ -71,7 +72,7 @@ // (Which means having a DNA block for a feature tied to a mob without DNA is entirely pointless.) /// Total amount of DNA blocks, must be equal to the highest DNA block number -#define DNA_FEATURE_BLOCKS 16 /// DOPPLER SHIFT EDIT: 16, up from 15 +#define DNA_FEATURE_BLOCKS 17 /// DOPPLER SHIFT EDIT: 17, up from 15 #define DNA_SEQUENCE_LENGTH 4 #define DNA_MUTATION_BLOCKS 8 diff --git a/code/__DEFINES/MC.dm b/code/__DEFINES/MC.dm index 2de9e7140ad26..115748a9a82d9 100644 --- a/code/__DEFINES/MC.dm +++ b/code/__DEFINES/MC.dm @@ -141,3 +141,11 @@ }\ /datum/controller/subsystem/ai_controllers/##X/fire() {..() /*just so it shows up on the profiler*/} \ /datum/controller/subsystem/ai_controllers/##X + +#define UNPLANNED_CONTROLLER_SUBSYSTEM_DEF(X) GLOBAL_REAL(SS##X, /datum/controller/subsystem/unplanned_controllers/##X);\ +/datum/controller/subsystem/unplanned_controllers/##X/New(){\ + NEW_SS_GLOBAL(SS##X);\ + PreInit();\ +}\ +/datum/controller/subsystem/unplanned_controllers/##X/fire() {..() /*just so it shows up on the profiler*/} \ +/datum/controller/subsystem/unplanned_controllers/##X diff --git a/code/__DEFINES/_helpers.dm b/code/__DEFINES/_helpers.dm index d9f75fe8e9d80..4560dac0d8e32 100644 --- a/code/__DEFINES/_helpers.dm +++ b/code/__DEFINES/_helpers.dm @@ -1,5 +1,18 @@ // Stuff that is relatively "core" and is used in other defines/helpers +/** + * The game's world.icon_size. \ + * Ideally divisible by 16. \ + * Ideally a number, but it + * can be a string ("32x32"), so more exotic coders + * will be sad if you use this in math. + */ +#define ICON_SIZE_ALL 32 +/// The X/Width dimension of ICON_SIZE. This will more than likely be the bigger axis. +#define ICON_SIZE_X 32 +/// The Y/Height dimension of ICON_SIZE. This will more than likely be the smaller axis. +#define ICON_SIZE_Y 32 + //Returns the hex value of a decimal number //len == length of returned string #define num2hex(X, len) num2text(X, len, 16) diff --git a/code/__DEFINES/achievements.dm b/code/__DEFINES/achievements.dm index 4f1cf4b746ac6..a6dccb5e2268e 100644 --- a/code/__DEFINES/achievements.dm +++ b/code/__DEFINES/achievements.dm @@ -58,6 +58,7 @@ #define MEDAL_SISYPHUS "Sisyphus" #define MEDAL_ARCHMAGE "Archmage" #define MEDAL_CIGARETTES "Cigarettes" +#define MEDAL_SHARKDRAGON "Sharkdragon" #define MEDAL_THEORETICAL_LIMITS "All Within Theoretical Limits" //Skill medal hub IDs diff --git a/code/__DEFINES/admin_verb.dm b/code/__DEFINES/admin_verb.dm index 71e0475e5c39c..ae8c75b058886 100644 --- a/code/__DEFINES/admin_verb.dm +++ b/code/__DEFINES/admin_verb.dm @@ -80,6 +80,7 @@ _ADMIN_VERB(verb_path_name, verb_permissions, verb_name, verb_desc, verb_categor #define ADMIN_CATEGORY_EVENTS "Admin.Events" #define ADMIN_CATEGORY_FUN "Admin.Fun" #define ADMIN_CATEGORY_GAME "Admin.Game" +#define ADMIN_CATEGORY_SHUTTLE "Admin.Shuttle" // Special categories that are separated #define ADMIN_CATEGORY_DEBUG "Debug" diff --git a/code/__DEFINES/alerts.dm b/code/__DEFINES/alerts.dm index e6f4feb259a59..ad68b1d55959d 100644 --- a/code/__DEFINES/alerts.dm +++ b/code/__DEFINES/alerts.dm @@ -14,12 +14,13 @@ #define ALERT_TOO_MUCH_NITRO "too_much_nitro" #define ALERT_NOT_ENOUGH_NITRO "not_enough_nitro" +#define ALERT_NOT_ENOUGH_WATER "not_enough_water" + /** Mob related */ #define ALERT_SUCCUMB "succumb" #define ALERT_BUCKLED "buckled" #define ALERT_HANDCUFFED "handcuffed" #define ALERT_LEGCUFFED "legcuffed" -#define ALERT_WOUNDED "wound" #define ALERT_IRRADIATED "irradiated" #define ALERT_EMBEDDED_OBJECT "embeddedobject" #define ALERT_SHOES_KNOT "shoealert" diff --git a/code/__DEFINES/basic_mobs.dm b/code/__DEFINES/basic_mobs.dm index e519fb25240be..6696da857c8e3 100644 --- a/code/__DEFINES/basic_mobs.dm +++ b/code/__DEFINES/basic_mobs.dm @@ -33,6 +33,9 @@ ///keeps track of how many gutlunches are born GLOBAL_VAR_INIT(gutlunch_count, 0) +///Pet customization settings saved for every client +GLOBAL_LIST_EMPTY(customized_pets) + //raptor defines #define RAPTOR_RED "Red" diff --git a/code/__DEFINES/configuration.dm b/code/__DEFINES/configuration.dm index 477bed243c1a2..39db31f794685 100644 --- a/code/__DEFINES/configuration.dm +++ b/code/__DEFINES/configuration.dm @@ -28,3 +28,9 @@ #define RESPAWN_FLAG_FREE 1 /// Can respawn, but not as the same character #define RESPAWN_FLAG_NEW_CHARACTER 2 + +// Human authority defines +#define HUMAN_AUTHORITY_DISABLED "DISABLED" +#define HUMAN_AUTHORITY_HUMAN_WHITELIST "HUMAN_WHITELIST" +#define HUMAN_AUTHORITY_NON_HUMAN_WHITELIST "NON_HUMAN_WHITELIST" +#define HUMAN_AUTHORITY_ENFORCED "ENFORCED" diff --git a/code/__DEFINES/construction/material.dm b/code/__DEFINES/construction/material.dm index 57d55ab804281..2764c0bbfaf56 100644 --- a/code/__DEFINES/construction/material.dm +++ b/code/__DEFINES/construction/material.dm @@ -21,6 +21,14 @@ #define MAT_CATEGORY_RIGID "rigid material" /// Materials that can be used to craft items #define MAT_CATEGORY_ITEM_MATERIAL "item material" +/** + * Materials that can also be used to craft items for designs that require two custom mats. + * This is mainly a work around to the fact we can't (easily) have the same category show + * multiple times in a list with different values, because list access operator [] will fetch the + * top-most value. + */ +#define MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY "item material complementary" + /// Use this flag on TRUE if you want the basic recipes #define MAT_CATEGORY_BASE_RECIPES "basic recipes" @@ -87,3 +95,10 @@ #define MATERIAL_RARITY_RARE 3 /// Is this material only going to spawn once in ore vents? (6% of vents on lavaland) #define MATERIAL_RARITY_UNDISCOVERED 1 + +///The key to access the 'optimal' amount of a material key from its assoc value list. +#define MATERIAL_LIST_OPTIMAL_AMOUNT "optimal_amount" +///The key to access the multiplier used to selectively control effects and modifiers of a material. +#define MATERIAL_LIST_MULTIPLIER "multiplier" +///A macro that ensures some multiplicative modifiers higher than 1 don't become lower than 1 and viceversa because of the multiplier. +#define GET_MATERIAL_MODIFIER(modifier, multiplier) (modifier >= 1 ? 1 + ((modifier) - 1) * (multiplier) : (modifier)**(multiplier)) diff --git a/code/__DEFINES/dcs/signals/signals_datum.dm b/code/__DEFINES/dcs/signals/signals_datum.dm index 81224e7a58d81..5565c143d6613 100644 --- a/code/__DEFINES/dcs/signals/signals_datum.dm +++ b/code/__DEFINES/dcs/signals/signals_datum.dm @@ -48,3 +48,6 @@ ///from /datum/component/on_hit_effect/send_signal(): (user, target, hit_zone) #define COMSIG_ON_HIT_EFFECT "comsig_on_hit_effect" + +///from /datum/component/bubble_icon_override/get_bubble_icon(): (list/holder) +#define COMSIG_GET_BUBBLE_ICON "get_bubble_icon" diff --git a/code/__DEFINES/dcs/signals/signals_fish.dm b/code/__DEFINES/dcs/signals/signals_fish.dm index 9b614f924549f..f7606b63a01db 100644 --- a/code/__DEFINES/dcs/signals/signals_fish.dm +++ b/code/__DEFINES/dcs/signals/signals_fish.dm @@ -24,8 +24,6 @@ #define COMSIG_FISH_EATEN_BY_OTHER_FISH "fish_eaten_by_other_fish" ///From /obj/item/fish/generate_reagents_to_add, which returns a holder when the fish is eaten or composted for example: (list/reagents) #define COMSIG_GENERATE_REAGENTS_TO_ADD "generate_reagents_to_add" -///From /obj/item/fish/feed: (fed_reagents, fed_reagent_type) -#define COMSIG_FISH_FED "fish_on_fed" ///From /obj/item/fish/update_size_and_weight: (new_size, new_weight) #define COMSIG_FISH_UPDATE_SIZE_AND_WEIGHT "fish_update_size_and_weight" ///From /obj/item/fish/update_fish_force: (weight_rank, bonus_malus) diff --git a/code/__DEFINES/dcs/signals/signals_hud.dm b/code/__DEFINES/dcs/signals/signals_hud.dm index 2d5d3eaa59cc3..b141f7d8f576b 100644 --- a/code/__DEFINES/dcs/signals/signals_hud.dm +++ b/code/__DEFINES/dcs/signals/signals_hud.dm @@ -1,5 +1,7 @@ /// Sent from /datum/hud/proc/on_eye_change(): (atom/old_eye, atom/new_eye) #define COMSIG_HUD_EYE_CHANGED "hud_eye_changed" +/// Sent from /datum/hud/proc/eye_z_changed() : (new_z) +#define COMSIG_HUD_Z_CHANGED "hud_z_changed" /// Sent from /datum/hud/proc/eye_z_changed() : (old_offset, new_offset) #define COMSIG_HUD_OFFSET_CHANGED "hud_offset_changed" /// Sent from /atom/movable/screen/lobby/button/collapse/proc/collapse_buttons() : () diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm index b95ffba607fd3..80c6f89a10884 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm @@ -42,8 +42,8 @@ /// Called from update_health_hud, whenever a bodypart is being updated on the health doll #define COMSIG_BODYPART_UPDATING_HEALTH_HUD "bodypart_updating_health_hud" - /// Return to override that bodypart's health hud with your own icon - #define COMPONENT_OVERRIDE_BODYPART_HEALTH_HUD (1<<0) + /// Return to override that bodypart's health hud with whatever is returned by the list + #define OVERRIDE_BODYPART_HEALTH_HUD (1<<0) /// Called from /obj/item/bodypart/check_for_injuries (mob/living/carbon/examiner, list/check_list) #define COMSIG_BODYPART_CHECKED_FOR_INJURY "bodypart_injury_checked" 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 285c0b0ac4e2a..633282001f67a 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm @@ -272,6 +272,9 @@ #define COMSIG_LIVING_GRAB "living_grab" // Return COMPONENT_CANCEL_ATTACK_CHAIN / COMPONENT_SKIP_ATTACK_CHAIN to stop the grab +/// From /datum/component/edible/get_perceived_food_quality(): (datum/component/edible/edible, list/extra_quality) +#define COMSIG_LIVING_GET_PERCEIVED_FOOD_QUALITY "get_perceived_food_quality" + ///Called when living finish eat (/datum/component/edible/proc/On_Consume) #define COMSIG_LIVING_FINISH_EAT "living_finish_eat" diff --git a/code/__DEFINES/dcs/signals/signals_mod.dm b/code/__DEFINES/dcs/signals/signals_mod.dm index d3439cf857291..8cabf7537ab99 100644 --- a/code/__DEFINES/dcs/signals/signals_mod.dm +++ b/code/__DEFINES/dcs/signals/signals_mod.dm @@ -39,3 +39,5 @@ #define COMSIG_MOD_WEARER_SET "mod_wearer_set" /// Called when the MODsuit wearer is unset. #define COMSIG_MOD_WEARER_UNSET "mod_wearer_unset" +/// Sent by the tether module when it triggers its snapping function +#define COMSIG_MOD_TETHER_SNAP "mod_tether_snap" diff --git a/code/__DEFINES/dcs/signals/signals_plane_master_group.dm b/code/__DEFINES/dcs/signals/signals_plane_master_group.dm new file mode 100644 index 0000000000000..d27adb5f8c957 --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_plane_master_group.dm @@ -0,0 +1,2 @@ +/// from /datum/plane_master_group/proc/set_hud(): (datum/hud/new_hud) +#define COMSIG_GROUP_HUD_CHANGED "group_hud_changed" diff --git a/code/__DEFINES/dcs/signals/signals_screentips.dm b/code/__DEFINES/dcs/signals/signals_screentips.dm index 8f7326ee2ee79..31a851c048395 100644 --- a/code/__DEFINES/dcs/signals/signals_screentips.dm +++ b/code/__DEFINES/dcs/signals/signals_screentips.dm @@ -21,3 +21,15 @@ /// Tells the contextual screentips system that the list context was mutated. #define CONTEXTUAL_SCREENTIP_SET (1 << 0) + + +/// A user screentip name override. +/// These are used for mobs that may override the names of atoms they hover over. +/// Examples include prosopagnosia (sees human names as Unknown regardless of what they are). +/// Called on /mob with a mutable screentip name list, the item being used, and the atom hovered over. +/// A screentip name override list is a list used for returning a string value from the signal. Only the first value matters. +/// If you mutate the list in this signal, you must return SCREENTIP_NAME_SET. +#define COMSIG_MOB_REQUESTING_SCREENTIP_NAME_FROM_USER "mob_requesting_screentip_name_from_user" + +/// Tells the screentips system that the list names was mutated. +#define SCREENTIP_NAME_SET (1 << 0) diff --git a/code/__DEFINES/gravity.dm b/code/__DEFINES/gravity.dm index f61734cd55fc9..da81c0465cabc 100644 --- a/code/__DEFINES/gravity.dm +++ b/code/__DEFINES/gravity.dm @@ -12,6 +12,34 @@ /// Singularity is stage 6 (11x11) #define STAGE_SIX 11 //From supermatter shard +// Minimum energy needed to reach a stage +/// Singularity stage 1 energy requirement +#define STAGE_ONE_ENERGY_REQUIREMENT 1 +/// Singularity stage 2 energy requirement +#define STAGE_TWO_ENERGY_REQUIREMENT 200 +/// Singularity stage 3 energy requirement +#define STAGE_THREE_ENERGY_REQUIREMENT 500 +/// Singularity stage 4 energy requirement +#define STAGE_FOUR_ENERGY_REQUIREMENT 1000 +/// Singularity stage 5 energy requirement +#define STAGE_FIVE_ENERGY_REQUIREMENT 2000 +/// Singularity stage 6 energy requirement (also needs to consume a SM shard) +#define STAGE_SIX_ENERGY_REQUIREMENT 3000 + +// These values get the median number between two stages to prevent expansion/shrinkage immediately +/// Singularity stage 1 +#define STAGE_ONE_ENERGY ((STAGE_TWO_ENERGY_REQUIREMENT - STAGE_ONE_ENERGY_REQUIREMENT) * 0.5) + STAGE_ONE_ENERGY_REQUIREMENT +/// Singularity stage 2 +#define STAGE_TWO_ENERGY ((STAGE_THREE_ENERGY_REQUIREMENT - STAGE_TWO_ENERGY_REQUIREMENT) * 0.5) + STAGE_TWO_ENERGY_REQUIREMENT +/// Singularity stage 3 +#define STAGE_THREE_ENERGY ((STAGE_FOUR_ENERGY_REQUIREMENT - STAGE_THREE_ENERGY_REQUIREMENT) * 0.5) + STAGE_THREE_ENERGY_REQUIREMENT +/// Singularity stage 4 +#define STAGE_FOUR_ENERGY ((STAGE_FIVE_ENERGY_REQUIREMENT - STAGE_FOUR_ENERGY_REQUIREMENT) * 0.5) + STAGE_FOUR_ENERGY_REQUIREMENT +/// Singularity stage 5 +#define STAGE_FIVE_ENERGY ((STAGE_SIX_ENERGY_REQUIREMENT - STAGE_FIVE_ENERGY_REQUIREMENT) * 0.5) + STAGE_FIVE_ENERGY_REQUIREMENT +/// Singularity stage 6 (hardcoded at 4000 since there is no stage 7) +#define STAGE_SIX_ENERGY 4000 + /** * The point where gravity is negative enough to pull you upwards. * That means walking checks for a ceiling instead of a floor, and you can fall "upwards" diff --git a/code/__DEFINES/interaction_flags.dm b/code/__DEFINES/interaction_flags.dm index fd66cee5bb93e..b031292b0242e 100644 --- a/code/__DEFINES/interaction_flags.dm +++ b/code/__DEFINES/interaction_flags.dm @@ -48,3 +48,5 @@ #define INTERACT_MACHINE_REQUIRES_SIGHT (1<<6) /// the user must be able to read to interact #define INTERACT_MACHINE_REQUIRES_LITERACY (1<<7) +/// user must be standing up in order to interact +#define INTERACT_MACHINE_REQUIRES_STANDING (1<<8) diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index c4399a668aadc..de895ce1a55ff 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -253,7 +253,7 @@ GLOBAL_LIST_INIT(turfs_pass_meteor, typecacheof(list( #define ismecha(A) (istype(A, /obj/vehicle/sealed/mecha)) -#define ismopable(A) (A && (A.layer <= FLOOR_CLEAN_LAYER)) //If something can be cleaned by floor-cleaning devices such as mops or clean bots +#define ismopable(A) (A && ((PLANE_TO_TRUE(A.plane) == FLOOR_PLANE) ? (A.layer <= FLOOR_CLEAN_LAYER) : (A.layer <= GAME_CLEAN_LAYER))) //If something can be cleaned by floor-cleaning devices such as mops or clean bots #define isorgan(A) (istype(A, /obj/item/organ)) @@ -330,4 +330,4 @@ GLOBAL_LIST_INIT(book_types, typecacheof(list( #define is_unassigned_job(job_type) (istype(job_type, /datum/job/unassigned)) #define isprojectilespell(thing) (istype(thing, /datum/action/cooldown/spell/pointed/projectile)) -#define is_multi_tile_object(atom) (atom.bound_width > world.icon_size || atom.bound_height > world.icon_size) +#define is_multi_tile_object(atom) (atom.bound_width > ICON_SIZE_X || atom.bound_height > ICON_SIZE_Y) diff --git a/code/__DEFINES/jobs.dm b/code/__DEFINES/jobs.dm index 953e7648009b8..b0b8993a22357 100644 --- a/code/__DEFINES/jobs.dm +++ b/code/__DEFINES/jobs.dm @@ -12,6 +12,11 @@ /// Used when the `get_job_unavailable_error_message` proc can't make sense of a given code. #define GENERIC_JOB_UNAVAILABLE_ERROR "Error: Unknown job availability." +// Human authority settings +// If you want to add another setting, make sure to also add it to the if chain in /datum/job_config_type/human_authority/validate_value() +#define JOB_AUTHORITY_HUMANS_ONLY "HUMANS_ONLY" +#define JOB_AUTHORITY_NON_HUMANS_ALLOWED "NON_HUMANS_ALLOWED" + #define DEFAULT_RELIGION "Christianity" #define DEFAULT_DEITY "Space Jesus" #define DEFAULT_BIBLE "Default Bible Name" @@ -25,6 +30,7 @@ #define JOB_CONFIG_REQUIRED_CHARACTER_AGE "Required Character Age" #define JOB_CONFIG_SPAWN_POSITIONS "Spawn Positions" #define JOB_CONFIG_TOTAL_POSITIONS "Total Positions" +#define JOB_CONFIG_HUMAN_AUTHORITY "Human Authority Whitelist Setting" /** * ======================= diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index d5c17a877a4b6..8005787676aec 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -32,6 +32,7 @@ #define DEFAULT_PLANE 0 //Marks out the default plane, even if we don't use it +#define WEATHER_PLANE 1 #define AREA_PLANE 2 #define MASSIVE_OBJ_PLANE 3 #define GHOST_PLANE 4 @@ -65,6 +66,8 @@ ///Things that should render ignoring lighting #define ABOVE_LIGHTING_PLANE 17 +#define WEATHER_GLOW_PLANE 18 + ///---------------- MISC ----------------------- ///Pipecrawling images @@ -148,6 +151,11 @@ #define ABOVE_OPEN_TURF_LAYER (12 + TOPDOWN_LAYER) ///catwalk overlay of /turf/open/floor/plating/catwalk_floor #define CATWALK_LAYER (13 + TOPDOWN_LAYER) +#define LOWER_RUNE_LAYER (14 + TOPDOWN_LAYER) +#define RUNE_LAYER (15 + TOPDOWN_LAYER) +/// [GAME_CLEAN_LAYER] but for floors. +/// Basically any layer below this (numerically) is "on" a floor for the purposes of washing +#define FLOOR_CLEAN_LAYER (20 + TOPDOWN_LAYER) //WALL_PLANE layers #define BELOW_CLOSED_TURF_LAYER 2.053 @@ -166,12 +174,10 @@ #define PLUMBING_PIPE_VISIBILE_LAYER 2.495//layer = initial(layer) + ducting_layer / 3333 in atmospherics/handle_layer() to determine order of duct overlap #define BOT_PATH_LAYER 2.497 #define LOW_OBJ_LAYER 2.5 -#define LOW_SIGIL_LAYER 2.52 -#define SIGIL_LAYER 2.53 #define HIGH_PIPE_LAYER 2.54 // Anything above this layer is not "on" a turf for the purposes of washing // I hate this life of ours -#define FLOOR_CLEAN_LAYER 2.55 +#define GAME_CLEAN_LAYER 2.55 #define TRAM_STRUCTURE_LAYER 2.57 #define TRAM_FLOOR_LAYER 2.58 #define TRAM_WALL_LAYER 2.59 diff --git a/code/__DEFINES/maps.dm b/code/__DEFINES/maps.dm index 3c16744f8a062..30186257a3488 100644 --- a/code/__DEFINES/maps.dm +++ b/code/__DEFINES/maps.dm @@ -223,7 +223,7 @@ Always compile, always use that verb, and always make sure that it works for wha #define CLUSTER_CHECK_ALL 30 //!Don't let anything cluster, like, at all /// Checks the job changes in the map config for the passed change key. -#define CHECK_MAP_JOB_CHANGE(job, change) SSmapping.config.job_changes?[job]?[change] +#define CHECK_MAP_JOB_CHANGE(job, change) SSmapping.current_map.job_changes?[job]?[change] ///Identifiers for away mission spawnpoints #define AWAYSTART_BEACH "AWAYSTART_BEACH" diff --git a/code/__DEFINES/maths.dm b/code/__DEFINES/maths.dm index 1939ca94ec455..a7a95817b4405 100644 --- a/code/__DEFINES/maths.dm +++ b/code/__DEFINES/maths.dm @@ -188,21 +188,21 @@ var/pixel_x = 0 var/pixel_y = 0 for(var/i in 1 to increments) - pixel_x += sin(angle)+16*sin(angle)*2 - pixel_y += cos(angle)+16*cos(angle)*2 + pixel_x += sin(angle)+(ICON_SIZE_X/2)*sin(angle)*2 + pixel_y += cos(angle)+(ICON_SIZE_Y/2)*cos(angle)*2 var/new_x = starting.x var/new_y = starting.y - while(pixel_x > 16) - pixel_x -= 32 + while(pixel_x > (ICON_SIZE_X/2)) + pixel_x -= ICON_SIZE_X new_x++ - while(pixel_x < -16) - pixel_x += 32 + while(pixel_x < -(ICON_SIZE_X/2)) + pixel_x += ICON_SIZE_X new_x-- - while(pixel_y > 16) - pixel_y -= 32 + while(pixel_y > (ICON_SIZE_Y/2)) + pixel_y -= ICON_SIZE_Y new_y++ - while(pixel_y < -16) - pixel_y += 32 + while(pixel_y < -(ICON_SIZE_Y/2)) + pixel_y += ICON_SIZE_Y new_y-- new_x = clamp(new_x, 1, world.maxx) new_y = clamp(new_y, 1, world.maxy) diff --git a/code/__DEFINES/memory_defines.dm b/code/__DEFINES/memory_defines.dm index 2b07ab6270d57..f6c537f9e8187 100644 --- a/code/__DEFINES/memory_defines.dm +++ b/code/__DEFINES/memory_defines.dm @@ -1,7 +1,7 @@ ///name of the file that has all the memory strings #define MEMORY_FILE "memories.json" ///name of the file that has all the saved engravings -#define ENGRAVING_SAVE_FILE "data/engravings/[SSmapping.config.map_name]_engravings.json" +#define ENGRAVING_SAVE_FILE "data/engravings/[SSmapping.current_map.map_name]_engravings.json" ///name of the file that has all the prisoner tattoos #define PRISONER_TATTOO_SAVE_FILE "data/engravings/prisoner_tattoos.json" ///Current version of the engraving persistence json diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index ea87ed30f4962..1e3de8f2674a1 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -44,6 +44,10 @@ #define VENTCRAWLER_NUDE 1 #define VENTCRAWLER_ALWAYS 2 +// Flags for the mob_flags var on /mob +/// May override the names used in screentips of OTHER OBJECTS hovered over. +#define MOB_HAS_SCREENTIPS_NAME_OVERRIDE (1 << 0) + //Mob bio-types flags ///The mob is organic, can heal from medical sutures. #define MOB_ORGANIC (1 << 0) @@ -381,6 +385,8 @@ #define SLIP_WHEN_CRAWLING (1<<4) /// the mob won't slip if the turf has the TRAIT_TURF_IGNORE_SLIPPERY trait. #define SLIPPERY_TURF (1<<5) +/// For mobs who are slippery, this requires the mob holding it to be lying down. +#define SLIPPERY_WHEN_LYING_DOWN (1<<6) #define MAX_CHICKENS 50 diff --git a/code/__DEFINES/movement.dm b/code/__DEFINES/movement.dm index 9a2c01f0bfb92..9706819610f5e 100644 --- a/code/__DEFINES/movement.dm +++ b/code/__DEFINES/movement.dm @@ -2,21 +2,21 @@ #define MIN_GLIDE_SIZE 1 /// The maximum for glide_size to be clamped to. /// This shouldn't be higher than the icon size, and generally you shouldn't be changing this, but it's here just in case. -#define MAX_GLIDE_SIZE 32 +#define MAX_GLIDE_SIZE ICON_SIZE_ALL /// Compensating for time dilation GLOBAL_VAR_INIT(glide_size_multiplier, 1.0) ///Broken down, here's what this does: -/// divides the world icon_size (32) by delay divided by ticklag to get the number of pixels something should be moving each tick. +/// divides the world icon_size by delay divided by ticklag to get the number of pixels something should be moving each tick. /// The division result is given a min value of 1 to prevent obscenely slow glide sizes from being set /// Then that's multiplied by the global glide size multiplier. 1.25 by default feels pretty close to spot on. This is just to try to get byond to behave. /// The whole result is then clamped to within the range above. /// Not very readable but it works -#define DELAY_TO_GLIDE_SIZE(delay) (clamp(((world.icon_size / max((delay) / world.tick_lag, 1)) * GLOB.glide_size_multiplier), MIN_GLIDE_SIZE, MAX_GLIDE_SIZE)) +#define DELAY_TO_GLIDE_SIZE(delay) (clamp(((ICON_SIZE_ALL / max((delay) / world.tick_lag, 1)) * GLOB.glide_size_multiplier), MIN_GLIDE_SIZE, MAX_GLIDE_SIZE)) ///Similar to DELAY_TO_GLIDE_SIZE, except without the clamping, and it supports piping in an unrelated scalar -#define MOVEMENT_ADJUSTED_GLIDE_SIZE(delay, movement_disparity) (world.icon_size / ((delay) / world.tick_lag) * movement_disparity * GLOB.glide_size_multiplier) +#define MOVEMENT_ADJUSTED_GLIDE_SIZE(delay, movement_disparity) (ICON_SIZE_ALL / ((delay) / world.tick_lag) * movement_disparity * GLOB.glide_size_multiplier) //Movement loop priority. Only one loop can run at a time, this dictates that // Higher numbers beat lower numbers diff --git a/code/__DEFINES/say.dm b/code/__DEFINES/say.dm index eacdd868a9556..80c316f3585a9 100644 --- a/code/__DEFINES/say.dm +++ b/code/__DEFINES/say.dm @@ -122,3 +122,7 @@ /// Meaning that if the message is visual, and sourced from a blind mob, they will not see it. /// This flag skips that behavior, and will always show the self message to the mob. #define ALWAYS_SHOW_SELF_MESSAGE (1<<1) + +///Defines for priorities for the bubble_icon_override comp +#define BUBBLE_ICON_PRIORITY_ACCESSORY 2 +#define BUBBLE_ICON_PRIORITY_ORGAN 1 diff --git a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm index 4335d535ee6f6..ee95f49a6aecb 100644 --- a/code/__DEFINES/sound.dm +++ b/code/__DEFINES/sound.dm @@ -32,6 +32,7 @@ #define INTERACTION_SOUND_RANGE_MODIFIER -3 #define EQUIP_SOUND_VOLUME 30 +#define LIQUID_SLOSHING_SOUND_VOLUME 10 #define PICKUP_SOUND_VOLUME 15 #define DROP_SOUND_VOLUME 20 #define YEET_SOUND_VOLUME 90 @@ -184,4 +185,12 @@ GLOBAL_LIST_INIT(announcer_keys, list( #define SFX_DEFAULT_FISH_SLAP "default_fish_slap" #define SFX_ALT_FISH_SLAP "alt_fish_slap" #define SFX_FISH_PICKUP "fish_pickup" +#define SFX_CAT_MEOW "cat_meow" +#define SFX_CAT_PURR "cat_purr" #define SFX_LIQUID_POUR "liquid_pour" +#define SFX_SNORE_FEMALE "snore_female" +#define SFX_SNORE_MALE "snore_male" +#define SFX_PLASTIC_BOTTLE_LIQUID_SLOSH "plastic_bottle_liquid_slosh" +#define SFX_DEFAULT_LIQUID_SLOSH "default_liquid_slosh" +#define SFX_PLATE_ARMOR_RUSTLE "plate_armor_rustle" +#define SFX_PIG_OINK "pig_oink" diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 563aace250578..307792f6fc1a9 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -195,6 +195,7 @@ // Subsystem fire priority, from lowest to highest priority // If the subsystem isn't listed here it's either DEFAULT or PROCESS (if it's a processing subsystem child) +#define FIRE_PRIORITY_UNPLANNED_NPC 3 #define FIRE_PRIORITY_IDLE_NPC 5 #define FIRE_PRIORITY_PING 10 #define FIRE_PRIORITY_SERVER_MAINT 10 diff --git a/code/__DEFINES/supermatter.dm b/code/__DEFINES/supermatter.dm index 5dee00db3103a..61be539749e1c 100644 --- a/code/__DEFINES/supermatter.dm +++ b/code/__DEFINES/supermatter.dm @@ -69,6 +69,15 @@ #define SLIGHTLY_CHARGED_ZAP_ICON_STATE "sm_arc_supercharged" #define OVER_9000_ZAP_ICON_STATE "sm_arc_dbz_referance" //Witty I know +// Zap energy accumulation keys. +/// Normal zap energy accumulation key from normal operations. +#define ZAP_ENERGY_ACCUMULATION_NORMAL "normal" +/// High energy zap energy accumulation key from high energy extra effects. +#define ZAP_ENERGY_ACCUMULATION_HIGH_ENERGY "high" + +/// Zap energy discharge portion per tick. +#define ZAP_ENERGY_DISCHARGE_PORTION 0.1 + #define SUPERMATTER_DEFAULT_BULLET_ENERGY 2 #define SUPERMATTER_CASCADE_PERCENT 80 diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 4fdf598f65977..690dabd42c572 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -116,6 +116,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_RESISTHEAT "resist_heat" /// Trait for when you can no longer gain body heat #define TRAIT_HYPOTHERMIC "body_hypothermic" +/// This non-living object is valid to be used in dna infusers +#define TRAIT_VALID_DNA_INFUSION "valid_dna_infusion" ///For when you've gotten a power from a dna vault #define TRAIT_USED_DNA_VAULT "used_dna_vault" /// For when you want to be able to touch hot things, but still want fire to be an issue. @@ -139,7 +141,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_NOFIRE "nonflammable" #define TRAIT_NOFIRE_SPREAD "no_fire_spreading" /// Prevents plasmamen from self-igniting if only their helmet is missing -#define TRAIT_NOSELFIGNITION_HEAD_ONLY "no_selfignition_head_only" +#define TRAIT_HEAD_ATMOS_SEALED "no_selfignition_head_only" #define TRAIT_NOGUNS "no_guns" ///Can toss a guns like a badass, causing additional damage/effect to their enemies #define TRAIT_TOSS_GUN_HARD "toss_gun_hard" @@ -185,6 +187,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_DISGUISED "disguised" /// Use when you want a mob to be able to metabolize plasma temporarily (e.g. plasma fixation disease symptom) #define TRAIT_PLASMA_LOVER_METABOLISM "plasma_lover_metabolism" +/// The mob is not harmed by tetrodotoxin. Instead, it heals them like omnizine +#define TRAIT_TETRODOTOXIN_HEALING "tetrodotoxin_healing" #define TRAIT_EASYDISMEMBER "easy_dismember" #define TRAIT_LIMBATTACHMENT "limb_attach" #define TRAIT_NOLIMBDISABLE "no_limb_disable" @@ -247,6 +251,16 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_MESSAGE_IN_A_BOTTLE_LOCATION "message_in_a_bottle_location" /// Stops other objects of the same type from being inserted inside the same aquarium it's in. #define TRAIT_UNIQUE_AQUARIUM_CONTENT "unique_aquarium_content" +/// Mobs that hate showers, being sprayed with water etc. +#define TRAIT_WATER_HATER "water_hater" +/// Improved boons from showers and some features centered around water, should also suppress TRAIT_WATER_HATER +#define TRAIT_WATER_ADAPTATION "water_adaptation" +/// Tells us that the mob urrently has the fire_handler/wet_stacks status effect +#define TRAIT_IS_WET "is_wet" +/// Mobs with this trait stay wet for longer and resist fire decaying wetness +#define TRAIT_WET_FOR_LONGER "wet_for_longer" +/// Mobs with this trait will be immune to slipping while also being slippery themselves when lying on the floor +#define TRAIT_SLIPPERY_WHEN_WET "slippery_when_wet" /// This trait lets you evaluate someone's fitness level against your own #define TRAIT_EXAMINE_FITNESS "reveal_power_level" /// These mobs have particularly hygienic tongues @@ -276,6 +290,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// Applied into wounds when they're scanned with the wound analyzer, halves time to treat them manually. #define TRAIT_WOUND_SCANNED "wound_scanned" +/// Owner will ignore any fire protection when calculating fire damage +#define TRAIT_IGNORE_FIRE_PROTECTION "ignore_fire_protection" + #define TRAIT_NODEATH "nodeath" #define TRAIT_NOHARDCRIT "nohardcrit" #define TRAIT_NOSOFTCRIT "nosoftcrit" @@ -724,6 +741,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_HONKSPAMMING "trait_honkspamming" /// Required by the waddling element since there are multiple sources of it. #define TRAIT_WADDLING "trait_waddling" +/// Mobs with trait will still waddle even when lying on the floor and make a different footstep sound when doing so. +#define TRAIT_FLOPPING "trait_flopping" /// Required by the on_hit_effect element, which is in turn added by other elements. #define TRAIT_ON_HIT_EFFECT "trait_on_hit_effect" @@ -836,8 +855,10 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_MUSICIAN "musician" #define TRAIT_LIGHT_DRINKER "light_drinker" #define TRAIT_EMPATH "empath" +#define TRAIT_EVIL "evil" #define TRAIT_FRIENDLY "friendly" #define TRAIT_GRABWEAKNESS "grab_weakness" +#define TRAIT_GRABRESISTANCE "grab_resistance" #define TRAIT_SNOB "snob" #define TRAIT_BALD "bald" #define TRAIT_SHAVED "shaved" @@ -963,6 +984,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai ///A trait for mechs that were created through the normal construction process, and not spawned by map or other effects. #define TRAIT_MECHA_CREATED_NORMALLY "trait_mecha_created_normally" +/// Stops a movable from being removed from the mob it's in by the content_barfer component. +#define TRAIT_NOT_BARFABLE "not_barfable" + ///fish traits #define TRAIT_FISH_STASIS "fish_stasis" #define TRAIT_FISH_FLOPPING "fish_flopping" @@ -991,6 +1015,15 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_FISH_SHOULD_TWOHANDED "fish_should_twohanded" ///This fish won't be killed when cooked. #define TRAIT_FISH_SURVIVE_COOKING "fish_survive_cooking" +/** + * This fish has been fed teslium without the electrogenesis having trait. + * Gives the electrogenesis, but at halved output, and it hurts the fish over time. + */ +#define TRAIT_FISH_ON_TESLIUM "fish_on_teslium" +/// This fish has been fed growth serum or something and will grow 5 times faster, up to 50% weight and size gain when fed. +#define TRAIT_FISH_QUICK_GROWTH "fish_quick_growth" +/// This fish has been fed mutagen or something. Evolutions will have more than twice the probability +#define TRAIT_FISH_MUTAGENIC "fish_mutagenic" /// Trait given to angelic constructs to let them purge cult runes #define TRAIT_ANGELIC "angelic" @@ -1067,6 +1100,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define STATION_TRAIT_UNIQUE_AI "station_trait_unique_ai" #define STATION_TRAIT_UNNATURAL_ATMOSPHERE "station_trait_unnatural_atmosphere" #define STATION_TRAIT_VENDING_SHORTAGE "station_trait_vending_shortage" +#define STATION_TRAIT_SPIKED_DRINKS "station_trait_spiked_drinks" ///Deathmatch traits #define TRAIT_DEATHMATCH_EXPLOSIVE_IMPLANTS "deathmath_explosive_implants" @@ -1292,6 +1326,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai ///Trait which allows mobs to parry mining mob projectiles #define TRAIT_MINING_PARRYING "mining_parrying" +///Trait which silences all chemical reactions in its container +#define TRAIT_SILENT_REACTIONS "silent_reactions" + /** * * This trait is used in some interactions very high in the interaction chain to allow diff --git a/code/__HELPERS/atoms.dm b/code/__HELPERS/atoms.dm index 6fc9086b81cc7..d54b29b3f4ac9 100644 --- a/code/__HELPERS/atoms.dm +++ b/code/__HELPERS/atoms.dm @@ -85,9 +85,9 @@ return get_dir(start, end) & (rand() * (dx+dy) < dy ? 3 : 12) /** - * Finds the distance between two atoms, in pixels - * centered = FALSE counts from turf edge to edge - * centered = TRUE counts from turf center to turf center + * Finds the distance between two atoms, in pixels \ + * centered = FALSE counts from turf edge to edge \ + * centered = TRUE counts from turf center to turf center \ * of course mathematically this is just adding world.icon_size on again **/ /proc/get_pixel_distance(atom/start, atom/end, centered = TRUE) @@ -95,7 +95,7 @@ return 0 . = bounds_dist(start, end) + sqrt((((start.pixel_x + end.pixel_x) ** 2) + ((start.pixel_y + end.pixel_y) ** 2))) if(centered) - . += world.icon_size + . += ICON_SIZE_ALL /** * Check if there is already a wall item on the turf loc @@ -336,6 +336,6 @@ rough example of the "cone" made by the 3 dirs checked var/icon_width = icon_dimensions["width"] var/icon_height = icon_dimensions["height"] return list( - "x" = icon_width > world.icon_size && pixel_x != 0 ? (icon_width - world.icon_size) * 0.5 : 0, - "y" = icon_height > world.icon_size && pixel_y != 0 ? (icon_height - world.icon_size) * 0.5 : 0, + "x" = icon_width > ICON_SIZE_X && pixel_x != 0 ? (icon_width - ICON_SIZE_X) * 0.5 : 0, + "y" = icon_height > ICON_SIZE_Y && pixel_y != 0 ? (icon_height - ICON_SIZE_Y) * 0.5 : 0, ) diff --git a/code/__HELPERS/filters.dm b/code/__HELPERS/filters.dm index cd44409ddb239..14233a2807636 100644 --- a/code/__HELPERS/filters.dm +++ b/code/__HELPERS/filters.dm @@ -23,7 +23,7 @@ GLOBAL_LIST_INIT(master_filter_info, list( ) ), // Not implemented, but if this isn't uncommented some windows will just error - // Needs either a proper matrix editor, or just a hook to our existing one + // Needs either a proper matrix editor, or just a hook to our existing one // Issue is filterrific assumes variables will have the same value type if they share the same name, which this violates // Gotta refactor this sometime "color" = list( @@ -169,7 +169,7 @@ GLOBAL_LIST_INIT(master_filter_info, list( if(!isnull(space)) .["space"] = space -/proc/displacement_map_filter(icon, render_source, x, y, size = 32) +/proc/displacement_map_filter(icon, render_source, x, y, size = ICON_SIZE_ALL) . = list("type" = "displace") if(!isnull(icon)) .["icon"] = icon diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 3eb89831957b8..92c725bd81bb7 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -302,7 +302,7 @@ * Tips that starts with the @ character won't be html encoded. That's necessary for any tip containing markup tags, * just make sure they don't also have html characters like <, > and ' which will be garbled. */ -/proc/send_tip_of_the_round(target, selected_tip) +/proc/send_tip_of_the_round(target, selected_tip, source = "Tip of the round") var/message if(selected_tip) message = selected_tip @@ -320,4 +320,4 @@ message = html_encode(message) else message = copytext(message, 2) - to_chat(target, span_purple(examine_block("Tip of the round: [message]"))) + to_chat(target, span_purple(examine_block("[source]: [message]"))) diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 7c12561c9977b..ec238d2e495b0 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -1038,7 +1038,7 @@ GLOBAL_LIST_EMPTY(friendly_animal_types) var/icon/target_icon = target var/icon_base64 = icon2base64(target_icon) - if (target_icon.Height() > world.icon_size || target_icon.Width() > world.icon_size) + if (target_icon.Height() > ICON_SIZE_Y || target_icon.Width() > ICON_SIZE_X) var/icon_md5 = md5(icon_base64) icon_base64 = bicon_cache[icon_md5] if (!icon_base64) // Doesn't exist yet, make it. @@ -1092,14 +1092,14 @@ GLOBAL_LIST_EMPTY(transformation_animation_objects) var/top_part_filter = filter(type="alpha",icon=icon('icons/effects/alphacolors.dmi',"white"),y=0) filters += top_part_filter var/filter_index = length(filters) - animate(filters[filter_index],y=-32,time=time) + animate(filters[filter_index],y=-ICON_SIZE_Y,time=time) //Appearing part var/obj/effect/overlay/appearing_part = new appearing_part.appearance = result_appearance appearing_part.appearance_flags |= KEEP_TOGETHER | KEEP_APART appearing_part.vis_flags = VIS_INHERIT_ID appearing_part.filters = filter(type="alpha",icon=icon('icons/effects/alphacolors.dmi',"white"),y=0,flags=MASK_INVERSE) - animate(appearing_part.filters[1],y=-32,time=time) + animate(appearing_part.filters[1],y=-ICON_SIZE_Y,time=time) transformation_objects += appearing_part //Transform effect thing if(transform_appearance) @@ -1146,19 +1146,19 @@ GLOBAL_LIST_EMPTY(transformation_animation_objects) if(!x_dimension || !y_dimension) return - if((x_dimension == world.icon_size) && (y_dimension == world.icon_size)) + if((x_dimension == ICON_SIZE_X) && (y_dimension == ICON_SIZE_Y)) return image_to_center //Offset the image so that its bottom left corner is shifted this many pixels //This makes it infinitely easier to draw larger inhands/images larger than world.iconsize //but still use them in game - var/x_offset = -((x_dimension / world.icon_size) - 1) * (world.icon_size * 0.5) - var/y_offset = -((y_dimension / world.icon_size) - 1) * (world.icon_size * 0.5) + var/x_offset = -((x_dimension / ICON_SIZE_X) - 1) * (ICON_SIZE_X * 0.5) + var/y_offset = -((y_dimension / ICON_SIZE_Y) - 1) * (ICON_SIZE_Y * 0.5) - //Correct values under world.icon_size - if(x_dimension < world.icon_size) + //Correct values under icon_size + if(x_dimension < ICON_SIZE_X) x_offset *= -1 - if(y_dimension < world.icon_size) + if(y_dimension < ICON_SIZE_Y) y_offset *= -1 image_to_center.pixel_x = x_offset @@ -1216,7 +1216,7 @@ GLOBAL_LIST_EMPTY(transformation_animation_objects) */ /proc/get_size_in_tiles(obj/target) var/icon/size_check = icon(target.icon, target.icon_state) - var/size = size_check.Width() / world.icon_size + var/size = size_check.Width() / ICON_SIZE_X return size @@ -1229,11 +1229,11 @@ GLOBAL_LIST_EMPTY(transformation_animation_objects) var/size = get_size_in_tiles(src) if(dir in list(NORTH, SOUTH)) - bound_width = size * world.icon_size - bound_height = world.icon_size + bound_width = size * ICON_SIZE_X + bound_height = ICON_SIZE_Y else - bound_width = world.icon_size - bound_height = size * world.icon_size + bound_width = ICON_SIZE_X + bound_height = size * ICON_SIZE_Y /// Returns a list containing the width and height of an icon file /proc/get_icon_dimensions(icon_path) @@ -1261,15 +1261,15 @@ GLOBAL_LIST_EMPTY(transformation_animation_objects) var/width = icon_dimensions["width"] var/height = icon_dimensions["height"] - if(width > world.icon_size) - alert_overlay.pixel_x = -(world.icon_size / 2) * ((width - world.icon_size) / world.icon_size) - if(height > world.icon_size) - alert_overlay.pixel_y = -(world.icon_size / 2) * ((height - world.icon_size) / world.icon_size) - if(width > world.icon_size || height > world.icon_size) + if(width > ICON_SIZE_X) + alert_overlay.pixel_x = -(ICON_SIZE_X / 2) * ((width - ICON_SIZE_X) / ICON_SIZE_X) + if(height > ICON_SIZE_Y) + alert_overlay.pixel_y = -(ICON_SIZE_Y / 2) * ((height - ICON_SIZE_Y) / ICON_SIZE_Y) + if(width > ICON_SIZE_X || height > ICON_SIZE_Y) if(width >= height) - scale = world.icon_size / width + scale = ICON_SIZE_X / width else - scale = world.icon_size / height + scale = ICON_SIZE_Y / height alert_overlay.transform = alert_overlay.transform.Scale(scale) return alert_overlay diff --git a/code/__HELPERS/maths.dm b/code/__HELPERS/maths.dm index 395aa12f1397f..7e6db6fb0209b 100644 --- a/code/__HELPERS/maths.dm +++ b/code/__HELPERS/maths.dm @@ -2,8 +2,8 @@ /proc/get_angle(atom/movable/start, atom/movable/end)//For beams. if(!start || !end) return 0 - var/dy =(32 * end.y + end.pixel_y) - (32 * start.y + start.pixel_y) - var/dx =(32 * end.x + end.pixel_x) - (32 * start.x + start.pixel_x) + var/dy =(ICON_SIZE_Y * end.y + end.pixel_y) - (ICON_SIZE_Y * start.y + start.pixel_y) + var/dx =(ICON_SIZE_X * end.x + end.pixel_x) - (ICON_SIZE_X * start.x + start.pixel_x) return delta_to_angle(dx, dy) /// Calculate the angle produced by a pair of x and y deltas @@ -18,8 +18,8 @@ /// Angle between two arbitrary points and horizontal line same as [/proc/get_angle] /proc/get_angle_raw(start_x, start_y, start_pixel_x, start_pixel_y, end_x, end_y, end_pixel_x, end_pixel_y) - var/dy = (32 * end_y + end_pixel_y) - (32 * start_y + start_pixel_y) - var/dx = (32 * end_x + end_pixel_x) - (32 * start_x + start_pixel_x) + var/dy = (ICON_SIZE_Y * end_y + end_pixel_y) - (ICON_SIZE_Y * start_y + start_pixel_y) + var/dx = (ICON_SIZE_X * end_x + end_pixel_x) - (ICON_SIZE_X * start_x + start_pixel_x) if(!dy) return (dx >= 0) ? 90 : 270 . = arctan(dx/dy) diff --git a/code/__HELPERS/mouse_control.dm b/code/__HELPERS/mouse_control.dm index 0c99e53e7a0cd..14588b41cb701 100644 --- a/code/__HELPERS/mouse_control.dm +++ b/code/__HELPERS/mouse_control.dm @@ -11,8 +11,8 @@ var/x = (text2num(screen_loc_X[1]) * 32 + text2num(screen_loc_X[2]) - 32) var/y = (text2num(screen_loc_Y[1]) * 32 + text2num(screen_loc_Y[2]) - 32) var/list/screenview = getviewsize(client.view) - var/screenviewX = screenview[1] * world.icon_size - var/screenviewY = screenview[2] * world.icon_size + var/screenviewX = screenview[1] * ICON_SIZE_X + var/screenviewY = screenview[2] * ICON_SIZE_Y var/ox = round(screenviewX/2) - client.pixel_x //"origin" x var/oy = round(screenviewY/2) - client.pixel_y //"origin" y var/angle = SIMPLIFY_DEGREES(ATAN2(y - oy, x - ox)) diff --git a/code/__HELPERS/screen_objs.dm b/code/__HELPERS/screen_objs.dm index cb8520225ab8c..00f6bd415704f 100644 --- a/code/__HELPERS/screen_objs.dm +++ b/code/__HELPERS/screen_objs.dm @@ -13,11 +13,11 @@ if(findtext(screen_loc, "EAST")) // If you're starting from the east, we start from the east too x += view_size[1] if(findtext(screen_loc, "WEST")) // HHHHHHHHHHHHHHHHHHHHHH WEST is technically a 1 tile offset from the start. Shoot me please - x += world.icon_size + x += ICON_SIZE_X if(findtext(screen_loc, "NORTH")) y += view_size[2] if(findtext(screen_loc, "SOUTH")) - y += world.icon_size + y += ICON_SIZE_Y var/list/x_and_y = splittext(screen_loc, ",") @@ -36,8 +36,8 @@ x_coord = text2num(cut_relative_direction(x_coord)) y_coord = text2num(cut_relative_direction(y_coord)) - x += x_coord * world.icon_size - y += y_coord * world.icon_size + x += x_coord * ICON_SIZE_X + y += y_coord * ICON_SIZE_Y if(length(x_pack) > 1) x += text2num(x_pack[2]) @@ -51,14 +51,14 @@ /proc/offset_to_screen_loc(x_offset, y_offset, view = null) if(view) var/list/view_bounds = view_to_pixels(view) - x_offset = clamp(x_offset, world.icon_size, view_bounds[1]) - y_offset = clamp(y_offset, world.icon_size, view_bounds[2]) + x_offset = clamp(x_offset, ICON_SIZE_X, view_bounds[1]) + y_offset = clamp(y_offset, ICON_SIZE_Y, view_bounds[2]) // Round with no argument is floor, so we get the non pixel offset here - var/x = round(x_offset / world.icon_size) - var/pixel_x = x_offset % world.icon_size - var/y = round(y_offset / world.icon_size) - var/pixel_y = y_offset % world.icon_size + var/x = round(x_offset / ICON_SIZE_X) + var/pixel_x = x_offset % ICON_SIZE_X + var/y = round(y_offset / ICON_SIZE_Y) + var/pixel_y = y_offset % ICON_SIZE_Y var/list/generated_loc = list() generated_loc += "[x]" @@ -88,9 +88,9 @@ // Bias to the right, down, left, and then finally up if(base_x + target_offset < view_size[1]) return offset_to_screen_loc(base_x + target_offset, base_y, view) - if(base_y - target_offset > world.icon_size) + if(base_y - target_offset > ICON_SIZE_Y) return offset_to_screen_loc(base_x, base_y - target_offset, view) - if(base_x - target_offset > world.icon_size) + if(base_x - target_offset > ICON_SIZE_X) return offset_to_screen_loc(base_x - target_offset, base_y, view) if(base_y + target_offset < view_size[2]) return offset_to_screen_loc(base_x, base_y + target_offset, view) @@ -104,12 +104,12 @@ /// Returns a screen_loc format for a tiling screen objects from start and end positions. Start should be bottom left corner, and end top right corner. /proc/spanning_screen_loc(start_px, start_py, end_px, end_py) - var/starting_tile_x = round(start_px / 32) - start_px -= starting_tile_x * 32 - var/starting_tile_y = round(start_py/ 32) - start_py -= starting_tile_y * 32 - var/ending_tile_x = round(end_px / 32) - end_px -= ending_tile_x * 32 - var/ending_tile_y = round(end_py / 32) - end_py -= ending_tile_y * 32 + var/starting_tile_x = round(start_px / ICON_SIZE_X) + start_px -= starting_tile_x * ICON_SIZE_X + var/starting_tile_y = round(start_py/ ICON_SIZE_Y) + start_py -= starting_tile_y * ICON_SIZE_Y + var/ending_tile_x = round(end_px / ICON_SIZE_X) + end_px -= ending_tile_x * ICON_SIZE_X + var/ending_tile_y = round(end_py / ICON_SIZE_Y) + end_py -= ending_tile_y * ICON_SIZE_Y return "[starting_tile_x]:[start_px],[starting_tile_y]:[start_py] to [ending_tile_x]:[end_px],[ending_tile_y]:[end_py]" diff --git a/code/__HELPERS/spatial_info.dm b/code/__HELPERS/spatial_info.dm index 529532f50cf4d..a2c47e87c0a10 100644 --- a/code/__HELPERS/spatial_info.dm +++ b/code/__HELPERS/spatial_info.dm @@ -211,37 +211,49 @@ for(var/obj/item/radio/radio as anything in radios) . |= get_hearers_in_LOS(radio.canhear_range, radio, FALSE) +//Used when converting pixels to tiles to make them accurate +#define OFFSET_X (0.5 / ICON_SIZE_X) +#define OFFSET_Y (0.5 / ICON_SIZE_Y) + ///Calculate if two atoms are in sight, returns TRUE or FALSE /proc/inLineOfSight(X1,Y1,X2,Y2,Z=1,PX1=16.5,PY1=16.5,PX2=16.5,PY2=16.5) - var/turf/T + var/turf/current_turf if(X1 == X2) if(Y1 == Y2) return TRUE //Light cannot be blocked on same tile else - var/s = SIGN(Y2-Y1) - Y1+=s + var/sign = SIGN(Y2-Y1) + Y1 += sign while(Y1 != Y2) - T=locate(X1,Y1,Z) - if(IS_OPAQUE_TURF(T)) + current_turf = locate(X1, Y1, Z) + if(IS_OPAQUE_TURF(current_turf)) return FALSE - Y1+=s + Y1 += sign else - var/m=(32*(Y2-Y1)+(PY2-PY1))/(32*(X2-X1)+(PX2-PX1)) - var/b=(Y1+PY1/32-0.015625)-m*(X1+PX1/32-0.015625) //In tiles + //This looks scary but we're just calculating a linear function (y = mx + b) + + //m = y/x + var/m = (ICON_SIZE_Y*(Y2-Y1) + (PY2-PY1)) / (ICON_SIZE_X*(X2-X1) + (PX2-PX1))//In pixels + + //b = y - mx + var/b = (Y1 + PY1/ICON_SIZE_Y - OFFSET_Y) - m*(X1 + PX1/ICON_SIZE_X - OFFSET_X)//In tiles + var/signX = SIGN(X2-X1) var/signY = SIGN(Y2-Y1) - if(X1= mx+b + Y1 += signY //Line exits tile vertically else - X1+=signX //Line exits tile horizontally - T=locate(X1,Y1,Z) - if(IS_OPAQUE_TURF(T)) + X1 += signX //Line exits tile horizontally + current_turf = locate(X1, Y1, Z) + if(IS_OPAQUE_TURF(current_turf)) return FALSE return TRUE +#undef OFFSET_X +#undef OFFSET_Y /proc/is_in_sight(atom/first_atom, atom/second_atom) var/turf/first_turf = get_turf(first_atom) diff --git a/code/__HELPERS/turfs.dm b/code/__HELPERS/turfs.dm index c4867ba999373..c779c4b681b0f 100644 --- a/code/__HELPERS/turfs.dm +++ b/code/__HELPERS/turfs.dm @@ -237,9 +237,9 @@ Turf and target are separate in case you want to teleport some distance from a t var/list/icon_dimensions = get_icon_dimensions(checked_atom.icon) var/checked_atom_icon_height = icon_dimensions["height"] var/checked_atom_icon_width = icon_dimensions["width"] - if(checked_atom_icon_height != world.icon_size || checked_atom_icon_width != world.icon_size) - pixel_x_offset += ((checked_atom_icon_width / world.icon_size) - 1) * (world.icon_size * 0.5) - pixel_y_offset += ((checked_atom_icon_height / world.icon_size) - 1) * (world.icon_size * 0.5) + if(checked_atom_icon_height != ICON_SIZE_Y || checked_atom_icon_width != ICON_SIZE_X) + pixel_x_offset += ((checked_atom_icon_width / ICON_SIZE_X) - 1) * (ICON_SIZE_X * 0.5) + pixel_y_offset += ((checked_atom_icon_height / ICON_SIZE_Y) - 1) * (ICON_SIZE_Y * 0.5) return list(pixel_x_offset, pixel_y_offset) @@ -248,8 +248,8 @@ Turf and target are separate in case you want to teleport some distance from a t **/ /proc/pixel_offset_turf(turf/offset_from, list/offsets) //DY and DX - var/rough_x = round(round(offsets[1], world.icon_size) / world.icon_size) - var/rough_y = round(round(offsets[2], world.icon_size) / world.icon_size) + var/rough_x = round(round(offsets[1], ICON_SIZE_X) / ICON_SIZE_X) + var/rough_y = round(round(offsets[2], ICON_SIZE_Y) / ICON_SIZE_Y) var/final_x = clamp(offset_from.x + rough_x, 1, world.maxx) var/final_y = clamp(offset_from.y + rough_y, 1, world.maxy) @@ -275,8 +275,8 @@ Turf and target are separate in case you want to teleport some distance from a t click_turf_y = origin.y + text2num(click_turf_y[1]) - round(actual_view[2] / 2) - 1 var/turf/click_turf = locate(clamp(click_turf_x, 1, world.maxx), clamp(click_turf_y, 1, world.maxy), click_turf_z) - LAZYSET(modifiers, ICON_X, "[(click_turf_px - click_turf.pixel_x) + ((click_turf_x - click_turf.x) * world.icon_size)]") - LAZYSET(modifiers, ICON_Y, "[(click_turf_py - click_turf.pixel_y) + ((click_turf_y - click_turf.y) * world.icon_size)]") + LAZYSET(modifiers, ICON_X, "[(click_turf_px - click_turf.pixel_x) + ((click_turf_x - click_turf.x) * ICON_SIZE_X)]") + LAZYSET(modifiers, ICON_Y, "[(click_turf_py - click_turf.pixel_y) + ((click_turf_y - click_turf.y) * ICON_SIZE_Y)]") return click_turf ///Almost identical to the params_to_turf(), but unused (remove?) diff --git a/code/__HELPERS/view.dm b/code/__HELPERS/view.dm index 30e8bc8f9f973..139bdedc425ff 100644 --- a/code/__HELPERS/view.dm +++ b/code/__HELPERS/view.dm @@ -16,8 +16,8 @@ if(!view) return list(0, 0) var/list/view_info = getviewsize(view) - view_info[1] *= world.icon_size - view_info[2] *= world.icon_size + view_info[1] *= ICON_SIZE_X + view_info[2] *= ICON_SIZE_Y return view_info /** diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index d1c8ae6a36544..e311a67a89f9c 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -162,6 +162,7 @@ DEFINE_BITFIELD(interaction_flags_machine, list( "INTERACT_MACHINE_REQUIRES_SILICON" = INTERACT_MACHINE_REQUIRES_SILICON, "INTERACT_MACHINE_REQUIRES_SIGHT" = INTERACT_MACHINE_REQUIRES_SIGHT, "INTERACT_MACHINE_REQUIRES_LITERACY" = INTERACT_MACHINE_REQUIRES_LITERACY, + "INTERACT_MACHINE_REQUIRES_STANDING" = INTERACT_MACHINE_REQUIRES_STANDING, )) DEFINE_BITFIELD(interaction_flags_item, list( @@ -258,6 +259,10 @@ DEFINE_BITFIELD(mob_biotypes, list( "MOB_UNDEAD" = MOB_UNDEAD, )) +DEFINE_BITFIELD(mob_flags, list( + "MOB_HAS_SCREENTIPS_NAME_OVERRIDE" = MOB_HAS_SCREENTIPS_NAME_OVERRIDE, +)) + DEFINE_BITFIELD(mob_respiration_type, list( "RESPIRATION_OXYGEN" = RESPIRATION_OXYGEN, "RESPIRATION_N2" = RESPIRATION_N2, diff --git a/code/_globalvars/lists/basic_ai.dm b/code/_globalvars/lists/basic_ai.dm index 8d79c9bfafeaf..a8646bb8d7f92 100644 --- a/code/_globalvars/lists/basic_ai.dm +++ b/code/_globalvars/lists/basic_ai.dm @@ -10,3 +10,10 @@ GLOBAL_LIST_INIT(ai_controllers_by_status, list( ///basic ai controllers based on their z level GLOBAL_LIST_EMPTY(ai_controllers_by_zlevel) + +///basic ai controllers that are currently performing idled behaviors +GLOBAL_LIST_INIT(unplanned_controllers, list( + AI_STATUS_ON = list(), + AI_STATUS_IDLE = list(), +)) + diff --git a/code/_globalvars/phobias.dm b/code/_globalvars/phobias.dm index 131e530ce82ac..e112d376adf5d 100644 --- a/code/_globalvars/phobias.dm +++ b/code/_globalvars/phobias.dm @@ -69,6 +69,7 @@ GLOBAL_LIST_INIT(phobia_mobs, list( )), "carps" = typecacheof(list( /mob/living/basic/carp, + /mob/living/basic/space_dragon, )), "conspiracies" = typecacheof(list( /mob/living/basic/drone, @@ -247,6 +248,7 @@ GLOBAL_LIST_INIT(phobia_objs, list( /obj/item/clothing/mask/gas/carp, /obj/item/cigarette/carp, /obj/item/clothing/under/suit/carpskin, + /obj/item/fish/baby_carp, /obj/item/food/cubancarp, /obj/item/food/fishmeat/carp, /obj/item/grenade/clusterbuster/spawner_spesscarp, diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 3a6768f06c34e..a242d69503121 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -43,6 +43,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_CHASM_STOPPER" = TRAIT_CHASM_STOPPER, "TRAIT_COMBAT_MODE_SKIP_INTERACTION" = TRAIT_COMBAT_MODE_SKIP_INTERACTION, "TRAIT_DEL_ON_SPACE_DUMP" = TRAIT_DEL_ON_SPACE_DUMP, + "TRAIT_VALID_DNA_INFUSION" = TRAIT_VALID_DNA_INFUSION, "TRAIT_FISH_CASE_COMPATIBILE" = TRAIT_FISH_CASE_COMPATIBILE, "TRAIT_FROZEN" = TRAIT_FROZEN, "TRAIT_HAS_LABEL" = TRAIT_HAS_LABEL, @@ -57,11 +58,13 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_MOVE_PHASING" = TRAIT_MOVE_PHASING, "TRAIT_MOVE_UPSIDE_DOWN" = TRAIT_MOVE_UPSIDE_DOWN, "TRAIT_MOVE_VENTCRAWLING" = TRAIT_MOVE_VENTCRAWLING, - "TRAIT_NOT_ENGRAVABLE" = TRAIT_NOT_ENGRAVABLE, + "TRAIT_MOVE_UPSIDE_DOWN" = TRAIT_MOVE_UPSIDE_DOWN, "TRAIT_NO_FLOATING_ANIM" = TRAIT_NO_FLOATING_ANIM, "TRAIT_NO_MANIFEST_CONTENTS_ERROR" = TRAIT_NO_MANIFEST_CONTENTS_ERROR, "TRAIT_NO_MISSING_ITEM_ERROR" = TRAIT_NO_MISSING_ITEM_ERROR, "TRAIT_NO_THROW_HITPUSH" = TRAIT_NO_THROW_HITPUSH, + "TRAIT_NOT_BARFABLE" = TRAIT_NOT_BARFABLE, + "TRAIT_NOT_ENGRAVABLE" = TRAIT_NOT_ENGRAVABLE, "TRAIT_ODD_CUSTOMIZABLE_FOOD_INGREDIENT" = TRAIT_ODD_CUSTOMIZABLE_FOOD_INGREDIENT, "TRAIT_ON_HIT_EFFECT" = TRAIT_ON_HIT_EFFECT, "TRAIT_RUNECHAT_HIDDEN" = TRAIT_RUNECHAT_HIDDEN, @@ -75,6 +78,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_WADDLING" = TRAIT_WADDLING, "TRAIT_WAS_RENAMED" = TRAIT_WAS_RENAMED, "TRAIT_WEATHER_IMMUNE" = TRAIT_WEATHER_IMMUNE, + "TRAIT_SILENT_REACTIONS" = TRAIT_SILENT_REACTIONS, ), /datum/controller/subsystem/economy = list( "TRAIT_MARKET_CRASHING" = TRAIT_MARKET_CRASHING, @@ -109,6 +113,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "STATION_TRAIT_UNIQUE_AI" = STATION_TRAIT_UNIQUE_AI, "STATION_TRAIT_UNNATURAL_ATMOSPHERE" = STATION_TRAIT_UNNATURAL_ATMOSPHERE, "STATION_TRAIT_VENDING_SHORTAGE" = STATION_TRAIT_VENDING_SHORTAGE, + "STATION_TRAIT_SPIKED_DRINKS" = STATION_TRAIT_SPIKED_DRINKS, ), /datum/deathmatch_lobby = list( "TRAIT_DEATHMATCH_EXPLOSIVE_IMPLANTS" = TRAIT_DEATHMATCH_EXPLOSIVE_IMPLANTS, @@ -230,6 +235,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_EMOTEMUTE" = TRAIT_EMOTEMUTE, "TRAIT_EMPATH" = TRAIT_EMPATH, "TRAIT_ENTRAILS_READER" = TRAIT_ENTRAILS_READER, + "TRAIT_EVIL" = TRAIT_EVIL, "TRAIT_EXAMINE_DEEPER_FISH" = TRAIT_EXAMINE_DEEPER_FISH, "TRAIT_EXAMINE_FISH" = TRAIT_EXAMINE_FISH, "TRAIT_EXAMINE_FISHING_SPOT" = TRAIT_EXAMINE_FISHING_SPOT, @@ -250,6 +256,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_FIXED_MUTANT_COLORS" = TRAIT_FIXED_MUTANT_COLORS, "TRAIT_FLESH_DESIRE" = TRAIT_FLESH_DESIRE, "TRAIT_FLOORED" = TRAIT_FLOORED, + "TRAIT_FLOPPING" = TRAIT_FLOPPING, "TRAIT_FORBID_MINING_SHUTTLE_CONSOLE_OUTSIDE_STATION" = TRAIT_FORBID_MINING_SHUTTLE_CONSOLE_OUTSIDE_STATION, "TRAIT_FORCED_GRAVITY" = TRAIT_FORCED_GRAVITY, "TRAIT_FORCED_STANDING" = TRAIT_FORCED_STANDING, @@ -267,6 +274,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_GIANT" = TRAIT_GIANT, "TRAIT_GODMODE" = TRAIT_GODMODE, "TRAIT_GOOD_HEARING" = TRAIT_GOOD_HEARING, + "TRAIT_GRABRESISTANCE" = TRAIT_GRABRESISTANCE, "TRAIT_GRABWEAKNESS" = TRAIT_GRABWEAKNESS, "TRAIT_GREENTEXT_CURSED" = TRAIT_GREENTEXT_CURSED, "TRAIT_GUNFLIP" = TRAIT_GUNFLIP, @@ -302,6 +310,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_INVISIBLE_MAN" = TRAIT_INVISIBLE_MAN, "TRAIT_INVISIMIN" = TRAIT_INVISIMIN, "TRAIT_IN_CALL" = TRAIT_IN_CALL, + "TRAIT_IS_WET" = TRAIT_IS_WET, "TRAIT_IWASBATONED" = TRAIT_IWASBATONED, "TRAIT_JOLLY" = TRAIT_JOLLY, "TRAIT_KISS_OF_DEATH" = TRAIT_KISS_OF_DEATH, @@ -362,7 +371,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_NOHUNGER" = TRAIT_NOHUNGER, "TRAIT_NOLIMBDISABLE" = TRAIT_NOLIMBDISABLE, "TRAIT_NOMOBSWAP" = TRAIT_NOMOBSWAP, - "TRAIT_NOSELFIGNITION_HEAD_ONLY" = TRAIT_NOSELFIGNITION_HEAD_ONLY, + "TRAIT_HEAD_ATMOS_SEALED" = TRAIT_HEAD_ATMOS_SEALED, "TRAIT_NOSOFTCRIT" = TRAIT_NOSOFTCRIT, "TRAIT_NO_AUGMENTS" = TRAIT_NO_AUGMENTS, "TRAIT_NO_BLOOD_OVERLAY" = TRAIT_NO_BLOOD_OVERLAY, @@ -465,6 +474,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_SIXTHSENSE" = TRAIT_SIXTHSENSE, "TRAIT_SKITTISH" = TRAIT_SKITTISH, "TRAIT_SLEEPIMMUNE" = TRAIT_SLEEPIMMUNE, + "TRAIT_SLIPPERY_WHEN_WET" = TRAIT_SLIPPERY_WHEN_WET, "TRAIT_SMOKER" = TRAIT_SMOKER, "TRAIT_SNEAK" = TRAIT_SNEAK, "TRAIT_SNOB" = TRAIT_SNOB, @@ -505,6 +515,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_TENACIOUS" = TRAIT_TENACIOUS, "TRAIT_TENTACLE_IMMUNE" = TRAIT_TENTACLE_IMMUNE, "TRAIT_TESLA_SHOCKIMMUNE" = TRAIT_TESLA_SHOCKIMMUNE, + "TRAIT_TETRODOTOXIN_HEALING" = TRAIT_TETRODOTOXIN_HEALING, "TRAIT_THERMAL_VISION" = TRAIT_THERMAL_VISION, "TRAIT_THINKING_IN_CHARACTER" = TRAIT_THINKING_IN_CHARACTER, "TRAIT_THROWINGARM" = TRAIT_THROWINGARM, @@ -538,9 +549,12 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_VIRUS_RESISTANCE" = TRAIT_VIRUS_RESISTANCE, "TRAIT_VORACIOUS" = TRAIT_VORACIOUS, "TRAIT_WAS_EVOLVED" = TRAIT_WAS_EVOLVED, + "TRAIT_WATER_ADAPTATION" = TRAIT_WATER_ADAPTATION, + "TRAIT_WATER_HATER" = TRAIT_WATER_HATER, "TRAIT_WEAK_SOUL" = TRAIT_WEAK_SOUL, "TRAIT_WEB_SURFER" = TRAIT_WEB_SURFER, "TRAIT_WEB_WEAVER" = TRAIT_WEB_WEAVER, + "TRAIT_WET_FOR_LONGER" = TRAIT_WET_FOR_LONGER, "TRAIT_WINE_TASTER" = TRAIT_WINE_TASTER, "TRAIT_WING_BUFFET" = TRAIT_WING_BUFFET, "TRAIT_WING_BUFFET_TIRED" = TRAIT_WING_BUFFET_TIRED, @@ -553,6 +567,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_SPEECH_BOOSTER" = TRAIT_SPEECH_BOOSTER, "TRAIT_MINING_PARRYING" = TRAIT_MINING_PARRYING, "TRAIT_ILLUSORY_EFFECT" = TRAIT_ILLUSORY_EFFECT, + "TRAIT_IGNORE_FIRE_PROTECTION" = TRAIT_IGNORE_FIRE_PROTECTION, ), /obj/item = list( "TRAIT_APC_SHOCKING" = TRAIT_APC_SHOCKING, @@ -622,14 +637,17 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_FISH_FLOPPING" = TRAIT_FISH_FLOPPING, "TRAIT_FISH_FROM_CASE" = TRAIT_FISH_FROM_CASE, "TRAIT_FISH_INK_ON_COOLDOWN" = TRAIT_FISH_INK_ON_COOLDOWN, + "TRAIT_FISH_MUTAGENIC" = TRAIT_FISH_MUTAGENIC, "TRAIT_FISH_NO_HUNGER" = TRAIT_FISH_NO_HUNGER, "TRAIT_FISH_NO_MATING" = TRAIT_FISH_NO_MATING, + "TRAIT_FISH_ON_TESLIUM" = TRAIT_FISH_ON_TESLIUM, "TRAIT_FISH_RECESSIVE" = TRAIT_FISH_RECESSIVE, "TRAIT_FISH_SELF_REPRODUCE" = TRAIT_FISH_SELF_REPRODUCE, "TRAIT_FISH_SHOULD_TWOHANDED" = TRAIT_FISH_SHOULD_TWOHANDED, "TRAIT_FISH_STASIS" = TRAIT_FISH_STASIS, "TRAIT_FISH_STINGER" = TRAIT_FISH_STINGER, "TRAIT_FISH_SURVIVE_COOKING" = TRAIT_FISH_SURVIVE_COOKING, + "TRAIT_FISH_QUICK_GROWTH" = TRAIT_FISH_QUICK_GROWTH, "TRAIT_FISH_TOXIN_IMMUNE" = TRAIT_FISH_TOXIN_IMMUNE, "TRAIT_RESIST_EMULSIFY" = TRAIT_RESIST_EMULSIFY, "TRAIT_FISH_WELL_COOKED" = TRAIT_FISH_WELL_COOKED, diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm index ebeac9c899904..e2d0c8194726d 100644 --- a/code/_globalvars/traits/admin_tooling.dm +++ b/code/_globalvars/traits/admin_tooling.dm @@ -22,6 +22,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_SCARY_FISHERMAN" = TRAIT_SCARY_FISHERMAN, "TRAIT_SNOWSTORM_IMMUNE" = TRAIT_SNOWSTORM_IMMUNE, "TRAIT_WEATHER_IMMUNE" = TRAIT_WEATHER_IMMUNE, + "TRAIT_SILENT_REACTIONS" = TRAIT_SILENT_REACTIONS, ), /mob = list( "TRAIT_ABDUCTOR_SCIENTIST_TRAINING" = TRAIT_ABDUCTOR_SCIENTIST_TRAINING, @@ -121,6 +122,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_GIANT" = TRAIT_GIANT, "TRAIT_GODMODE" = TRAIT_GODMODE, "TRAIT_GOOD_HEARING" = TRAIT_GOOD_HEARING, + "TRAIT_GRABRESISTANCE" = TRAIT_GRABRESISTANCE, "TRAIT_GRABWEAKNESS" = TRAIT_GRABWEAKNESS, "TRAIT_GREENTEXT_CURSED" = TRAIT_GREENTEXT_CURSED, "TRAIT_GUNFLIP" = TRAIT_GUNFLIP, @@ -262,6 +264,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_SIXTHSENSE" = TRAIT_SIXTHSENSE, "TRAIT_SKITTISH" = TRAIT_SKITTISH, "TRAIT_SLEEPIMMUNE" = TRAIT_SLEEPIMMUNE, + "TRAIT_SLIPPERY_WHEN_WET" = TRAIT_SLIPPERY_WHEN_WET, "TRAIT_SMOKER" = TRAIT_SMOKER, "TRAIT_SNOB" = TRAIT_SNOB, "TRAIT_SOFTSPOKEN" = TRAIT_SOFTSPOKEN, @@ -283,6 +286,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_TAGGER" = TRAIT_TAGGER, "TRAIT_TENTACLE_IMMUNE" = TRAIT_TENTACLE_IMMUNE, "TRAIT_TESLA_SHOCKIMMUNE" = TRAIT_TESLA_SHOCKIMMUNE, + "TRAIT_TETRODOTOXIN_HEALING" = TRAIT_TETRODOTOXIN_HEALING, "TRAIT_THERMAL_VISION" = TRAIT_THERMAL_VISION, "TRAIT_THROWINGARM" = TRAIT_THROWINGARM, "TRAIT_TIME_STOP_IMMUNE" = TRAIT_TIME_STOP_IMMUNE, @@ -308,16 +312,20 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_VIRUSIMMUNE" = TRAIT_VIRUSIMMUNE, "TRAIT_VIRUS_RESISTANCE" = TRAIT_VIRUS_RESISTANCE, "TRAIT_VORACIOUS" = TRAIT_VORACIOUS, - "TRAIT_WOUND_LICKER" = TRAIT_WOUND_LICKER, + "TRAIT_WATER_ADAPTATION" = TRAIT_WATER_ADAPTATION, + "TRAIT_WATER_HATER" = TRAIT_WATER_HATER, "TRAIT_WEAK_SOUL" = TRAIT_WEAK_SOUL, "TRAIT_WEB_SURFER" = TRAIT_WEB_SURFER, "TRAIT_WEB_WEAVER" = TRAIT_WEB_WEAVER, + "TRAIT_WET_FOR_LONGER" = TRAIT_WET_FOR_LONGER, "TRAIT_WINE_TASTER" = TRAIT_WINE_TASTER, + "TRAIT_WOUND_LICKER" = TRAIT_WOUND_LICKER, "TRAIT_XENO_HOST" = TRAIT_XENO_HOST, "TRAIT_XENO_IMMUNE" = TRAIT_XENO_IMMUNE, "TRAIT_XRAY_HEARING" = TRAIT_XRAY_HEARING, "TRAIT_XRAY_VISION" = TRAIT_XRAY_VISION, "TRAIT_MINING_PARRYING" = TRAIT_MINING_PARRYING, + "TRAIT_IGNORE_FIRE_PROTECTION" = TRAIT_IGNORE_FIRE_PROTECTION, ), /obj/item = list( "TRAIT_APC_SHOCKING" = TRAIT_APC_SHOCKING, @@ -343,14 +351,17 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_FISH_FED_LUBE" = TRAIT_FISH_FED_LUBE, "TRAIT_FISH_FROM_CASE" = TRAIT_FISH_FROM_CASE, "TRAIT_FISH_INK_ON_COOLDOWN" = TRAIT_FISH_INK_ON_COOLDOWN, + "TRAIT_FISH_MUTAGENIC" = TRAIT_FISH_MUTAGENIC, "TRAIT_FISH_NO_HUNGER" = TRAIT_FISH_NO_HUNGER, "TRAIT_FISH_NO_MATING" = TRAIT_FISH_NO_MATING, + "TRAIT_FISH_ON_TESLIUM" = TRAIT_FISH_ON_TESLIUM, "TRAIT_FISH_RECESSIVE" = TRAIT_FISH_RECESSIVE, "TRAIT_FISH_SELF_REPRODUCE" = TRAIT_FISH_SELF_REPRODUCE, "TRAIT_FISH_SHOULD_TWOHANDED" = TRAIT_FISH_SHOULD_TWOHANDED, "TRAIT_FISH_STASIS" = TRAIT_FISH_STASIS, "TRAIT_FISH_STINGER" = TRAIT_FISH_STINGER, "TRAIT_FISH_SURVIVE_COOKING" = TRAIT_FISH_SURVIVE_COOKING, + "TRAIT_FISH_QUICK_GROWTH" = TRAIT_FISH_QUICK_GROWTH, "TRAIT_FISH_TOXIN_IMMUNE" = TRAIT_FISH_TOXIN_IMMUNE, "TRAIT_RESIST_EMULSIFY" = TRAIT_RESIST_EMULSIFY, "TRAIT_YUCKY_FISH" = TRAIT_YUCKY_FISH, diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 0c441ba928ee4..ff9a1fc54eb1b 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -400,15 +400,15 @@ mouse_opacity = MOUSE_OPACITY_OPAQUE screen_loc = "CENTER" -#define MAX_SAFE_BYOND_ICON_SCALE_TILES (MAX_SAFE_BYOND_ICON_SCALE_PX / world.icon_size) -#define MAX_SAFE_BYOND_ICON_SCALE_PX (33 * 32) //Not using world.icon_size on purpose. +#define MAX_SAFE_BYOND_ICON_SCALE_TILES (MAX_SAFE_BYOND_ICON_SCALE_PX / ICON_SIZE_ALL) +#define MAX_SAFE_BYOND_ICON_SCALE_PX (33 * 32) //Not using world.icon_size on purpose. //Ok well I trust you /atom/movable/screen/click_catcher/proc/UpdateGreed(view_size_x = 15, view_size_y = 15) var/icon/newicon = icon('icons/hud/screen_gen.dmi', "catcher") var/ox = min(MAX_SAFE_BYOND_ICON_SCALE_TILES, view_size_x) var/oy = min(MAX_SAFE_BYOND_ICON_SCALE_TILES, view_size_y) - var/px = view_size_x * world.icon_size - var/py = view_size_y * world.icon_size + var/px = view_size_x * ICON_SIZE_X + var/py = view_size_y * ICON_SIZE_Y var/sx = min(MAX_SAFE_BYOND_ICON_SCALE_PX, px) var/sy = min(MAX_SAFE_BYOND_ICON_SCALE_PX, py) newicon.Scale(sx, sy) diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 5e4ee1e849dbb..f9191348fdb24 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -183,6 +183,11 @@ desc = "There's sleeping gas in the air and you're breathing it in. Find some fresh air. The box in your backpack has an oxygen tank and breath mask in it." icon_state = ALERT_TOO_MUCH_N2O +/atom/movable/screen/alert/not_enough_water + name = "Choking (No H2O)" + desc = "You're not getting enough water. Drench yourself in some water (e.g. showers) or get some water vapor before you pass out!" + icon_state = ALERT_NOT_ENOUGH_WATER + //End gas alerts /atom/movable/screen/alert/gross diff --git a/code/_onclick/hud/credits.dm b/code/_onclick/hud/credits.dm index c4650437c6396..2ce3923c88740 100644 --- a/code/_onclick/hud/credits.dm +++ b/code/_onclick/hud/credits.dm @@ -1,6 +1,6 @@ #define CREDIT_ROLL_SPEED 125 #define CREDIT_SPAWN_SPEED 10 -#define CREDIT_ANIMATE_HEIGHT (14 * world.icon_size) +#define CREDIT_ANIMATE_HEIGHT (14 * ICON_SIZE_Y) #define CREDIT_EASE_DURATION 22 #define CREDITS_PATH "[global.config.directory]/contributors.dmi" @@ -45,9 +45,9 @@ parent = P icon_state = credited maptext = MAPTEXT_PIXELLARI(credited) - maptext_x = world.icon_size + 8 - maptext_y = (world.icon_size / 2) - 4 - maptext_width = world.icon_size * 3 + maptext_x = ICON_SIZE_X + 8 + maptext_y = (ICON_SIZE_Y / 2) - 4 + maptext_width = ICON_SIZE_X * 3 var/matrix/M = matrix(transform) M.Translate(0, CREDIT_ANIMATE_HEIGHT) animate(src, transform = M, time = CREDIT_ROLL_SPEED) diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm index 83ac1b8be93ed..91b5c9b8e2af8 100644 --- a/code/_onclick/hud/fullscreen.dm +++ b/code/_onclick/hud/fullscreen.dm @@ -72,6 +72,8 @@ if(screen.needs_offsetting) screen.plane = GET_NEW_PLANE(initial(screen.plane), offset) +INITIALIZE_IMMEDIATE(/atom/movable/screen/fullscreen) + /atom/movable/screen/fullscreen icon = 'icons/hud/screen_full.dmi' icon_state = "default" diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 90370d267162b..f92bb4682e1c8 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -94,7 +94,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( var/atom/movable/screen/healths var/atom/movable/screen/stamina - var/atom/movable/screen/healthdoll + var/atom/movable/screen/healthdoll/healthdoll var/atom/movable/screen/spacesuit var/atom/movable/screen/hunger // subtypes can override this to force a specific UI style @@ -198,6 +198,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( SIGNAL_HANDLER update_parallax_pref() // If your eye changes z level, so should your parallax prefs var/turf/eye_turf = get_turf(eye) + SEND_SIGNAL(src, COMSIG_HUD_Z_CHANGED, eye_turf.z) var/new_offset = GET_TURF_PLANE_OFFSET(eye_turf) if(current_plane_offset == new_offset) return @@ -504,6 +505,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( if(ismob(mymob) && mymob.hud_used == src) show_hud(hud_version) +/// Handles dimming inventory slots that a mob can't equip items to in their current state /datum/hud/proc/update_locked_slots() return @@ -548,7 +550,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( if(!our_client) position_action(button, button.linked_action.default_button_position) return - button.screen_loc = get_valid_screen_location(relative_to.screen_loc, world.icon_size, our_client.view_size.getView()) // Asks for a location adjacent to our button that won't overflow the map + button.screen_loc = get_valid_screen_location(relative_to.screen_loc, ICON_SIZE_ALL, our_client.view_size.getView()) // Asks for a location adjacent to our button that won't overflow the map button.location = relative_to.location @@ -712,14 +714,14 @@ GLOBAL_LIST_INIT(available_ui_styles, list( // We're primarially concerned about width here, if someone makes us 1x2000 I wish them a swift and watery death var/furthest_screen_loc = ButtonNumberToScreenCoords(column_max - 1) var/list/offsets = screen_loc_to_offset(furthest_screen_loc, owner_view) - if(offsets[1] > world.icon_size && offsets[1] < view_size[1] && offsets[2] > world.icon_size && offsets[2] < view_size[2]) // We're all good + if(offsets[1] > ICON_SIZE_X && offsets[1] < view_size[1] && offsets[2] > ICON_SIZE_Y && offsets[2] < view_size[2]) // We're all good return for(column_max in column_max - 1 to 1 step -1) // Yes I could do this by unwrapping ButtonNumberToScreenCoords, but I don't feel like it var/tested_screen_loc = ButtonNumberToScreenCoords(column_max) offsets = screen_loc_to_offset(tested_screen_loc, owner_view) // We've found a valid max length, pack it in - if(offsets[1] > world.icon_size && offsets[1] < view_size[1] && offsets[2] > world.icon_size && offsets[2] < view_size[2]) + if(offsets[1] > ICON_SIZE_X && offsets[1] < view_size[1] && offsets[2] > ICON_SIZE_Y && offsets[2] < view_size[2]) break // Use our newly resized column max refresh_actions() diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 0ab0f022ca22e..cdf63cb68812c 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -276,7 +276,7 @@ hunger = new /atom/movable/screen/hunger(null, src) infodisplay += hunger - healthdoll = new /atom/movable/screen/healthdoll(null, src) + healthdoll = new /atom/movable/screen/healthdoll/human(null, src) infodisplay += healthdoll stamina = new /atom/movable/screen/stamina(null, src) @@ -306,16 +306,40 @@ /datum/hud/human/update_locked_slots() if(!mymob) return - var/mob/living/carbon/human/H = mymob - if(!istype(H) || !H.dna.species) - return - var/datum/species/S = H.dna.species + var/blocked_slots = NONE + + var/mob/living/carbon/human/human_mob = mymob + if(istype(human_mob)) + blocked_slots |= human_mob.dna?.species?.no_equip_flags + if(isnull(human_mob.w_uniform) && !HAS_TRAIT(human_mob, TRAIT_NO_JUMPSUIT)) + var/obj/item/bodypart/chest = human_mob.get_bodypart(BODY_ZONE_CHEST) + if(isnull(chest) || IS_ORGANIC_LIMB(chest)) + blocked_slots |= ITEM_SLOT_ID|ITEM_SLOT_BELT + var/obj/item/bodypart/left_leg = human_mob.get_bodypart(BODY_ZONE_L_LEG) + if(isnull(left_leg) || IS_ORGANIC_LIMB(left_leg)) + blocked_slots |= ITEM_SLOT_LPOCKET + var/obj/item/bodypart/right_leg = human_mob.get_bodypart(BODY_ZONE_R_LEG) + if(isnull(right_leg) || IS_ORGANIC_LIMB(right_leg)) + blocked_slots |= ITEM_SLOT_RPOCKET + if(isnull(human_mob.wear_suit)) + blocked_slots |= ITEM_SLOT_SUITSTORE + if(human_mob.num_hands <= 0) + blocked_slots |= ITEM_SLOT_GLOVES + if(human_mob.num_legs < 2) // update this when you can wear shoes on one foot + blocked_slots |= ITEM_SLOT_FEET + var/obj/item/bodypart/head/head = human_mob.get_bodypart(BODY_ZONE_HEAD) + if(isnull(head)) + blocked_slots |= ITEM_SLOT_HEAD|ITEM_SLOT_EARS|ITEM_SLOT_EYES|ITEM_SLOT_MASK + var/obj/item/organ/internal/eyes/eyes = human_mob.get_organ_slot(ORGAN_SLOT_EYES) + if(eyes?.no_glasses) + blocked_slots |= ITEM_SLOT_EYES + if(human_mob.bodyshape & BODYSHAPE_DIGITIGRADE) + blocked_slots |= ITEM_SLOT_FEET + for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) - if(inv.slot_id) - if(S.no_equip_flags & inv.slot_id) - inv.alpha = 128 - else - inv.alpha = initial(inv.alpha) + if(!inv.slot_id) + continue + inv.alpha = (blocked_slots & inv.slot_id) ? 128 : initial(inv.alpha) /datum/hud/human/hidden_inventory_update(mob/viewer) if(!mymob) diff --git a/code/_onclick/hud/map_popups.dm b/code/_onclick/hud/map_popups.dm index f0277d187ff4d..bf524b6c8d906 100644 --- a/code/_onclick/hud/map_popups.dm +++ b/code/_onclick/hud/map_popups.dm @@ -105,8 +105,8 @@ if(!popup_name) return clear_map("[popup_name]_map") - var/x_value = world.icon_size * tilesize * width - var/y_value = world.icon_size * tilesize * height + var/x_value = ICON_SIZE_X * tilesize * width + var/y_value = ICON_SIZE_Y * tilesize * height var/map_name = create_popup(popup_name, title, x_value, y_value) var/atom/movable/screen/background/background = new diff --git a/code/_onclick/hud/movable_screen_objects.dm b/code/_onclick/hud/movable_screen_objects.dm index 2910a9f0cc829..cac1be97ae688 100644 --- a/code/_onclick/hud/movable_screen_objects.dm +++ b/code/_onclick/hud/movable_screen_objects.dm @@ -37,8 +37,8 @@ var/client/our_client = usr.client var/list/offset = screen_loc_to_offset(LAZYACCESS(modifiers, SCREEN_LOC)) if(snap2grid) //Discard Pixel Values - offset[1] = FLOOR(offset[1], world.icon_size) // drops any pixel offset - offset[2] = FLOOR(offset[2], world.icon_size) // drops any pixel offset + offset[1] = FLOOR(offset[1], ICON_SIZE_X) // drops any pixel offset + offset[2] = FLOOR(offset[2], ICON_SIZE_Y) // drops any pixel offset else //Normalise Pixel Values (So the object drops at the center of the mouse, not 16 pixels off) offset[1] += x_off offset[2] += y_off diff --git a/code/_onclick/hud/parallax/parallax.dm b/code/_onclick/hud/parallax/parallax.dm index 135c3f0caef6e..ee266cd21e314 100644 --- a/code/_onclick/hud/parallax/parallax.dm +++ b/code/_onclick/hud/parallax/parallax.dm @@ -191,7 +191,7 @@ if(!offset_x && !offset_y && !force) return - var/glide_rate = round(world.icon_size / screenmob.glide_size * world.tick_lag, world.tick_lag) + var/glide_rate = round(ICON_SIZE_ALL / screenmob.glide_size * world.tick_lag, world.tick_lag) C.previous_turf = posobj var/largest_change = max(abs(offset_x), abs(offset_y)) @@ -297,8 +297,8 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer) /atom/movable/screen/parallax_layer/proc/update_o(view) if (!view) view = world.view - - var/static/parallax_scaler = world.icon_size / 480 + var/static/pixel_grid_size = ICON_SIZE_ALL * 15 + var/static/parallax_scaler = ICON_SIZE_ALL / pixel_grid_size // Turn the view size into a grid of correctly scaled overlays var/list/viewscales = getviewsize(view) @@ -311,8 +311,8 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer) if(x == 0 && y == 0) continue var/mutable_appearance/texture_overlay = mutable_appearance(icon, icon_state) - texture_overlay.pixel_w += 480 * x - texture_overlay.pixel_z += 480 * y + texture_overlay.pixel_w += pixel_grid_size * x + texture_overlay.pixel_z += pixel_grid_size * y new_overlays += texture_overlay cut_overlays() add_overlay(new_overlays) diff --git a/code/_onclick/hud/picture_in_picture.dm b/code/_onclick/hud/picture_in_picture.dm index b6ac49446fc80..f2cf8f4b21081 100644 --- a/code/_onclick/hud/picture_in_picture.dm +++ b/code/_onclick/hud/picture_in_picture.dm @@ -56,7 +56,7 @@ move_tab.icon_state = "move" move_tab.plane = HUD_PLANE var/matrix/M = matrix() - M.Translate(0, (height + 0.25) * world.icon_size) + M.Translate(0, (height + 0.25) * ICON_SIZE_Y) move_tab.transform = M add_overlay(move_tab) @@ -69,7 +69,7 @@ MA.plane = HUD_PLANE button_x.appearance = MA M = matrix() - M.Translate((max(4, width) - 0.75) * world.icon_size, (height + 0.25) * world.icon_size) + M.Translate((max(4, width) - 0.75) * ICON_SIZE_X, (height + 0.25) * ICON_SIZE_Y) button_x.transform = M vis_contents += button_x @@ -82,7 +82,7 @@ MA.plane = HUD_PLANE button_expand.appearance = MA M = matrix() - M.Translate(world.icon_size, (height + 0.25) * world.icon_size) + M.Translate(ICON_SIZE_X, (height + 0.25) * ICON_SIZE_Y) button_expand.transform = M vis_contents += button_expand @@ -95,7 +95,7 @@ MA.plane = HUD_PLANE button_shrink.appearance = MA M = matrix() - M.Translate(2 * world.icon_size, (height + 0.25) * world.icon_size) + M.Translate(2 * ICON_SIZE_X, (height + 0.25) * ICON_SIZE_Y) button_shrink.transform = M vis_contents += button_shrink @@ -103,7 +103,7 @@ if((width > 0) && (height > 0)) var/matrix/M = matrix() M.Scale(width + 0.5, height + 0.5) - M.Translate((width-1)/2 * world.icon_size, (height-1)/2 * world.icon_size) + M.Translate((width-1)/2 * ICON_SIZE_X, (height-1)/2 * ICON_SIZE_Y) standard_background.transform = M add_overlay(standard_background) @@ -115,7 +115,7 @@ src.width = width src.height = height - y_off = -height * world.icon_size - 16 + y_off = (-height * ICON_SIZE_Y) - (ICON_SIZE_Y / 2) cut_overlays() add_background() diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm index 3bd370120b3a4..ab95d3bb392eb 100644 --- a/code/_onclick/hud/radial.dm +++ b/code/_onclick/hud/radial.dm @@ -388,8 +388,8 @@ GLOBAL_LIST_EMPTY(radial_menus) if (user_space) var/turf/user_turf = get_turf(user) var/turf/anchor_turf = get_turf(anchor) - offset_x = (anchor_turf.x - user_turf.x) * world.icon_size + anchor.pixel_x - user.pixel_x - offset_y = (anchor_turf.y - user_turf.y) * world.icon_size + anchor.pixel_y - user.pixel_y + offset_x = (anchor_turf.x - user_turf.x) * ICON_SIZE_X + anchor.pixel_x - user.pixel_x + offset_y = (anchor_turf.y - user_turf.y) * ICON_SIZE_Y + anchor.pixel_y - user.pixel_y menu.show_to(user, offset_x, offset_y) menu.wait(user, anchor, require_near) var/answer = menu.selected_choice diff --git a/code/_onclick/hud/rendering/plane_master_group.dm b/code/_onclick/hud/rendering/plane_master_group.dm index 23096cc0e9ccd..4bed46f983f4a 100644 --- a/code/_onclick/hud/rendering/plane_master_group.dm +++ b/code/_onclick/hud/rendering/plane_master_group.dm @@ -24,10 +24,23 @@ build_plane_masters(0, SSmapping.max_plane_offset) /datum/plane_master_group/Destroy() - orphan_hud() + set_hud(null) QDEL_LIST_ASSOC_VAL(plane_masters) return ..() +/datum/plane_master_group/proc/set_hud(datum/hud/new_hud) + if(new_hud == our_hud) + return + if(our_hud) + our_hud.master_groups -= key + hide_hud() + our_hud = new_hud + if(new_hud) + our_hud.master_groups[key] = src + show_hud() + build_planes_offset(our_hud, active_offset) + SEND_SIGNAL(src, COMSIG_GROUP_HUD_CHANGED, our_hud) + /// Display a plane master group to some viewer, so show all our planes to it /datum/plane_master_group/proc/attach_to(datum/hud/viewing_hud) if(viewing_hud.master_groups[key]) @@ -42,18 +55,11 @@ relay_loc = "1,1" rebuild_plane_masters() - our_hud = viewing_hud + set_hud(viewing_hud) our_hud.master_groups[key] = src show_hud() build_planes_offset(our_hud, active_offset) -/// Hide the plane master from its current hud, fully clear it out -/datum/plane_master_group/proc/orphan_hud() - if(our_hud) - our_hud.master_groups -= key - hide_hud() - our_hud = null - /// Well, refresh our group, mostly useful for plane specific updates /datum/plane_master_group/proc/refresh_hud() hide_hud() diff --git a/code/_onclick/hud/rendering/plane_masters/plane_master_subtypes.dm b/code/_onclick/hud/rendering/plane_masters/plane_master_subtypes.dm index c96361348f0de..acfa5ee274ca2 100644 --- a/code/_onclick/hud/rendering/plane_masters/plane_master_subtypes.dm +++ b/code/_onclick/hud/rendering/plane_masters/plane_master_subtypes.dm @@ -243,6 +243,18 @@ documentation = "Holds the areas themselves, which ends up meaning it holds any overlays/effects we apply to areas. NOT snow or rad storms, those go on above lighting" plane = AREA_PLANE +/atom/movable/screen/plane_master/weather + name = "Weather" + documentation = "Holds the main tiling 32x32 sprites of weather. We mask against walls that are on the edge of weather effects." + plane = WEATHER_PLANE + start_hidden = TRUE + +/atom/movable/screen/plane_master/weather/set_home(datum/plane_master_group/home) + . = ..() + if(!.) + return + home.AddComponent(/datum/component/hide_weather_planes, src) + /atom/movable/screen/plane_master/massive_obj name = "Massive object" documentation = "Huge objects need to render above everything else on the game plane, otherwise they'd well, get clipped and look not that huge. This does that." @@ -285,6 +297,18 @@ documentation = "Anything on the game plane that needs a space to draw on that will be above the lighting plane.\
Mostly little alerts and effects, also sometimes contains things that are meant to look as if they glow." +/atom/movable/screen/plane_master/weather_glow + name = "Weather Glow" + documentation = "Holds the glowing parts of the main tiling 32x32 sprites of weather." + plane = WEATHER_GLOW_PLANE + start_hidden = TRUE + +/atom/movable/screen/plane_master/weather_glow/set_home(datum/plane_master_group/home) + . = ..() + if(!.) + return + home.AddComponent(/datum/component/hide_weather_planes, src) + /** * Handles emissive overlays and emissive blockers. */ diff --git a/code/_onclick/hud/rendering/render_plate.dm b/code/_onclick/hud/rendering/render_plate.dm index e4cdc41ca1cfb..66339c837d050 100644 --- a/code/_onclick/hud/rendering/render_plate.dm +++ b/code/_onclick/hud/rendering/render_plate.dm @@ -345,7 +345,7 @@ if(!.) return - RegisterSignal(mymob, COMSIG_MOB_SIGHT_CHANGE, PROC_REF(handle_sight)) + RegisterSignal(mymob, COMSIG_MOB_SIGHT_CHANGE, PROC_REF(handle_sight), override = TRUE) handle_sight(mymob, mymob.sight, NONE) /atom/movable/screen/plane_master/rendering_plate/light_mask/hide_from(mob/oldmob) diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 31390c62cbb91..efc7f1c3cfedf 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -724,6 +724,88 @@ screen_loc = ui_living_healthdoll var/filtered = FALSE //so we don't repeatedly create the mask of the mob every update +/atom/movable/screen/healthdoll/human + /// Tracks components of our doll, each limb is a separate atom in our vis_contents + VAR_PRIVATE/list/atom/movable/screen/limbs + /// Lazylist, tracks all body zones that are wounded currently + /// Used so we can sync animations should the list be updated + VAR_PRIVATE/list/animated_zones + +/atom/movable/screen/healthdoll/human/Initialize(mapload, datum/hud/hud_owner) + . = ..() + limbs = list() + for(var/i in GLOB.all_body_zones) + var/atom/movable/screen/healthdoll_limb/limb = new(src, null) + // layer chest above other limbs, it's the center after all + limb.layer = i == BODY_ZONE_CHEST ? layer + 0.05 : layer + limbs[i] = limb + // why viscontents? why not overlays? - because i want to animate filters + vis_contents += limb + update_appearance() + +/atom/movable/screen/healthdoll/human/Destroy() + QDEL_LIST_ASSOC_VAL(limbs) + vis_contents.Cut() + return ..() + +/atom/movable/screen/healthdoll/human/update_icon_state() + . = ..() + var/mob/living/carbon/human/owner = hud?.mymob + if(isnull(owner)) + return + if(owner.stat == DEAD) + for(var/limb in limbs) + limbs[limb].icon_state = "[limb]DEAD" + return + + var/list/current_animated = LAZYLISTDUPLICATE(animated_zones) + + for(var/obj/item/bodypart/body_part as anything in owner.bodyparts) + var/icon_key = 0 + var/part_zone = body_part.body_zone + + var/list/overridable_key = list(icon_key) + if(body_part.bodypart_disabled) + icon_key = 7 + else if(owner.stat == DEAD) + icon_key = "DEAD" + else if(SEND_SIGNAL(body_part, COMSIG_BODYPART_UPDATING_HEALTH_HUD, owner, overridable_key) & OVERRIDE_BODYPART_HEALTH_HUD) + icon_key = overridable_key[1] // thanks i hate it + else if(!owner.has_status_effect(/datum/status_effect/grouped/screwy_hud/fake_healthy)) + var/damage = body_part.get_damage() / body_part.max_damage + // calculate what icon state (1-5, or 0 if undamaged) to use based on damage + icon_key = clamp(ceil(damage * 5), 0, 5) + + if(length(body_part.wounds)) + LAZYSET(animated_zones, part_zone, TRUE) + else + LAZYREMOVE(animated_zones, part_zone) + limbs[part_zone].icon_state = "[part_zone][icon_key]" + // handle leftovers + for(var/missing_zone in owner.get_missing_limbs()) + limbs[missing_zone].icon_state = "[missing_zone]6" + LAZYREMOVE(animated_zones, missing_zone) + // time to re-sync animations, something changed + if(animated_zones ~! current_animated) + for(var/animated_zone in animated_zones) + var/atom/wounded_zone = limbs[animated_zone] + var/existing_filter = wounded_zone.get_filter("wound_outline") + if(existing_filter) + animate(existing_filter) // stop animation so we can resync + else + wounded_zone.add_filter("wound_outline", 1, list("type" = "outline", "color" = "#FF0033", "alpha" = 0, "size" = 1.2)) + existing_filter = wounded_zone.get_filter("wound_outline") + animate(existing_filter, alpha = 200, time = 1.5 SECONDS, loop = -1) + animate(alpha = 0, time = 1.5 SECONDS) + if(LAZYLEN(current_animated)) // avoid null - list() runtimes please + for(var/lost_zone in current_animated - animated_zones) + limbs[lost_zone].remove_filter("wound_outline") + +// Basically just holds an icon we can put a filter on +/atom/movable/screen/healthdoll_limb + screen_loc = ui_living_healthdoll + vis_flags = VIS_INHERIT_ID | VIS_INHERIT_PLANE + /atom/movable/screen/mood name = "mood" icon_state = "mood5" @@ -904,7 +986,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/splash) animate(get_filter("hunger_outline"), alpha = 200, time = 1.5 SECONDS, loop = -1) animate(alpha = 0, time = 1.5 SECONDS) - else if(get_filter("hunger_outline")) + else remove_filter("hunger_outline") // Update color of the food diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index 72df7ceeb9777..08c6ae681655a 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -107,9 +107,22 @@ /datum/config_entry/flag/protect_assistant_from_antagonist //If assistants can be traitor/cult/other -/datum/config_entry/flag/enforce_human_authority //If non-human species are barred from joining as a head of staff +/datum/config_entry/string/human_authority //Controls how to enforce human authority + default = "HUMAN_WHITELIST" -/datum/config_entry/flag/enforce_human_authority_on_everyone //If non-human species are barred from joining as a head of staff, including jobs flagged as allowed for non-humans, ie. Quartermaster. +/////////////////////////////////////////////////Outdated human authority settings +/datum/config_entry/flag/enforce_human_authority + deprecated_by = /datum/config_entry/string/human_authority + +/datum/config_entry/flag/enforce_human_authority/DeprecationUpdate(value) + return value ? HUMAN_AUTHORITY_NON_HUMAN_WHITELIST : HUMAN_AUTHORITY_DISABLED + +/datum/config_entry/flag/enforce_human_authority_on_everyone + deprecated_by = /datum/config_entry/string/human_authority + +/datum/config_entry/flag/enforce_human_authority_on_everyone/DeprecationUpdate(value) + return value ? HUMAN_AUTHORITY_ENFORCED : HUMAN_AUTHORITY_DISABLED +///////////////////////////////////////////////// /datum/config_entry/flag/allow_latejoin_antagonists // If late-joining players can be traitor/changeling diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm index c17d86902a8a6..e1ed3284441f6 100644 --- a/code/controllers/configuration/entries/general.dm +++ b/code/controllers/configuration/entries/general.dm @@ -313,7 +313,7 @@ /datum/config_entry/string/banappeals /datum/config_entry/string/wikiurl - default = "http://www.tgstation13.org/wiki" + default = "http://tgstation13.org/wiki" /datum/config_entry/string/forumurl default = "http://tgstation13.org/phpBB/index.php" @@ -738,3 +738,27 @@ /datum/config_entry/number/upload_limit_admin default = 5242880 min_val = 0 + +/// The minimum number of tallies a map vote entry can have. +/datum/config_entry/number/map_vote_minimum_tallies + default = 1 + min_val = 0 + max_val = 50 + +/// The flat amount all maps get by default +/datum/config_entry/number/map_vote_flat_bonus + default = 5 + min_val = 0 + max_val = INFINITY + +/// The maximum number of tallies a map vote entry can have. +/datum/config_entry/number/map_vote_maximum_tallies + default = 200 + min_val = 0 + max_val = INFINITY + +/// The number of tallies that are carried over between rounds. +/datum/config_entry/number/map_vote_tally_carryover_percentage + default = 100 + min_val = 0 + max_val = 100 diff --git a/code/controllers/configuration/entries/jobs.dm b/code/controllers/configuration/entries/jobs.dm index 06563e01a8e3d..d25ae3964eb1f 100644 --- a/code/controllers/configuration/entries/jobs.dm +++ b/code/controllers/configuration/entries/jobs.dm @@ -133,6 +133,11 @@ var/list/working_list = list() for(var/config_datum_key in job_config_datum_singletons) var/datum/job_config_type/config_datum = job_config_datum_singletons[config_datum_key] + + // Dont make the entry if it doesn't apply to this job + if(!config_datum.validate_entry(occupation)) + continue + var/config_read_value = job_config[job_key][config_datum_key] if(!config_datum.validate_value(config_read_value)) working_list += list( @@ -155,6 +160,11 @@ var/returnable_list = list() for(var/config_datum_key in job_config_datum_singletons) var/datum/job_config_type/config_datum = job_config_datum_singletons[config_datum_key] + + // Dont make the entry if it doesn't apply to this job + if(!config_datum.validate_entry(new_occupation)) + continue + // Remember, every time we write the TOML from scratch, we want to have it commented out by default. // This is to ensure that the server operator knows that they are overriding codebase defaults when they remove the comment. // Having comments mean that we allow server operators to defer to codebase standards when they deem acceptable. They must uncomment to override the codebase default. @@ -171,6 +181,11 @@ var/list/datums_to_read = job_config_datum_singletons - list(JOB_CONFIG_TOTAL_POSITIONS, JOB_CONFIG_SPAWN_POSITIONS) for(var/config_datum_key in datums_to_read) var/datum/job_config_type/config_datum = job_config_datum_singletons[config_datum_key] + + // Dont make the entry if it doesn't apply to this job + if(!config_datum.validate_entry(new_occupation)) + continue + returnable_list += list( "# [config_datum_key]" = config_datum.get_current_value(new_occupation), ) diff --git a/code/controllers/subsystem/ai_controllers.dm b/code/controllers/subsystem/ai_controllers.dm index 49c571a9a0763..8a5eb43bfc9dd 100644 --- a/code/controllers/subsystem/ai_controllers.dm +++ b/code/controllers/subsystem/ai_controllers.dm @@ -8,8 +8,10 @@ SUBSYSTEM_DEF(ai_controllers) runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME ///type of status we are interested in running var/planning_status = AI_STATUS_ON - /// The tick cost of all active AI, calculated on fire. + /// The average tick cost of all active AI, calculated on fire. var/our_cost + /// The tick cost of all currently processed AI, being summed together + var/summing_cost /datum/controller/subsystem/ai_controllers/Initialize() setup_subtrees() @@ -21,6 +23,8 @@ SUBSYSTEM_DEF(ai_controllers) return ..() /datum/controller/subsystem/ai_controllers/fire(resumed) + if(!resumed) + summing_cost = 0 var/timer = TICK_USAGE_REAL for(var/datum/ai_controller/ai_controller as anything in GLOB.ai_controllers_by_status[planning_status]) if(!ai_controller.able_to_plan) @@ -30,7 +34,14 @@ SUBSYSTEM_DEF(ai_controllers) if(!length(ai_controller.current_behaviors)) //Still no plan ai_controller.planning_failed() - our_cost = MC_AVERAGE(our_cost, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) + if(MC_TICK_CHECK) + break + + summing_cost += TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer) + if(MC_TICK_CHECK) + return + + our_cost = MC_AVERAGE(our_cost, summing_cost) ///Creates all instances of ai_subtrees and assigns them to the ai_subtrees list. /datum/controller/subsystem/ai_controllers/proc/setup_subtrees() diff --git a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm index 18ba37eb13785..83c666de64ac4 100644 --- a/code/controllers/subsystem/blackbox.dm +++ b/code/controllers/subsystem/blackbox.dm @@ -357,7 +357,7 @@ Versioning "z_coord" = L.z, "last_words" = L.last_words, "suicide" = did_they_suicide, - "map" = SSmapping.config.map_name, + "map" = SSmapping.current_map.map_name, "internet_address" = world.internet_address || "0", "port" = "[world.port]", "round_id" = GLOB.round_id, diff --git a/code/controllers/subsystem/explosions.dm b/code/controllers/subsystem/explosions.dm index 2f678291eb6c7..20194e66626ca 100644 --- a/code/controllers/subsystem/explosions.dm +++ b/code/controllers/subsystem/explosions.dm @@ -352,7 +352,7 @@ ADMIN_VERB(check_bomb_impacts, R_DEBUG, "Check Bomb Impact", "See what the effec who_did_it = "\[Projectile firer: [ADMIN_LOOKUPFLW(fired_projectile.firer)]\]" who_did_it_game_log = "\[Projectile firer: [key_name(fired_projectile.firer)]\]" else - who_did_it = "\[Projectile firer: [ADMIN_LOOKUPFLW(fired_projectile.firer.fingerprintslast)]\]" + who_did_it = "\[Projectile firer: [ADMIN_LOOKUPFLW(fired_projectile.firer?.fingerprintslast)]\]" who_did_it_game_log = "\[Projectile firer: [key_name(fired_projectile.firer.fingerprintslast)]\]" // Otherwise if the explosion cause is an atom, try get the fingerprints. else if(istype(explosion_cause)) diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index 74b820894b256..9af14f226ace5 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -73,10 +73,11 @@ SUBSYSTEM_DEF(job) /// This is just the message we prepen and put into all of the config files to ensure documentation. We use this in more than one place, so let's put it in the SS to make life a bit easier. var/config_documentation = "## This is the configuration file for the job system.\n## This will only be enabled when the config flag LOAD_JOBS_FROM_TXT is enabled.\n\ - ## We use a system of keys here that directly correlate to the job, just to ensure they don't desync if we choose to change the name of a job.\n## You are able to change (as of now) five different variables in this file.\n\ + ## We use a system of keys here that directly correlate to the job, just to ensure they don't desync if we choose to change the name of a job.\n## You are able to change (as of now) five (six if the job is a command head) different variables in this file.\n\ ## Total Positions are how many job slots you get in a shift, Spawn Positions are how many you get that load in at spawn. If you set this to -1, it is unrestricted.\n## Playtime Requirements is in minutes, and the job will unlock when a player reaches that amount of time.\n\ ## However, that can be superseded by Required Account Age, which is a time in days that you need to have had an account on the server for.\n\ - ## Also there is a required character age in years. It prevents player from joining as this job, if their character's age as is lower than required. Setting it to 0 means it is turned off for this job.\n\n\ + ## Also there is a required character age in years. It prevents player from joining as this job, if their character's age as is lower than required. Setting it to 0 means it is turned off for this job.\n\ + ## Lastly there's Human Authority Whitelist Setting. You can set it to either \"HUMANS_ONLY\" or \"NON_HUMANS_ALLOWED\". Check the \"Human Authority\" setting on the game_options file to know which you should choose. Note that this entry only appears on jobs that are marked as heads of staff.\n\n\ ## As time goes on, more config options may be added to this file.\n\ ## You can use the admin verb 'Generate Job Configuration' in-game to auto-regenerate this config as a downloadable file without having to manually edit this file if we add more jobs or more things you can edit here.\n\ ## It will always respect prior-existing values in the config, but will appropriately add more fields when they generate.\n## It's strongly advised you create your own version of this file rather than use the one provisioned on the codebase.\n\n\ @@ -362,13 +363,21 @@ SUBSYSTEM_DEF(job) for(var/datum/job/job as anything in command_department.department_jobs) if((job.current_positions >= job.total_positions) && job.total_positions != -1) continue + var/list/candidates = find_occupation_candidates(job, level) if(!candidates.len) continue + var/mob/dead/new_player/candidate = pick(candidates) - // Eligibility checks done as part of find_occupation_candidates - if(assign_role(candidate, job, do_eligibility_checks = FALSE)) - .++ + + // Eligibility checks done as part of find_occupation_candidates() above. + if(!assign_role(candidate, job, do_eligibility_checks = FALSE)) + continue + + .++ + + if((job.current_positions >= job.spawn_positions) && job.spawn_positions != -1) + job_debug("JOBS: Command Job is now full, Job: [job], Positions: [job.current_positions], Limit: [job.spawn_positions]") /// Attempts to fill out all available AI positions. /datum/controller/subsystem/job/proc/fill_ai_positions() @@ -443,13 +452,22 @@ SUBSYSTEM_DEF(job) // From assign_all_overflow_positions() // 4. Anyone with the overflow role enabled has been given the overflow role. - // Shuffle the joinable occupation list and filter out ineligible occupations due to above job assignments. + // Copy the joinable occupation list and filter out ineligible occupations due to above job assignments. var/list/available_occupations = joinable_occupations.Copy() + var/datum/job_department/command_department = get_department_type(/datum/job_department/command) + for(var/datum/job/job in available_occupations) // Make sure the job isn't filled. If it is, remove it from the list so it doesn't get checked. if((job.current_positions >= job.spawn_positions) && job.spawn_positions != -1) job_debug("DO: Job is now filled, Job: [job], Current: [job.current_positions], Limit: [job.spawn_positions]") available_occupations -= job + continue + + // Command jobs are handled via fill_all_head_positions_at_priority(...) + // Remove these jobs from the list of available occupations to prevent multiple players being assigned to the same + // limited role without constantly having to iterate over the available_occupations list and re-check them. + if(job in command_department?.department_jobs) + available_occupations -= job job_debug("DO: Running standard job assignment") diff --git a/code/controllers/subsystem/library.dm b/code/controllers/subsystem/library.dm index a657e442748a4..bfe77f70f02dd 100644 --- a/code/controllers/subsystem/library.dm +++ b/code/controllers/subsystem/library.dm @@ -26,14 +26,14 @@ SUBSYSTEM_DEF(library) /datum/controller/subsystem/library/proc/load_shelves() var/list/datum/callback/load_callbacks = list() - + for(var/obj/structure/bookcase/case_to_load as anything in shelves_to_load) if(!case_to_load) stack_trace("A null bookcase somehow ended up in SSlibrary's shelves_to_load list. Did something harddel?") continue load_callbacks += CALLBACK(case_to_load, TYPE_PROC_REF(/obj/structure/bookcase, load_shelf)) shelves_to_load = null - + //Load all of the shelves asyncronously at the same time, blocking until the last one is finished. callback_select(load_callbacks, savereturns = FALSE) @@ -59,6 +59,6 @@ SUBSYSTEM_DEF(library) /datum/controller/subsystem/library/proc/prepare_library_areas() library_areas = typesof(/area/station/service/library) - /area/station/service/library/abandoned - var/list/additional_areas = SSmapping.config.library_areas + var/list/additional_areas = SSmapping.current_map.library_areas if(additional_areas) library_areas += additional_areas diff --git a/code/controllers/subsystem/map_vote.dm b/code/controllers/subsystem/map_vote.dm new file mode 100644 index 0000000000000..7d0be38f92072 --- /dev/null +++ b/code/controllers/subsystem/map_vote.dm @@ -0,0 +1,160 @@ +#define MAP_VOTE_CACHE_LOCATION "data/map_vote_cache.json" + +SUBSYSTEM_DEF(map_vote) + name = "Map Vote" + flags = SS_NO_FIRE + + /// Has an admin specifically set a map. + var/admin_override = FALSE + + /// Have we already done a vote. + var/already_voted = FALSE + + /// The map that has been chosen for next round. + var/datum/map_config/next_map_config + + /// Stores the current map vote cache, so that players can look at the current tally. + var/list/map_vote_cache + + /// Stores the previous map vote cache, used when a map vote is reverted. + var/list/previous_cache + + /// Stores a formatted html string of the tally counts + var/tally_printout = span_red("Loading...") + +/datum/controller/subsystem/map_vote/Initialize() + if(rustg_file_exists(MAP_VOTE_CACHE_LOCATION)) + map_vote_cache = json_decode(file2text(MAP_VOTE_CACHE_LOCATION)) + var/carryover = CONFIG_GET(number/map_vote_tally_carryover_percentage) + for(var/map_id in map_vote_cache) + map_vote_cache[map_id] = round(map_vote_cache[map_id] * (carryover / 100)) + sanitize_cache() + else + map_vote_cache = list() + update_tally_printout() + return SS_INIT_SUCCESS + +/datum/controller/subsystem/map_vote/proc/write_cache() + rustg_file_write(json_encode(map_vote_cache), MAP_VOTE_CACHE_LOCATION) + +/datum/controller/subsystem/map_vote/proc/sanitize_cache() + var/max = CONFIG_GET(number/map_vote_maximum_tallies) + for(var/map_id in map_vote_cache) + if(!(map_id in config.maplist)) + map_vote_cache -= map_id + var/count = map_vote_cache[map_id] + if(count > max) + map_vote_cache[map_id] = max + +/datum/controller/subsystem/map_vote/proc/send_map_vote_notice(...) + var/static/last_message_at + if(last_message_at == world.time) + message_admins("Call to send_map_vote_notice twice in one game tick. Yell at someone to condense messages.") + last_message_at = world.time + + var/list/messages = args.Copy() + to_chat(world, span_purple(examine_block("Map Vote\n
\n[messages.Join("\n")]"))) + +/datum/controller/subsystem/map_vote/proc/finalize_map_vote(datum/vote/map_vote/map_vote) + if(already_voted) + message_admins("Attempted to finalize a map vote after a map vote has already been finalized.") + return + already_voted = TRUE + + var/flat = CONFIG_GET(number/map_vote_flat_bonus) + previous_cache = map_vote_cache.Copy() + for(var/map_id in map_vote.choices) + var/datum/map_config/map = config.maplist[map_id] + map_vote_cache[map_id] += (map_vote.choices[map_id] * map.voteweight) + flat + sanitize_cache() + write_cache() + update_tally_printout() + + if(admin_override) + send_map_vote_notice("Admin Override is in effect. Map will not be changed.", "Tallies are recorded and saved.") + return + + var/list/valid_maps = filter_cache_to_valid_maps() + if(!length(valid_maps)) + send_map_vote_notice("No valid maps.") + return + + var/winner = pick_weight(filter_cache_to_valid_maps()) + set_next_map(config.maplist[winner]) + send_map_vote_notice("Map Selected - [span_bold(next_map_config.map_name)]") + + // do not reset tallies if only one map is even possible + if(length(valid_maps) > 1) + map_vote_cache[winner] = CONFIG_GET(number/map_vote_minimum_tallies) + write_cache() + update_tally_printout() + +/// Returns a list of all map options that are invalid for the current population. +/datum/controller/subsystem/map_vote/proc/get_valid_map_vote_choices() + var/list/valid_maps = list() + + // Fill in our default choices with all of the maps in our map config, if they are votable and not blocked. + var/list/maps = shuffle(global.config.maplist) + for(var/map in maps) + var/datum/map_config/possible_config = config.maplist[map] + if(!possible_config.votable || (possible_config.map_name in SSpersistence.blocked_maps)) + continue + valid_maps += possible_config.map_name + + var/filter_threshold = 0 + if(SSticker.HasRoundStarted()) + filter_threshold = get_active_player_count(alive_check = FALSE, afk_check = TRUE, human_check = FALSE) + else + filter_threshold = length(GLOB.clients) + + for(var/map in valid_maps) + var/datum/map_config/possible_config = config.maplist[map] + if(possible_config.config_min_users > 0 && filter_threshold < possible_config.config_min_users) + valid_maps -= map + + else if(possible_config.config_max_users > 0 && filter_threshold > possible_config.config_max_users) + valid_maps -= map + + return valid_maps + +/datum/controller/subsystem/map_vote/proc/filter_cache_to_valid_maps() + var/connected_players = length(GLOB.player_list) + var/list/valid_maps = list() + for(var/map_id in map_vote_cache) + var/datum/map_config/map = config.maplist[map_id] + if(!map.votable) + continue + if(map.config_min_users > 0 && (connected_players < map.config_min_users)) + continue + if(map.config_max_users > 0 && (connected_players > map.config_max_users)) + continue + valid_maps[map_id] = map_vote_cache[map_id] + return valid_maps + +/datum/controller/subsystem/map_vote/proc/set_next_map(datum/map_config/change_to) + if(!change_to.MakeNextMap()) + message_admins("Failed to set new map with next_map.json for [change_to.map_name]!") + return FALSE + + next_map_config = change_to + return TRUE + +/datum/controller/subsystem/map_vote/proc/revert_next_map() + if(!next_map_config) + return + if(previous_cache) + map_vote_cache = previous_cache + previous_cache = null + + already_voted = FALSE + admin_override = FALSE + send_map_vote_notice("Next map reverted. Voting re-enabled.") + +#undef MAP_VOTE_CACHE_LOCATION + +/datum/controller/subsystem/map_vote/proc/update_tally_printout() + var/list/data = list() + 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 = examine_block("Current Tallies\n
\n[data.Join("\n")]") diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index 4f15983496f53..f1f162f9aefbc 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -6,19 +6,12 @@ SUBSYSTEM_DEF(mapping) var/list/nuke_tiles = list() var/list/nuke_threats = list() - var/datum/map_config/config - var/datum/map_config/next_map_config + /// The current map config the server loaded at round start. + var/datum/map_config/current_map /// DOPPLER SHIFT ADDITION BEGIN var/datum/map_config/config_mining /// DOPPLER SHIFT ADDITION END - /// Has the map for the next round been voted for already? - var/map_voted = FALSE - /// Has the map for the next round been deliberately chosen by an admin? - var/map_force_chosen = FALSE - /// Has the map vote been rocked? - var/map_vote_rocked = FALSE - var/list/map_templates = list() var/list/ruins_templates = list() @@ -98,26 +91,26 @@ SUBSYSTEM_DEF(mapping) /datum/controller/subsystem/mapping/PreInit() ..() #ifdef FORCE_MAP - config = load_map_config(FORCE_MAP, FORCE_MAP_DIRECTORY) + current_map = load_map_config(FORCE_MAP, FORCE_MAP_DIRECTORY) #else - config = load_map_config(error_if_missing = FALSE) + current_map = load_map_config(error_if_missing = FALSE) /// DOPPLER SHIFT ADDITION BEGIN - world.log << "Config loaded for map [config.map_name]" - if (!isnull(config.minetype) && config.minetype != "none" && config.minetype != "lavaland") - world.log << "Minetype requested: [config.minetype]" - config_mining = load_map_config(filename = "mining_configs/[config.minetype]", directory = MAP_DIRECTORY_MAPS, error_if_missing = TRUE) + world.log << "Config loaded for map [current_map.map_name]" + if (!isnull(current_map.minetype) && current_map.minetype != "none" && current_map.minetype != "lavaland") + world.log << "Minetype requested: [current_map.minetype]" + config_mining = load_map_config(filename = "mining_configs/[current_map.minetype]", directory = MAP_DIRECTORY_MAPS, error_if_missing = TRUE) /// DOPPLER SHIFT ADDITION END #endif /datum/controller/subsystem/mapping/Initialize() if(initialized) return SS_INIT_SUCCESS - if(config.defaulted) - var/old_config = config - config = global.config.defaultmap - if(!config || config.defaulted) - to_chat(world, span_boldannounce("Unable to load next or default map config, defaulting to MetaStation.")) - config = old_config + if(current_map.defaulted) + var/datum/map_config/old_config = current_map + current_map = config.defaultmap + if(!current_map || current_map.defaulted) + to_chat(world, span_boldannounce("Unable to load next or default map config, defaulting to [old_config.map_name].")) + current_map = old_config plane_offset_to_true = list() true_to_offset_planes = list() plane_to_offset = list() @@ -141,11 +134,11 @@ SUBSYSTEM_DEF(mapping) #ifndef LOWMEMORYMODE // Create space ruin levels - while (space_levels_so_far < config.space_ruin_levels) + while (space_levels_so_far < current_map.space_ruin_levels) add_new_zlevel("Ruin Area [space_levels_so_far+1]", ZTRAITS_SPACE) ++space_levels_so_far // Create empty space levels - while (space_levels_so_far < config.space_empty_levels + config.space_ruin_levels) + while (space_levels_so_far < current_map.space_empty_levels + current_map.space_ruin_levels) empty_space = add_new_zlevel("Empty Area [space_levels_so_far+1]", list(ZTRAIT_LINKAGE = CROSSLINKED)) ++space_levels_so_far @@ -153,7 +146,7 @@ SUBSYSTEM_DEF(mapping) if(CONFIG_GET(flag/roundstart_away)) createRandomZlevel(prob(CONFIG_GET(number/config_gateway_chance))) - else if (SSmapping.config.load_all_away_missions) // we're likely in a local testing environment, so punch it. + else if (SSmapping.current_map.load_all_away_missions) // we're likely in a local testing environment, so punch it. load_all_away_missions() loading_ruins = TRUE @@ -372,9 +365,7 @@ Used by the AI doomsday and the self-destruct nuke. holodeck_templates = SSmapping.holodeck_templates areas_in_z = SSmapping.areas_in_z - config = SSmapping.config - next_map_config = SSmapping.next_map_config - + current_map = SSmapping.current_map clearing_reserved_turfs = SSmapping.clearing_reserved_turfs z_list = SSmapping.z_list @@ -404,13 +395,23 @@ Used by the AI doomsday and the self-destruct nuke. if (!length(traits)) // null or empty - default for (var/i in 1 to total_z) - traits += list(default_traits) + traits += list(default_traits.Copy()) else if (total_z != traits.len) // mismatch INIT_ANNOUNCE("WARNING: [traits.len] trait sets specified for [total_z] z-levels in [path]!") if (total_z < traits.len) // ignore extra traits traits.Cut(total_z + 1) while (total_z > traits.len) // fall back to defaults on extra levels - traits += list(default_traits) + traits += list(default_traits.Copy()) + + if(total_z > 1) // it's a multi z map + for(var/z in 1 to total_z) + if(z == 1) // bottom z-level + traits[z]["Up"] = TRUE + else if(z == total_z) // top z-level + traits[z]["Down"] = TRUE + else + traits[z]["Down"] = TRUE + traits[z]["Up"] = TRUE // preload the relevant space_level datums var/start_z = world.maxz + 1 @@ -448,36 +449,36 @@ Used by the AI doomsday and the self-destruct nuke. // load the station station_start = world.maxz + 1 - INIT_ANNOUNCE("Loading [config.map_name]...") - LoadGroup(FailedZs, "Station", config.map_path, config.map_file, config.traits, ZTRAITS_STATION) + INIT_ANNOUNCE("Loading [current_map.map_name]...") + LoadGroup(FailedZs, "Station", current_map.map_path, current_map.map_file, current_map.traits, ZTRAITS_STATION) if(SSdbcore.Connect()) var/datum/db_query/query_round_map_name = SSdbcore.NewQuery({" UPDATE [format_table_name("round")] SET map_name = :map_name WHERE id = :round_id - "}, list("map_name" = config.map_name, "round_id" = GLOB.round_id)) + "}, list("map_name" = current_map.map_name, "round_id" = GLOB.round_id)) query_round_map_name.Execute() qdel(query_round_map_name) #ifndef LOWMEMORYMODE - /// DOPPLER SHIFT REMOVAL BEGIN - /*if(config.minetype == "lavaland") + /*if(current_map.minetype == "lavaland") + if(current_map.minetype == "lavaland") LoadGroup(FailedZs, "Lavaland", "map_files/Mining", "Lavaland.dmm", default_traits = ZTRAITS_LAVALAND) - else if (!isnull(config.minetype) && config.minetype != "none") - INIT_ANNOUNCE("WARNING: An unknown minetype '[config.minetype]' was set! This is being ignored! Update the maploader code!")*/ + else if (!isnull(current_map.minetype) && current_map.minetype != "none") + INIT_ANNOUNCE("WARNING: An unknown minetype '[current_map.minetype]' was set! This is being ignored! Update the maploader code!")*/ /// DOPPLER SHIFT REMOVAL BEGIN, ADDITION BEGIN - INIT_ANNOUNCE("Trying to setup mining Z for [config.map_name]: [config.minetype]") + INIT_ANNOUNCE("Trying to setup mining Z for [current_map.map_name]: [current_map.minetype]") if(!isnull(config_mining)) INIT_ANNOUNCE("Loading custom mining planet [config_mining.map_name] in [config_mining.map_path]/[config_mining.map_file] with expected traits [config_mining.traits]") world.log << "Fallback - loading custom mining planet [config_mining.map_name] in [config_mining.map_path]/[config_mining.map_file] with expected traits [config_mining.traits]" LoadGroup(FailedZs, "Mining Planet", config_mining.map_path, config_mining.map_file, config_mining.traits, ZTRAITS_CUSTOM_MINING) - else if(config.minetype == "lavaland") + else if(current_map.minetype == "lavaland") INIT_ANNOUNCE("Loading Lavaland...") world.log << "Fallback - loading Lavaland..." LoadGroup(FailedZs, "Lavaland", "map_files/Mining", "Lavaland.dmm", default_traits = ZTRAITS_LAVALAND) - else if (!isnull(config.minetype) && config.minetype != "none") - INIT_ANNOUNCE("WARNING: An unknown minetype '[config.minetype]' was set, and we couldn't load a map json for it! Update the maploader or check your filepath - expected to be _maps/[config.minetype].json") - world.log << "Fallback warning - an unknown minetype [config.minetype] was set, and we couldn't load a config for it!" + else if (!isnull(current_map.minetype) && current_map.minetype != "none") + INIT_ANNOUNCE("WARNING: An unknown minetype '[current_map.minetype]' was set, and we couldn't load a map json for it! Update the maploader or check your filepath - expected to be _maps/[current_map.minetype].json") + world.log << "Fallback warning - an unknown minetype [current_map.minetype] was set, and we couldn't load a config for it!" /// DOPPLER SHIFT ADDITION END #endif @@ -491,10 +492,8 @@ Used by the AI doomsday and the self-destruct nuke. #undef INIT_ANNOUNCE // Custom maps are removed after station loading so the map files does not persist for no reason. - if(config.map_path == CUSTOM_MAP_PATH) - fdel("_maps/custom/[config.map_file]") - // And as the file is now removed set the next map to default. - next_map_config = load_default_map_config() + if(current_map.map_path == CUSTOM_MAP_PATH) + fdel("_maps/custom/[current_map.map_file]") /** * Global list of AREA TYPES that are associated with the station. @@ -526,88 +525,6 @@ GLOBAL_LIST_EMPTY(the_station_areas) for(var/area/A as anything in GLOB.areas) A.RunTerrainPopulation() -/datum/controller/subsystem/mapping/proc/maprotate() - if(map_voted || SSmapping.next_map_config) //If voted or set by other means. - return - - var/players = GLOB.clients.len - var/list/mapvotes = list() - //count votes - var/pmv = CONFIG_GET(flag/preference_map_voting) - if(pmv) - for (var/client/c in GLOB.clients) - var/vote = c.prefs.read_preference(/datum/preference/choiced/preferred_map) - if (!vote) - if (global.config.defaultmap) - mapvotes[global.config.defaultmap.map_name] += 1 - continue - mapvotes[vote] += 1 - else - for(var/M in global.config.maplist) - mapvotes[M] = 1 - - //filter votes - for (var/map in mapvotes) - if (!map) - mapvotes.Remove(map) - continue - if (!(map in global.config.maplist)) - mapvotes.Remove(map) - continue - if(map in SSpersistence.blocked_maps) - mapvotes.Remove(map) - continue - var/datum/map_config/VM = global.config.maplist[map] - if (!VM) - mapvotes.Remove(map) - continue - if (VM.voteweight <= 0) - mapvotes.Remove(map) - continue - if (VM.config_min_users > 0 && players < VM.config_min_users) - mapvotes.Remove(map) - continue - if (VM.config_max_users > 0 && players > VM.config_max_users) - mapvotes.Remove(map) - continue - - if(pmv) - mapvotes[map] = mapvotes[map]*VM.voteweight - - var/pickedmap = pick_weight(mapvotes) - if (!pickedmap) - return - var/datum/map_config/VM = global.config.maplist[pickedmap] - message_admins("Randomly rotating map to [VM.map_name]") - . = changemap(VM) - if (. && VM.map_name != config.map_name) - to_chat(world, span_boldannounce("Map rotation has chosen [VM.map_name] for next round!")) - -/datum/controller/subsystem/mapping/proc/mapvote() - if(map_voted || SSmapping.next_map_config) //If voted or set by other means. - return - if(SSvote.current_vote) //Theres already a vote running, default to rotation. - maprotate() - return - SSvote.initiate_vote(/datum/vote/map_vote, "automatic map rotation", forced = TRUE) - -/datum/controller/subsystem/mapping/proc/changemap(datum/map_config/change_to) - if(!change_to.MakeNextMap()) - next_map_config = load_default_map_config() - message_admins("Failed to set new map with next_map.json for [change_to.map_name]! Using default as backup!") - return - - var/filter_threshold = get_active_player_count(alive_check = FALSE, afk_check = TRUE, human_check = FALSE) - if (change_to.config_min_users > 0 && filter_threshold != 0 && filter_threshold < change_to.config_min_users) - message_admins("[change_to.map_name] was chosen for the next map, despite there being less current players than its set minimum population range!") - log_game("[change_to.map_name] was chosen for the next map, despite there being less current players than its set minimum population range!") - if (change_to.config_max_users > 0 && filter_threshold > change_to.config_max_users) - message_admins("[change_to.map_name] was chosen for the next map, despite there being more current players than its set maximum population range!") - log_game("[change_to.map_name] was chosen for the next map, despite there being more current players than its set maximum population range!") - - next_map_config = change_to - return TRUE - /datum/controller/subsystem/mapping/proc/preloadTemplates(path = "_maps/templates/") //see master controller setup var/list/filelist = flist(path) for(var/map in filelist) @@ -622,10 +539,10 @@ GLOBAL_LIST_EMPTY(the_station_areas) /datum/controller/subsystem/mapping/proc/preloadRuinTemplates() // Still supporting bans by filename var/list/banned = generateMapList("spaceruinblacklist.txt") - if(config.minetype == "lavaland") + if(current_map.minetype == "lavaland") banned += generateMapList("lavaruinblacklist.txt") - else if(config.blacklist_file) - banned += generateMapList(config.blacklist_file) + else if(current_map.blacklist_file) + banned += generateMapList(current_map.blacklist_file) for(var/item in sort_list(subtypesof(/datum/map_template/ruin), GLOBAL_PROC_REF(cmp_ruincost_priority))) var/datum/map_template/ruin/ruin_type = item @@ -985,7 +902,7 @@ ADMIN_VERB(load_away_mission, R_FUN, "Load Away Mission", "Load a specific away /// Returns true if the map we're playing on is on a planet /datum/controller/subsystem/mapping/proc/is_planetary() - return config.planetary + return current_map.planetary /// For debug purposes, will add every single away mission present in a given directory. /// You can optionally pass in a string directory to load from instead of the default. diff --git a/code/controllers/subsystem/materials.dm b/code/controllers/subsystem/materials.dm index f000688fbc71b..e8763dd33f3af 100644 --- a/code/controllers/subsystem/materials.dm +++ b/code/controllers/subsystem/materials.dm @@ -149,7 +149,7 @@ SUBSYSTEM_DEF(materials) /// Returns a list to be used as an object's custom_materials. Lists will be cached and re-used based on the parameters. -/datum/controller/subsystem/materials/proc/FindOrCreateMaterialCombo(list/materials_declaration, multiplier) +/datum/controller/subsystem/materials/proc/FindOrCreateMaterialCombo(list/materials_declaration, multiplier = 1) if(!LAZYLEN(materials_declaration)) return null // If we get a null we pass it right back, we don't want to generate stack traces just because something is clearing out its materials list. diff --git a/code/controllers/subsystem/persistence/_persistence.dm b/code/controllers/subsystem/persistence/_persistence.dm index 6438015d11d38..d38d7fa372e25 100644 --- a/code/controllers/subsystem/persistence/_persistence.dm +++ b/code/controllers/subsystem/persistence/_persistence.dm @@ -111,7 +111,7 @@ SUBSYSTEM_DEF(persistence) for(var/map in config.maplist) var/datum/map_config/VM = config.maplist[map] var/run = 0 - if(VM.map_name == SSmapping.config.map_name) + if(VM.map_name == SSmapping.current_map.map_name) run++ for(var/name in SSpersistence.saved_maps) if(VM.map_name == name) @@ -128,7 +128,7 @@ SUBSYSTEM_DEF(persistence) saved_maps += mapstosave for(var/i = mapstosave; i > 1; i--) saved_maps[i] = saved_maps[i-1] - saved_maps[1] = SSmapping.config.map_name + saved_maps[1] = SSmapping.current_map.map_name var/json_file = file(FILE_RECENT_MAPS) var/list/file_data = list() file_data["data"] = saved_maps diff --git a/code/controllers/subsystem/persistence/engravings.dm b/code/controllers/subsystem/persistence/engravings.dm index 6808a101bb8d5..ad00c7909d723 100644 --- a/code/controllers/subsystem/persistence/engravings.dm +++ b/code/controllers/subsystem/persistence/engravings.dm @@ -14,7 +14,7 @@ saved_engravings = json["entries"] if(!saved_engravings.len) - log_world("Failed to load engraved messages on map [SSmapping.config.map_name]") + log_world("Failed to load engraved messages on map [SSmapping.current_map.map_name]") return var/list/viable_turfs = get_area_turfs(/area/station/maintenance, subtypes = TRUE) + get_area_turfs(/area/station/security/prison, subtypes = TRUE) @@ -42,7 +42,7 @@ successfully_loaded_engravings++ turfs_to_pick_from -= engraved_wall - log_world("Loaded [successfully_loaded_engravings] engraved messages on map [SSmapping.config.map_name]") + log_world("Loaded [successfully_loaded_engravings] engraved messages on map [SSmapping.current_map.map_name]") ///Saves all new engravings in the world. /datum/controller/subsystem/persistence/proc/save_wall_engravings() diff --git a/code/controllers/subsystem/polling.dm b/code/controllers/subsystem/polling.dm index b237edd3870b6..409f59bbff247 100644 --- a/code/controllers/subsystem/polling.dm +++ b/code/controllers/subsystem/polling.dm @@ -280,7 +280,7 @@ SUBSYSTEM_DEF(polling) return FALSE if(check_jobban) - if(is_banned_from(potential_candidate.ckey, list(check_jobban, ROLE_SYNDICATE))) + if(is_banned_from(potential_candidate.ckey, list(ROLE_SYNDICATE) + check_jobban)) return FALSE return TRUE diff --git a/code/controllers/subsystem/processing/manufacturing.dm b/code/controllers/subsystem/processing/manufacturing.dm new file mode 100644 index 0000000000000..8bc9c6af5d57b --- /dev/null +++ b/code/controllers/subsystem/processing/manufacturing.dm @@ -0,0 +1,4 @@ +PROCESSING_SUBSYSTEM_DEF(manufacturing) + name = "Manufacturing Processing" + wait = 1 SECONDS + stat_tag = "MN" diff --git a/code/controllers/subsystem/processing/quirks.dm b/code/controllers/subsystem/processing/quirks.dm index 45354d4bd6164..aca5ca557cdc8 100644 --- a/code/controllers/subsystem/processing/quirks.dm +++ b/code/controllers/subsystem/processing/quirks.dm @@ -26,6 +26,7 @@ GLOBAL_LIST_INIT_TYPED(quirk_blacklist, /list/datum/quirk, list( list(/datum/quirk/photophobia, /datum/quirk/nyctophobia), list(/datum/quirk/item_quirk/settler, /datum/quirk/freerunning), list(/datum/quirk/numb, /datum/quirk/selfaware), + list(/datum/quirk/empath, /datum/quirk/evil), )) GLOBAL_LIST_INIT(quirk_string_blacklist, generate_quirk_string_blacklist()) diff --git a/code/controllers/subsystem/sprite_accessories.dm b/code/controllers/subsystem/sprite_accessories.dm index 5a428a07c65e5..a399cf8e8773a 100644 --- a/code/controllers/subsystem/sprite_accessories.dm +++ b/code/controllers/subsystem/sprite_accessories.dm @@ -43,9 +43,10 @@ SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity var/list/tail_spines_list //Mutant Human bits - var/list/tails_list_human + var/list/tails_list_felinid var/list/tails_list_lizard var/list/tails_list_monkey + var/list/tails_list_fish var/list/ears_list var/list/wings_list var/list/wings_open_list @@ -87,9 +88,11 @@ SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity socks_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/socks)[DEFAULT_SPRITE_LIST] lizard_markings_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/lizard_markings)[DEFAULT_SPRITE_LIST] - tails_list_human = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human)[DEFAULT_SPRITE_LIST] //DOPPLER EDIT, we remove the blank - old code: tails_list_human = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, add_blank = TRUE)[DEFAULT_SPRITE_LIST] + tails_list_felinid = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human)[DEFAULT_SPRITE_LIST] //DOPPLER EDIT, we remove the blank - old code: tails_list_felinid = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, add_blank = TRUE)[DEFAULT_SPRITE_LIST] tails_list_lizard = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard)[DEFAULT_SPRITE_LIST] tails_list_monkey = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/monkey)[DEFAULT_SPRITE_LIST] + //tails fo fish organ infusions, not for prefs. + tails_list_fish = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/fish)[DEFAULT_SPRITE_LIST] snouts_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/snouts)[DEFAULT_SPRITE_LIST] horns_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/horns, add_blank = TRUE)[DEFAULT_SPRITE_LIST] ears_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/ears, add_blank = TRUE)[DEFAULT_SPRITE_LIST] diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm index 020598a573b67..cf158586ce497 100644 --- a/code/controllers/subsystem/statpanel.dm +++ b/code/controllers/subsystem/statpanel.dm @@ -22,9 +22,9 @@ SUBSYSTEM_DEF(statpanels) /datum/controller/subsystem/statpanels/fire(resumed = FALSE) if (!resumed) num_fires++ - var/datum/map_config/cached = SSmapping.next_map_config + var/datum/map_config/cached = SSmap_vote.next_map_config global_data = list( - "Map: [SSmapping.config?.map_name || "Loading..."]", + "Map: [SSmapping.current_map?.map_name || "Loading..."]", cached ? "Next Map: [cached.map_name]" : null, "Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]", "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]", diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 74825c3fb72cb..16d540319fde7 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -93,12 +93,12 @@ SUBSYSTEM_DEF(ticker) switch(L.len) if(3) //rare+MAP+sound.ogg or MAP+rare.sound.ogg -- Rare Map-specific sounds if(use_rare_music) - if(L[1] == "rare" && L[2] == SSmapping.config.map_name) + if(L[1] == "rare" && L[2] == SSmapping.current_map.map_name) music += S - else if(L[2] == "rare" && L[1] == SSmapping.config.map_name) + else if(L[2] == "rare" && L[1] == SSmapping.current_map.map_name) music += S if(2) //rare+sound.ogg or MAP+sound.ogg -- Rare sounds or Map-specific sounds - if((use_rare_music && L[1] == "rare") || (L[1] == SSmapping.config.map_name)) + if((use_rare_music && L[1] == "rare") || (L[1] == SSmapping.current_map.map_name)) music += S if(1) //sound.ogg -- common sound if(L[1] == "exclude") @@ -157,7 +157,7 @@ SUBSYSTEM_DEF(ticker) for(var/client/C in GLOB.clients) window_flash(C, ignorepref = TRUE) //let them know lobby has opened up. to_chat(world, span_notice("Welcome to [station_name()]!")) - send2chat(new /datum/tgs_message_content("New round starting on [SSmapping.config.map_name]!"), CONFIG_GET(string/channel_announce_new_game)) + send2chat(new /datum/tgs_message_content("New round starting on [SSmapping.current_map.map_name]!"), CONFIG_GET(string/channel_announce_new_game)) current_state = GAME_STATE_PREGAME SEND_SIGNAL(src, COMSIG_TICKER_ENTER_PREGAME) @@ -211,7 +211,6 @@ SUBSYSTEM_DEF(ticker) toggle_ooc(TRUE) // Turn it on toggle_dooc(TRUE) declare_completion(force_ending) - check_maprotate() Master.SetRunLevel(RUNLEVEL_POSTGAME) /// Checks if the round should be ending, called every ticker tick @@ -523,13 +522,6 @@ SUBSYSTEM_DEF(ticker) queued_players -= next_in_line queue_delay = 0 -/datum/controller/subsystem/ticker/proc/check_maprotate() - if(!CONFIG_GET(flag/maprotation)) - return - if(world.time - SSticker.round_start_time < 10 MINUTES) //Not forcing map rotation for very short rounds. - return - INVOKE_ASYNC(SSmapping, TYPE_PROC_REF(/datum/controller/subsystem/mapping/, maprotate)) - /datum/controller/subsystem/ticker/proc/HasRoundStarted() return current_state >= GAME_STATE_PLAYING diff --git a/code/controllers/subsystem/time_track.dm b/code/controllers/subsystem/time_track.dm index b3a4fe7e8698f..4c706fdaf6db3 100644 --- a/code/controllers/subsystem/time_track.dm +++ b/code/controllers/subsystem/time_track.dm @@ -42,7 +42,7 @@ SUBSYSTEM_DEF(time_track) ) /datum/controller/subsystem/time_track/Initialize() - GLOB.perf_log = "[GLOB.log_directory]/perf-[GLOB.round_id ? GLOB.round_id : "NULL"]-[SSmapping.config?.map_name].csv" + GLOB.perf_log = "[GLOB.log_directory]/perf-[GLOB.round_id ? GLOB.round_id : "NULL"]-[SSmapping.current_map.map_name].csv" world.Profile(PROFILE_RESTART, type = "sendmaps") //Need to do the sendmaps stuff in its own file, since it works different then everything else var/list/sendmaps_headers = list() diff --git a/code/controllers/subsystem/title.dm b/code/controllers/subsystem/title.dm index dbaa7ddeb48c0..8df9349ff0398 100644 --- a/code/controllers/subsystem/title.dm +++ b/code/controllers/subsystem/title.dm @@ -25,7 +25,7 @@ SUBSYSTEM_DEF(title) for(var/S in provisional_title_screens) var/list/L = splittext(S,"+") - if((L.len == 1 && (L[1] != "exclude" && L[1] != "blank.png")) || (L.len > 1 && ((use_rare_screens && LOWER_TEXT(L[1]) == "rare") || (LOWER_TEXT(L[1]) == LOWER_TEXT(SSmapping.config.map_name))))) + if((L.len == 1 && (L[1] != "exclude" && L[1] != "blank.png")) || (L.len > 1 && ((use_rare_screens && LOWER_TEXT(L[1]) == "rare") || (LOWER_TEXT(L[1]) == LOWER_TEXT(SSmapping.current_map.map_name))))) title_screens += S if(length(title_screens)) diff --git a/code/controllers/subsystem/unplanned_ai_idle_controllers.dm b/code/controllers/subsystem/unplanned_ai_idle_controllers.dm new file mode 100644 index 0000000000000..6385239e18c70 --- /dev/null +++ b/code/controllers/subsystem/unplanned_ai_idle_controllers.dm @@ -0,0 +1,4 @@ +UNPLANNED_CONTROLLER_SUBSYSTEM_DEF(idle_unplanned_controllers) + name = "Unplanned AI Idle Controllers" + wait = 2.5 SECONDS + target_status = AI_STATUS_IDLE diff --git a/code/controllers/subsystem/unplanned_controllers.dm b/code/controllers/subsystem/unplanned_controllers.dm new file mode 100644 index 0000000000000..3fb5f46dd069d --- /dev/null +++ b/code/controllers/subsystem/unplanned_controllers.dm @@ -0,0 +1,18 @@ +/// Handles making mobs perform lightweight "idle" behaviors such as wandering around when they have nothing planned +SUBSYSTEM_DEF(unplanned_controllers) + name = "Unplanned AI Controllers" + flags = SS_POST_FIRE_TIMING|SS_BACKGROUND|SS_NO_INIT + priority = FIRE_PRIORITY_UNPLANNED_NPC + init_order = INIT_ORDER_AI_CONTROLLERS + wait = 0.25 SECONDS + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME + ///what ai status are we interested in + var/target_status = AI_STATUS_ON + +/datum/controller/subsystem/unplanned_controllers/stat_entry(msg) + msg = "Planning AIs:[length(GLOB.unplanned_controllers[target_status])]" + return ..() + +/datum/controller/subsystem/unplanned_controllers/fire(resumed) + for(var/datum/ai_controller/ai_controller as anything in GLOB.unplanned_controllers[target_status]) + ai_controller.idle_behavior.perform_idle_behavior(wait * 0.1, ai_controller) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 7bed63cc36fc8..d0e642bd3aa2d 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -101,24 +101,28 @@ SUBSYSTEM_DEF(vote) // stringify the winners to prevent potential unimplemented serialization errors. // Perhaps this can be removed in the future and we assert that vote choices must implement serialization. - var/final_winner_string = final_winner && "[final_winner]" + var/final_winner_string = (final_winner && "[final_winner]") || "NO WINNER" var/list/winners_string = list() - for(var/winner in winners) - winners_string += "[winner]" + + if(length(winners)) + for(var/winner in winners) + winners_string += "[winner]" + else + winners_string = list("NO WINNER") var/list/vote_log_data = list( + "type" = "[current_vote.type]", "choices" = vote_choice_data, "total" = total_votes, "winners" = winners_string, "final_winner" = final_winner_string, ) - var/log_string = replacetext(to_display, "\n", "\\n") // 'keep' the newlines, but dont actually print them as newlines - log_vote(log_string, vote_log_data) - to_chat(world, span_infoplain(vote_font("\n[to_display]"))) + log_vote("vote finalized", vote_log_data) + if(to_display) + to_chat(world, span_infoplain(vote_font("\n[to_display]"))) // Finally, doing any effects on vote completion - if (final_winner) // if no one voted, or the vote cannot be won, final_winner will be null - current_vote.finalize_vote(final_winner) + current_vote.finalize_vote(final_winner) /** * One selection per person, and the selection with the most votes wins. diff --git a/code/datums/achievements/misc_achievements.dm b/code/datums/achievements/misc_achievements.dm index bd1719783e12a..4e37400d51d69 100644 --- a/code/datums/achievements/misc_achievements.dm +++ b/code/datums/achievements/misc_achievements.dm @@ -234,7 +234,13 @@ icon_state = "sisyphus" /datum/award/achievement/misc/cigarettes - name = "Unhealthy snacks" + name = "Unhealthy Snacks" desc = "You were curious to taste it. And then another. You must have more!" database_id = MEDAL_CIGARETTES icon_state = "cigarettes" + +/datum/award/achievement/misc/sharkdragon + name = "You're What You Eat" + desc = "Nutritionists often recommend a balanced and varied diet. However that clearly isn't the case for some creatures." + database_id = MEDAL_SHARKDRAGON + icon_state = "dragon_plus_fish" diff --git a/code/datums/actions/mobs/lava_swoop.dm b/code/datums/actions/mobs/lava_swoop.dm index 2b07734b4a852..428c975665676 100644 --- a/code/datums/actions/mobs/lava_swoop.dm +++ b/code/datums/actions/mobs/lava_swoop.dm @@ -144,11 +144,17 @@ for(var/turf/T in walled) drakewalls += new /obj/effect/temp_visual/drakewall(T) // no people with lava immunity can just run away from the attack for free var/list/indestructible_turfs = list() - for(var/turf/T in RANGE_TURFS(2, center)) - if(isindestructiblefloor(T)) + + for(var/turf/turf_target as anything in RANGE_TURFS(2, center)) + if(isindestructiblefloor(turf_target)) + continue + if(isindestructiblewall(turf_target)) + indestructible_turfs += turf_target continue - if(isindestructiblewall(T)) - indestructible_turfs += T + if(ismineralturf(turf_target)) + var/turf/closed/mineral/mineral_turf = turf_target + mineral_turf.gets_drilled(owner) + SLEEP_CHECK_DEATH(1 SECONDS, owner) // give them a bit of time to realize what attack is actually happening var/list/turfs = RANGE_TURFS(2, center) diff --git a/code/datums/ai/_ai_controller.dm b/code/datums/ai/_ai_controller.dm index 4d5b660044322..d6230ec8d3534 100644 --- a/code/datums/ai/_ai_controller.dm +++ b/code/datums/ai/_ai_controller.dm @@ -90,8 +90,17 @@ multiple modular subtrees with behaviors ///Sets the current movement target, with an optional param to override the movement behavior /datum/ai_controller/proc/set_movement_target(source, atom/target, datum/ai_movement/new_movement) + if(current_movement_target) + UnregisterSignal(current_movement_target, list(COMSIG_MOVABLE_MOVED, COMSIG_PREQDELETED)) + if(!isnull(target) && !isatom(target)) + stack_trace("[pawn]'s current movement target is not an atom, rather a [target.type]! Did you accidentally set it to a weakref?") + CancelActions() + return movement_target_source = source current_movement_target = target + if(!isnull(current_movement_target)) + RegisterSignal(current_movement_target, COMSIG_MOVABLE_MOVED, PROC_REF(on_movement_target_move)) + RegisterSignal(current_movement_target, COMSIG_PREQDELETED, PROC_REF(on_movement_target_delete)) if(new_movement) change_ai_movement_type(new_movement) @@ -153,6 +162,20 @@ multiple modular subtrees with behaviors SIGNAL_HANDLER set_new_cells() + if(current_movement_target) + check_target_max_distance() + +/datum/ai_controller/proc/on_movement_target_move(atom/source) + SIGNAL_HANDLER + check_target_max_distance() + +/datum/ai_controller/proc/on_movement_target_delete(atom/source) + SIGNAL_HANDLER + set_movement_target(source = type, target = null) + +/datum/ai_controller/proc/check_target_max_distance() + if(get_dist(current_movement_target, pawn) > max_target_distance) + CancelActions() /datum/ai_controller/proc/set_new_cells() if(isnull(our_cells)) @@ -284,6 +307,7 @@ multiple modular subtrees with behaviors GLOB.ai_controllers_by_zlevel[pawn_turf.z] -= src if(ai_status) GLOB.ai_controllers_by_status[ai_status] -= src + remove_from_unplanned_controllers() pawn.ai_controller = null pawn = null if(destroy) @@ -311,23 +335,34 @@ multiple modular subtrees with behaviors return FALSE return TRUE -///Runs any actions that are currently running -/datum/ai_controller/process(seconds_per_tick) +///Can this pawn interact with objects? +/datum/ai_controller/proc/ai_can_interact() + SHOULD_CALL_PARENT(TRUE) + return !QDELETED(pawn) - if(!length(current_behaviors) && idle_behavior) - idle_behavior.perform_idle_behavior(seconds_per_tick, src) //Do some stupid shit while we have nothing to do - return +///Interact with objects +/datum/ai_controller/proc/ai_interact(target, combat_mode, list/modifiers) + if(!ai_can_interact()) + return FALSE - if(current_movement_target) - if(!isatom(current_movement_target)) - stack_trace("[pawn]'s current movement target is not an atom, rather a [current_movement_target.type]! Did you accidentally set it to a weakref?") - CancelActions() - return + var/atom/final_target = isdatum(target) ? target : blackboard[target] //incase we got a blackboard key instead - if(get_dist(pawn, current_movement_target) > max_target_distance) //The distance is out of range - CancelActions() - return + if(QDELETED(final_target)) + return FALSE + var/params = list2params(modifiers) + var/mob/living/living_pawn = pawn + if(isnull(combat_mode)) + living_pawn.ClickOn(final_target, params) + return TRUE + + var/old_combat_mode = living_pawn.combat_mode + living_pawn.set_combat_mode(combat_mode) + living_pawn.ClickOn(final_target, params) + living_pawn.set_combat_mode(old_combat_mode) + return TRUE +///Runs any actions that are currently running +/datum/ai_controller/process(seconds_per_tick) for(var/datum/ai_behavior/current_behavior as anything in current_behaviors) @@ -342,9 +377,9 @@ multiple modular subtrees with behaviors ProcessBehavior(action_seconds_per_tick, current_behavior) return - if(!current_movement_target) - stack_trace("[pawn] wants to perform action type [current_behavior.type] which requires movement, but has no current movement target!") - return //This can cause issues, so don't let these slide. + if(isnull(current_movement_target)) + fail_behavior(current_behavior) + return ///Stops pawns from performing such actions that should require the target to be adjacent. var/atom/movable/moving_pawn = pawn var/can_reach = !(current_behavior.behavior_flags & AI_BEHAVIOR_REQUIRE_REACH) || moving_pawn.CanReach(current_movement_target) @@ -391,17 +426,24 @@ multiple modular subtrees with behaviors //remove old status, if we've got one if(ai_status) GLOB.ai_controllers_by_status[ai_status] -= src + remove_from_unplanned_controllers() stop_previous_processing() ai_status = new_ai_status GLOB.ai_controllers_by_status[new_ai_status] += src + if(ai_status == AI_STATUS_OFF) + CancelActions() + return + if(!length(current_behaviors)) + add_to_unplanned_controllers() + return + start_ai_processing() + +/datum/ai_controller/proc/start_ai_processing() switch(ai_status) if(AI_STATUS_ON) START_PROCESSING(SSai_behaviors, src) if(AI_STATUS_IDLE) START_PROCESSING(SSidle_ai_behaviors, src) - CancelActions() - if(AI_STATUS_OFF) - CancelActions() /datum/ai_controller/proc/stop_previous_processing() switch(ai_status) @@ -415,6 +457,16 @@ multiple modular subtrees with behaviors update_able_to_run() addtimer(CALLBACK(src, PROC_REF(update_able_to_run)), time) +/datum/ai_controller/proc/add_to_unplanned_controllers() + if(isnull(ai_status) || ai_status == AI_STATUS_OFF || isnull(idle_behavior)) + return + GLOB.unplanned_controllers[ai_status][src] = TRUE + +/datum/ai_controller/proc/remove_from_unplanned_controllers() + if(isnull(ai_status) || ai_status == AI_STATUS_OFF) + return + GLOB.unplanned_controllers[ai_status] -= src + /datum/ai_controller/proc/modify_cooldown(datum/ai_behavior/behavior, new_cooldown) behavior_cooldowns[behavior] = new_cooldown @@ -433,6 +485,7 @@ multiple modular subtrees with behaviors if(!behavior.setup(arglist(arguments))) return + var/should_exit_unplanned = !length(current_behaviors) planned_behaviors[behavior] = TRUE current_behaviors[behavior] = TRUE @@ -445,6 +498,9 @@ multiple modular subtrees with behaviors if(!(behavior.behavior_flags & AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION)) //this one blocks planning! able_to_plan = FALSE + if(should_exit_unplanned) + exit_unplanned_mode() + SEND_SIGNAL(src, AI_CONTROLLER_BEHAVIOR_QUEUED(behavior_type), arguments) /datum/ai_controller/proc/check_able_to_plan() @@ -456,6 +512,16 @@ multiple modular subtrees with behaviors /datum/ai_controller/proc/dequeue_behavior(datum/ai_behavior/behavior) current_behaviors -= behavior able_to_plan = check_able_to_plan() + if(!length(current_behaviors)) + enter_unplanned_mode() + +/datum/ai_controller/proc/exit_unplanned_mode() + remove_from_unplanned_controllers() + start_ai_processing() + +/datum/ai_controller/proc/enter_unplanned_mode() + add_to_unplanned_controllers() + stop_previous_processing() /datum/ai_controller/proc/ProcessBehavior(seconds_per_tick, datum/ai_behavior/behavior) var/list/arguments = list(seconds_per_tick, src) @@ -479,11 +545,14 @@ multiple modular subtrees with behaviors if(!length(current_behaviors)) return for(var/datum/ai_behavior/current_behavior as anything in current_behaviors) - var/list/arguments = list(src, FALSE) - var/list/stored_arguments = behavior_args[current_behavior.type] - if(stored_arguments) - arguments += stored_arguments - current_behavior.finish_action(arglist(arguments)) + fail_behavior(current_behavior) + +/datum/ai_controller/proc/fail_behavior(datum/ai_behavior/current_behavior) + var/list/arguments = list(src, FALSE) + var/list/stored_arguments = behavior_args[current_behavior.type] + if(stored_arguments) + arguments += stored_arguments + current_behavior.finish_action(arglist(arguments)) /// Turn the controller on or off based on if you're alive, we only register to this if the flag is present so don't need to check again /datum/ai_controller/proc/on_stat_changed(mob/living/source, new_stat) diff --git a/code/datums/ai/babies/babies_behaviors.dm b/code/datums/ai/babies/babies_behaviors.dm index ad57d309a2c72..aa8a15a03e40b 100644 --- a/code/datums/ai/babies/babies_behaviors.dm +++ b/code/datums/ai/babies/babies_behaviors.dm @@ -58,17 +58,9 @@ var/mob/target = controller.blackboard[target_key] if(QDELETED(target) || target.stat != CONSCIOUS) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED - var/mob/living/basic/living_pawn = controller.pawn - living_pawn.set_combat_mode(FALSE) - living_pawn.melee_attack(target) + controller.ai_interact(target = target, combat_mode = FALSE) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED /datum/ai_behavior/make_babies/finish_action(datum/ai_controller/controller, succeeded, target_key) . = ..() controller.clear_blackboard_key(target_key) - if(!succeeded) - return - var/mob/living/living_pawn = controller.pawn - if(QDELETED(living_pawn)) // pawn can be null at this point - return - living_pawn.set_combat_mode(initial(living_pawn.combat_mode)) diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm index 883c157a96ba9..aba62f2dc7b79 100644 --- a/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm +++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm @@ -8,8 +8,6 @@ . = ..() if(!controller.blackboard[targeting_strategy_key]) CRASH("No targeting strategy was supplied in the blackboard for [controller.pawn]") - if(HAS_TRAIT(controller.pawn, TRAIT_HANDS_BLOCKED)) - return FALSE //Hiding location is priority var/atom/target = controller.blackboard[hiding_location_key] || controller.blackboard[target_key] if(QDELETED(target)) @@ -35,11 +33,8 @@ controller.set_blackboard_key(hiding_location_key, hiding_target) - if(hiding_target) //Slap it! - basic_mob.melee_attack(hiding_target) - else - basic_mob.melee_attack(target) - + var/atom/final_target = hiding_target || target + controller.ai_interact(target = final_target, combat_mode = TRUE) if(terminate_after_action) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED return AI_BEHAVIOR_DELAY diff --git a/code/datums/ai/basic_mobs/basic_subtrees/mine_walls.dm b/code/datums/ai/basic_mobs/basic_subtrees/mine_walls.dm index dc3f6ddcf9015..12875f9a3f345 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/mine_walls.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/mine_walls.dm @@ -24,9 +24,8 @@ var/mob/living/basic/living_pawn = controller.pawn var/turf/closed/mineral/target = controller.blackboard[target_key] var/is_gibtonite_turf = istype(target, /turf/closed/mineral/gibtonite) - if(QDELETED(target)) + if(!controller.ai_interact(target = target)) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED - living_pawn.melee_attack(target) if(is_gibtonite_turf) living_pawn.manual_emote("sighs...") //accept whats about to happen to us diff --git a/code/datums/ai/basic_mobs/basic_subtrees/ranged_skirmish.dm b/code/datums/ai/basic_mobs/basic_subtrees/ranged_skirmish.dm index 3640a2052b55e..43a3d400bc58d 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/ranged_skirmish.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/ranged_skirmish.dm @@ -43,6 +43,5 @@ if (distance > max_range || distance < min_range) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED - var/mob/living/basic/gunman = controller.pawn - gunman.RangedAttack(target) + controller.ai_interact(target = target, combat_mode = TRUE) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED diff --git a/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm b/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm index 0e6780adeac76..7d877731e2b05 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm @@ -216,11 +216,9 @@ /datum/ai_planning_subtree/random_speech/cats speech_chance = 10 - speak = list( - "mrawww!", - "meow!", - "maw!", - ) + sound = list(SFX_CAT_MEOW) + emote_hear = list("meows.") + emote_see = list("meows.") /datum/ai_planning_subtree/random_speech/blackboard //literal tower of babel, subtree form speech_chance = 1 diff --git a/code/datums/ai/basic_mobs/pet_commands/fetch.dm b/code/datums/ai/basic_mobs/pet_commands/fetch.dm index 87606fa0c6555..5ff208560d2a1 100644 --- a/code/datums/ai/basic_mobs/pet_commands/fetch.dm +++ b/code/datums/ai/basic_mobs/pet_commands/fetch.dm @@ -109,7 +109,7 @@ if(!basic_pawn.Adjacent(snack)) return AI_BEHAVIOR_DELAY - basic_pawn.melee_attack(snack) // snack attack! + controller.ai_interact(target = snack) if(QDELETED(snack)) // we ate it! return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED diff --git a/code/datums/ai/generic/generic_behaviors.dm b/code/datums/ai/generic/generic_behaviors.dm index 1c0e1f65adf96..c6fcbcfb57265 100644 --- a/code/datums/ai/generic/generic_behaviors.dm +++ b/code/datums/ai/generic/generic_behaviors.dm @@ -101,11 +101,10 @@ if(QDELETED(target)) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED - pawn.set_combat_mode(FALSE) if(held_item) held_item.melee_attack_chain(pawn, target) else - pawn.UnarmedAttack(target, TRUE) + controller.ai_interact(target = target, combat_mode = FALSE) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED diff --git a/code/datums/ai/hunting_behavior/hunting_behaviors.dm b/code/datums/ai/hunting_behavior/hunting_behaviors.dm index ba2da1c2d04e8..c202c4be6a7d8 100644 --- a/code/datums/ai/hunting_behavior/hunting_behaviors.dm +++ b/code/datums/ai/hunting_behavior/hunting_behaviors.dm @@ -117,31 +117,23 @@ if(always_reset_target && hunting_target_key) controller.clear_blackboard_key(hunting_target_key) -/datum/ai_behavior/hunt_target/unarmed_attack_target - ///do we toggle combat mode before interacting with the object? - var/switch_combat_mode = FALSE +/datum/ai_behavior/hunt_target/interact_with_target + ///what combat mode should we use to interact with + var/behavior_combat_mode = TRUE -/datum/ai_behavior/hunt_target/unarmed_attack_target/target_caught(mob/living/hunter, obj/structure/cable/hunted) - if(switch_combat_mode) - hunter.combat_mode = !(hunter.combat_mode) - hunter.UnarmedAttack(hunted, TRUE) +/datum/ai_behavior/hunt_target/interact_with_target/target_caught(mob/living/hunter, obj/structure/cable/hunted) + var/datum/ai_controller/controller = hunter.ai_controller + controller.ai_interact(target = hunted, combat_mode = behavior_combat_mode) -/datum/ai_behavior/hunt_target/unarmed_attack_target/finish_action(datum/ai_controller/controller, succeeded, hunting_target_key, hunting_cooldown_key) - . = ..() - if(!switch_combat_mode) - return - var/mob/living/living_pawn = controller.pawn - living_pawn.combat_mode = initial(living_pawn.combat_mode) - -/datum/ai_behavior/hunt_target/unarmed_attack_target/switch_combat_mode - switch_combat_mode = TRUE +/datum/ai_behavior/hunt_target/interact_with_target/combat_mode_off + behavior_combat_mode = FALSE -/datum/ai_behavior/hunt_target/unarmed_attack_target/reset_target +/datum/ai_behavior/hunt_target/interact_with_target/reset_target always_reset_target = TRUE -/datum/ai_behavior/hunt_target/unarmed_attack_target/reset_target_combat_mode +/datum/ai_behavior/hunt_target/interact_with_target/reset_target_combat_mode_off always_reset_target = TRUE - switch_combat_mode = TRUE + behavior_combat_mode = FALSE /datum/ai_behavior/hunt_target/use_ability_on_target always_reset_target = TRUE diff --git a/code/datums/ai/hunting_behavior/hunting_corpses.dm b/code/datums/ai/hunting_behavior/hunting_corpses.dm index e720e4da947af..89d100263fb1a 100644 --- a/code/datums/ai/hunting_behavior/hunting_corpses.dm +++ b/code/datums/ai/hunting_behavior/hunting_corpses.dm @@ -1,7 +1,7 @@ /// Find and attack corpses /datum/ai_planning_subtree/find_and_hunt_target/corpses finding_behavior = /datum/ai_behavior/find_hunt_target/corpses - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target hunt_targets = list(/mob/living) /// Find nearby dead mobs diff --git a/code/datums/ai/hunting_behavior/hunting_lights.dm b/code/datums/ai/hunting_behavior/hunting_lights.dm index 6b82e87f2693b..5062a8aaf929e 100644 --- a/code/datums/ai/hunting_behavior/hunting_lights.dm +++ b/code/datums/ai/hunting_behavior/hunting_lights.dm @@ -1,11 +1,11 @@ /datum/ai_planning_subtree/find_and_hunt_target/look_for_light_fixtures target_key = BB_LOW_PRIORITY_HUNTING_TARGET finding_behavior = /datum/ai_behavior/find_hunt_target/light_fixtures - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/light_fixtures + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/light_fixtures hunt_targets = list(/obj/machinery/light) hunt_range = 7 -/datum/ai_behavior/hunt_target/unarmed_attack_target/light_fixtures +/datum/ai_behavior/hunt_target/interact_with_target/light_fixtures hunt_cooldown = 10 SECONDS always_reset_target = TRUE diff --git a/code/datums/ai/hunting_behavior/hunting_mouse.dm b/code/datums/ai/hunting_behavior/hunting_mouse.dm index d0e7161fd2de6..f97ebf27ddf6f 100644 --- a/code/datums/ai/hunting_behavior/hunting_mouse.dm +++ b/code/datums/ai/hunting_behavior/hunting_mouse.dm @@ -1,13 +1,13 @@ // Mouse subtree to hunt down delicious cheese. /datum/ai_planning_subtree/find_and_hunt_target/look_for_cheese - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/mouse + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/mouse hunt_targets = list(/obj/item/food/cheese) hunt_range = 1 // Mouse subtree to hunt down ... delicious cabling? /datum/ai_planning_subtree/find_and_hunt_target/look_for_cables target_key = BB_LOW_PRIORITY_HUNTING_TARGET - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/mouse + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/mouse finding_behavior = /datum/ai_behavior/find_hunt_target/mouse_cable hunt_targets = list(/obj/structure/cable) hunt_range = 0 // Only look below us @@ -28,5 +28,5 @@ return below_the_cable.underfloor_accessibility >= UNDERFLOOR_INTERACTABLE // Our hunts have a decent cooldown. -/datum/ai_behavior/hunt_target/unarmed_attack_target/mouse +/datum/ai_behavior/hunt_target/interact_with_target/mouse hunt_cooldown = 20 SECONDS diff --git a/code/datums/ai/idle_behaviors/_idle_behavior.dm b/code/datums/ai/idle_behaviors/_idle_behavior.dm index 315233bb71d57..bacb8e7cdf37b 100644 --- a/code/datums/ai/idle_behaviors/_idle_behavior.dm +++ b/code/datums/ai/idle_behaviors/_idle_behavior.dm @@ -1,4 +1,5 @@ /datum/idle_behavior /datum/idle_behavior/proc/perform_idle_behavior(seconds_per_tick, datum/ai_controller/controller) - return + set waitfor = FALSE + SHOULD_CALL_PARENT(TRUE) diff --git a/code/datums/ai/idle_behaviors/idle_dog.dm b/code/datums/ai/idle_behaviors/idle_dog.dm index 46e0d040c9dae..4d036e9a7a5d9 100644 --- a/code/datums/ai/idle_behaviors/idle_dog.dm +++ b/code/datums/ai/idle_behaviors/idle_dog.dm @@ -1,5 +1,6 @@ ///Dog specific idle behavior. /datum/idle_behavior/idle_dog/perform_idle_behavior(seconds_per_tick, datum/ai_controller/basic_controller/dog/controller) + . = ..() var/mob/living/living_pawn = controller.pawn if(!isturf(living_pawn.loc) || living_pawn.pulledby) return diff --git a/code/datums/ai/idle_behaviors/idle_haunted.dm b/code/datums/ai/idle_behaviors/idle_haunted.dm index a67b5d6cbe04d..5784b5104f6b8 100644 --- a/code/datums/ai/idle_behaviors/idle_haunted.dm +++ b/code/datums/ai/idle_behaviors/idle_haunted.dm @@ -4,6 +4,7 @@ var/teleport_chance = 4 /datum/idle_behavior/idle_ghost_item/perform_idle_behavior(seconds_per_tick, datum/ai_controller/controller) + . = ..() var/obj/item/item_pawn = controller.pawn if(ismob(item_pawn.loc)) //Being held. dont teleport return diff --git a/code/datums/ai/idle_behaviors/idle_monkey.dm b/code/datums/ai/idle_behaviors/idle_monkey.dm index 5b5e189435deb..c32534dce529e 100644 --- a/code/datums/ai/idle_behaviors/idle_monkey.dm +++ b/code/datums/ai/idle_behaviors/idle_monkey.dm @@ -13,6 +13,7 @@ ) /datum/idle_behavior/idle_monkey/perform_idle_behavior(seconds_per_tick, datum/ai_controller/controller) + . = ..() var/mob/living/living_pawn = controller.pawn if(SPT_PROB(25, seconds_per_tick) && (living_pawn.mobility_flags & MOBILITY_MOVE) && isturf(living_pawn.loc) && !living_pawn.pulledby) diff --git a/code/datums/ai/monkey/monkey_behaviors.dm b/code/datums/ai/monkey/monkey_behaviors.dm index e6720d7d96a78..126c08daa1e8b 100644 --- a/code/datums/ai/monkey/monkey_behaviors.dm +++ b/code/datums/ai/monkey/monkey_behaviors.dm @@ -186,7 +186,7 @@ if(weapon) weapon.melee_attack_chain(living_pawn, target) else - living_pawn.UnarmedAttack(target, null, disarm ? list("right" = TRUE) : null) //Fake a right click if we're disarmin + controller.ai_interact(target = target, modifiers = disarm ? list(RIGHT_CLICK = TRUE) : null) controller.set_blackboard_key(BB_MONKEY_GUN_WORKED, TRUE) // We reset their memory of the gun being 'broken' if they accomplish some other attack else if(weapon) var/atom/real_target = target diff --git a/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm b/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm index 83691ea8a8ace..388899207d1f5 100644 --- a/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm +++ b/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm @@ -127,15 +127,21 @@ if(ORGAN_COLOR_INHERIT) draw_color = bodypart_owner.draw_color if(ORGAN_COLOR_HAIR) + var/datum/species/species = bodypart_owner.owner?.dna?.species + var/fixed_color = species?.get_fixed_hair_color(bodypart_owner.owner) // DOPPLER EDIT, old code: var/fixed_color = species?.get_fixed_hair_color(bodypart_owner) if(!ishuman(bodypart_owner.owner)) + draw_color = fixed_color return var/mob/living/carbon/human/human_owner = bodypart_owner.owner var/obj/item/bodypart/head/my_head = human_owner.get_bodypart(BODY_ZONE_HEAD) //not always the same as bodypart_owner //head hair color takes priority, owner hair color is a backup if we lack a head or something - if(my_head) - draw_color = my_head.hair_color - else - draw_color = human_owner.hair_color + if(!my_head) + draw_color = fixed_color || human_owner.hair_color + return + if(my_head.head_flags & (HEAD_HAIR|HEAD_FACIAL_HAIR)) + draw_color = my_head.fixed_hair_color || my_head.hair_color + else //inherit mutant color of the bodypart if the owner doesn't have hair. + draw_color = bodypart_owner.draw_color return TRUE diff --git a/code/datums/bodypart_overlays/texture_bodypart_overlay.dm b/code/datums/bodypart_overlays/texture_bodypart_overlay.dm index 83c8ce5f12121..623a61b8912f0 100644 --- a/code/datums/bodypart_overlays/texture_bodypart_overlay.dm +++ b/code/datums/bodypart_overlays/texture_bodypart_overlay.dm @@ -22,3 +22,7 @@ blocks_emissive = EMISSIVE_BLOCK_NONE texture_icon_state = "spacey" texture_icon = 'icons/mob/human/textures.dmi' + +/datum/bodypart_overlay/texture/carpskin + texture_icon_state = "carpskin" + texture_icon = 'icons/mob/human/textures.dmi' diff --git a/code/datums/brain_damage/imaginary_friend.dm b/code/datums/brain_damage/imaginary_friend.dm index da0388f6c54d2..ad60f6cd9a6a5 100644 --- a/code/datums/brain_damage/imaginary_friend.dm +++ b/code/datums/brain_damage/imaginary_friend.dm @@ -396,7 +396,7 @@ var/obj/visual = image('icons/hud/screen_gen.dmi', our_tile, "arrow", FLY_LAYER) INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(flick_overlay_global), visual, group_clients(), 2.5 SECONDS) - animate(visual, pixel_x = (tile.x - our_tile.x) * world.icon_size + pointed_atom.pixel_x, pixel_y = (tile.y - our_tile.y) * world.icon_size + pointed_atom.pixel_y, time = 1.7, easing = EASE_OUT) + animate(visual, pixel_x = (tile.x - our_tile.x) * ICON_SIZE_X + pointed_atom.pixel_x, pixel_y = (tile.y - our_tile.y) * ICON_SIZE_Y + pointed_atom.pixel_y, time = 1.7, easing = EASE_OUT) /mob/camera/imaginary_friend/create_thinking_indicator() if(active_thinking_indicator || active_typing_indicator || !HAS_TRAIT(src, TRAIT_THINKING_IN_CHARACTER)) diff --git a/code/datums/cogbar.dm b/code/datums/cogbar.dm index 0b5ead1e51e8f..6505158b58d88 100644 --- a/code/datums/cogbar.dm +++ b/code/datums/cogbar.dm @@ -44,7 +44,7 @@ /// Adds the cog to the user, visible by other players /datum/cogbar/proc/add_cog_to_user() - cog = SSvis_overlays.add_vis_overlay(user, + cog = SSvis_overlays.add_vis_overlay(user, icon = 'icons/effects/progressbar.dmi', iconstate = "cog", plane = HIGH_GAME_PLANE, @@ -52,7 +52,7 @@ unique = TRUE, alpha = 0, ) - cog.pixel_y = world.icon_size + offset_y + cog.pixel_y = ICON_SIZE_Y + offset_y animate(cog, alpha = 255, time = COGBAR_ANIMATION_TIME) if(isnull(user_client)) @@ -61,7 +61,7 @@ blank = image('icons/blanks/32x32.dmi', cog, "nothing") SET_PLANE_EXPLICIT(blank, HIGH_GAME_PLANE, user) blank.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA - blank.override = TRUE + blank.override = TRUE user_client.images += blank @@ -74,7 +74,7 @@ animate(cog, alpha = 0, time = COGBAR_ANIMATION_TIME) - QDEL_IN(src, COGBAR_ANIMATION_TIME) + QDEL_IN(src, COGBAR_ANIMATION_TIME) /// When the user is deleted, remove the cog @@ -82,6 +82,6 @@ SIGNAL_HANDLER qdel(src) - + #undef COGBAR_ANIMATION_TIME diff --git a/code/datums/components/adjust_fishing_difficulty.dm b/code/datums/components/adjust_fishing_difficulty.dm index b2f5f71a757d8..4e329b039409c 100644 --- a/code/datums/components/adjust_fishing_difficulty.dm +++ b/code/datums/components/adjust_fishing_difficulty.dm @@ -65,9 +65,9 @@ add_examine_line(user, examine_text, "Buckling to [source.p_them()]") /datum/component/adjust_fishing_difficulty/proc/add_examine_line(mob/user, list/examine_text, method) - var/percent = HAS_MIND_TRAIT(user, TRAIT_EXAMINE_DEEPER_FISH) ? "[modifier]% " : "" - var/text = "[method] will make fishing [percent][modifier > 0 ? "easier" : "harder"]." - if(modifier > 0) + var/percent = HAS_MIND_TRAIT(user, TRAIT_EXAMINE_DEEPER_FISH) ? "[abs(modifier)]% " : "" + var/text = "[method] will make fishing [percent][modifier < 0 ? "easier" : "harder"]." + if(modifier < 0) examine_text += span_nicegreen(text) else examine_text += span_danger(text) diff --git a/code/datums/components/appearance_on_aggro.dm b/code/datums/components/appearance_on_aggro.dm index 6d4cab3d91410..143c0b260cdbd 100644 --- a/code/datums/components/appearance_on_aggro.dm +++ b/code/datums/components/appearance_on_aggro.dm @@ -25,7 +25,7 @@ /datum/component/appearance_on_aggro/RegisterWithParent() RegisterSignal(parent, COMSIG_AI_BLACKBOARD_KEY_SET(target_key), PROC_REF(on_set_target)) - RegisterSignals(parent, list(COMSIG_AI_BLACKBOARD_KEY_CLEARED(target_key), COMSIG_LIVING_DEATH), PROC_REF(on_clear_or_death)) + RegisterSignals(parent, list(COMSIG_AI_BLACKBOARD_KEY_CLEARED(target_key), COMSIG_LIVING_DEATH, COMSIG_MOB_LOGIN), PROC_REF(revert_appearance)) if (!isnull(aggro_state)) RegisterSignal(parent, COMSIG_ATOM_UPDATE_ICON_STATE, PROC_REF(on_icon_state_updated)) if (!isnull(aggro_overlay)) @@ -33,7 +33,12 @@ /datum/component/appearance_on_aggro/UnregisterFromParent() . = ..() - UnregisterSignal(parent, list(COMSIG_AI_BLACKBOARD_KEY_SET(target_key), COMSIG_AI_BLACKBOARD_KEY_CLEARED(target_key), COMSIG_LIVING_DEATH)) + UnregisterSignal(parent, list( + COMSIG_AI_BLACKBOARD_KEY_SET(target_key), + COMSIG_AI_BLACKBOARD_KEY_CLEARED(target_key), + COMSIG_LIVING_DEATH, + COMSIG_MOB_LOGIN, + )) /datum/component/appearance_on_aggro/proc/on_set_target(mob/living/source) SIGNAL_HANDLER @@ -51,11 +56,8 @@ revert_appearance(parent) return ..() -/datum/component/appearance_on_aggro/proc/on_clear_or_death(atom/source) - SIGNAL_HANDLER - revert_appearance(parent) - /datum/component/appearance_on_aggro/proc/revert_appearance(mob/living/source) + SIGNAL_HANDLER if (!isnull(aggro_overlay) || !isnull(aggro_state)) source.update_appearance(UPDATE_ICON) if (!isnull(alpha_on_deaggro)) diff --git a/code/datums/components/bubble_icon_override.dm b/code/datums/components/bubble_icon_override.dm new file mode 100644 index 0000000000000..da070b8f5dc82 --- /dev/null +++ b/code/datums/components/bubble_icon_override.dm @@ -0,0 +1,99 @@ +/** + * A component that overrides the bubble_icon variable when equipped or implanted + * while having a simple priority system, so accessories have higher priority than + * organs, for example. + */ +/datum/component/bubble_icon_override + dupe_mode = COMPONENT_DUPE_ALLOWED + can_transfer = TRUE //sure why not + ///The override to the default bubble icon for the atom + var/bubble_icon + ///The priority of this bubble icon compared to others + var/priority + +/datum/component/bubble_icon_override/Initialize(bubble_icon, priority) + if(!isclothing(parent) && !isorgan(parent)) + return COMPONENT_INCOMPATIBLE + src.bubble_icon = bubble_icon + src.priority = priority + +/datum/component/bubble_icon_override/RegisterWithParent() + if(isclothing(parent)) + RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(on_equipped)) + RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(on_dropped)) + else if(isorgan(parent)) + RegisterSignal(parent, COMSIG_ORGAN_IMPLANTED, PROC_REF(on_organ_implanted)) + RegisterSignal(parent, COMSIG_ORGAN_REMOVED, PROC_REF(on_organ_removed)) + var/mob/living/target = get_bubble_icon_target() + if(target) + register_owner(target) + +/datum/component/bubble_icon_override/proc/register_owner(mob/living/owner) + RegisterSignal(owner, COMSIG_GET_BUBBLE_ICON, PROC_REF(return_bubble_icon)) + get_bubble_icon(owner) + +/datum/component/bubble_icon_override/UnregisterFromParent() + UnregisterSignal(parent, list( + COMSIG_ITEM_EQUIPPED, + COMSIG_ITEM_DROPPED, + COMSIG_ORGAN_IMPLANTED, + COMSIG_ORGAN_REMOVED, + )) + var/mob/living/target = get_bubble_icon_target() + if(target) + unregister_owner(target) + +/datum/component/bubble_icon_override/proc/unregister_owner(mob/living/owner) + UnregisterSignal(owner, list(COMSIG_GET_BUBBLE_ICON)) + get_bubble_icon(owner) + +///Returns the potential wearer/owner of the object when the component is un/registered to/from it +/datum/component/bubble_icon_override/proc/get_bubble_icon_target() + if(isclothing(parent)) + var/obj/item/clothing/clothing = parent + if(istype(clothing, /obj/item/clothing/accessory)) + clothing = clothing.loc + if(!istype(clothing)) + return null + var/mob/living/wearer = clothing.loc + if(istype(wearer) && (wearer.get_slot_by_item(clothing) & clothing.slot_flags)) + return parent + else if(isorgan(parent)) + var/obj/item/organ/organ = parent + return organ.owner + +/datum/component/bubble_icon_override/proc/on_equipped(obj/item/source, mob/equipper, slot) + SIGNAL_HANDLER + if(slot & source.slot_flags) + register_owner(equipper) + +/datum/component/bubble_icon_override/proc/on_dropped(obj/item/source, mob/dropper) + SIGNAL_HANDLER + unregister_owner(dropper) + +/datum/component/bubble_icon_override/proc/on_organ_implanted(obj/item/organ/source, mob/owner) + SIGNAL_HANDLER + register_owner(owner) + +/datum/component/bubble_icon_override/proc/on_organ_removed(obj/item/organ/source, mob/owner) + SIGNAL_HANDLER + unregister_owner(owner) + +/** + * Get the bubble icon with the highest priority from all instances of bubble_icon_override + * currently registered with the target. + */ +/datum/component/bubble_icon_override/proc/get_bubble_icon(mob/living/target) + if(QDELETED(parent)) + return + var/list/holder = list(null) + SEND_SIGNAL(target, COMSIG_GET_BUBBLE_ICON, holder) + var/bubble_icon = holder[1] + target.bubble_icon = bubble_icon || initial(target.bubble_icon) + +/datum/component/bubble_icon_override/proc/return_bubble_icon(datum/source, list/holder) + SIGNAL_HANDLER + var/enemy_priority = holder[holder[1]] + if(enemy_priority < priority) + holder[1] = bubble_icon + holder[bubble_icon] = priority diff --git a/code/datums/components/callouts.dm b/code/datums/components/callouts.dm index 98d489cc915a9..52a3e007905c3 100644 --- a/code/datums/components/callouts.dm +++ b/code/datums/components/callouts.dm @@ -136,7 +136,7 @@ color = colorize_string(creator.GetVoice(), 2, 0.9) update_appearance() var/turf/target_loc = get_turf(target) - animate(src, pixel_x = (target_loc.x - loc.x) * world.icon_size + target.pixel_x, pixel_y = (target_loc.y - loc.y) * world.icon_size + target.pixel_y, time = 0.2 SECONDS, easing = EASE_OUT) + animate(src, pixel_x = (target_loc.x - loc.x) * ICON_SIZE_X + target.pixel_x, pixel_y = (target_loc.y - loc.y) * ICON_SIZE_Y + target.pixel_y, time = 0.2 SECONDS, easing = EASE_OUT) /datum/callout_option var/name = "ERROR" diff --git a/code/datums/components/cleaner.dm b/code/datums/components/cleaner.dm index 75319a7133f4d..7072f271c7a6a 100644 --- a/code/datums/components/cleaner.dm +++ b/code/datums/components/cleaner.dm @@ -96,8 +96,8 @@ ADD_TRAIT(target, TRAIT_CURRENTLY_CLEANING, REF(src)) // We need to update our planes on overlay changes RegisterSignal(target, COMSIG_MOVABLE_Z_CHANGED, PROC_REF(cleaning_target_moved)) - var/mutable_appearance/low_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", FLOOR_CLEAN_LAYER, target, GAME_PLANE) - var/mutable_appearance/high_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", FLOOR_CLEAN_LAYER, target, ABOVE_GAME_PLANE) + var/mutable_appearance/low_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", GAME_CLEAN_LAYER, target, GAME_PLANE) + var/mutable_appearance/high_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", GAME_CLEAN_LAYER, target, ABOVE_GAME_PLANE) var/list/icon_offsets = target.get_oversized_icon_offsets() low_bubble.pixel_x = icon_offsets["x"] low_bubble.pixel_y = icon_offsets["y"] @@ -140,13 +140,13 @@ if(same_z_layer) return // First, get rid of the old overlay - var/mutable_appearance/old_low_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", FLOOR_CLEAN_LAYER, old_turf, GAME_PLANE) - var/mutable_appearance/old_high_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", FLOOR_CLEAN_LAYER, old_turf, ABOVE_GAME_PLANE) + var/mutable_appearance/old_low_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", GAME_CLEAN_LAYER, old_turf, GAME_PLANE) + var/mutable_appearance/old_high_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", GAME_CLEAN_LAYER, old_turf, ABOVE_GAME_PLANE) source.cut_overlay(old_low_bubble) source.cut_overlay(old_high_bubble) // Now, add the new one - var/mutable_appearance/new_low_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", FLOOR_CLEAN_LAYER, new_turf, GAME_PLANE) - var/mutable_appearance/new_high_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", FLOOR_CLEAN_LAYER, new_turf, ABOVE_GAME_PLANE) + var/mutable_appearance/new_low_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", GAME_CLEAN_LAYER, new_turf, GAME_PLANE) + var/mutable_appearance/new_high_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", GAME_CLEAN_LAYER, new_turf, ABOVE_GAME_PLANE) source.add_overlay(new_low_bubble) source.add_overlay(new_high_bubble) diff --git a/code/datums/components/clothing_dirt.dm b/code/datums/components/clothing_dirt.dm new file mode 100644 index 0000000000000..40f0ddb07e249 --- /dev/null +++ b/code/datums/components/clothing_dirt.dm @@ -0,0 +1,88 @@ +/// This component applies tint to clothing when its exposed to pepperspray, used in /obj/item/clothing/mask/gas. + +/datum/component/clothing_dirt + /// Amount of dirt stacks on the clothing + var/dirtiness = 0 + +/datum/component/clothing_dirt/Initialize() + if(!isclothing(parent)) + return COMPONENT_INCOMPATIBLE + +/datum/component/clothing_dirt/RegisterWithParent() + RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) + RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(on_equip)) + RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(on_drop)) + RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, PROC_REF(on_clean)) + RegisterSignal(parent, COMSIG_ATOM_EXPOSE_REAGENTS, PROC_REF(on_expose), TRUE) + +/datum/component/clothing_dirt/UnregisterFromParent() + var/obj/item/clothing/clothing = parent + clothing.tint -= dirtiness + if(iscarbon(clothing.loc)) + var/mob/living/carbon/wearer = clothing.loc + wearer.update_tint() + UnregisterSignal(wearer, COMSIG_ATOM_EXPOSE_REAGENTS) + else + UnregisterSignal(parent, COMSIG_ATOM_EXPOSE_REAGENTS) + UnregisterSignal(parent, list( + COMSIG_ATOM_EXAMINE, + COMSIG_ITEM_EQUIPPED, + COMSIG_MOB_UNEQUIPPED_ITEM, + COMSIG_COMPONENT_CLEAN_ACT, + )) + return ..() + +/datum/component/clothing_dirt/proc/on_equip(datum/source, mob/user, slot) + SIGNAL_HANDLER + var/obj/item/clothing/clothing = parent + if (!(slot & clothing.slot_flags)) + return + UnregisterSignal(parent, COMSIG_ATOM_EXPOSE_REAGENTS) + RegisterSignal(user, COMSIG_ATOM_EXPOSE_REAGENTS, PROC_REF(on_expose), TRUE) + +/datum/component/clothing_dirt/proc/on_drop(datum/source, mob/holder) + SIGNAL_HANDLER + UnregisterSignal(holder, COMSIG_ATOM_EXPOSE_REAGENTS) + RegisterSignal(parent, COMSIG_ATOM_EXPOSE_REAGENTS, PROC_REF(on_expose), TRUE) + +/datum/component/clothing_dirt/proc/on_examine(datum/source, mob/user, list/examine_list) + SIGNAL_HANDLER + if (dirtiness > 0) + examine_list += span_warning("It appears to be covered in some oily substance. Won't see much while wearing it until you wash it off.") + +/datum/component/clothing_dirt/proc/on_expose(atom/target, list/reagents, datum/reagents/source, methods) + SIGNAL_HANDLER + + var/mob/living/carbon/wearer + if(iscarbon(target)) + wearer = target + if(is_protected(wearer)) + return + + var/datum/reagent/consumable/condensedcapsaicin/pepper = locate() in reagents + if(isnull(pepper)) + return + + var/obj/item/clothing/clothing = parent + if (methods & (TOUCH | VAPOR)) + clothing.tint -= dirtiness + dirtiness = min(dirtiness + round(reagents[pepper] / 5), 3) + clothing.tint += dirtiness + if(!isnull(wearer)) + wearer.update_tint() + +/datum/component/clothing_dirt/proc/is_protected(mob/living/carbon/wearer) + return wearer.head && (wearer.head.flags_cover & PEPPERPROOF) + +/datum/component/clothing_dirt/proc/on_clean(datum/target, clean_types) + SIGNAL_HANDLER + var/obj/item/clothing/clothing = parent + var/mob/living/carbon/wearer + if(iscarbon(clothing.loc)) + wearer = clothing.loc + + if (clean_types & (CLEAN_WASH|CLEAN_SCRUB)) + clothing.tint -= dirtiness + dirtiness = 0 + if(!isnull(wearer)) + wearer.update_tint() diff --git a/code/datums/components/crafting/crafting.dm b/code/datums/components/crafting/crafting.dm index 54f77d4579e23..bf13b7cd5bae4 100644 --- a/code/datums/components/crafting/crafting.dm +++ b/code/datums/components/crafting/crafting.dm @@ -21,6 +21,8 @@ var/display_craftable_only = FALSE var/display_compact = FALSE var/forced_mode = FALSE + /// crafting flags we ignore when considering a recipe + var/ignored_flags = NONE /* This is what procs do: get_environment - gets a list of things accessable for crafting by user @@ -205,16 +207,16 @@ if(!check_tools(crafter, recipe, contents)) return ", missing tool." + var/considered_flags = recipe.crafting_flags & ~(ignored_flags) - - if((recipe.crafting_flags & CRAFT_ONE_PER_TURF) && (locate(recipe.result) in dest_turf)) + if((considered_flags & CRAFT_ONE_PER_TURF) && (locate(recipe.result) in dest_turf)) return ", already one here!" - if(recipe.crafting_flags & CRAFT_CHECK_DIRECTION) - if(!valid_build_direction(dest_turf, crafter.dir, is_fulltile = (recipe.crafting_flags & CRAFT_IS_FULLTILE))) + if(considered_flags & CRAFT_CHECK_DIRECTION) + if(!valid_build_direction(dest_turf, crafter.dir, is_fulltile = (considered_flags & CRAFT_IS_FULLTILE))) return ", won't fit here!" - if(recipe.crafting_flags & CRAFT_ON_SOLID_GROUND) + if(considered_flags & CRAFT_ON_SOLID_GROUND) if(isclosedturf(dest_turf)) return ", cannot be made on a wall!" @@ -222,7 +224,7 @@ if(!locate(/obj/structure/thermoplastic) in dest_turf) // for tram construction return ", must be made on solid ground!" - if(recipe.crafting_flags & CRAFT_CHECK_DENSITY) + if(considered_flags & CRAFT_CHECK_DENSITY) for(var/obj/object in dest_turf) if(object.density && !(object.obj_flags & IGNORE_DENSITY) || object.obj_flags & BLOCKS_CONSTRUCTION) return ", something is in the way!" @@ -703,3 +705,20 @@ if(recipe == potential_recipe) return TRUE return FALSE + +/datum/component/personal_crafting/machine + ignored_flags = CRAFT_CHECK_DENSITY + +/datum/component/personal_crafting/machine/get_environment(atom/crafter, list/blacklist = null, radius_range = 1) + . = list() + for(var/atom/movable/content in crafter.contents) + if((content.flags_1 & HOLOGRAM_1) || (blacklist && (content.type in blacklist))) + continue + if(isitem(content)) + var/obj/item/item = content + if(item.item_flags & ABSTRACT) //let's not tempt fate, shall we? + continue + . += content + +/datum/component/personal_crafting/machine/check_tools(atom/source, datum/crafting_recipe/recipe, list/surroundings) + return TRUE diff --git a/code/datums/components/crafting/structures.dm b/code/datums/components/crafting/structures.dm index c4a9b48ec36b6..090ec31ce226f 100644 --- a/code/datums/components/crafting/structures.dm +++ b/code/datums/components/crafting/structures.dm @@ -74,3 +74,14 @@ ) category = CAT_STRUCTURE crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_MUST_BE_LEARNED + +/datum/crafting_recipe/manucrate + name = "Manufacturing Storage Unit" + result = /obj/machinery/power/manufacturing/storagebox + tool_behaviors = list(TOOL_SCREWDRIVER, TOOL_WELDER) + time = 6 SECONDS + reqs = list( + /obj/item/stack/sheet/iron = 10, + ) + category = CAT_STRUCTURE + crafting_flags = CRAFT_CHECK_DENSITY diff --git a/code/datums/components/fish_growth.dm b/code/datums/components/fish_growth.dm index 3ec1427fd51a8..7c9aed1048c27 100644 --- a/code/datums/components/fish_growth.dm +++ b/code/datums/components/fish_growth.dm @@ -44,7 +44,6 @@ return var/datum/fish_evolution/evolution = GLOB.fish_evolutions[result_type] evolution.RegisterSignal(parent, COMSIG_FISH_BEFORE_GROWING, TYPE_PROC_REF(/datum/fish_evolution, growth_checks)) - evolution.register_fish(parent) /datum/component/fish_growth/UnregisterFromParent() UnregisterSignal(parent, list(COMSIG_FISH_LIFE, COMSIG_FISH_BEFORE_GROWING)) @@ -55,6 +54,8 @@ return var/deciseconds_elapsed = seconds_per_tick * 10 var/growth = growth_rate * deciseconds_elapsed + if(HAS_TRAIT(source, TRAIT_FISH_QUICK_GROWTH)) + growth *= 2 if(SEND_SIGNAL(source, COMSIG_FISH_BEFORE_GROWING, seconds_per_tick, growth) & COMPONENT_DONT_GROW) return maturation += growth diff --git a/code/datums/components/food/edible.dm b/code/datums/components/food/edible.dm index 9e2964273fd48..22592a039aa04 100644 --- a/code/datums/components/food/edible.dm +++ b/code/datums/components/food/edible.dm @@ -98,6 +98,9 @@ Behavior that's still missing from this component that original food items had t else if(isturf(parent) || isstructure(parent)) RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, PROC_REF(TryToEatIt)) + if(foodtypes & GORE) + ADD_TRAIT(parent, TRAIT_VALID_DNA_INFUSION, REF(src)) + /datum/component/edible/UnregisterFromParent() UnregisterSignal(parent, list( COMSIG_ATOM_ATTACK_ANIMAL, @@ -114,6 +117,9 @@ Behavior that's still missing from this component that original food items had t qdel(GetComponent(/datum/component/connect_loc_behalf)) + if(foodtypes & GORE) + REMOVE_TRAIT(parent, TRAIT_VALID_DNA_INFUSION, REF(src)) + /datum/component/edible/InheritComponent( datum/component/edible/old_comp, i_am_original, @@ -138,6 +144,9 @@ Behavior that's still missing from this component that original food items had t tastes = old_comp.tastes eatverbs = old_comp.eatverbs + if(foodtypes & GORE) + ADD_TRAIT(parent, TRAIT_VALID_DNA_INFUSION, REF(src)) + // only edit if we're OG if(!i_am_original) return @@ -599,8 +608,12 @@ Behavior that's still missing from this component that original food items had t return food.crafting_complexity + complexity_to_add /// Get food quality adjusted according to eater's preferences -/datum/component/edible/proc/get_perceived_food_quality(mob/living/carbon/human/eater) +/datum/component/edible/proc/get_perceived_food_quality(mob/living/eater) var/food_quality = get_recipe_complexity() + var/list/extra_quality = list() + SEND_SIGNAL(eater, COMSIG_LIVING_GET_PERCEIVED_FOOD_QUALITY, src, extra_quality) + for(var/quality in extra_quality) + food_quality += quality if(HAS_TRAIT(parent, TRAIT_FOOD_SILVER)) // it's not real food if(!isjellyperson(eater)) //if you aren't a jellyperson, it makes you sick no matter how nice it looks diff --git a/code/datums/components/food_storage.dm b/code/datums/components/food_storage.dm index 873c1646adbe1..843f611e5ff3e 100644 --- a/code/datums/components/food_storage.dm +++ b/code/datums/components/food_storage.dm @@ -18,7 +18,7 @@ /datum/component/food_storage/Initialize(_minimum_weight_class = WEIGHT_CLASS_SMALL, _bad_chance = 0, _good_chance = 100) - RegisterSignal(parent, COMSIG_ATOM_ATTACKBY_SECONDARY, PROC_REF(try_inserting_item)) + RegisterSignal(parent, COMSIG_ATOM_ITEM_INTERACTION_SECONDARY, PROC_REF(try_inserting_item)) RegisterSignal(parent, COMSIG_CLICK_CTRL, PROC_REF(try_removing_item)) RegisterSignal(parent, COMSIG_FOOD_EATEN, PROC_REF(consume_food_storage)) RegisterSignal(parent, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, PROC_REF(on_requesting_context_from_item)) @@ -48,34 +48,34 @@ * inserted_item - the item being placed into the food * user - the person inserting the item */ -/datum/component/food_storage/proc/try_inserting_item(datum/source, obj/item/inserted_item, mob/living/user, params) +/datum/component/food_storage/proc/try_inserting_item(datum/source, mob/living/user, obj/item/inserted_item, list/modifiers) SIGNAL_HANDLER // No matryoshka-ing food storage if(istype(inserted_item, /obj/item/storage) || IS_EDIBLE(inserted_item)) - return + return NONE //Harm intent will bypass inserting for injecting food with syringes and such if(user.combat_mode) - return + return NONE if(inserted_item.w_class > minimum_weight_class) to_chat(user, span_warning("\The [inserted_item.name] won't fit in \the [parent].")) - return + return ITEM_INTERACT_BLOCKING if(!QDELETED(stored_item)) to_chat(user, span_warning("There's something in \the [parent].")) - return + return ITEM_INTERACT_BLOCKING if(HAS_TRAIT(inserted_item, TRAIT_NODROP)) to_chat(user, span_warning("\the [inserted_item] is stuck to your hand, you can't put into \the [parent]!")) - return + return ITEM_INTERACT_BLOCKING user.visible_message(span_notice("[user.name] begins inserting [inserted_item.name] into \the [parent]."), \ span_notice("You start to insert the [inserted_item.name] into \the [parent].")) INVOKE_ASYNC(src, PROC_REF(insert_item), inserted_item, user) - return COMPONENT_CANCEL_ATTACK_CHAIN + return ITEM_INTERACT_SUCCESS /** Begins the process of attempting to remove the stored item. * @@ -108,15 +108,17 @@ * user - the person inserting the item. */ /datum/component/food_storage/proc/insert_item(obj/item/inserted_item, mob/user) - if(do_after(user, 1.5 SECONDS, target = parent)) - var/atom/food = parent - to_chat(user, span_notice("You slip [inserted_item.name] inside \the [parent].")) - inserted_item.forceMove(food) - user.log_message("inserted [inserted_item] into [parent].", LOG_ATTACK) - food.add_fingerprint(user) - inserted_item.add_fingerprint(user) - - stored_item = inserted_item + if(!do_after(user, 1.5 SECONDS, target = parent)) + return + + var/atom/food = parent + to_chat(user, span_notice("You slip [inserted_item.name] inside \the [parent].")) + inserted_item.forceMove(food) + user.log_message("inserted [inserted_item] into [parent].", LOG_ATTACK) + food.add_fingerprint(user) + inserted_item.add_fingerprint(user) + + stored_item = inserted_item /** Removes the item from the food, after a do_after. * diff --git a/code/datums/components/hide_weather_planes.dm b/code/datums/components/hide_weather_planes.dm new file mode 100644 index 0000000000000..97f34f57d313e --- /dev/null +++ b/code/datums/components/hide_weather_planes.dm @@ -0,0 +1,136 @@ +/** + * Component that manages a list of plane masters that are dependent on weather + * Force hides/shows them depending on the weather activity of their z stack + * Transparency is achieved by manipulating the alpha of the planes that are visible + * Applied to the plane master group that owns them + */ +/datum/component/hide_weather_planes + dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS + var/list/datum/weather/active_weather = list() + var/list/atom/movable/screen/plane_master/plane_masters = list() + +/datum/component/hide_weather_planes/Initialize(atom/movable/screen/plane_master/care_about) + if(!istype(parent, /datum/plane_master_group)) + return COMPONENT_INCOMPATIBLE + var/datum/plane_master_group/home = parent + plane_masters += care_about + RegisterSignal(care_about, COMSIG_QDELETING, PROC_REF(plane_master_deleted)) + + var/list/starting_signals = list() + var/list/ending_signals = list() + for(var/datum/weather/weather_type as anything in typesof(/datum/weather)) + starting_signals += COMSIG_WEATHER_TELEGRAPH(weather_type) + ending_signals += COMSIG_WEATHER_END(weather_type) + + RegisterSignals(SSdcs, starting_signals, PROC_REF(weather_started)) + RegisterSignals(SSdcs, ending_signals, PROC_REF(weather_finished)) + + if(home.our_hud) + attach_hud(home.our_hud) + else + RegisterSignal(home, COMSIG_GROUP_HUD_CHANGED, PROC_REF(new_hud_attached)) + +/datum/component/hide_weather_planes/Destroy(force) + hide_planes() + active_weather = null + plane_masters = null + return ..() + +/datum/component/hide_weather_planes/InheritComponent(datum/component/new_comp, i_am_original, atom/movable/screen/plane_master/care_about) + if(!i_am_original) + return + var/datum/plane_master_group/home = parent + var/mob/our_lad = home.our_hud?.mymob + var/our_offset = GET_TURF_PLANE_OFFSET(our_lad) + plane_masters += care_about + RegisterSignal(care_about, COMSIG_QDELETING, PROC_REF(plane_master_deleted)) + if(length(active_weather)) + //If there's weather to care about we unhide our new plane and adjust its alpha + care_about.unhide_plane(our_lad) + + if(care_about.offset >= our_offset) + care_about.enable_alpha() + else + care_about.disable_alpha() + else + care_about.hide_plane(our_lad) + +/datum/component/hide_weather_planes/proc/new_hud_attached(datum/source, datum/hud/new_hud) + SIGNAL_HANDLER + attach_hud(new_hud) + +/datum/component/hide_weather_planes/proc/attach_hud(datum/hud/new_hud) + RegisterSignal(new_hud, COMSIG_HUD_Z_CHANGED, PROC_REF(z_changed)) + var/mob/eye = new_hud?.mymob?.client?.eye + var/turf/eye_location = get_turf(eye) + z_changed(new_hud, eye_location?.z) + +/datum/component/hide_weather_planes/proc/plane_master_deleted(atom/movable/screen/plane_master/source) + SIGNAL_HANDLER + plane_masters -= source + +/** + * Unhides the relevant planes for the weather to be visible and manipulated. + * Also updates the alpha of the planes so enabled planes are either fully opaque or fully transparent + */ +/datum/component/hide_weather_planes/proc/display_planes() + var/datum/plane_master_group/home = parent + var/mob/our_lad = home.our_hud?.mymob + var/our_offset = GET_TURF_PLANE_OFFSET(our_lad) + for(var/atom/movable/screen/plane_master/weather_concious as anything in plane_masters) + //If the plane is hidden, unhide it + if(weather_concious.force_hidden) + weather_concious.unhide_plane(our_lad) + + //Now we update the alpha of the plane based on our offset. Weather above us (lower offset) are transparent, weather at or below us (higher offset) are opaque. + if(weather_concious.offset >= our_offset) + weather_concious.enable_alpha() + else + weather_concious.disable_alpha() + +///Hides the planes from the mob when no weather is occuring +/datum/component/hide_weather_planes/proc/hide_planes() + var/datum/plane_master_group/home = parent + var/mob/our_lad = home.our_hud?.mymob + for(var/atom/movable/screen/plane_master/weather_concious as anything in plane_masters) + weather_concious.hide_plane(our_lad) + +/datum/component/hide_weather_planes/proc/z_changed(datum/source, new_z) + SIGNAL_HANDLER + active_weather = list() + if(!SSmapping.initialized) + return + + var/list/connected_levels = SSmapping.get_connected_levels(new_z) + for(var/datum/weather/active as anything in SSweather.processing) + if(length(connected_levels & active.impacted_z_levels)) + active_weather += WEAKREF(active) + + if(length(active_weather)) + display_planes() + else + hide_planes() + +/datum/component/hide_weather_planes/proc/weather_started(datum/source, datum/weather/starting) + SIGNAL_HANDLER + var/datum/plane_master_group/home = parent + var/mob/eye = home.our_hud?.mymob?.client?.eye + var/turf/viewing_from = get_turf(eye) + if(!viewing_from) + return + + var/list/connected_levels = SSmapping.get_connected_levels(viewing_from) + if(length(connected_levels & starting.impacted_z_levels)) + active_weather += WEAKREF(starting) + + if(!length(active_weather)) + return + display_planes() + +/datum/component/hide_weather_planes/proc/weather_finished(datum/source, datum/weather/stopping) + SIGNAL_HANDLER + active_weather -= WEAKREF(stopping) + + if(length(active_weather)) + return + hide_planes() diff --git a/code/datums/components/holderloving.dm b/code/datums/components/holderloving.dm index 0670fa6086e2c..e41d986600df6 100644 --- a/code/datums/components/holderloving.dm +++ b/code/datums/components/holderloving.dm @@ -39,6 +39,7 @@ COMSIG_ATOM_EXITED, COMSIG_ITEM_STORED, ), PROC_REF(check_my_loc)) + RegisterSignal(parent, COMSIG_ITEM_PRE_UNEQUIP, PROC_REF(no_unequip)) /datum/component/holderloving/UnregisterFromParent() UnregisterSignal(holder, list(COMSIG_MOVABLE_MOVED, COMSIG_QDELETING)) @@ -48,6 +49,7 @@ COMSIG_ATOM_ENTERED, COMSIG_ATOM_EXITED, COMSIG_ITEM_STORED, + COMSIG_ITEM_PRE_UNEQUIP, )) /datum/component/holderloving/PostTransfer() @@ -63,6 +65,7 @@ /datum/component/holderloving/proc/holder_deleting(datum/source, force) SIGNAL_HANDLER + if(del_parent_with_holder) qdel(parent) else @@ -70,6 +73,20 @@ /datum/component/holderloving/proc/check_my_loc(datum/source) SIGNAL_HANDLER + var/obj/item/item_parent = parent if(!check_valid_loc(item_parent.loc)) item_parent.forceMove(holder) + +/datum/component/holderloving/proc/no_unequip(obj/item/I, force, atom/newloc, no_move, invdrop, silent) + SIGNAL_HANDLER + + // just allow it + if(force) + return NONE + // dropping onto a turf just forcemoves it back to the holder. let it happen, it's intuitive + // no_move says it's just going to be moved a second time. so let it happen, it'll just be moved back if it's invalid anyway + if(isturf(newloc) || no_move) + return NONE + // the item is being unequipped to somewhere invalid. stop it + return COMPONENT_ITEM_BLOCK_UNEQUIP diff --git a/code/datums/components/item_equipped_movement_rustle.dm b/code/datums/components/item_equipped_movement_rustle.dm new file mode 100644 index 0000000000000..435914dada785 --- /dev/null +++ b/code/datums/components/item_equipped_movement_rustle.dm @@ -0,0 +1,67 @@ +/datum/component/item_equipped_movement_rustle + + ///sound that plays, use an SFX define if there is multiple. + var/rustle_sounds = SFX_SUIT_STEP + ///human that has the item equipped. + var/mob/holder + + ///what move are we on. + var/move_counter = 0 + ///how many moves to take before playing the sound. + var/move_delay = 4 + + ///volume at which the sound plays. + var/volume = 20 + ///does the sound vary? + var/sound_vary = TRUE + ///extra-range for this component's sound. + var/sound_extra_range = -1 + ///sound exponent for the rustle. + var/sound_falloff_exponent = 5 + ///when sounds start falling off for the rustle rustle. + var/sound_falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE + +/datum/component/item_equipped_movement_rustle/Initialize(custom_sounds, move_delay_override, volume_override, extrarange, falloff_exponent, falloff_distance) + if(!isitem(parent)) + return COMPONENT_INCOMPATIBLE + + RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(on_equip)) + RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(on_unequip)) + + if(custom_sounds) + rustle_sounds = custom_sounds + if(isnum(volume_override)) + volume = volume_override + if(isnum(move_delay_override)) + move_delay = move_delay_override + if(isnum(extrarange)) + sound_extra_range = extrarange + if(isnum(falloff_exponent)) + sound_falloff_exponent = falloff_exponent + if(isnum(falloff_distance)) + sound_falloff_distance = falloff_distance + +/datum/component/item_equipped_movement_rustle/proc/on_equip(datum/source, mob/equipper, slot) + var/obj/item/our_item = parent + if(!(slot & our_item.slot_flags)) + return + SIGNAL_HANDLER + holder = equipper + RegisterSignal(holder, COMSIG_MOVABLE_MOVED, PROC_REF(try_step), override = TRUE) + +/datum/component/item_equipped_movement_rustle/proc/on_unequip(datum/source, mob/equipper, slot) + SIGNAL_HANDLER + move_counter = 0 + UnregisterSignal(equipper, COMSIG_MOVABLE_MOVED) + holder = null + +/datum/component/item_equipped_movement_rustle/proc/try_step(obj/item/clothing/source) + SIGNAL_HANDLER + + move_counter++ + if(move_counter >= move_delay) + play_rustle_sound() + move_counter = 0 + +/datum/component/item_equipped_movement_rustle/proc/play_rustle_sound() + playsound(parent, rustle_sounds, volume, sound_vary, sound_extra_range, sound_falloff_exponent, falloff_distance = sound_falloff_distance) diff --git a/code/datums/components/jetpack.dm b/code/datums/components/jetpack.dm index 1da8822091b90..ccbe2b3fd4dac 100644 --- a/code/datums/components/jetpack.dm +++ b/code/datums/components/jetpack.dm @@ -100,15 +100,14 @@ RegisterSignal(user, COMSIG_MOVABLE_MOVED, PROC_REF(move_react)) RegisterSignal(user, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(pre_move_react)) RegisterSignal(user, COMSIG_MOB_CLIENT_MOVE_NOGRAV, PROC_REF(on_client_move)) + RegisterSignal(user, COMSIG_MOB_ATTEMPT_HALT_SPACEMOVE, PROC_REF(on_pushoff)) START_PROCESSING(SSnewtonian_movement, src) setup_trail(user) /datum/component/jetpack/proc/deactivate(datum/source, mob/old_user) SIGNAL_HANDLER - UnregisterSignal(old_user, COMSIG_MOVABLE_MOVED) - UnregisterSignal(old_user, COMSIG_MOVABLE_PRE_MOVE) - UnregisterSignal(old_user, COMSIG_MOB_CLIENT_MOVE_NOGRAV) + UnregisterSignal(old_user, list(COMSIG_MOVABLE_PRE_MOVE, COMSIG_MOVABLE_MOVED, COMSIG_MOB_CLIENT_MOVE_NOGRAV, COMSIG_MOB_ATTEMPT_HALT_SPACEMOVE)) STOP_PROCESSING(SSnewtonian_movement, src) user = null @@ -161,3 +160,11 @@ var/max_drift_force = (DEFAULT_INERTIA_SPEED / source.cached_multiplicative_slowdown - 1) / INERTIA_SPEED_COEF + 1 source.newtonian_move(dir2angle(source.client.intended_direction), instant = TRUE, drift_force = drift_force, controlled_cap = max_drift_force) source.setDir(source.client.intended_direction) + +/datum/component/jetpack/proc/on_pushoff(mob/source, movement_dir, continuous_move, atom/backup) + SIGNAL_HANDLER + + if (!should_trigger(source) || !check_on_move.Invoke(FALSE)) + return + + return COMPONENT_PREVENT_SPACEMOVE_HALT diff --git a/code/datums/components/life_link.dm b/code/datums/components/life_link.dm index 628aceabc955a..314a3d7931bde 100644 --- a/code/datums/components/life_link.dm +++ b/code/datums/components/life_link.dm @@ -128,7 +128,7 @@ return holder.icon_state = "hud[RoundHealth(host)]" var/icon/size_check = icon(mob_parent.icon, mob_parent.icon_state, mob_parent.dir) - holder.pixel_y = size_check.Height() - world.icon_size + holder.pixel_y = size_check.Height() - ICON_SIZE_Y /// Update our vital status on the medical hud /datum/component/life_link/proc/update_med_hud_status(mob/living/mob_parent) @@ -136,7 +136,7 @@ if(isnull(holder)) return var/icon/size_check = icon(mob_parent.icon, mob_parent.icon_state, mob_parent.dir) - holder.pixel_y = size_check.Height() - world.icon_size + holder.pixel_y = size_check.Height() - ICON_SIZE_Y if(host.stat == DEAD || HAS_TRAIT(host, TRAIT_FAKEDEATH)) holder.icon_state = "huddead" else diff --git a/code/datums/components/material/material_container.dm b/code/datums/components/material/material_container.dm index 10544116ce579..912ae33411677 100644 --- a/code/datums/components/material/material_container.dm +++ b/code/datums/components/material/material_container.dm @@ -725,7 +725,7 @@ "name" = material.name, "ref" = REF(material), "amount" = amount, - "color" = material.greyscale_colors + "color" = material.greyscale_color || material.color )) return data diff --git a/code/datums/components/pet_commands/pet_commands_basic.dm b/code/datums/components/pet_commands/pet_commands_basic.dm index 9f4dda9cca394..fd4e1f922c8b4 100644 --- a/code/datums/components/pet_commands/pet_commands_basic.dm +++ b/code/datums/components/pet_commands/pet_commands_basic.dm @@ -298,5 +298,5 @@ return ..() /datum/pet_command/point_targeting/fish/execute_action(datum/ai_controller/controller) - controller.queue_behavior(/datum/ai_behavior/hunt_target/unarmed_attack_target/reset_target_combat_mode, BB_CURRENT_PET_TARGET) + controller.queue_behavior(/datum/ai_behavior/hunt_target/interact_with_target/reset_target_combat_mode_off, BB_CURRENT_PET_TARGET) return SUBTREE_RETURN_FINISH_PLANNING diff --git a/code/datums/components/profound_fisher.dm b/code/datums/components/profound_fisher.dm index 61f6543bd12bf..9638af4a8f2c2 100644 --- a/code/datums/components/profound_fisher.dm +++ b/code/datums/components/profound_fisher.dm @@ -9,6 +9,7 @@ return COMPONENT_INCOMPATIBLE src.our_rod = our_rod || new(parent) src.our_rod.internal = TRUE + ADD_TRAIT(src.our_rod, TRAIT_NOT_BARFABLE, REF(src)) RegisterSignal(src.our_rod, COMSIG_QDELETING, PROC_REF(on_rod_qdel)) if(!isgloves) @@ -43,6 +44,7 @@ /datum/component/profound_fisher/Destroy() our_rod.internal = FALSE UnregisterSignal(our_rod, COMSIG_QDELETING) + REMOVE_TRAIT(our_rod, TRAIT_NOT_BARFABLE, REF(src)) our_rod = null return ..() diff --git a/code/datums/components/scope.dm b/code/datums/components/scope.dm index 903f8d9bd917f..46388a15e26e8 100644 --- a/code/datums/components/scope.dm +++ b/code/datums/components/scope.dm @@ -246,18 +246,18 @@ if(isnull(icon_x)) icon_x = text2num(LAZYACCESS(modifiers, ICON_X)) if(isnull(icon_x)) - icon_x = view_list[1]*world.icon_size/2 + icon_x = view_list[1]*ICON_SIZE_X/2 var/icon_y = text2num(LAZYACCESS(modifiers, VIS_Y)) if(isnull(icon_y)) icon_y = text2num(LAZYACCESS(modifiers, ICON_Y)) if(isnull(icon_y)) - icon_y = view_list[2]*world.icon_size/2 - var/x_cap = range_modifier * view_list[1]*world.icon_size / 2 - var/y_cap = range_modifier * view_list[2]*world.icon_size / 2 - var/uncapped_x = round(range_modifier * (icon_x - view_list[1]*world.icon_size/2) * MOUSE_POINTER_OFFSET_MULT) - var/uncapped_y = round(range_modifier * (icon_y - view_list[2]*world.icon_size/2) * MOUSE_POINTER_OFFSET_MULT) + icon_y = view_list[2]*ICON_SIZE_Y/2 + var/x_cap = range_modifier * view_list[1]*ICON_SIZE_X / 2 + var/y_cap = range_modifier * view_list[2]*ICON_SIZE_Y / 2 + var/uncapped_x = round(range_modifier * (icon_x - view_list[1]*ICON_SIZE_X/2) * MOUSE_POINTER_OFFSET_MULT) + var/uncapped_y = round(range_modifier * (icon_y - view_list[2]*ICON_SIZE_Y/2) * MOUSE_POINTER_OFFSET_MULT) given_x = clamp(uncapped_x, -x_cap, x_cap) given_y = clamp(uncapped_y, -y_cap, y_cap) - given_turf = locate(owner.x+round(given_x/world.icon_size, 1),owner.y+round(given_y/world.icon_size, 1),owner.z) + given_turf = locate(owner.x+round(given_x/ICON_SIZE_X, 1),owner.y+round(given_y/ICON_SIZE_Y, 1),owner.z) #undef MOUSE_POINTER_OFFSET_MULT diff --git a/code/datums/components/self_ignition.dm b/code/datums/components/self_ignition.dm new file mode 100644 index 0000000000000..6736a746355e0 --- /dev/null +++ b/code/datums/components/self_ignition.dm @@ -0,0 +1,57 @@ +/// Component used by plasmeme limbs. Ignites the owner and prevents fire armor from working if they're exposed to oxygen +/datum/component/self_ignition + /// How many fire stacks do we apply per second? + /// Default value is 0.25 / 6 (default amount of limbs) + var/fire_stacks_per_second = 0.0416 + /// How many fire stacks are removed when we're exposed to hypernoblium + /// Default value is 10 / 6 (default amount of limbs) + var/fire_stacks_loss = 1.66 + +/datum/component/self_ignition/Initialize(fire_stacks_per_second = 0.0416, fire_stacks_loss = 1.66) + . = ..() + if(!isbodypart(parent)) + return COMPONENT_INCOMPATIBLE + src.fire_stacks_per_second = fire_stacks_per_second + src.fire_stacks_loss = fire_stacks_loss + +/datum/component/self_ignition/RegisterWithParent() + RegisterSignal(parent, COMSIG_BODYPART_ATTACHED, PROC_REF(on_attached)) + RegisterSignal(parent, COMSIG_BODYPART_REMOVED, PROC_REF(on_detached)) + +/datum/component/self_ignition/proc/on_attached(datum/source, mob/living/carbon/human/new_owner) + SIGNAL_HANDLER + RegisterSignal(new_owner, COMSIG_LIVING_LIFE, PROC_REF(on_life)) + +/datum/component/self_ignition/proc/on_detached(datum/source, mob/living/carbon/human/old_owner) + SIGNAL_HANDLER + UnregisterSignal(old_owner, COMSIG_LIVING_LIFE) + REMOVE_TRAIT(old_owner, TRAIT_IGNORE_FIRE_PROTECTION, REF(parent)) + +/datum/component/self_ignition/proc/on_life(mob/living/carbon/human/owner, seconds_per_tick, times_fired) + SIGNAL_HANDLER + + if (owner.is_atmos_sealed(additional_flags = PLASMAMAN_PREVENT_IGNITION, check_hands = TRUE, ignore_chest_pressureprot = TRUE)) + if (!owner.on_fire) + REMOVE_TRAIT(owner, TRAIT_IGNORE_FIRE_PROTECTION, REF(parent)) + return + + var/datum/gas_mixture/environment = owner.loc.return_air() + if (!environment?.total_moles()) + return + + if(environment.gases[/datum/gas/hypernoblium] && environment.gases[/datum/gas/hypernoblium][MOLES] >= 5) + if(owner.on_fire && owner.fire_stacks > 0) + owner.adjust_fire_stacks(-fire_stacks_loss * seconds_per_tick) + return + + if (HAS_TRAIT(owner, TRAIT_NOFIRE)) + return + + ADD_TRAIT(owner, TRAIT_IGNORE_FIRE_PROTECTION, REF(parent)) + + if(!environment.gases[/datum/gas/oxygen] || environment.gases[/datum/gas/oxygen][MOLES] < 1) //Same threshhold that extinguishes fire + return + + owner.adjust_fire_stacks(fire_stacks_per_second * seconds_per_tick) + if(owner.ignite_mob()) + owner.visible_message(span_danger("[owner]'s body reacts with the atmosphere and bursts into flames!"), span_userdanger("Your body reacts with the atmosphere and bursts into flame!")) diff --git a/code/datums/components/shell.dm b/code/datums/components/shell.dm index 2e9ee73c32a06..bb3054aea6ae6 100644 --- a/code/datums/components/shell.dm +++ b/code/datums/components/shell.dm @@ -173,7 +173,7 @@ if(istype(item, /obj/item/inducer)) var/obj/item/inducer/inducer = item - INVOKE_ASYNC(inducer, TYPE_PROC_REF(/obj/item, attack_atom), attached_circuit || parent, attacker, list()) + INVOKE_ASYNC(inducer, TYPE_PROC_REF(/obj/item, interact_with_atom), attached_circuit || parent, attacker, list()) return COMPONENT_NO_AFTERATTACK if(attached_circuit) diff --git a/code/datums/components/slippery.dm b/code/datums/components/slippery.dm index 8a934cdd4c1d5..8d2dbda379eda 100644 --- a/code/datums/components/slippery.dm +++ b/code/datums/components/slippery.dm @@ -38,14 +38,11 @@ COMSIG_ATOM_ENTERED = PROC_REF(Slip), ) - ///what we give to connect_loc if we're an item and get equipped by a mob. makes slippable mobs moving over our holder slip - var/static/list/holder_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(Slip_on_wearer), + ///what we give to connect_loc if we're an item and get equipped by a mob, or if we're a mob. makes slippable mobs moving over the mob slip + var/static/list/mob_connections = list( + COMSIG_ATOM_ENTERED = PROC_REF(slip_on_mob), ) - /// The connect_loc_behalf component for the holder_connections list. - var/datum/weakref/holder_connect_loc_behalf - /** * Initialize the slippery component behaviour * @@ -79,14 +76,14 @@ src.slot_whitelist = slot_whitelist add_connect_loc_behalf_to_parent() - if(ismovable(parent)) - if(isitem(parent)) - RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(on_equip)) - RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(on_drop)) - RegisterSignal(parent, COMSIG_ITEM_APPLY_FANTASY_BONUSES, PROC_REF(apply_fantasy_bonuses)) - RegisterSignal(parent, COMSIG_ITEM_REMOVE_FANTASY_BONUSES, PROC_REF(remove_fantasy_bonuses)) - else + if(!ismovable(parent)) RegisterSignal(parent, COMSIG_ATOM_ENTERED, PROC_REF(Slip)) + else if(isitem(parent)) + src.lube_flags |= SLIPPERY_WHEN_LYING_DOWN + RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(on_equip)) + RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(on_drop)) + RegisterSignal(parent, COMSIG_ITEM_APPLY_FANTASY_BONUSES, PROC_REF(apply_fantasy_bonuses)) + RegisterSignal(parent, COMSIG_ITEM_REMOVE_FANTASY_BONUSES, PROC_REF(remove_fantasy_bonuses)) /datum/component/slippery/Destroy(force) can_slip_callback = null @@ -114,8 +111,13 @@ lube_flags = previous_lube_flags /datum/component/slippery/proc/add_connect_loc_behalf_to_parent() - if(ismovable(parent)) - AddComponent(/datum/component/connect_loc_behalf, parent, default_connections) + var/list/connections_to_use + if(isliving(parent)) + connections_to_use = mob_connections + else if(ismovable(parent)) + connections_to_use = default_connections + if(connections_to_use) + AddComponent(/datum/component/connect_loc_behalf, parent, connections_to_use) /datum/component/slippery/InheritComponent( datum/component/slippery/component, @@ -184,7 +186,7 @@ if((!LAZYLEN(slot_whitelist) || (slot in slot_whitelist)) && isliving(equipper)) holder = equipper qdel(GetComponent(/datum/component/connect_loc_behalf)) - AddComponent(/datum/component/connect_loc_behalf, holder, holder_connections) + AddComponent(/datum/component/connect_loc_behalf, holder, mob_connections) RegisterSignal(holder, COMSIG_QDELETING, PROC_REF(holder_deleted)) /** @@ -227,10 +229,11 @@ * * source - the source of the signal * * arrived - the atom/movable that slipped on us. */ -/datum/component/slippery/proc/Slip_on_wearer(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs) +/datum/component/slippery/proc/slip_on_mob(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs) SIGNAL_HANDLER - if(holder.body_position == LYING_DOWN && !holder.buckled) + var/mob/living/living = holder || parent + if(!(lube_flags & SLIPPERY_WHEN_LYING_DOWN) || (living.body_position == LYING_DOWN && !living.buckled)) Slip(source, arrived) /datum/component/slippery/UnregisterFromParent() diff --git a/code/datums/components/splat.dm b/code/datums/components/splat.dm index 5d47d17b98c9c..d22613204bbbd 100644 --- a/code/datums/components/splat.dm +++ b/code/datums/components/splat.dm @@ -71,4 +71,5 @@ if(can_splat_on && is_type_in_typecache(hit_atom, GLOB.splattable)) hit_atom.AddComponent(/datum/component/face_decal/splat, icon_state, layer, splat_color || source.color, memory_type, moodlet_type) SEND_SIGNAL(source, COMSIG_MOVABLE_SPLAT, hit_atom) - qdel(source) + if(!isprojectile(source)) + qdel(source) diff --git a/code/datums/components/sticker.dm b/code/datums/components/sticker.dm index a11ab10e7c6f8..b627f9923204b 100644 --- a/code/datums/components/sticker.dm +++ b/code/datums/components/sticker.dm @@ -84,8 +84,8 @@ var/atom/parent_atom = parent sticker_overlay = mutable_appearance(icon = our_sticker.icon, icon_state = our_sticker.icon_state, layer = parent_atom.layer + 0.01, appearance_flags = RESET_COLOR) - sticker_overlay.pixel_w = px - world.icon_size / 2 - sticker_overlay.pixel_z = py - world.icon_size / 2 + sticker_overlay.pixel_w = px - ICON_SIZE_X / 2 + sticker_overlay.pixel_z = py - ICON_SIZE_Y / 2 parent_atom.add_overlay(sticker_overlay) stick_callback?.Invoke(parent) diff --git a/code/datums/components/tether.dm b/code/datums/components/tether.dm index b991891930cd1..d5e00ddb39858 100644 --- a/code/datums/components/tether.dm +++ b/code/datums/components/tether.dm @@ -13,14 +13,17 @@ var/atom/embed_target /// Beam effect var/datum/beam/tether_beam + /// Tether module if we were created by one + var/obj/item/mod/module/tether/parent_module -/datum/component/tether/Initialize(atom/tether_target, max_dist = 7, tether_name, atom/embed_target = null, start_distance = null) +/datum/component/tether/Initialize(atom/tether_target, max_dist = 7, tether_name, atom/embed_target = null, start_distance = null, parent_module = null) if(!ismovable(parent) || !istype(tether_target) || !tether_target.loc) return COMPONENT_INCOMPATIBLE src.tether_target = tether_target src.embed_target = embed_target src.max_dist = max_dist + src.parent_module = parent_module cur_dist = max_dist if (start_distance != null) cur_dist = start_distance @@ -46,6 +49,9 @@ RegisterSignal(embed_target, COMSIG_ITEM_UNEMBEDDED, PROC_REF(on_embedded_removed)) RegisterSignal(embed_target, COMSIG_QDELETING, PROC_REF(on_delete)) + if (!isnull(parent_module)) + RegisterSignals(parent_module, list(COMSIG_QDELETING, COMSIG_MOVABLE_MOVED, COMSIG_MOD_TETHER_SNAP), PROC_REF(snap)) + /datum/component/tether/UnregisterFromParent() UnregisterSignal(parent, list(COMSIG_MOVABLE_PRE_MOVE, COMSIG_MOVABLE_MOVED)) if (!QDELETED(tether_target)) @@ -111,8 +117,15 @@ var/atom/atom_target = parent // Something broke us out, snap the tether if (get_dist(atom_target, tether_target) > cur_dist + 1 || !isturf(atom_target.loc) || !isturf(tether_target.loc) || atom_target.z != tether_target.z) - atom_target.visible_message(span_warning("[atom_target]'s [tether_name] snaps!"), span_userdanger("Your [tether_name] snaps!"), span_hear("You hear a cable snapping.")) - qdel(src) + snap() + +/datum/component/tether/proc/snap() + SIGNAL_HANDLER + + var/atom/atom_target = parent + atom_target.visible_message(span_warning("[atom_target]'s [tether_name] snaps!"), span_userdanger("Your [tether_name] snaps!"), span_hear("You hear a cable snapping.")) + playsound(atom_target, 'sound/effects/snap.ogg', 50, TRUE) + qdel(src) /datum/component/tether/proc/on_delete() SIGNAL_HANDLER @@ -132,7 +145,7 @@ var/list/modifiers = params2list(params) if(LAZYACCESS(modifiers, CTRL_CLICK)) location.balloon_alert(user, "cutting the tether...") - if (!do_after(user, 5 SECONDS, user)) + if (!do_after(user, 1 SECONDS, user)) return qdel(src) diff --git a/code/datums/components/trapdoor.dm b/code/datums/components/trapdoor.dm index 9efce370e82c7..a5d28107556c6 100644 --- a/code/datums/components/trapdoor.dm +++ b/code/datums/components/trapdoor.dm @@ -19,19 +19,37 @@ var/conspicuous /// overlay that makes trapdoors more obvious var/static/trapdoor_overlay + /** + * list of lists that are arguments for readding decals when the linked trapdoor comes back. pain. + * + * we are storing this data FOR the trapdoor component we are linked to. kinda like a multitool. + * format: list(list(element's description, element's cleanable, element's directional, element's pic)) + * the list will be filled with all the data of the deleting elements (when ChangeTurf is called) only when the trapdoor begins to open. + * so any other case the elements will be changed but not recorded. + */ + var/list/stored_decals = list() + /// Trapdoor shuts close automatically + var/autoclose = TRUE + /// Delay before trapdoor shuts close + var/autoclose_delay = 5 SECONDS -/datum/component/trapdoor/Initialize(starts_open, trapdoor_turf_path, assembly, conspicuous = TRUE) +/datum/component/trapdoor/Initialize(starts_open, trapdoor_turf_path, assembly, conspicuous = TRUE, list/carried_decals = null, autoclose = TRUE) if(!isopenturf(parent)) return COMPONENT_INCOMPATIBLE src.conspicuous = conspicuous src.assembly = assembly + src.autoclose = autoclose + if(carried_decals) + stored_decals = carried_decals.Copy() if(!trapdoor_overlay) trapdoor_overlay = mutable_appearance('icons/turf/overlays.dmi', "border_black", ABOVE_NORMAL_TURF_LAYER) if(IS_OPEN(parent)) openspace_trapdoor_setup(trapdoor_turf_path, assembly) + if(autoclose) + addtimer(CALLBACK(src, PROC_REF(try_closing)), autoclose_delay) else tile_trapdoor_setup(trapdoor_turf_path, assembly) @@ -45,7 +63,7 @@ ///initializing as a closed trapdoor, we need to take data from the tile we're on to give it to the open state to store /datum/component/trapdoor/proc/tile_trapdoor_setup(trapdoor_turf_path) src.trapdoor_turf_path = parent.type - if(assembly && assembly.stored_decals.len) + if(stored_decals.len) reapply_all_decals() if(conspicuous) var/turf/parent_turf = parent @@ -60,6 +78,7 @@ else RegisterSignal(assembly, COMSIG_ASSEMBLY_PULSED, PROC_REF(toggle_trapdoor)) RegisterSignal(parent, COMSIG_ATOM_TOOL_ACT(TOOL_MULTITOOL), PROC_REF(try_unlink)) + RegisterSignal(parent, COMSIG_ATOM_ITEM_INTERACTION, PROC_REF(try_link)) /datum/component/trapdoor/UnregisterFromParent() . = ..() @@ -69,6 +88,7 @@ UnregisterSignal(parent, COMSIG_TURF_CHANGE) UnregisterSignal(parent, COMSIG_ATOM_EXAMINE) UnregisterSignal(parent, COMSIG_ATOM_TOOL_ACT(TOOL_MULTITOOL)) + UnregisterSignal(parent, COMSIG_ATOM_ITEM_INTERACTION) /datum/component/trapdoor/proc/try_unlink(turf/source, mob/user, obj/item/tool) SIGNAL_HANDLER @@ -81,14 +101,44 @@ INVOKE_ASYNC(src, PROC_REF(async_try_unlink), source, user, tool) return +/datum/component/trapdoor/proc/try_link(turf/source, mob/user, obj/item/tool) + SIGNAL_HANDLER + if(!istype(tool, /obj/item/trapdoor_remote)) + return + var/obj/item/trapdoor_remote/remote = tool + if(!remote.internals) + source.balloon_alert(user, "missing internals") + return + if(IS_OPEN(parent)) + source.balloon_alert(user, "can't link trapdoor when its open") + return + if(assembly) + source.balloon_alert(user, "already linked") + return + source.balloon_alert(user, "linking trapdoor") + INVOKE_ASYNC(src, PROC_REF(async_try_link), source, user, tool) + +/datum/component/trapdoor/proc/async_try_link(turf/source, mob/user, obj/item/trapdoor_remote/remote) + if(!do_after(user, 2 SECONDS, target=source)) + return + if(IS_OPEN(parent)) + source.balloon_alert(user, "can't link trapdoor when its open") + return + src.assembly = remote.internals + ++assembly.linked + source.balloon_alert(user, "trapdoor linked") + UnregisterSignal(SSdcs, COMSIG_GLOB_TRAPDOOR_LINK) + RegisterSignal(assembly, COMSIG_ASSEMBLY_PULSED, PROC_REF(toggle_trapdoor)) + RegisterSignal(parent, COMSIG_ATOM_TOOL_ACT(TOOL_MULTITOOL), PROC_REF(try_unlink)) + /datum/component/trapdoor/proc/async_try_unlink(turf/source, mob/user, obj/item/tool) if(!do_after(user, 5 SECONDS, target=source)) return if(IS_OPEN(parent)) source.balloon_alert(user, "can't unlink trapdoor when its open") return - assembly.linked = FALSE - assembly.stored_decals = list() + assembly.linked = max(assembly.linked - 1, 0) + stored_decals = list() UnregisterSignal(assembly, COMSIG_ASSEMBLY_PULSED) UnregisterSignal(parent, COMSIG_ATOM_TOOL_ACT(TOOL_MULTITOOL)) RegisterSignal(SSdcs, COMSIG_GLOB_TRAPDOOR_LINK, PROC_REF(on_link_requested)) @@ -98,7 +148,7 @@ /datum/component/trapdoor/proc/decal_detached(datum/source, description, cleanable, directional, pic) SIGNAL_HANDLER ///so it adds the list to the list, not appending it to the end. thank you byond, very cool. - assembly.stored_decals += list(list(description, cleanable, directional, pic)) + stored_decals += list(list(description, cleanable, directional, pic)) /** * ## reapply_all_decals @@ -106,9 +156,9 @@ * changing turfs does not bring over decals, so we must perform a little bit of element reapplication. */ /datum/component/trapdoor/proc/reapply_all_decals() - for(var/list/element_data as anything in assembly.stored_decals) + for(var/list/element_data as anything in stored_decals) apply_decal(element_data[1], element_data[2], element_data[3], element_data[4]) - assembly.stored_decals = list() + stored_decals = list() /// small proc that takes passed arguments and drops it into a new element /datum/component/trapdoor/proc/apply_decal(description, cleanable, directional, pic) @@ -117,11 +167,11 @@ ///called by linking remotes to tie an assembly to the trapdoor /datum/component/trapdoor/proc/on_link_requested(datum/source, obj/item/assembly/trapdoor/assembly) SIGNAL_HANDLER - if(get_dist(parent, assembly) > TRAPDOOR_LINKING_SEARCH_RANGE || assembly.linked) + if(get_dist(parent, assembly) > TRAPDOOR_LINKING_SEARCH_RANGE) return . = LINKED_UP src.assembly = assembly - assembly.linked = TRUE + ++assembly.linked UnregisterSignal(SSdcs, COMSIG_GLOB_TRAPDOOR_LINK) RegisterSignal(assembly, COMSIG_ASSEMBLY_PULSED, PROC_REF(toggle_trapdoor)) RegisterSignal(parent, COMSIG_ATOM_TOOL_ACT(TOOL_MULTITOOL), PROC_REF(try_unlink)) @@ -129,6 +179,8 @@ ///signal called by our assembly being pulsed /datum/component/trapdoor/proc/toggle_trapdoor(datum/source) SIGNAL_HANDLER + if(assembly) + autoclose = assembly.autoclose if(!IS_OPEN(parent)) try_opening() else @@ -145,8 +197,8 @@ // otherwise, break trapdoor dying_trapdoor.visible_message(span_warning("The trapdoor mechanism in [dying_trapdoor] is broken!")) if(assembly) - assembly.linked = FALSE - assembly.stored_decals.Cut() + assembly.linked = max(assembly.linked - 1, 0) + stored_decals.Cut() assembly = null return post_change_callbacks += CALLBACK(src, TYPE_PROC_REF(/datum/component/trapdoor, carry_over_trapdoor), trapdoor_turf_path, conspicuous, assembly) @@ -158,7 +210,7 @@ * apparently callbacks with arguments on invoke and the callback itself have the callback args go first. interesting! */ /datum/component/trapdoor/proc/carry_over_trapdoor(trapdoor_turf_path, conspicuous, assembly, turf/new_turf) - new_turf.AddComponent(/datum/component/trapdoor, FALSE, trapdoor_turf_path, assembly, conspicuous) + new_turf.AddComponent(/datum/component/trapdoor, FALSE, trapdoor_turf_path, assembly, conspicuous, stored_decals, autoclose) /** * ## on_examine @@ -213,20 +265,12 @@ var/search_cooldown_time = 10 SECONDS ///if true, a trapdoor in the world has a reference to this assembly and is listening for when it is pulsed. var/linked = FALSE - /** - * list of lists that are arguments for readding decals when the linked trapdoor comes back. pain. - * - * we are storing this data FOR the trapdoor component we are linked to. kinda like a multitool. - * format: list(list(element's description, element's cleanable, element's directional, element's pic)) - * the list will be filled with all the data of the deleting elements (when ChangeTurf is called) only when the trapdoor begins to open. - * so any other case the elements will be changed but not recorded. - */ - var/list/stored_decals = list() - + /// Linked trapdoors will automatically close + var/autoclose = TRUE /obj/item/assembly/trapdoor/pulsed(mob/pulser) . = ..() - if(linked) + if(linked > 0) return if(!COOLDOWN_FINISHED(src, search_cooldown)) if(loc && pulser) @@ -272,8 +316,12 @@ . += span_notice("The internals can be removed with a screwdriver.") if(!internals.linked) . += span_warning("[src] is not linked to a trapdoor.") + . += span_notice("[src] will link to nearby trapdoors when used.") return - . += span_notice("[src] is linked to a trapdoor.") + . += span_notice("[src] is linked to [internals.linked] trapdoor(s).") + . += span_notice("It can be linked to additional trapdoor(s) by using it on a trapdoor.") + . += span_notice("Trapdoor can be unlinked with multitool.") + . += span_notice("Autoclose is [internals.autoclose ? "enabled" : "disabled"], ctrl-click to toggle.") if(!COOLDOWN_FINISHED(src, trapdoor_cooldown)) . += span_warning("It is on a short cooldown.") @@ -310,7 +358,7 @@ internals.pulsed(user) // The pulse linked successfully if(internals.linked) - user.balloon_alert(user, "linked") + user.balloon_alert(user, "linked [internals.linked] trapdoors") // The pulse failed to link else user.balloon_alert(user, "link failed!") @@ -328,6 +376,17 @@ internals.pulsed(user) return TRUE +/obj/item/trapdoor_remote/item_ctrl_click(mob/user) + if (!user.is_holding(src)) + return CLICK_ACTION_BLOCKING + if(!internals) + user.balloon_alert(user, "no device!") + return CLICK_ACTION_BLOCKING + + internals.autoclose = !internals.autoclose + user.balloon_alert(user, "autoclose [internals.autoclose ? "enabled" : "disabled"]") + return CLICK_ACTION_SUCCESS + #undef TRAPDOOR_LINKING_SEARCH_RANGE ///subtype with internals already included. If you're giving a department a roundstart trapdoor, this is what you want diff --git a/code/datums/datum.dm b/code/datums/datum.dm index d170aeca8522e..d4abc7c69adc3 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -408,10 +408,15 @@ var/list/names = islist(name_or_names) ? name_or_names : list(name_or_names) + . = FALSE for(var/name in names) if(filter_data[name]) filter_data -= name - update_filters() + . = TRUE + + if(.) + update_filters() + return . /datum/proc/clear_filters() ASSERT(isatom(src) || isimage(src)) diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm index 966987828bd54..4a359ca1f2dc0 100644 --- a/code/datums/diseases/transformation.dm +++ b/code/datums/diseases/transformation.dm @@ -230,7 +230,7 @@ /datum/disease/transformation/slime name = "Advanced Mutation Transformation" - cure_text = "frost oil" + cure_text = "Frost oil" cures = list(/datum/reagent/consumable/frostoil) cure_chance = 55 agent = "Advanced Mutation Toxin" diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 3ed40a11d5c55..5a7391f7825e3 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -150,9 +150,19 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) SEND_SIGNAL(holder, COMSIG_CARBON_GAIN_MUTATION, mutation_type, class) return force_give(new mutation_type (class, time, copymut = mutation)) -/datum/dna/proc/remove_mutation(mutation_type) +/datum/dna/proc/remove_mutation(datum/mutation/human/mutation_type, mutadone) + + var/datum/mutation/human/actual_mutation = get_mutation(mutation_type) + + if(!actual_mutation) + return FALSE + + // Check that it exists first before trying to remove it with mutadone + if(actual_mutation.mutadone_proof && mutadone) + return FALSE + SEND_SIGNAL(holder, COMSIG_CARBON_LOSE_MUTATION, mutation_type) - return force_lose(get_mutation(mutation_type)) + return force_lose(actual_mutation) /datum/dna/proc/check_mutation(mutation_type) return get_mutation(mutation_type) @@ -213,7 +223,7 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) if(features["lizard_markings"]) L[DNA_LIZARD_MARKINGS_BLOCK] = construct_block(SSaccessories.lizard_markings_list.Find(features["lizard_markings"]), length(SSaccessories.lizard_markings_list)) if(features["tail_cat"]) - L[DNA_TAIL_BLOCK] = construct_block(SSaccessories.tails_list_human.Find(features["tail_cat"]), length(SSaccessories.tails_list_human)) + L[DNA_TAIL_BLOCK] = construct_block(SSaccessories.tails_list_felinid.Find(features["tail_cat"]), length(SSaccessories.tails_list_felinid)) if(features["tail_lizard"]) L[DNA_LIZARD_TAIL_BLOCK] = construct_block(SSaccessories.tails_list_lizard.Find(features["tail_lizard"]), length(SSaccessories.tails_list_lizard)) if(features["snout"]) @@ -236,6 +246,8 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) L[DNA_MUSHROOM_CAPS_BLOCK] = construct_block(SSaccessories.caps_list.Find(features["caps"]), length(SSaccessories.caps_list)) if(features["pod_hair"]) L[DNA_POD_HAIR_BLOCK] = construct_block(SSaccessories.pod_hair_list.Find(features["pod_hair"]), length(SSaccessories.pod_hair_list)) + if(features["fish_tail"]) + L[DNA_FISH_TAIL_BLOCK] = construct_block(SSaccessories.tails_list_fish.Find(features["fish_tail"]), length(SSaccessories.tails_list_fish)) /// DOPPLER SHIFT ADDITION BEGIN if(features["breasts"]) L[DNA_BREASTS_BLOCK] = construct_block(SSaccessories.breasts_list.Find(features["breasts"]), length(SSaccessories.breasts_list)) @@ -361,7 +373,7 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) if(DNA_LIZARD_MARKINGS_BLOCK) set_uni_feature_block(blocknumber, construct_block(SSaccessories.lizard_markings_list.Find(features["lizard_markings"]), length(SSaccessories.lizard_markings_list))) if(DNA_TAIL_BLOCK) - set_uni_feature_block(blocknumber, construct_block(SSaccessories.tails_list_human.Find(features["tail_cat"]), length(SSaccessories.tails_list_human))) + set_uni_feature_block(blocknumber, construct_block(SSaccessories.tails_list_felinid.Find(features["tail_cat"]), length(SSaccessories.tails_list_felinid))) if(DNA_LIZARD_TAIL_BLOCK) set_uni_feature_block(blocknumber, construct_block(SSaccessories.tails_list_lizard.Find(features["tail_lizard"]), length(SSaccessories.tails_list_lizard))) if(DNA_SNOUT_BLOCK) @@ -384,6 +396,8 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) set_uni_feature_block(blocknumber, construct_block(SSaccessories.caps_list.Find(features["caps"]), length(SSaccessories.caps_list))) if(DNA_POD_HAIR_BLOCK) set_uni_feature_block(blocknumber, construct_block(SSaccessories.pod_hair_list.Find(features["pod_hair"]), length(SSaccessories.pod_hair_list))) + if(DNA_FISH_TAIL_BLOCK) + set_uni_feature_block(blocknumber, construct_block(SSaccessories.tails_list_fish.Find(features["fish_tail"]), length(SSaccessories.tails_list_fish))) /// DOPPLER SHIFT ADDITION BEGIN if(DNA_BREASTS_BLOCK) set_uni_feature_block(blocknumber, construct_block(SSaccessories.breasts_list.Find(features["breasts"]), length(SSaccessories.breasts_list))) @@ -487,7 +501,7 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) /datum/dna/stored/add_mutation(mutation_name) //no mutation changes on stored dna. return -/datum/dna/stored/remove_mutation(mutation_name) +/datum/dna/stored/remove_mutation(mutation_name, mutadone) return /datum/dna/stored/check_mutation(mutation_name) @@ -670,7 +684,7 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) if(dna.features["spines"]) dna.features["spines"] = SSaccessories.spines_list[deconstruct_block(get_uni_feature_block(features, DNA_SPINES_BLOCK), length(SSaccessories.spines_list))] if(dna.features["tail_cat"]) - dna.features["tail_cat"] = SSaccessories.tails_list_human[deconstruct_block(get_uni_feature_block(features, DNA_TAIL_BLOCK), length(SSaccessories.tails_list_human))] + dna.features["tail_cat"] = SSaccessories.tails_list_felinid[deconstruct_block(get_uni_feature_block(features, DNA_TAIL_BLOCK), length(SSaccessories.tails_list_felinid))] if(dna.features["tail_lizard"]) dna.features["tail_lizard"] = SSaccessories.tails_list_lizard[deconstruct_block(get_uni_feature_block(features, DNA_LIZARD_TAIL_BLOCK), length(SSaccessories.tails_list_lizard))] if(dna.features["ears"]) @@ -689,6 +703,8 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) dna.features["caps"] = SSaccessories.caps_list[deconstruct_block(get_uni_feature_block(features, DNA_MUSHROOM_CAPS_BLOCK), length(SSaccessories.caps_list))] if(dna.features["pod_hair"]) dna.features["pod_hair"] = SSaccessories.pod_hair_list[deconstruct_block(get_uni_feature_block(features, DNA_POD_HAIR_BLOCK), length(SSaccessories.pod_hair_list))] + if(dna.features["fish_tail"]) + dna.features["fish_tail"] = SSaccessories.tails_list_fish[deconstruct_block(get_uni_feature_block(features, DNA_FISH_TAIL_BLOCK), length(SSaccessories.tails_list_fish))] /// DOPPLER SHIFT ADDITION BEGIN if(dna.features["breasts"]) dna.features["breasts"] = SSaccessories.breasts_list[deconstruct_block(get_uni_feature_block(features, DNA_BREASTS_BLOCK), length(SSaccessories.breasts_list))] diff --git a/code/datums/drift_handler.dm b/code/datums/drift_handler.dm index c70ea9802d6dc..7000483f9ab11 100644 --- a/code/datums/drift_handler.dm +++ b/code/datums/drift_handler.dm @@ -166,7 +166,7 @@ if(ignore_next_glide) ignore_next_glide = FALSE return - var/glide_delay = round(world.icon_size / glide_size, 1) * world.tick_lag + var/glide_delay = round(ICON_SIZE_ALL / glide_size, 1) * world.tick_lag drifting_loop.pause_for(glide_delay) delayed = TRUE @@ -213,6 +213,10 @@ if (drift_force < INERTIA_FORCE_SPACEMOVE_GRAB || isnull(drifting_loop)) return + if (!isnull(source.client) && source.client.intended_direction) + if ((source.client.intended_direction & movement_dir) && !(get_dir(source, backup) & movement_dir)) + return + if (drift_force <= INERTIA_FORCE_SPACEMOVE_REDUCTION / source.inertia_force_weight) glide_to_halt(get_loop_delay(source)) return COMPONENT_PREVENT_SPACEMOVE_HALT diff --git a/code/datums/elements/climbable.dm b/code/datums/elements/climbable.dm index 113cc8aaa90ef..5700ca3bc2e85 100644 --- a/code/datums/elements/climbable.dm +++ b/code/datums/elements/climbable.dm @@ -106,8 +106,8 @@ if(ISDIAGONALDIR(climbed_thing.dir) && same_loc) if(params) //we check the icon x and y parameters of the click-drag to determine step_dir. var/list/modifiers = params2list(params) - var/x_dist = (text2num(LAZYACCESS(modifiers, ICON_X)) - world.icon_size/2) * (climbed_thing.dir & WEST ? -1 : 1) - var/y_dist = (text2num(LAZYACCESS(modifiers, ICON_Y)) - world.icon_size/2) * (climbed_thing.dir & SOUTH ? -1 : 1) + var/x_dist = (text2num(LAZYACCESS(modifiers, ICON_X)) - ICON_SIZE_X/2) * (climbed_thing.dir & WEST ? -1 : 1) + var/y_dist = (text2num(LAZYACCESS(modifiers, ICON_Y)) - ICON_SIZE_Y/2) * (climbed_thing.dir & SOUTH ? -1 : 1) dir_step = (x_dist >= y_dist ? (EAST|WEST) : (NORTH|SOUTH)) & climbed_thing.dir else dir_step = get_dir(user, get_step(climbed_thing, climbed_thing.dir)) diff --git a/code/datums/elements/content_barfer.dm b/code/datums/elements/content_barfer.dm index e30294bc08a7f..533a88503e21e 100644 --- a/code/datums/elements/content_barfer.dm +++ b/code/datums/elements/content_barfer.dm @@ -20,7 +20,9 @@ /datum/element/content_barfer/proc/barf_contents(mob/living/target) SIGNAL_HANDLER - for(var/atom/movable/barfed_out in target) + for(var/atom/movable/barfed_out as anything in target) + if(HAS_TRAIT(barfed_out, TRAIT_NOT_BARFABLE)) + continue barfed_out.forceMove(target.loc) if(prob(90)) step(barfed_out, pick(GLOB.alldirs)) diff --git a/code/datums/elements/decals/blood.dm b/code/datums/elements/decals/blood.dm index 857b9e2b678ea..16fd4241147d4 100644 --- a/code/datums/elements/decals/blood.dm +++ b/code/datums/elements/decals/blood.dm @@ -24,8 +24,8 @@ icon = I.icon icon_state = I.icon_state var/icon/icon_for_size = icon(icon, icon_state) - var/scale_factor_x = icon_for_size.Width()/world.icon_size - var/scale_factor_y = icon_for_size.Height()/world.icon_size + var/scale_factor_x = icon_for_size.Width()/ICON_SIZE_X + var/scale_factor_y = icon_for_size.Height()/ICON_SIZE_Y var/mutable_appearance/blood_splatter = mutable_appearance('icons/effects/blood.dmi', "itemblood", appearance_flags = RESET_COLOR) //MA of the blood that we apply blood_splatter.transform = blood_splatter.transform.Scale(scale_factor_x, scale_factor_y) blood_splatter.blend_mode = BLEND_INSET_OVERLAY diff --git a/code/datums/elements/footstep.dm b/code/datums/elements/footstep.dm index a162e58752d55..698f7896a70b4 100644 --- a/code/datums/elements/footstep.dm +++ b/code/datums/elements/footstep.dm @@ -71,38 +71,55 @@ if(source.body_position == LYING_DOWN) //play crawling sound if we're lying if(turf.footstep) - playsound(turf, 'sound/effects/footstep/crawl1.ogg', 15 * volume, falloff_distance = 1, vary = sound_vary) + var/sound = 'sound/effects/footstep/crawl1.ogg' + if(HAS_TRAIT(source, TRAIT_FLOPPING)) + sound = pick(SFX_FISH_PICKUP, 'sound/mobs/non-humanoids/fish/fish_drop1.ogg') + playsound(turf, sound, 15 * volume, falloff_distance = 1, vary = sound_vary) return - if(iscarbon(source)) - var/mob/living/carbon/carbon_source = source - if(!carbon_source.get_bodypart(BODY_ZONE_L_LEG) && !carbon_source.get_bodypart(BODY_ZONE_R_LEG)) - return - if(carbon_source.move_intent == MOVE_INTENT_WALK) - return// stealth + if(iscarbon(source) && source.move_intent == MOVE_INTENT_WALK) + return // stealth + steps_for_living[source] += 1 var/steps = steps_for_living[source] - if(steps >= 6) + if(steps >= 24) + // right foot = 0, 4, 8, 12, 16, 20 + // left foot = 2, 6, 10, 14, 18, 22 + // 24 -> return to 0 -> right foot, repeat steps_for_living[source] = 0 steps = 0 if(steps % 2) + // skipping every other step, anyways. gets noisy otherwise return - if(steps != 0 && !source.has_gravity()) // don't need to step as often when you hop around + if(steps % 6 != 0 && !source.has_gravity()) + // don't need to step as often when you hop around return - . = list(FOOTSTEP_MOB_SHOE = turf.footstep, FOOTSTEP_MOB_BAREFOOT = turf.barefootstep, FOOTSTEP_MOB_HEAVY = turf.heavyfootstep, FOOTSTEP_MOB_CLAW = turf.clawfootstep, STEP_SOUND_PRIORITY = STEP_SOUND_NO_PRIORITY) - var/overriden = SEND_SIGNAL(turf, COMSIG_TURF_PREPARE_STEP_SOUND, .) & FOOTSTEP_OVERRIDEN - //The turf has no footstep sound (e.g. open space) and none of the objects on that turf (e.g. catwalks) overrides it - if(!overriden && isnull(turf.footstep)) + var/list/footstep_data = list( + FOOTSTEP_MOB_SHOE = turf.footstep, + FOOTSTEP_MOB_BAREFOOT = turf.barefootstep, + FOOTSTEP_MOB_HEAVY = turf.heavyfootstep, + FOOTSTEP_MOB_CLAW = turf.clawfootstep, + STEP_SOUND_PRIORITY = STEP_SOUND_NO_PRIORITY, + ) + var/sigreturn = SEND_SIGNAL(turf, COMSIG_TURF_PREPARE_STEP_SOUND, footstep_data) + if(sigreturn & FOOTSTEP_OVERRIDEN) + return footstep_data + if(isnull(turf.footstep)) + // The turf has no footstep sound (e.g. open space) + // and none of the objects on that turf (e.g. catwalks) overrides it return null - return . + return footstep_data /datum/element/footstep/proc/play_simplestep(mob/living/source, atom/oldloc, direction, forced, list/old_locs, momentum_change) SIGNAL_HANDLER + if(source.moving_diagonally == SECOND_DIAG_STEP) + return // to prevent a diagonal step from counting as 2 + if (forced || SHOULD_DISABLE_FOOTSTEPS(source)) return @@ -122,9 +139,54 @@ /datum/element/footstep/proc/play_humanstep(mob/living/carbon/human/source, atom/oldloc, direction, forced, list/old_locs, momentum_change) SIGNAL_HANDLER + if(source.moving_diagonally == SECOND_DIAG_STEP) + return // to prevent a diagonal step from counting as 2 + if (forced || SHOULD_DISABLE_FOOTSTEPS(source) || !momentum_change) return + var/list/prepared_steps = prepare_step(source) + if(isnull(prepared_steps)) + return + + var/footstep_type = null + var/list/footstep_sounds + var/stepcount = steps_for_living[source] + // any leg covering sounds defaults to shoe sounds + if((source.wear_suit?.body_parts_covered|source.w_uniform?.body_parts_covered|source.shoes?.body_parts_covered) & FEET) + footstep_type = FOOTSTEP_MOB_SHOE + // now pick whether to draw from left foot or right foot sounds + else + var/obj/item/bodypart/leg/left_leg = source.get_bodypart(BODY_ZONE_L_LEG) + var/obj/item/bodypart/leg/right_leg = source.get_bodypart(BODY_ZONE_R_LEG) + if(stepcount == 2 || stepcount == 6) + footstep_sounds = left_leg?.special_footstep_sounds || right_leg?.special_footstep_sounds + footstep_type = left_leg?.footstep_type || right_leg?.footstep_type + else + footstep_sounds = right_leg?.special_footstep_sounds || left_leg?.special_footstep_sounds + footstep_type = right_leg?.footstep_type || left_leg?.footstep_type + + // allow for snowflake effects to take priority + if(!length(footstep_sounds)) + switch(footstep_type) + if(FOOTSTEP_MOB_CLAW) + footstep_sounds = GLOB.clawfootstep[prepared_steps[footstep_type]] + if(FOOTSTEP_MOB_BAREFOOT) + footstep_sounds = GLOB.barefootstep[prepared_steps[footstep_type]] + if(FOOTSTEP_MOB_HEAVY) + footstep_sounds = GLOB.heavyfootstep[prepared_steps[footstep_type]] + if(FOOTSTEP_MOB_SHOE) + footstep_sounds = GLOB.footstep[prepared_steps[footstep_type]] + if(null) + return + else + // Got an unsupported type, somehow + CRASH("Invalid footstep type for human footstep: \[[footstep_type]\]") + + // no snowflake, and no (found) footstep sounds, nothing to do + if(!length(footstep_sounds)) + return + var/volume_multiplier = 1 var/range_adjustment = 0 @@ -132,37 +194,20 @@ volume_multiplier = 0.6 range_adjustment = -2 - var/list/prepared_steps = prepare_step(source) - if(isnull(prepared_steps)) - return - - //cache for sanic speed (lists are references anyways) - var/footstep_sounds = GLOB.footstep - ///list returned by playsound() filled by client mobs who heard the footstep. given to play_fov_effect() + // list returned by playsound() filled by client mobs who heard the footstep. given to play_fov_effect() var/list/heard_clients - - if((source.wear_suit?.body_parts_covered | source.w_uniform?.body_parts_covered | source.shoes?.body_parts_covered) & FEET) - // we are wearing shoes - - var/shoestep_type = prepared_steps[FOOTSTEP_MOB_SHOE] - if(!isnull(shoestep_type) && footstep_sounds[shoestep_type]) // shoestep type can be null - heard_clients = playsound(source.loc, pick(footstep_sounds[shoestep_type][1]), - footstep_sounds[shoestep_type][2] * volume * volume_multiplier, - TRUE, - footstep_sounds[shoestep_type][3] + e_range + range_adjustment, falloff_distance = 1, vary = sound_vary) - else - // we are barefoot - - if(source.dna.species.special_step_sounds) - heard_clients = playsound(source.loc, pick(source.dna.species.special_step_sounds), 50, TRUE, falloff_distance = 1, vary = sound_vary) - else - var/barefoot_type = prepared_steps[FOOTSTEP_MOB_BAREFOOT] - var/bare_footstep_sounds = GLOB.barefootstep - if(!isnull(barefoot_type) && bare_footstep_sounds[barefoot_type]) // barefoot_type can be null - heard_clients = playsound(source.loc, pick(bare_footstep_sounds[barefoot_type][1]), - bare_footstep_sounds[barefoot_type][2] * volume * volume_multiplier, - TRUE, - bare_footstep_sounds[barefoot_type][3] + e_range + range_adjustment, falloff_distance = 1, vary = sound_vary) + var/picked_sound = pick(footstep_sounds[1]) + var/picked_volume = footstep_sounds[2] * volume * volume_multiplier + var/picked_range = footstep_sounds[3] + e_range + range_adjustment + + heard_clients = playsound( + source = source, + soundin = picked_sound, + vol = picked_volume, + vary = sound_vary, + extrarange = picked_range, + falloff_distance = 1, + ) if(heard_clients) play_fov_effect(source, 5, "footstep", direction, ignore_self = TRUE, override_list = heard_clients) @@ -172,6 +217,9 @@ /datum/element/footstep/proc/play_simplestep_machine(atom/movable/source, atom/oldloc, direction, forced, list/old_locs, momentum_change) SIGNAL_HANDLER + if(source.moving_diagonally == SECOND_DIAG_STEP) + return // to prevent a diagonal step from counting as 2 + if (forced || SHOULD_DISABLE_FOOTSTEPS(source)) return diff --git a/code/datums/elements/immerse.dm b/code/datums/elements/immerse.dm index 65f7d45b9ab77..d50ae906c0a55 100644 --- a/code/datums/elements/immerse.dm +++ b/code/datums/elements/immerse.dm @@ -142,8 +142,8 @@ */ /datum/element/immerse/proc/add_immerse_overlay(atom/movable/movable) var/list/icon_dimensions = get_icon_dimensions(movable.icon) - var/width = icon_dimensions["width"] || world.icon_size - var/height = icon_dimensions["height"] || world.icon_size + var/width = icon_dimensions["width"] || ICON_SIZE_X + var/height = icon_dimensions["height"] || ICON_SIZE_Y var/is_below_water = movable.layer < WATER_LEVEL_LAYER ? "underwater-" : "" @@ -184,19 +184,19 @@ * but since we want the appearance to stay where it should be, * we have to counteract this one. */ - var/extra_width = (width - world.icon_size) * 0.5 - var/extra_height = (height - world.icon_size) * 0.5 + var/extra_width = (width - ICON_SIZE_X) * 0.5 + var/extra_height = (height - ICON_SIZE_Y) * 0.5 var/mutable_appearance/overlay_appearance = new() var/icon/immerse_icon = generated_immerse_icons["[icon]-[icon_state]-[mask_icon]"] - var/last_i = width/world.icon_size + var/last_i = width/ICON_SIZE_X for(var/i in -1 to last_i) var/mutable_appearance/underwater = mutable_appearance(icon, icon_state) - underwater.pixel_x = world.icon_size * i - extra_width - underwater.pixel_y = -world.icon_size - extra_height + underwater.pixel_x = ICON_SIZE_X * i - extra_width + underwater.pixel_y = -ICON_SIZE_Y - extra_height overlay_appearance.overlays += underwater var/mutable_appearance/water_level = is_below_water ? underwater : mutable_appearance(immerse_icon) - water_level.pixel_x = world.icon_size * i - extra_width + water_level.pixel_x = ICON_SIZE_X * i - extra_width water_level.pixel_y = -extra_height overlay_appearance.overlays += water_level diff --git a/code/datums/elements/light_eater.dm b/code/datums/elements/light_eater.dm index 27500b066fefa..3f51590da1c6e 100644 --- a/code/datums/elements/light_eater.dm +++ b/code/datums/elements/light_eater.dm @@ -127,7 +127,19 @@ */ /datum/element/light_eater/proc/on_interacting_with(obj/item/source, mob/living/user, atom/target) SIGNAL_HANDLER - eat_lights(target, source) + if(eat_lights(target, source)) + // do a "pretend" attack if we're hitting something that can't normally be + if(isobj(target)) + var/obj/smacking = target + if(smacking.obj_flags & CAN_BE_HIT) + return NONE + else if(!isturf(target)) + return NONE + user.do_attack_animation(target) + user.changeNext_move(CLICK_CD_RAPID) + target.play_attack_sound() + // not particularly picky about what happens afterwards in the attack chain + return NONE /** * Called when a source object is used to block a thrown object, projectile, or attack diff --git a/code/datums/elements/mirage_border.dm b/code/datums/elements/mirage_border.dm index 999455a0b8343..ca7c422dd1127 100644 --- a/code/datums/elements/mirage_border.dm +++ b/code/datums/elements/mirage_border.dm @@ -24,9 +24,9 @@ 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) if(direction & SOUTH) - holder.pixel_y -= world.icon_size * range + holder.pixel_y -= ICON_SIZE_Y * range if(direction & WEST) - holder.pixel_x -= world.icon_size * range + holder.pixel_x -= ICON_SIZE_X * range /datum/element/mirage_border/Detach(atom/movable/target) . = ..() diff --git a/code/datums/elements/organ_set_bonus.dm b/code/datums/elements/organ_set_bonus.dm index aeb63356fb485..1c75bf7de1486 100644 --- a/code/datums/elements/organ_set_bonus.dm +++ b/code/datums/elements/organ_set_bonus.dm @@ -57,6 +57,8 @@ var/required_biotype = MOB_ORGANIC /// A list of traits added to the mob upon bonus activation, can be of any length. var/list/bonus_traits = list() + /// Limb overlay to apply upon activation + var/limb_overlay /datum/status_effect/organ_set_bonus/proc/set_organs(new_value) organs = new_value @@ -80,6 +82,13 @@ owner.add_traits(bonus_traits, REF(src)) if(bonus_activate_text) to_chat(owner, bonus_activate_text) + if(!iscarbon(owner) || !limb_overlay) + return TRUE + var/mob/living/carbon/carbon_owner = owner + for(var/obj/item/bodypart/limb in carbon_owner.bodyparts) + limb.add_bodypart_overlay(new limb_overlay()) + limb.variable_color = COLOR_WHITE + carbon_owner.update_body() return TRUE /datum/status_effect/organ_set_bonus/proc/disable_bonus() @@ -89,3 +98,12 @@ owner.remove_traits(bonus_traits, REF(src)) if(bonus_deactivate_text) to_chat(owner, bonus_deactivate_text) + if(!iscarbon(owner) || QDELETED(owner) || !limb_overlay) + return + var/mob/living/carbon/carbon_owner = owner + for(var/obj/item/bodypart/limb in carbon_owner.bodyparts) + var/overlay = locate(limb_overlay) in limb.bodypart_overlays + if(overlay) + limb.remove_bodypart_overlay(overlay) + limb.variable_color = null + carbon_owner.update_body() diff --git a/code/datums/elements/pet_bonus.dm b/code/datums/elements/pet_bonus.dm index 5ef8b515077ac..d809b9ef4bdad 100644 --- a/code/datums/elements/pet_bonus.dm +++ b/code/datums/elements/pet_bonus.dm @@ -8,17 +8,17 @@ element_flags = ELEMENT_BESPOKE argument_hash_start_idx = 2 - ///optional cute message to send when you pet your pet! - var/emote_message + ///string key of the emote to do when pet. + var/emote_name ///actual moodlet given, defaults to the pet animal one var/moodlet -/datum/element/pet_bonus/Attach(datum/target, emote_message, moodlet = /datum/mood_event/pet_animal) +/datum/element/pet_bonus/Attach(datum/target, emote_name, moodlet = /datum/mood_event/pet_animal) . = ..() if(!isliving(target)) return ELEMENT_INCOMPATIBLE - src.emote_message = emote_message + src.emote_name = emote_name src.moodlet = moodlet RegisterSignal(target, COMSIG_ATOM_ATTACK_HAND, PROC_REF(on_attack_hand)) @@ -34,6 +34,6 @@ new /obj/effect/temp_visual/heart(pet.loc) SEND_SIGNAL(pet, COMSIG_ANIMAL_PET, petter, modifiers) - if(emote_message && prob(33)) - pet.manual_emote(emote_message) + if(emote_name && prob(33)) + INVOKE_ASYNC(pet, TYPE_PROC_REF(/mob, emote), emote_name) petter.add_mood_event("petting_bonus", moodlet, pet) diff --git a/code/datums/elements/venomous.dm b/code/datums/elements/venomous.dm index 9f9e4940df13e..93bb455509821 100644 --- a/code/datums/elements/venomous.dm +++ b/code/datums/elements/venomous.dm @@ -7,7 +7,7 @@ element_flags = ELEMENT_BESPOKE argument_hash_start_idx = 2 ///Path of the reagent added - var/poison_type + var/reagents ///Details of how we inject our venom var/injection_flags ///How much of the reagent added. if it's a list, it'll pick a range with the range being list(lower_value, upper_value) @@ -17,7 +17,7 @@ /datum/element/venomous/Attach(datum/target, poison_type, amount_added, injection_flags = NONE, thrown_effect = FALSE) . = ..() - src.poison_type = poison_type + src.reagents = poison_type src.amount_added = amount_added src.injection_flags = injection_flags src.thrown_effect = thrown_effect @@ -41,4 +41,17 @@ final_amount_added = rand(amount_added[1], amount_added[2]) else final_amount_added = amount_added - target.reagents?.add_reagent(poison_type, final_amount_added) + + var/datum/reagents/tmp_holder = new(final_amount_added) + tmp_holder.my_atom = src + tmp_holder.add_reagent(reagents, final_amount_added) + + tmp_holder.trans_to( + target = target, + amount = tmp_holder.total_volume, + multiplier = 1, + methods = INJECT, + transferred_by = ismob(element_owner) ? element_owner : null, + show_message = FALSE, + ) + qdel(tmp_holder) diff --git a/code/datums/elements/waddling.dm b/code/datums/elements/waddling.dm index 45c7fe5e93773..5605bca57e7c8 100644 --- a/code/datums/elements/waddling.dm +++ b/code/datums/elements/waddling.dm @@ -18,7 +18,7 @@ return if(isliving(moved)) var/mob/living/living_moved = moved - if (living_moved.incapacitated || living_moved.body_position == LYING_DOWN) + if (living_moved.incapacitated || (living_moved.body_position == LYING_DOWN && !HAS_TRAIT(living_moved, TRAIT_FLOPPING))) return waddling_animation(moved) @@ -28,3 +28,16 @@ var/prev_transform = target.transform animate(pixel_z = prev_pixel_z, transform = turn(target.transform, pick(-12, 0, 12)), time=2) animate(transform = prev_transform, time = 0) + +// DOPPLER ADDITION START +/datum/element/waddling/flopping_only + +/datum/element/waddling/flopping_only/Waddle(atom/movable/moved, atom/oldloc, direction, forced) + if(forced || CHECK_MOVE_LOOP_FLAGS(moved, MOVEMENT_LOOP_OUTSIDE_CONTROL)) + return + if(isliving(moved)) + var/mob/living/living_moved = moved + if (living_moved.incapacitated || !(living_moved.body_position == LYING_DOWN) || !HAS_TRAIT(living_moved, TRAIT_FLOPPING)) + return + waddling_animation(moved) +// DOPPLER ADDITION END diff --git a/code/datums/greyscale/_greyscale_config.dm b/code/datums/greyscale/_greyscale_config.dm index b8b428ce4222f..cb0f552f4ae2e 100644 --- a/code/datums/greyscale/_greyscale_config.dm +++ b/code/datums/greyscale/_greyscale_config.dm @@ -249,7 +249,7 @@ /datum/greyscale_config/proc/GenerateBundle(list/colors, list/render_steps, icon/last_external_icon) if(!istype(colors)) colors = SSgreyscale.ParseColorString(colors) - if(length(colors) != expected_colors) + if(length(colors) < expected_colors) CRASH("[DebugName()] expected [expected_colors] color arguments but only received [length(colors)]") var/list/generated_icons = list() diff --git a/code/datums/greyscale/config_types/greyscale_configs/greyscale_items.dm b/code/datums/greyscale/config_types/greyscale_configs/greyscale_items.dm index 2137aea08f3b4..62f30855abb1f 100644 --- a/code/datums/greyscale/config_types/greyscale_configs/greyscale_items.dm +++ b/code/datums/greyscale/config_types/greyscale_configs/greyscale_items.dm @@ -229,6 +229,21 @@ icon_file = 'icons/obj/toys/plushes.dmi' json_config = 'code/datums/greyscale/json_configs/plushie_carp.json' +/datum/greyscale_config/pet_carrier + name = "Pet Carrier" + icon_file = 'icons/obj/pet_carrier.dmi' + json_config = 'code/datums/greyscale/json_configs/pet_carrier.json' + +/datum/greyscale_config/pet_carrier_inhands_left + name = "Pet Carrier Left" + icon_file = 'icons/mob/inhands/items_lefthand.dmi' + json_config = 'code/datums/greyscale/json_configs/pet_carrier_inhands.json' + +/datum/greyscale_config/pet_carrier_inhands_right + name = "Pet Carrier Right" + icon_file = 'icons/mob/inhands/items_righthand.dmi' + json_config = 'code/datums/greyscale/json_configs/pet_carrier_inhands.json' + /datum/greyscale_config/plush_lizard name = "Plushie Lizard" icon_file = 'icons/obj/toys/plushes.dmi' diff --git a/code/datums/greyscale/config_types/mutant_organ_config.dm b/code/datums/greyscale/config_types/mutant_organ_config.dm index 18789a27ccaaf..3427622472835 100644 --- a/code/datums/greyscale/config_types/mutant_organ_config.dm +++ b/code/datums/greyscale/config_types/mutant_organ_config.dm @@ -2,3 +2,8 @@ name = "Mutant Organ" icon_file = 'icons/obj/medical/organs/infuser_organs.dmi' json_config = 'code/datums/greyscale/json_configs/mutant_organs.json' + +/datum/greyscale_config/fish_tail + name = "Fish Tail" + icon_file = 'icons/obj/medical/organs/infuser_organs.dmi' + json_config = 'code/datums/greyscale/json_configs/fish_tail.json' diff --git a/code/datums/greyscale/json_configs/bandanaskull_inhands.json b/code/datums/greyscale/json_configs/bandanaskull_inhands.json index b7067cf3c2e71..40fade079736c 100644 --- a/code/datums/greyscale/json_configs/bandanaskull_inhands.json +++ b/code/datums/greyscale/json_configs/bandanaskull_inhands.json @@ -14,3 +14,4 @@ } ] } + diff --git a/code/datums/greyscale/json_configs/fish_tail.json b/code/datums/greyscale/json_configs/fish_tail.json new file mode 100644 index 0000000000000..3293c1df4ba08 --- /dev/null +++ b/code/datums/greyscale/json_configs/fish_tail.json @@ -0,0 +1,15 @@ +{ + "fish_tail": [ + { + "type": "icon_state", + "icon_state": "fish_tail", + "blend_mode": "overlay", + "color_ids": [ 1 ] + }, + { + "type": "icon_state", + "icon_state": "fish_tail_meat", + "blend_mode": "overlay" + } + ] +} \ No newline at end of file diff --git a/code/datums/greyscale/json_configs/items/cleric_mace.json b/code/datums/greyscale/json_configs/items/cleric_mace.json index 781c790ea6ab5..5197ebc45a2ef 100644 --- a/code/datums/greyscale/json_configs/items/cleric_mace.json +++ b/code/datums/greyscale/json_configs/items/cleric_mace.json @@ -9,7 +9,8 @@ { "type": "icon_state", "icon_state": "handle", - "blend_mode": "overlay" + "blend_mode": "overlay", + "color_ids": [ 2 ] } ], "default_worn": [ @@ -22,7 +23,8 @@ { "type": "icon_state", "icon_state": "worn_handle", - "blend_mode": "overlay" + "blend_mode": "overlay", + "color_ids": [ 2 ] } ] } diff --git a/code/datums/greyscale/json_configs/items/cleric_mace_worn.json b/code/datums/greyscale/json_configs/items/cleric_mace_worn.json index c49a829aa2c21..5725cfa689a42 100644 --- a/code/datums/greyscale/json_configs/items/cleric_mace_worn.json +++ b/code/datums/greyscale/json_configs/items/cleric_mace_worn.json @@ -9,7 +9,8 @@ { "type": "icon_state", "icon_state": "worn_handle", - "blend_mode": "overlay" + "blend_mode": "overlay", + "color_ids": [ 2 ] } ] } diff --git a/code/datums/greyscale/json_configs/kitsune.json b/code/datums/greyscale/json_configs/kitsune.json index bee6418321387..495520fbbd806 100644 --- a/code/datums/greyscale/json_configs/kitsune.json +++ b/code/datums/greyscale/json_configs/kitsune.json @@ -12,5 +12,19 @@ "blend_mode": "overlay", "color_ids": [ 2 ] } + ], + "kitsune_up": [ + { + "type": "icon_state", + "icon_state": "kitsune_base_up", + "blend_mode": "overlay", + "color_ids": [ 1 ] + }, + { + "type": "icon_state", + "icon_state": "kitsune_stripe_up", + "blend_mode": "overlay", + "color_ids": [ 2 ] + } ] } diff --git a/code/datums/greyscale/json_configs/pet_carrier.json b/code/datums/greyscale/json_configs/pet_carrier.json new file mode 100644 index 0000000000000..1674765268ff2 --- /dev/null +++ b/code/datums/greyscale/json_configs/pet_carrier.json @@ -0,0 +1,87 @@ +{ + "pet_carrier_open": [ + { + "type": "icon_state", + "icon_state": "pet_carrier_open", + "blend_mode": "overlay" + }, + { + "type": "icon_state", + "icon_state": "pet_carrier_gags", + "blend_mode": "overlay", + "color_ids": [ 1 ] + } + ], + "pet_carrier_closed_unlocked": [ + { + "type": "icon_state", + "icon_state": "pet_carrier_unlocked", + "blend_mode": "overlay" + }, + { + "type": "icon_state", + "icon_state": "pet_carrier_closed", + "blend_mode": "overlay" + }, + { + "type": "icon_state", + "icon_state": "pet_carrier_gags", + "blend_mode": "overlay", + "color_ids": [ 1 ] + } + ], + "pet_carrier_closed_locked": [ + { + "type": "icon_state", + "icon_state": "pet_carrier_locked", + "blend_mode": "overlay" + }, + { + "type": "icon_state", + "icon_state": "pet_carrier_closed", + "blend_mode": "overlay" + }, + { + "type": "icon_state", + "icon_state": "pet_carrier_gags", + "blend_mode": "overlay", + "color_ids": [ 1 ] + } + ], + "pet_carrier_occupied_unlocked": [ + { + "type": "icon_state", + "icon_state": "pet_carrier_unlocked", + "blend_mode": "overlay" + }, + { + "type": "icon_state", + "icon_state": "pet_carrier_occupied", + "blend_mode": "overlay" + }, + { + "type": "icon_state", + "icon_state": "pet_carrier_gags", + "blend_mode": "overlay", + "color_ids": [ 1 ] + } + ], + "pet_carrier_occupied_locked": [ + { + "type": "icon_state", + "icon_state": "pet_carrier_locked", + "blend_mode": "overlay" + }, + { + "type": "icon_state", + "icon_state": "pet_carrier_occupied", + "blend_mode": "overlay" + }, + { + "type": "icon_state", + "icon_state": "pet_carrier_gags", + "blend_mode": "overlay", + "color_ids": [ 1 ] + } + ] +} diff --git a/code/datums/greyscale/json_configs/pet_carrier_inhands.json b/code/datums/greyscale/json_configs/pet_carrier_inhands.json new file mode 100644 index 0000000000000..05978e3c8292b --- /dev/null +++ b/code/datums/greyscale/json_configs/pet_carrier_inhands.json @@ -0,0 +1,15 @@ +{ + "pet_carrier": [ + { + "type": "icon_state", + "icon_state": "pet_carrier", + "blend_mode": "overlay" + }, + { + "type": "icon_state", + "icon_state": "pet_carrier_gags", + "blend_mode": "overlay", + "color_ids": [ 1 ] + } + ] +} diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm index 732323d28655c..c6e8236e55964 100644 --- a/code/datums/helper_datums/getrev.dm +++ b/code/datums/helper_datums/getrev.dm @@ -87,6 +87,6 @@ msg += "
Current Informational Settings:" msg += "Protect Authority Roles From Traitor: [CONFIG_GET(flag/protect_roles_from_antagonist)]" msg += "Protect Assistant Role From Traitor: [CONFIG_GET(flag/protect_assistant_from_antagonist)]" - msg += "Enforce Human Authority: [CONFIG_GET(flag/enforce_human_authority)]" + msg += "Enforce Human Authority: [CONFIG_GET(string/human_authority)]" msg += "Allow Latejoin Antagonists: [CONFIG_GET(flag/allow_latejoin_antagonists)]" to_chat(src, span_infoplain(msg.Join("
"))) diff --git a/code/datums/id_trim/_id_trim.dm b/code/datums/id_trim/_id_trim.dm index a64b71e357fd0..32bafcb41d3f7 100644 --- a/code/datums/id_trim/_id_trim.dm +++ b/code/datums/id_trim/_id_trim.dm @@ -30,9 +30,6 @@ var/pointer_color /datum/id_trim/proc/find_job() - for (var/datum/job/job as anything in SSjob.all_occupations) - if (job.title == assignment) - return job return null /// Returns the SecHUD job icon state for whatever this object's ID card is, if it has one. diff --git a/code/datums/id_trim/jobs.dm b/code/datums/id_trim/jobs.dm index f63b772a83e09..6c78d2fceffbb 100644 --- a/code/datums/id_trim/jobs.dm +++ b/code/datums/id_trim/jobs.dm @@ -27,7 +27,7 @@ job = SSjob.get_job_type(job) if(isnull(job_changes)) - job_changes = SSmapping.config.job_changes + job_changes = SSmapping.current_map.job_changes if(!length(job_changes)) refresh_trim_access() @@ -76,6 +76,9 @@ return TRUE +/datum/id_trim/job/find_job() + return job + /datum/id_trim/job/assistant assignment = JOB_ASSISTANT trim_state = "trim_assistant" diff --git a/code/datums/job_configs/_job_configs.dm b/code/datums/job_configs/_job_configs.dm index 84e2cb4ec0a41..b3a32cd8a2b83 100644 --- a/code/datums/job_configs/_job_configs.dm +++ b/code/datums/job_configs/_job_configs.dm @@ -33,6 +33,12 @@ stack_trace("Attempted to validate value for the default job config! You're doing something wrong!!") return FALSE +/// Check if the config entry should be made for a specific job +/// By default returns TRUE, meaning that by default every job will have the config entry created by the datum +/// An example of what this could be used for is: A value that only appears if the job is a head of staff +/datum/job_config_type/proc/validate_entry(datum/job/occupation) + return TRUE + /// This is the proc that we actually invoke to set the config-based values for each job. Is also intended to handle all in-depth logic checks pertient to the job datum itself. /// Return TRUE if the value was set successfully (or if expected behavior did indeed occur), FALSE if it was not. /datum/job_config_type/proc/set_current_value(datum/job/occupation, value) diff --git a/code/datums/job_configs/human_authority.dm b/code/datums/job_configs/human_authority.dm new file mode 100644 index 0000000000000..68b6c64f95cfa --- /dev/null +++ b/code/datums/job_configs/human_authority.dm @@ -0,0 +1,17 @@ +/// Whether if the job should whitelist humans, whitelist nonhumans, or neither +/datum/job_config_type/human_authority + name = JOB_CONFIG_HUMAN_AUTHORITY + datum_var_name = "human_authority" + +/datum/job_config_type/human_authority/validate_value(value) + if(value == JOB_AUTHORITY_HUMANS_ONLY) + return TRUE + + if(value == JOB_AUTHORITY_NON_HUMANS_ALLOWED) + return TRUE + + return FALSE + +/datum/job_config_type/human_authority/validate_entry(datum/job/occupation) + return occupation.job_flags & JOB_HEAD_OF_STAFF + diff --git a/code/datums/materials/_material.dm b/code/datums/materials/_material.dm index 5dc8c26d0f6a3..cff0ea0e6d1c5 100644 --- a/code/datums/materials/_material.dm +++ b/code/datums/materials/_material.dm @@ -13,12 +13,20 @@ Simple datum which is instanced once per type and is used for every object of sa /// What the material is indexed by in the SSmaterials.materials list. Defaults to the type of the material. var/id - ///Base color of the material, is used for greyscale. Item isn't changed in color if this is null. - ///Deprecated, use greyscale_color instead. + /** + * Base color of the material, for items that don't have greyscale configs nor are made of multiple materials. Item isn't changed in color if this is null. + * This can be a RGB or color matrix, but it cannot be RGBA as alpha is automatically filled in. + */ var/color - ///Determines the color palette of the material. Formatted the same as atom/var/greyscale_colors - var/greyscale_colors - ///Base alpha of the material, is used for greyscale icons. + /** + * If the color is a color matrix and either the item uses greyscale configs or is made of multiple colored materials. This will be used instead because + * neither greyscale configs nor BlendRGB() support color matrices. + * Also this has to be RRGGBB, six characters, no alpha channel as it's automatically filled in. + * + * Basically, set this if the color is a color matrix (list) + */ + var/greyscale_color + /// Base alpha of the material var/alpha = 255 ///Starlight color of the material ///This is the color of light it'll emit if its turf is transparent and over space. Defaults to COLOR_STARLIGHT if not set @@ -67,6 +75,8 @@ Simple datum which is instanced once per type and is used for every object of sa var/mineral_rarity = MATERIAL_RARITY_COMMON /// How many points per units of ore does this grant? var/points_per_unit = 1 + /// The slowdown that is added to items. + var/added_slowdown = 0 /** Handles initializing the material. * @@ -85,84 +95,11 @@ Simple datum which is instanced once per type and is used for every object of sa return TRUE ///This proc is called when the material is added to an object. -/datum/material/proc/on_applied(atom/source, amount, material_flags) - if(material_flags & MATERIAL_COLOR) //Prevent changing things with pre-set colors, to keep colored toolboxes their looks for example - if(color) //Do we have a custom color? - source.add_atom_colour(color, FIXED_COLOUR_PRIORITY) - if(alpha) - source.alpha = alpha - if(texture_layer_icon_state) - ADD_KEEP_TOGETHER(source, MATERIAL_SOURCE(src)) - source.add_filter("material_texture_[name]",1,layering_filter(icon=cached_texture_filter_icon,blend_mode=BLEND_INSET_OVERLAY)) - - if(material_flags & MATERIAL_GREYSCALE) - var/config_path = get_greyscale_config_for(source.greyscale_config) - source.set_greyscale(greyscale_colors, config_path) - - if(alpha < 255) - source.opacity = FALSE - if(material_flags & MATERIAL_ADD_PREFIX) - source.name = "[name] [source.name]" - - if(beauty_modifier) - source.AddElement(/datum/element/beauty, beauty_modifier * amount) - - if(isobj(source)) //objs - on_applied_obj(source, amount, material_flags) - - else if(istype(source, /turf)) //turfs - on_applied_turf(source, amount, material_flags) - - source.mat_update_desc(src) - -///This proc is called when a material updates an object's description -/atom/proc/mat_update_desc(datum/material/mat) +/datum/material/proc/on_applied(atom/source, mat_amount, multiplier) return -///This proc is called when the material is added to an object specifically. -/datum/material/proc/on_applied_obj(obj/o, amount, material_flags) - if(material_flags & MATERIAL_AFFECT_STATISTICS) - var/new_max_integrity = CEILING(o.max_integrity * integrity_modifier, 1) - o.modify_max_integrity(new_max_integrity) - o.force *= strength_modifier - o.throwforce *= strength_modifier - o.set_armor(o.get_armor().generate_new_with_multipliers(armor_modifiers)) - - if(!isitem(o)) - return - var/obj/item/item = o - - if(material_flags & MATERIAL_GREYSCALE) - var/worn_path = get_greyscale_config_for(item.greyscale_config_worn) - var/lefthand_path = get_greyscale_config_for(item.greyscale_config_inhand_left) - var/righthand_path = get_greyscale_config_for(item.greyscale_config_inhand_right) - item.set_greyscale( - new_worn_config = worn_path, - new_inhand_left = lefthand_path, - new_inhand_right = righthand_path - ) - - if(!item_sound_override) - return - item.hitsound = item_sound_override - item.usesound = item_sound_override - item.mob_throw_hit_sound = item_sound_override - item.equip_sound = item_sound_override - item.pickup_sound = item_sound_override - item.drop_sound = item_sound_override - -/datum/material/proc/on_applied_turf(turf/T, amount, material_flags) - if(isopenturf(T)) - if(turf_sound_override) - var/turf/open/O = T - O.footstep = turf_sound_override - O.barefootstep = turf_sound_override + "barefoot" - O.clawfootstep = turf_sound_override + "claw" - O.heavyfootstep = FOOTSTEP_GENERIC_HEAVY - if(alpha < 255) - T.AddElement(/datum/element/turf_z_transparency) - setup_glow(T) - T.rust_resistance = mat_rust_resistance +///This proc is called when the material becomes the one the object is composed of the most +/datum/material/proc/on_main_applied(atom/source, mat_amount, multiplier) return /datum/material/proc/setup_glow(turf/on) @@ -183,61 +120,13 @@ Simple datum which is instanced once per type and is used for every object of sa /datum/material/proc/lit_turf_deleted(turf/source) source.set_light(0, 0, null) -/datum/material/proc/get_greyscale_config_for(datum/greyscale_config/config_path) - if(!config_path) - return - for(var/datum/greyscale_config/path as anything in subtypesof(config_path)) - if(type != initial(path.material_skin)) - continue - return path - ///This proc is called when the material is removed from an object. /datum/material/proc/on_removed(atom/source, amount, material_flags) - if(material_flags & MATERIAL_COLOR) //Prevent changing things with pre-set colors, to keep colored toolboxes their looks for example - if(color) - source.remove_atom_colour(FIXED_COLOUR_PRIORITY, color) - if(texture_layer_icon_state) - source.remove_filter("material_texture_[name]") - REMOVE_KEEP_TOGETHER(source, MATERIAL_SOURCE(src)) - source.alpha = initial(source.alpha) - - if(material_flags & MATERIAL_GREYSCALE) - source.set_greyscale(initial(source.greyscale_colors), initial(source.greyscale_config)) - - if(material_flags & MATERIAL_ADD_PREFIX) - source.name = initial(source.name) - - if(beauty_modifier) - source.RemoveElement(/datum/element/beauty, beauty_modifier * amount) - - if(isobj(source)) //objs - on_removed_obj(source, amount, material_flags) - - if(istype(source, /turf)) //turfs - on_removed_turf(source, amount, material_flags) - -///This proc is called when the material is removed from an object specifically. -/datum/material/proc/on_removed_obj(obj/o, amount, material_flags) - if(material_flags & MATERIAL_AFFECT_STATISTICS) - var/new_max_integrity = initial(o.max_integrity) - o.modify_max_integrity(new_max_integrity) - o.force = initial(o.force) - o.throwforce = initial(o.throwforce) - - if(isitem(o) && (material_flags & MATERIAL_GREYSCALE)) - var/obj/item/item = o - item.set_greyscale( - new_worn_config = initial(item.greyscale_config_worn), - new_inhand_left = initial(item.greyscale_config_inhand_left), - new_inhand_right = initial(item.greyscale_config_inhand_right) - ) + return -/datum/material/proc/on_removed_turf(turf/T, amount, material_flags) - if(alpha < 255) - T.RemoveElement(/datum/element/turf_z_transparency) - // yeets glow - T.UnregisterSignal(SSdcs, COMSIG_STARLIGHT_COLOR_CHANGED) - T.set_light(0, 0, null) +///This proc is called when the material is no longer the one the object is composed by the most +/datum/material/proc/on_main_removed(atom/source, mat_amount, multiplier) + return /** * This proc is called when the mat is found in an item that's consumed by accident. see /obj/item/proc/on_accidental_consumption. @@ -258,3 +147,11 @@ Simple datum which is instanced once per type and is used for every object of sa /datum/material/proc/return_composition(amount = 1) // Yes we need the parenthesis, without them BYOND stringifies src into "src" and things break. return list((src) = amount) + +///Returns the list of armor modifiers, with each element having its assoc value multiplied by the multiplier arg +/datum/material/proc/get_armor_modifiers(multiplier) + SHOULD_NOT_OVERRIDE(TRUE) + var/list/return_list = list() + for(var/armor in armor_modifiers) + return_list[armor] = return_list[armor] * multiplier + return return_list diff --git a/code/datums/materials/alloys.dm b/code/datums/materials/alloys.dm index 8bfdf0b58d9fe..d13a88c49c3a2 100644 --- a/code/datums/materials/alloys.dm +++ b/code/datums/materials/alloys.dm @@ -27,31 +27,21 @@ name = "plasteel" desc = "The heavy duty result of infusing iron with plasma." color = "#706374" - greyscale_colors = "#706374" init_flags = MATERIAL_INIT_MAPLOAD value_per_unit = 0.135 strength_modifier = 1.25 integrity_modifier = 1.5 // Heavy duty. armor_modifiers = list(MELEE = 1.4, BULLET = 1.4, LASER = 1.1, ENERGY = 1.1, BOMB = 1.5, BIO = 1, FIRE = 1.1, ACID = 1) sheet_type = /obj/item/stack/sheet/plasteel - categories = list(MAT_CATEGORY_RIGID=TRUE, MAT_CATEGORY_BASE_RECIPES=TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) composition = list(/datum/material/iron=1, /datum/material/plasma=1) mat_rust_resistance = RUST_RESISTANCE_REINFORCED - -/datum/material/alloy/plasteel/on_applied_obj(obj/item/target_item, amount, material_flags) - . = ..() - if(!istype(target_item)) - return - - target_item.slowdown += MATERIAL_SLOWDOWN_PLASTEEL * amount / SHEET_MATERIAL_AMOUNT - -/datum/material/alloy/plasteel/on_removed_obj(obj/item/target_item, amount, material_flags) - . = ..() - - if(!istype(target_item)) - return - - target_item.slowdown -= MATERIAL_SLOWDOWN_PLASTEEL * amount / SHEET_MATERIAL_AMOUNT + added_slowdown = 0.05 /** Plastitanium * @@ -61,14 +51,18 @@ name = "plastitanium" desc = "The extremely heat resistant result of infusing titanium with plasma." color = "#3a313a" - greyscale_colors = "#3a313a" init_flags = MATERIAL_INIT_MAPLOAD value_per_unit = 0.225 strength_modifier = 0.9 // It's a lightweight alloy. integrity_modifier = 1.3 armor_modifiers = list(MELEE = 1.1, BULLET = 1.1, LASER = 1.4, ENERGY = 1.4, BOMB = 1.1, BIO = 1.2, FIRE = 1.5, ACID = 1) sheet_type = /obj/item/stack/sheet/mineral/plastitanium - categories = list(MAT_CATEGORY_RIGID=TRUE, MAT_CATEGORY_BASE_RECIPES=TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) composition = list(/datum/material/titanium=1, /datum/material/plasma=1) mat_rust_resistance = RUST_RESISTANCE_TITANIUM @@ -80,7 +74,6 @@ name = "plasmaglass" desc = "Plasma-infused silicate. It is much more durable and heat resistant than either of its component materials." color = "#ff80f4" - greyscale_colors = "#ff80f496" alpha = 150 starlight_color = COLOR_STRONG_MAGENTA init_flags = MATERIAL_INIT_MAPLOAD @@ -90,7 +83,12 @@ shard_type = /obj/item/shard/plasma debris_type = /obj/effect/decal/cleanable/glass/plasma value_per_unit = 0.075 - categories = list(MAT_CATEGORY_RIGID=TRUE, MAT_CATEGORY_BASE_RECIPES=TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) composition = list(/datum/material/glass=1, /datum/material/plasma=0.5) /** Titaniumglass @@ -101,7 +99,6 @@ name = "titanium glass" desc = "A specialized silicate-titanium alloy that is commonly used in shuttle windows." color = "#cfbee0" - greyscale_colors = "#cfbee096" alpha = 150 starlight_color = COLOR_COMMAND_BLUE init_flags = MATERIAL_INIT_MAPLOAD @@ -110,7 +107,12 @@ shard_type = /obj/item/shard/titanium debris_type = /obj/effect/decal/cleanable/glass/titanium value_per_unit = 0.04 - categories = list(MAT_CATEGORY_RIGID=TRUE, MAT_CATEGORY_BASE_RECIPES=TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) composition = list(/datum/material/glass=1, /datum/material/titanium=0.5) /** Plastitanium Glass @@ -121,7 +123,6 @@ name = "plastitanium glass" desc = "A specialized silicate-plastitanium alloy." color = "#5d3369" - greyscale_colors = "#5d336996" starlight_color = COLOR_CENTCOM_BLUE alpha = 150 init_flags = MATERIAL_INIT_MAPLOAD @@ -131,7 +132,12 @@ shard_type = /obj/item/shard/plastitanium debris_type = /obj/effect/decal/cleanable/glass/plastitanium value_per_unit = 0.125 - categories = list(MAT_CATEGORY_RIGID=TRUE, MAT_CATEGORY_BASE_RECIPES=TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) composition = list(/datum/material/glass=1, /datum/material/alloy/plastitanium=0.5) /** Alien Alloy @@ -144,30 +150,27 @@ name = "alien alloy" desc = "An extremely dense alloy similar to plasteel in composition. It requires exotic metallurgical processes to create." color = "#6041aa" - greyscale_colors = "#6041aa" init_flags = MATERIAL_INIT_MAPLOAD strength_modifier = 1.5 // It's twice the density of plasteel and just as durable. Getting hit with it is going to HURT. integrity_modifier = 1.5 armor_modifiers = list(MELEE = 1.4, BULLET = 1.4, LASER = 1.2, ENERGY = 1.2, BOMB = 1.5, BIO = 1.2, FIRE = 1.2, ACID = 1.2) sheet_type = /obj/item/stack/sheet/mineral/abductor value_per_unit = 0.4 - categories = list(MAT_CATEGORY_RIGID=TRUE, MAT_CATEGORY_BASE_RECIPES=TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) composition = list(/datum/material/iron=2, /datum/material/plasma=2) + added_slowdown = 0.1 -/datum/material/alloy/alien/on_applied_obj(obj/item/target_item, amount, material_flags) +/datum/material/alloy/alien/on_applied(atom/target, mat_amount, multiplier) . = ..() + if(isobj(target)) + target.AddElement(/datum/element/obj_regen, _rate=0.02) // 2% regen per tick. - target_item.AddElement(/datum/element/obj_regen, _rate=0.02) // 2% regen per tick. - if(!istype(target_item)) - return - - target_item.slowdown += MATERIAL_SLOWDOWN_ALIEN_ALLOY * amount / SHEET_MATERIAL_AMOUNT - -/datum/material/alloy/alien/on_removed_obj(obj/item/target_item, amount, material_flags) +/datum/material/alloy/alien/on_removed(atom/target, mat_amount, multiplier) . = ..() - - target_item.RemoveElement(/datum/element/obj_regen, _rate=0.02) - if(!istype(target_item)) - return - - target_item.slowdown -= MATERIAL_SLOWDOWN_ALIEN_ALLOY * amount / SHEET_MATERIAL_AMOUNT + if(isobj(target)) + target.RemoveElement(/datum/element/obj_regen, _rate=0.02) diff --git a/code/datums/materials/basemats.dm b/code/datums/materials/basemats.dm index 66f4bccbd6f7b..76d44c1f16455 100644 --- a/code/datums/materials/basemats.dm +++ b/code/datums/materials/basemats.dm @@ -3,8 +3,13 @@ name = "iron" desc = "Common iron ore often found in sedimentary and igneous layers of the crust." color = "#B6BEC2" - greyscale_colors = "#B6BEC2" - categories = list(MAT_CATEGORY_SILO = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_SILO = TRUE, + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/iron ore_type = /obj/item/stack/ore/iron value_per_unit = 5 / SHEET_MATERIAL_AMOUNT @@ -24,9 +29,14 @@ name = "glass" desc = "Glass forged by melting sand." color = "#6292AF" - greyscale_colors = "#6292AF" alpha = 150 - categories = list(MAT_CATEGORY_SILO = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_SILO = TRUE, + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) integrity_modifier = 0.1 sheet_type = /obj/item/stack/sheet/glass ore_type = /obj/item/stack/ore/glass/basalt @@ -46,15 +56,15 @@ victim.apply_damage(10, BRUTE, BODY_ZONE_HEAD, wound_bonus = 5, sharpness = TRUE) //cronch return TRUE -/datum/material/glass/on_applied_obj(atom/source, amount, material_flags) +/datum/material/glass/on_main_applied(atom/source, mat_amount, multiplier) . = ..() - if(!isstack(source)) - source.AddElement(/datum/element/can_shatter, shard_type, round(amount / SHEET_MATERIAL_AMOUNT), SFX_SHATTER) + if(isobj(source) && !isstack(source)) + source.AddElement(/datum/element/can_shatter, shard_type, round(mat_amount / SHEET_MATERIAL_AMOUNT * multiplier), SFX_SHATTER) -/datum/material/glass/on_removed(atom/source, amount, material_flags) +/datum/material/glass/on_main_removed(atom/source, mat_amount, multiplier) . = ..() - - source.RemoveElement(/datum/element/can_shatter, shard_type) + if(isobj(source) && !isstack(source)) + source.RemoveElement(/datum/element/can_shatter, shard_type, round(mat_amount / SHEET_MATERIAL_AMOUNT * multiplier), SFX_SHATTER) /* Color matrices are like regular colors but unlike with normal colors, you can go over 255 on a channel. @@ -66,8 +76,13 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "silver" desc = "Silver" color = "#B5BCBB" - greyscale_colors = "#B5BCBB" - categories = list(MAT_CATEGORY_SILO = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_SILO = TRUE, + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/silver ore_type = /obj/item/stack/ore/silver value_per_unit = 50 / SHEET_MATERIAL_AMOUNT @@ -87,9 +102,14 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "gold" desc = "Gold" color = "#E6BB45" - greyscale_colors = "#E6BB45" strength_modifier = 1.2 - categories = list(MAT_CATEGORY_SILO = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_SILO = TRUE, + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/gold ore_type = /obj/item/stack/ore/gold value_per_unit = 125 / SHEET_MATERIAL_AMOUNT @@ -110,8 +130,13 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "diamond" desc = "Highly pressurized carbon" color = "#C9D8F2" - greyscale_colors = "#C9D8F2" - categories = list(MAT_CATEGORY_SILO = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_SILO = TRUE, + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/diamond ore_type = /obj/item/stack/ore/diamond alpha = 132 @@ -133,8 +158,13 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "uranium" desc = "Uranium" color = "#2C992C" - greyscale_colors = "#2C992C" - categories = list(MAT_CATEGORY_SILO = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_SILO = TRUE, + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/uranium ore_type = /obj/item/stack/ore/uranium value_per_unit = 100 / SHEET_MATERIAL_AMOUNT @@ -145,7 +175,7 @@ Unless you know what you're doing, only use the first three numbers. They're in mineral_rarity = MATERIAL_RARITY_SEMIPRECIOUS points_per_unit = 30 / SHEET_MATERIAL_AMOUNT -/datum/material/uranium/on_applied(atom/source, amount, material_flags) +/datum/material/uranium/on_applied(atom/source, mat_amount, multiplier) . = ..() // Uranium structures should irradiate, but not items, because item irradiation is a lot more annoying. @@ -153,15 +183,15 @@ Unless you know what you're doing, only use the first three numbers. They're in if (isitem(source)) return - source.AddElement(/datum/element/radioactive) + source.AddElement(/datum/element/radioactive, chance = URANIUM_IRRADIATION_CHANCE * multiplier) -/datum/material/uranium/on_removed(atom/source, amount, material_flags) +/datum/material/uranium/on_removed(atom/source, mat_amount, multiplier) . = ..() if (isitem(source)) return - source.RemoveElement(/datum/element/radioactive) + source.RemoveElement(/datum/element/radioactive, chance = URANIUM_IRRADIATION_CHANCE * multiplier) /datum/material/uranium/on_accidental_mat_consumption(mob/living/carbon/victim, obj/item/source_item) victim.reagents.add_reagent(/datum/reagent/uranium, rand(4, 6)) @@ -173,8 +203,13 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "plasma" desc = "Isn't plasma a state of matter? Oh whatever." color = "#BA3692" - greyscale_colors = "#BA3692" - categories = list(MAT_CATEGORY_SILO = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_SILO = TRUE, + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/plasma ore_type = /obj/item/stack/ore/plasma value_per_unit = 200 / SHEET_MATERIAL_AMOUNT @@ -183,15 +218,15 @@ Unless you know what you're doing, only use the first three numbers. They're in mineral_rarity = MATERIAL_RARITY_PRECIOUS points_per_unit = 15 / SHEET_MATERIAL_AMOUNT -/datum/material/plasma/on_applied(atom/source, amount, material_flags) +/datum/material/plasma/on_applied(atom/source, mat_amount, multiplier) . = ..() if(ismovable(source)) - source.AddElement(/datum/element/firestacker, amount=1) - source.AddComponent(/datum/component/combustible_flooder, "plasma", amount*0.05) //Empty temp arg, fully dependent on whatever ignited it. + source.AddElement(/datum/element/firestacker, 1 * multiplier) + source.AddComponent(/datum/component/combustible_flooder, "plasma", mat_amount * 0.05 * multiplier) //Empty temp arg, fully dependent on whatever ignited it. -/datum/material/plasma/on_removed(atom/source, amount, material_flags) +/datum/material/plasma/on_removed(atom/source, mat_amount, multiplier) . = ..() - source.RemoveElement(/datum/element/firestacker, amount=1) + source.RemoveElement(/datum/element/firestacker, mat_amount = 1 * multiplier) qdel(source.GetComponent(/datum/component/combustible_flooder)) qdel(source.GetComponent(/datum/component/explodable)) @@ -205,10 +240,15 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "bluespace crystal" desc = "Crystals with bluespace properties" color = "#2E50B7" - greyscale_colors = "#2E50B7" alpha = 200 starlight_color = COLOR_BLUE - categories = list(MAT_CATEGORY_SILO = TRUE, MAT_CATEGORY_ITEM_MATERIAL = TRUE) + categories = list( + MAT_CATEGORY_SILO = TRUE, + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) beauty_modifier = 0.5 sheet_type = /obj/item/stack/sheet/bluespace_crystal ore_type = /obj/item/stack/ore/bluespace_crystal @@ -229,8 +269,14 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "bananium" desc = "Material with hilarious properties" color = list(460/255, 464/255, 0, 0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0) //obnoxiously bright yellow //It's literally perfect I can't change it - greyscale_colors = "#FFF269" - categories = list(MAT_CATEGORY_SILO = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + greyscale_color = "#FFF269" + categories = list( + MAT_CATEGORY_SILO = TRUE, + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/bananium ore_type = /obj/item/stack/ore/bananium value_per_unit = 1000 / SHEET_MATERIAL_AMOUNT @@ -239,12 +285,12 @@ Unless you know what you're doing, only use the first three numbers. They're in mineral_rarity = MATERIAL_RARITY_UNDISCOVERED points_per_unit = 60 / SHEET_MATERIAL_AMOUNT -/datum/material/bananium/on_applied(atom/source, amount, material_flags) +/datum/material/bananium/on_applied(atom/source, mat_amount, multiplier) . = ..() - source.LoadComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 50, falloff_exponent = 20) - source.AddComponent(/datum/component/slippery, min(amount / 10, 80)) + source.LoadComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 50 * multiplier, falloff_exponent = 20) + source.AddComponent(/datum/component/slippery, min(mat_amount / 10 * multiplier, 80 * multiplier)) -/datum/material/bananium/on_removed(atom/source, amount, material_flags) +/datum/material/bananium/on_removed(atom/source, mat_amount, multiplier) . = ..() qdel(source.GetComponent(/datum/component/slippery)) qdel(source.GetComponent(/datum/component/squeak)) @@ -259,9 +305,14 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "titanium" desc = "Titanium" color = "#EFEFEF" - greyscale_colors = "#EFEFEF" strength_modifier = 1.3 - categories = list(MAT_CATEGORY_SILO = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_SILO = TRUE, + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/titanium ore_type = /obj/item/stack/ore/titanium value_per_unit = 125 / SHEET_MATERIAL_AMOUNT @@ -281,9 +332,13 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "runite" desc = "Runite" color = "#526F77" - greyscale_colors = "#526F77" strength_modifier = 1.3 - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/runite value_per_unit = 600 / SHEET_MATERIAL_AMOUNT beauty_modifier = 0.5 @@ -300,11 +355,16 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "plastic" desc = "Plastic" color = "#BFB9AC" - greyscale_colors = "#BFB9AC" strength_modifier = 0.85 sheet_type = /obj/item/stack/sheet/plastic ore_type = /obj/item/stack/ore/slag //No plastic or coal ore, so we use slag. - categories = list(MAT_CATEGORY_SILO = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_SILO = TRUE, + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) value_per_unit = 25 / SHEET_MATERIAL_AMOUNT beauty_modifier = -0.01 armor_modifiers = list(MELEE = 1.5, BULLET = 1.1, LASER = 0.3, ENERGY = 0.5, BOMB = 1, BIO = 1, FIRE = 1.1, ACID = 1) @@ -319,9 +379,8 @@ Unless you know what you're doing, only use the first three numbers. They're in ///Force decrease and mushy sound effect. (Not yet implemented) /datum/material/biomass name = "biomass" - desc = "Organic matter" + desc = "Organic matter." color = "#735b4d" - greyscale_colors = "#735b4d" strength_modifier = 0.8 value_per_unit = 50 / SHEET_MATERIAL_AMOUNT @@ -329,24 +388,28 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "wood" desc = "Flexible, durable, but flamable. Hard to come across in space." color = "#855932" - greyscale_colors = "#855932" strength_modifier = 0.5 sheet_type = /obj/item/stack/sheet/mineral/wood - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) value_per_unit = 20 / SHEET_MATERIAL_AMOUNT beauty_modifier = 0.1 armor_modifiers = list(MELEE = 1.1, BULLET = 1.1, LASER = 0.4, ENERGY = 0.4, BOMB = 1, BIO = 0.2, ACID = 0.3) texture_layer_icon_state = "woodgrain" -/datum/material/wood/on_applied_obj(obj/source, amount, material_flags) +/datum/material/wood/on_main_applied(atom/source, mat_amount, multiplier) . = ..() - if(material_flags & MATERIAL_AFFECT_STATISTICS) + if(source.material_flags & MATERIAL_AFFECT_STATISTICS && isobj(source)) var/obj/wooden = source wooden.resistance_flags |= FLAMMABLE -/datum/material/wood/on_removed_obj(obj/source, amount, material_flags) +/datum/material/wood/on_main_removed(atom/source, mat_amount, multiplier) . = ..() - if(material_flags & MATERIAL_AFFECT_STATISTICS) + if(source.material_flags & MATERIAL_AFFECT_STATISTICS && isobj(source)) var/obj/wooden = source wooden.resistance_flags &= ~FLAMMABLE @@ -362,9 +425,13 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "adamantine" desc = "A powerful material made out of magic, I mean science!" color = "#2B7A74" - greyscale_colors = "#2B7A74" strength_modifier = 1.5 - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/adamantine value_per_unit = 500 / SHEET_MATERIAL_AMOUNT beauty_modifier = 0.4 @@ -381,8 +448,12 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "mythril" desc = "How this even exists is byond me" color = "#f2d5d7" - greyscale_colors = "#f2d5d7" - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/mythril value_per_unit = 1500 / SHEET_MATERIAL_AMOUNT strength_modifier = 1.2 @@ -391,13 +462,13 @@ Unless you know what you're doing, only use the first three numbers. They're in mineral_rarity = MATERIAL_RARITY_UNDISCOVERED //Doesn't naturally spawn on lavaland. points_per_unit = 100 / SHEET_MATERIAL_AMOUNT -/datum/material/mythril/on_applied_obj(atom/source, amount, material_flags) +/datum/material/mythril/on_applied(atom/source, mat_amount, multiplier) . = ..() if(isitem(source)) source.AddComponent(/datum/component/fantasy) ADD_TRAIT(source, TRAIT_INNATELY_FANTASTICAL_ITEM, REF(src)) // DO THIS LAST OR WE WILL NEVER GET OUR BONUSES!!! -/datum/material/mythril/on_removed_obj(atom/source, amount, material_flags) +/datum/material/mythril/on_removed(atom/source, mat_amount, multiplier) . = ..() if(isitem(source)) REMOVE_TRAIT(source, TRAIT_INNATELY_FANTASTICAL_ITEM, REF(src)) // DO THIS FIRST OR WE WILL NEVER GET OUR BONUSES DELETED!!! @@ -412,19 +483,23 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "hot ice" desc = "A weird kind of ice, feels warm to the touch" color = "#88cdf1" - greyscale_colors = "#88cdf196" alpha = 150 starlight_color = COLOR_BLUE_LIGHT - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/hot_ice value_per_unit = 400 / SHEET_MATERIAL_AMOUNT beauty_modifier = 0.2 -/datum/material/hot_ice/on_applied(atom/source, amount, material_flags) +/datum/material/hot_ice/on_applied(atom/source, mat_amount, multiplier) . = ..() - source.AddComponent(/datum/component/combustible_flooder, "plasma", amount*1.5, amount*0.2+300) + source.AddComponent(/datum/component/combustible_flooder, "plasma", mat_amount * 1.5 * multiplier, (mat_amount * 0.2 + 300) * multiplier) -/datum/material/hot_ice/on_removed(atom/source, amount, material_flags) +/datum/material/hot_ice/on_removed(atom/source, mat_amount, multiplier) qdel(source.GetComponent(/datum/component/combustible_flooder)) return ..() @@ -438,10 +513,14 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "Metal Hydrogen" desc = "Solid metallic hydrogen. Some say it should be impossible" color = "#62708A" - greyscale_colors = "#62708A" alpha = 150 starlight_color = COLOR_MODERATE_BLUE - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/metal_hydrogen value_per_unit = 700 / SHEET_MATERIAL_AMOUNT beauty_modifier = 0.35 @@ -457,8 +536,11 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "sand" desc = "You know, it's amazing just how structurally sound sand can be." color = "#EDC9AF" - greyscale_colors = "#EDC9AF" - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/sandblock value_per_unit = 2 / SHEET_MATERIAL_AMOUNT strength_modifier = 0.5 @@ -477,8 +559,12 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "sandstone" desc = "Bialtaakid 'ant taerif ma hdha." color = "#ECD5A8" - greyscale_colors = "#ECD5A8" - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/sandstone value_per_unit = 5 / SHEET_MATERIAL_AMOUNT armor_modifiers = list(MELEE = 0.5, BULLET = 0.5, LASER = 1.25, ENERGY = 0.5, BOMB = 0.5, BIO = 0.25, FIRE = 1.5, ACID = 1.5) @@ -490,8 +576,11 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "snow" desc = "There's no business like snow business." color = COLOR_WHITE - greyscale_colors = COLOR_WHITE - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/snow value_per_unit = 5 / SHEET_MATERIAL_AMOUNT armor_modifiers = list(MELEE = 0.25, BULLET = 0.25, LASER = 0.25, ENERGY = 0.25, BOMB = 0.25, BIO = 0.25, FIRE = 0.25, ACID = 1.5) @@ -507,8 +596,12 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "runed metal" desc = "Mir'ntrath barhah Nar'sie." color = "#504742" - greyscale_colors = "#504742" - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/runed_metal value_per_unit = 1500 / SHEET_MATERIAL_AMOUNT armor_modifiers = list(MELEE = 1.2, BULLET = 1.2, LASER = 1, ENERGY = 1, BOMB = 1.2, BIO = 1.2, FIRE = 1.5, ACID = 1.5) @@ -524,8 +617,12 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "bronze" desc = "Clock Cult? Never heard of it." color = "#876223" - greyscale_colors = "#876223" - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/bronze value_per_unit = 50 / SHEET_MATERIAL_AMOUNT armor_modifiers = list(MELEE = 1, BULLET = 1, LASER = 1, ENERGY = 1, BOMB = 1, BIO = 1, FIRE = 1.5, ACID = 1.5) @@ -535,8 +632,12 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "paper" desc = "Ten thousand folds of pure starchy power." color = "#E5DCD5" - greyscale_colors = "#E5DCD5" - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/paperframes value_per_unit = 5 / SHEET_MATERIAL_AMOUNT armor_modifiers = list(MELEE = 0.1, BULLET = 0.1, LASER = 0.1, ENERGY = 0.1, BOMB = 0.1, BIO = 0.1, ACID = 1.5) @@ -544,15 +645,15 @@ Unless you know what you're doing, only use the first three numbers. They're in turf_sound_override = FOOTSTEP_SAND texture_layer_icon_state = "paper" -/datum/material/paper/on_applied_obj(obj/source, amount, material_flags) +/datum/material/paper/on_main_applied(atom/source, mat_amount, multiplier) . = ..() - if(material_flags & MATERIAL_AFFECT_STATISTICS) + if(isobj(source) && source.material_flags & MATERIAL_AFFECT_STATISTICS) var/obj/paper = source paper.resistance_flags |= FLAMMABLE paper.obj_flags |= UNIQUE_RENAME -/datum/material/paper/on_removed_obj(obj/source, amount, material_flags) - if(material_flags & MATERIAL_AFFECT_STATISTICS) +/datum/material/paper/on_main_removed(atom/source, mat_amount, multiplier) + if(isobj(source) && source.material_flags & MATERIAL_AFFECT_STATISTICS) var/obj/paper = source paper.resistance_flags &= ~FLAMMABLE return ..() @@ -561,22 +662,26 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "cardboard" desc = "They say cardboard is used by hobos to make incredible things." color = "#5F625C" - greyscale_colors = "#5F625C" - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/cardboard value_per_unit = 6 / SHEET_MATERIAL_AMOUNT armor_modifiers = list(MELEE = 0.25, BULLET = 0.25, LASER = 0.25, ENERGY = 0.25, BOMB = 0.25, BIO = 0.25, ACID = 1.5) beauty_modifier = -0.1 -/datum/material/cardboard/on_applied_obj(obj/source, amount, material_flags) +/datum/material/cardboard/on_main_applied(atom/source, mat_amount, multiplier) . = ..() - if(material_flags & MATERIAL_AFFECT_STATISTICS) + if(isobj(source) && source.material_flags & MATERIAL_AFFECT_STATISTICS) var/obj/cardboard = source cardboard.resistance_flags |= FLAMMABLE cardboard.obj_flags |= UNIQUE_RENAME -/datum/material/cardboard/on_removed_obj(obj/source, amount, material_flags) - if(material_flags & MATERIAL_AFFECT_STATISTICS) +/datum/material/cardboard/on_main_removed(atom/source, mat_amount, multiplier) + if(isobj(source) && source.material_flags & MATERIAL_AFFECT_STATISTICS) var/obj/cardboard = source cardboard.resistance_flags &= ~FLAMMABLE return ..() @@ -585,8 +690,12 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "bone" desc = "Man, building with this will make you the coolest caveman on the block." color = "#e3dac9" - greyscale_colors = "#e3dac9" - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/bone value_per_unit = 100 / SHEET_MATERIAL_AMOUNT armor_modifiers = list(MELEE = 1.2, BULLET = 0.75, LASER = 0.75, ENERGY = 1.2, BOMB = 1, BIO = 1, FIRE = 1.5, ACID = 1.5) @@ -596,8 +705,12 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "bamboo" desc = "If it's good enough for pandas, it's good enough for you." color = "#87a852" - greyscale_colors = "#87a852" - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/bamboo value_per_unit = 5 / SHEET_MATERIAL_AMOUNT armor_modifiers = list(MELEE = 0.5, BULLET = 0.5, LASER = 0.5, ENERGY = 0.5, BOMB = 0.5, BIO = 0.51, FIRE = 0.5, ACID = 1.5) @@ -609,8 +722,12 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "zaukerite" desc = "A light absorbing crystal" color = COLOR_ALMOST_BLACK - greyscale_colors = COLOR_ALMOST_BLACK - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/zaukerite value_per_unit = 900 / SHEET_MATERIAL_AMOUNT armor_modifiers = list(MELEE = 0.9, BULLET = 0.9, LASER = 1.75, ENERGY = 1.75, BOMB = 0.5, BIO = 1, FIRE = 0.1, ACID = 1) diff --git a/code/datums/materials/hauntium.dm b/code/datums/materials/hauntium.dm index 79e254417208d..b8eee26a08f36 100644 --- a/code/datums/materials/hauntium.dm +++ b/code/datums/materials/hauntium.dm @@ -2,10 +2,15 @@ name = "hauntium" desc = "very scary!" color = list(460/255, 464/255, 460/255, 0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0) - greyscale_colors = "#FFFFFF64" + greyscale_color = "#FFFFFF" alpha = 100 starlight_color = COLOR_ALMOST_BLACK - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/hauntium value_per_unit = 0.05 beauty_modifier = 0.25 @@ -13,10 +18,14 @@ strength_modifier = 1.2 armor_modifiers = list(MELEE = 1.1, BULLET = 1.1, LASER = 1.15, ENERGY = 1.15, BOMB = 1, BIO = 1, FIRE = 1, ACID = 0.7) -/datum/material/hauntium/on_applied_obj(obj/o, amount, material_flags) +/datum/material/hauntium/on_main_applied(atom/source, mat_amount, multiplier) . = ..() - o.make_haunted(INNATE_TRAIT, "#f8f8ff") + if(isobj(source)) + var/obj/obj = source + obj.make_haunted(INNATE_TRAIT, "#f8f8ff") -/datum/material/hauntium/on_removed_obj(obj/o, amount, material_flags) +/datum/material/hauntium/on_main_removed(atom/source, mat_amount, multiplier) . = ..() - o.remove_haunted(INNATE_TRAIT) + if(isobj(source)) + var/obj/obj = source + obj.remove_haunted(INNATE_TRAIT) diff --git a/code/datums/materials/meat.dm b/code/datums/materials/meat.dm index 552fa7a84cdf2..008099a526e93 100644 --- a/code/datums/materials/meat.dm +++ b/code/datums/materials/meat.dm @@ -4,8 +4,12 @@ desc = "Meat" id = /datum/material/meat // So the bespoke versions are categorized under this color = rgb(214, 67, 67) - greyscale_colors = rgb(214, 67, 67) - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/meat value_per_unit = 0.05 beauty_modifier = -0.3 @@ -15,33 +19,28 @@ turf_sound_override = FOOTSTEP_MEAT texture_layer_icon_state = "meat" -/datum/material/meat/on_removed(atom/source, amount, material_flags) +/datum/material/meat/on_main_applied(atom/source, mat_amount, multiplier) . = ..() - qdel(source.GetComponent(/datum/component/edible)) - qdel(source.GetComponent(/datum/component/blood_walk)) - qdel(source.GetComponent(/datum/component/bloody_spreader)) + if(!IS_EDIBLE(source)) + make_edible(source, mat_amount, multiplier) -/datum/material/meat/on_applied_obj(obj/O, amount, material_flags) +/datum/material/meat/on_applied(atom/source, mat_amount, multiplier) . = ..() - make_meaty(O, amount, material_flags) + if(IS_EDIBLE(source)) + make_edible(source, mat_amount, multiplier) -/datum/material/meat/on_applied_turf(turf/T, amount, material_flags) - . = ..() - make_meaty(T, amount, material_flags) - -/datum/material/meat/proc/make_meaty(atom/source, amount, material_flags) - var/nutriment_count = 3 * (amount / SHEET_MATERIAL_AMOUNT) - var/oil_count = 2 * (amount / SHEET_MATERIAL_AMOUNT) +/datum/material/meat/proc/make_edible(atom/source, mat_amount, multiplier) + var/nutriment_count = 3 * (mat_amount / SHEET_MATERIAL_AMOUNT) + var/oil_count = 2 * (mat_amount / SHEET_MATERIAL_AMOUNT) source.AddComponent(/datum/component/edible, \ initial_reagents = list(/datum/reagent/consumable/nutriment = nutriment_count, /datum/reagent/consumable/nutriment/fat/oil = oil_count), \ foodtypes = RAW | MEAT | GROSS, \ eat_time = 3 SECONDS, \ tastes = list("Meaty")) - source.AddComponent( /datum/component/bloody_spreader,\ - blood_left = (nutriment_count + oil_count) * 0.3,\ + blood_left = (nutriment_count + oil_count) * 0.3 * multiplier,\ blood_dna = list("meaty DNA" = "MT-"),\ diseases = null,\ ) @@ -54,9 +53,18 @@ /datum/component/blood_walk,\ blood_type = /obj/effect/decal/cleanable/blood,\ blood_spawn_chance = 35,\ - max_blood = (nutriment_count + oil_count) * 0.3,\ + max_blood = (nutriment_count + oil_count) * 0.3 * multiplier,\ ) +/datum/material/meat/on_removed(atom/source, mat_amount, multiplier) + . = ..() + qdel(source.GetComponent(/datum/component/blood_walk)) + qdel(source.GetComponent(/datum/component/bloody_spreader)) + +/datum/material/meat/on_main_removed(atom/source, mat_amount, multiplier) + . = ..() + qdel(source.GetComponent(/datum/component/edible)) + /datum/material/meat/mob_meat init_flags = MATERIAL_INIT_BESPOKE var/subjectname = "" diff --git a/code/datums/materials/pizza.dm b/code/datums/materials/pizza.dm index 588018576befe..1906e5786d238 100644 --- a/code/datums/materials/pizza.dm +++ b/code/datums/materials/pizza.dm @@ -2,8 +2,12 @@ name = "pizza" desc = "~Jamme, jamme, n'coppa, jamme ja! Jamme, jamme, n'coppa jamme ja, funi-culi funi-cala funi-culi funi-cala!! Jamme jamme ja funiculi funicula!~" color = "#FF9F23" - greyscale_colors = "#FF9F23" - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/pizza value_per_unit = 0.05 beauty_modifier = 0.1 @@ -13,23 +17,25 @@ turf_sound_override = FOOTSTEP_MEAT texture_layer_icon_state = "pizza" -/datum/material/pizza/on_removed(atom/source, amount, material_flags) +/datum/material/pizza/on_main_applied(atom/source, mat_amount, multiplier) . = ..() - qdel(source.GetComponent(/datum/component/edible)) - -/datum/material/pizza/on_applied_obj(obj/O, amount, material_flags) - . = ..() - make_edible(O, amount, material_flags) + if(!IS_EDIBLE(source)) + make_edible(source, mat_amount) -/datum/material/pizza/on_applied_turf(turf/T, amount, material_flags) +/datum/material/pizza/on_applied(atom/source, mat_amount, multiplier) . = ..() - make_edible(T, amount, material_flags) + if(IS_EDIBLE(source)) + make_edible(source, mat_amount) -/datum/material/pizza/proc/make_edible(atom/source, amount, material_flags) - var/nutriment_count = 3 * (amount / SHEET_MATERIAL_AMOUNT) - var/oil_count = 2 * (amount / SHEET_MATERIAL_AMOUNT) +/datum/material/pizza/proc/make_edible(atom/source, mat_amount) + var/nutriment_count = 3 * (mat_amount / SHEET_MATERIAL_AMOUNT) + var/oil_count = 2 * (mat_amount / SHEET_MATERIAL_AMOUNT) source.AddComponent(/datum/component/edible, \ initial_reagents = list(/datum/reagent/consumable/nutriment = nutriment_count, /datum/reagent/consumable/nutriment/fat/oil = oil_count), \ foodtypes = GRAIN | MEAT | DAIRY | VEGETABLES, \ eat_time = 3 SECONDS, \ tastes = list("crust", "tomato", "cheese", "meat")) + +/datum/material/pizza/on_main_removed(atom/source, mat_amount, multiplier) + . = ..() + qdel(source.GetComponent(/datum/component/edible)) diff --git a/code/datums/mood_events/dna_infuser_events.dm b/code/datums/mood_events/dna_infuser_events.dm index 6da7235cfc1da..26c07d76b111e 100644 --- a/code/datums/mood_events/dna_infuser_events.dm +++ b/code/datums/mood_events/dna_infuser_events.dm @@ -7,3 +7,11 @@ description = "There's a lot that could be on your mind right now. But this feeling of contentedness, a universal calling to simply sit back and observe is washing over you..." mood_change = 10 special_screen_obj = "mood_gondola" + +/datum/mood_event/fish_waterless + mood_change = -3 + description = "It sucks to be dry. I feel like a fish out of water." + +/datum/mood_event/fish_water + mood_change = 1 + description = "Glug glug!" diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm index 695bf43949653..30999a874b77b 100644 --- a/code/datums/mood_events/generic_negative_events.dm +++ b/code/datums/mood_events/generic_negative_events.dm @@ -501,3 +501,8 @@ // Felinids apparently hate being hit over the head with cardboard if(isfelinid(owner)) mood_change = -2 + +/datum/mood_event/encountered_evil + description = "I didn't want to believe it, but there are people out there that are genuinely evil." + mood_change = -4 + timeout = 1 MINUTES diff --git a/code/datums/mutations/antenna.dm b/code/datums/mutations/antenna.dm index 5684b20c454f7..7730ab16d9cc9 100644 --- a/code/datums/mutations/antenna.dm +++ b/code/datums/mutations/antenna.dm @@ -96,6 +96,11 @@ to_chat(owner, span_warning("You plunge into your mind... Yep, it's your mind.")) return + if(HAS_TRAIT(cast_on, TRAIT_EVIL)) + to_chat(owner, span_warning("As you reach into [cast_on]'s mind, \ + you feel the overwhelming emptiness within. A truly evil being. \ + [HAS_TRAIT(owner, TRAIT_EVIL) ? "It's nice to find someone who is like-minded." : "What is wrong with this person?"]")) + to_chat(owner, span_boldnotice("You plunge into [cast_on]'s mind...")) if(prob(20)) // chance to alert the read-ee diff --git a/code/datums/position_point_vector.dm b/code/datums/position_point_vector.dm index c963d0ad76025..b8b697c053bca 100644 --- a/code/datums/position_point_vector.dm +++ b/code/datums/position_point_vector.dm @@ -91,9 +91,9 @@ /datum/point/proc/initialize_location(tile_x, tile_y, tile_z, p_x = 0, p_y = 0) if(!isnull(tile_x)) - x = ((tile_x - 1) * world.icon_size) + world.icon_size * 0.5 + p_x + 1 + x = ((tile_x - 1) * ICON_SIZE_X) + ICON_SIZE_X * 0.5 + p_x + 1 if(!isnull(tile_y)) - y = ((tile_y - 1) * world.icon_size) + world.icon_size * 0.5 + p_y + 1 + y = ((tile_y - 1) * ICON_SIZE_Y) + ICON_SIZE_Y * 0.5 + p_y + 1 if(!isnull(tile_z)) z = tile_z @@ -107,23 +107,23 @@ AM.pixel_y = return_py() /datum/point/proc/return_turf() - return locate(CEILING(x / world.icon_size, 1), CEILING(y / world.icon_size, 1), z) + return locate(CEILING(x / ICON_SIZE_X, 1), CEILING(y / ICON_SIZE_Y, 1), z) /datum/point/proc/return_coordinates() //[turf_x, turf_y, z] - return list(CEILING(x / world.icon_size, 1), CEILING(y / world.icon_size, 1), z) + return list(CEILING(x / ICON_SIZE_X, 1), CEILING(y / ICON_SIZE_Y, 1), z) /datum/point/proc/return_position() return new /datum/position(src) /datum/point/proc/return_px() - return MODULUS(x, world.icon_size) - 16 - 1 + return MODULUS(x, ICON_SIZE_X) - (ICON_SIZE_X/2) - 1 /datum/point/proc/return_py() - return MODULUS(y, world.icon_size) - 16 - 1 + return MODULUS(y, ICON_SIZE_Y) - (ICON_SIZE_Y/2) - 1 /datum/point/vector /// Pixels per iteration - var/speed = 32 + var/speed = ICON_SIZE_ALL var/iteration = 0 var/angle = 0 /// Calculated x movement amounts to prevent having to do trig every step. @@ -149,9 +149,9 @@ /// Same effect as initiliaze_location, but without setting the starting_x/y/z /datum/point/vector/proc/set_location(tile_x, tile_y, tile_z, p_x = 0, p_y = 0) if(!isnull(tile_x)) - x = ((tile_x - 1) * world.icon_size) + world.icon_size * 0.5 + p_x + 1 + x = ((tile_x - 1) * ICON_SIZE_X) + ICON_SIZE_X * 0.5 + p_x + 1 if(!isnull(tile_y)) - y = ((tile_y - 1) * world.icon_size) + world.icon_size * 0.5 + p_y + 1 + y = ((tile_y - 1) * ICON_SIZE_Y) + ICON_SIZE_Y * 0.5 + p_y + 1 if(!isnull(tile_z)) z = tile_z diff --git a/code/datums/progressbar.dm b/code/datums/progressbar.dm index b560a67aa6c90..676cf455bfc51 100644 --- a/code/datums/progressbar.dm +++ b/code/datums/progressbar.dm @@ -69,8 +69,8 @@ continue progress_bar.listindex-- - progress_bar.bar.pixel_y = world.icon_size + offset_y + (PROGRESSBAR_HEIGHT * (progress_bar.listindex - 1)) - var/dist_to_travel = world.icon_size + offset_y + (PROGRESSBAR_HEIGHT * (progress_bar.listindex - 1)) - PROGRESSBAR_HEIGHT + progress_bar.bar.pixel_y = ICON_SIZE_Y + offset_y + (PROGRESSBAR_HEIGHT * (progress_bar.listindex - 1)) + var/dist_to_travel = ICON_SIZE_Y + offset_y + (PROGRESSBAR_HEIGHT * (progress_bar.listindex - 1)) - PROGRESSBAR_HEIGHT animate(progress_bar.bar, pixel_y = dist_to_travel, time = PROGRESSBAR_ANIMATION_TIME, easing = SINE_EASING) LAZYREMOVEASSOC(user.progressbars, bar_loc, src) @@ -123,7 +123,7 @@ bar.pixel_y = 0 bar.alpha = 0 user_client.images += bar - animate(bar, pixel_y = world.icon_size + offset_y + (PROGRESSBAR_HEIGHT * (listindex - 1)), alpha = 255, time = PROGRESSBAR_ANIMATION_TIME, easing = SINE_EASING) + animate(bar, pixel_y = ICON_SIZE_Y + offset_y + (PROGRESSBAR_HEIGHT * (listindex - 1)), alpha = 255, time = PROGRESSBAR_ANIMATION_TIME, easing = SINE_EASING) ///Updates the progress bar image visually. diff --git a/code/datums/quirks/negative_quirks/prosopagnosia.dm b/code/datums/quirks/negative_quirks/prosopagnosia.dm index 8634e13bf638c..9b41713e6cef9 100644 --- a/code/datums/quirks/negative_quirks/prosopagnosia.dm +++ b/code/datums/quirks/negative_quirks/prosopagnosia.dm @@ -7,3 +7,19 @@ medical_record_text = "Patient suffers from prosopagnosia and cannot recognize faces." hardcore_value = 5 mail_goodies = list(/obj/item/skillchip/appraiser) // bad at recognizing faces but good at recognizing IDs + +/datum/quirk/prosopagnosia/add(client/client_source) + RegisterSignal(quirk_holder, COMSIG_MOB_REQUESTING_SCREENTIP_NAME_FROM_USER, PROC_REF(screentip_name_override)) + quirk_holder.mob_flags |= MOB_HAS_SCREENTIPS_NAME_OVERRIDE + +/datum/quirk/prosopagnosia/remove() + UnregisterSignal(quirk_holder, COMSIG_MOB_REQUESTING_SCREENTIP_NAME_FROM_USER) + +/datum/quirk/prosopagnosia/proc/screentip_name_override(datum/source, list/returned_name, obj/item/held_item, atom/hovered) + SIGNAL_HANDLER + + if(!ishuman(hovered)) + return NONE + + returned_name[1] = "Unknown" + return SCREENTIP_NAME_SET diff --git a/code/datums/quirks/neutral_quirks/evil.dm b/code/datums/quirks/neutral_quirks/evil.dm new file mode 100644 index 0000000000000..6753a7d034cfd --- /dev/null +++ b/code/datums/quirks/neutral_quirks/evil.dm @@ -0,0 +1,12 @@ +/datum/quirk/evil + name = "Fundamentally Evil" + desc = "Where you would have a soul is but an ink-black void. While you are committed to maintaining your social standing, \ + anyone who stares too long into your cold, uncaring eyes will know the truth. You are truly evil. There is nothing \ + wrong with you. You chose to be evil, committed to it. Your ambitions come first above all." + icon = FA_ICON_HAND_MIDDLE_FINGER + value = 0 + mob_trait = TRAIT_EVIL + gain_text = span_notice("You shed what little remains of your humanity. You have work to do.") + lose_text = span_notice("You suddenly care more about others and their needs.") + medical_record_text = "Patient has passed all our social fitness tests with flying colours, but had trouble on the empathy tests." + mail_goodies = list(/obj/item/food/grown/citrus/lemon) diff --git a/code/datums/ruins/icemoon.dm b/code/datums/ruins/icemoon.dm index ec34f51bdedb4..5cc2bf6a24ba6 100644 --- a/code/datums/ruins/icemoon.dm +++ b/code/datums/ruins/icemoon.dm @@ -61,6 +61,12 @@ description = "Moffuchi's Family Pizzeria chain has a reputation for providing affordable artisanal meals of questionable edibility. This particular pizzeria seems to have been abandoned for some time." suffix = "icemoon_surface_pizza.dmm" +/datum/map_template/ruin/icemoon/Lodge + name = "Ice-Ruin Hunters Lodge" + id = "lodge" + description = "An old hunting hunting lodge. I wonder if anyone is still home?" + suffix = "icemoon_surface_lodge.dmm" + /datum/map_template/ruin/icemoon/frozen_phonebooth name = "Ice-Ruin Frozen Phonebooth" id = "frozen_phonebooth" diff --git a/code/datums/ruins/space.dm b/code/datums/ruins/space.dm index 790ae33ade4b1..f2d76d9b86e6e 100644 --- a/code/datums/ruins/space.dm +++ b/code/datums/ruins/space.dm @@ -513,3 +513,25 @@ suffix = "hauntedtradingpost.dmm" name = "Space-Ruin Donk Co. Interstellar Trading Post 6016" description = "A small station for trading ships to dock at. It's been abandoned for some time, but its security systems have kept looters away. Rumored to be haunted." + +/datum/map_template/ruin/space/commsbuoy + id = "commsbuoy" + suffix = "commsbuoy_lowtech.dmm" + name = "Kosmokomm Communications Buoy" + description = "One of the SSC's many Comms Buoys, acting as a broadcaster, receiver and relay for interstellar communications. Due to the \ + shoddy tech available, it does not enable local communications." + +/datum/map_template/ruin/space/commsbuoy_pirate + id = "commsbuoy_pirate" + suffix = "commsbuoy_pirate.dmm" + name = "Pirated Communications Buoy" + description = "A Comms Buoy satellite that has been hijacked by local criminal elements, acting as a broadcaster, receiver and relay for \ + evil interstellar communications. Due to the shoddy tech available, it does not enable local communications." + +/datum/map_template/ruin/space/commsbuoy_nt + id = "commsbuoy_nt" + suffix = "commsbuoy_nt.dmm" + name = "Nanotrasen Model-7 Communications Buoy" + description = "One of Nanotrasen's highly advanced Communication Buoys. Besides acting as a broadcaster, receiver and relay for interstellar \ + communications, the satellite also includes a Local-Network array and two multi-function satellite dishes, providing the local sector with \ + connectivity - as long as you have your Employee ID handy. Though, this one has been reported to have some recent malfunctions." diff --git a/code/datums/shuttles/emergency.dm b/code/datums/shuttles/emergency.dm index 2af1a238a7258..3662727fa5c9a 100644 --- a/code/datums/shuttles/emergency.dm +++ b/code/datums/shuttles/emergency.dm @@ -31,13 +31,13 @@ mobile.event_list.Cut() if(use_all_events) for(var/path in events) - mobile.event_list.Add(new path(mobile)) + mobile.add_shuttle_event(path) events -= path else for(var/i in 1 to event_amount) var/path = pick_weight(events) events -= path - mobile.event_list.Add(new path(mobile)) + mobile.add_shuttle_event(path) /datum/map_template/shuttle/emergency/backup suffix = "backup" diff --git a/code/datums/sprite_accessories.dm b/code/datums/sprite_accessories.dm index b216fe9c8269a..344ef6abfad0e 100644 --- a/code/datums/sprite_accessories.dm +++ b/code/datums/sprite_accessories.dm @@ -1758,6 +1758,23 @@ /// Describes which tail spine sprites to use, if any. var/spine_key = NONE +///Used for fish-infused tails, which come in different flavors. +/datum/sprite_accessory/tails/fish + icon = 'icons/mob/human/fish_features.dmi' + color_src = HAIR_COLOR + +/datum/sprite_accessory/tails/fish/default + name = "Fish" + icon_state = "fish" + +/datum/sprite_accessory/tails/fish/shark + name = "Shark" + icon_state = "shark" + +/datum/sprite_accessory/tails/fish/orca + name = "Orca" + icon_state = "orca" + /datum/sprite_accessory/tails/lizard icon = 'icons/mob/human/species/lizard/lizard_tails.dmi' spine_key = SPINE_KEY_LIZARD @@ -1790,7 +1807,7 @@ icon_state = "short" spine_key = NONE -/datum/sprite_accessory/tails/human/cat +/datum/sprite_accessory/tails/felinid/cat name = "Cat" icon = 'icons/mob/human/cat_features.dmi' icon_state = "default" diff --git a/code/datums/station_traits/negative_traits.dm b/code/datums/station_traits/negative_traits.dm index 8b5aadb3a06d6..b113589b70226 100644 --- a/code/datums/station_traits/negative_traits.dm +++ b/code/datums/station_traits/negative_traits.dm @@ -756,4 +756,13 @@ advisory_string += "The ongoing blizzard has interfered with our surveillance equipment, and we cannot provide an accurate threat summary at this time. We advise you to stay safe and avoid traversing the area around the station." return advisory_string +/datum/station_trait/spiked_drinks + name = "Spiked Drinks" + trait_type = STATION_TRAIT_NEGATIVE + weight = 3 + cost = STATION_TRAIT_COST_LOW + show_in_report = TRUE + report_message = "Due to a mishap at the Robust Softdrinks Megafactory, some drinks may contain traces of ethanol or psychoactive chemicals." + trait_to_give = STATION_TRAIT_SPIKED_DRINKS + #undef GLOW_NEBULA diff --git a/code/datums/station_traits/neutral_traits.dm b/code/datums/station_traits/neutral_traits.dm index 5432701992b29..7d83439b6d494 100644 --- a/code/datums/station_traits/neutral_traits.dm +++ b/code/datums/station_traits/neutral_traits.dm @@ -544,3 +544,47 @@ dynamic_category = RULESET_CATEGORY_NO_WITTING_CREW_ANTAGONISTS threat_reduction = 15 dynamic_threat_id = "Background Checks" + + +/datum/station_trait/pet_day + name = "Bring Your Pet To Work Day" + trait_type = STATION_TRAIT_NEUTRAL + show_in_report = FALSE + weight = 2 + sign_up_button = TRUE + +/datum/station_trait/pet_day/New() + . = ..() + RegisterSignal(SSdcs, COMSIG_GLOB_JOB_AFTER_SPAWN, PROC_REF(on_job_after_spawn)) + +/datum/station_trait/pet_day/setup_lobby_button(atom/movable/screen/lobby/button/sign_up/lobby_button) + lobby_button.desc = "Want to bring your innocent pet to a giant metal deathtrap? Click here to customize it!" + RegisterSignal(lobby_button, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_lobby_button_update_overlays)) + return ..() + +/datum/station_trait/pet_day/can_display_lobby_button(client/player) + return sign_up_button + +/datum/station_trait/pet_day/on_round_start() + return + +/datum/station_trait/pet_day/on_lobby_button_click(atom/movable/screen/lobby/button/sign_up/lobby_button, updates) + var/mob/our_player = lobby_button.get_mob() + var/client/player_client = our_player.client + if(isnull(player_client)) + return + var/datum/pet_customization/customization = GLOB.customized_pets[REF(player_client)] + if(isnull(customization)) + customization = new(player_client) + INVOKE_ASYNC(customization, TYPE_PROC_REF(/datum, ui_interact), our_player) + +/datum/station_trait/pet_day/proc/on_job_after_spawn(datum/source, datum/job/job, mob/living/spawned, client/player_client) + SIGNAL_HANDLER + + var/datum/pet_customization/customization = GLOB.customized_pets[REF(player_client)] + if(isnull(customization)) + return + INVOKE_ASYNC(customization, TYPE_PROC_REF(/datum/pet_customization, create_pet), spawned, player_client) + +/datum/station_trait/pet_day/proc/on_lobby_button_update_overlays(atom/movable/screen/lobby/button/sign_up/lobby_button, list/overlays) + overlays += "select_pet" diff --git a/code/datums/status_effects/debuffs/debuffs.dm b/code/datums/status_effects/debuffs/debuffs.dm index 865e9869ebeea..5dab783eb37a0 100644 --- a/code/datums/status_effects/debuffs/debuffs.dm +++ b/code/datums/status_effects/debuffs/debuffs.dm @@ -245,7 +245,7 @@ var/mob/living/carbon/carbon_owner = owner carbon_owner.handle_dreams() - if(prob(2) && owner.health > owner.crit_threshold) + if(prob(8) && owner.health > owner.crit_threshold) owner.emote("snore") /atom/movable/screen/alert/status_effect/asleep diff --git a/code/datums/status_effects/debuffs/fire_stacks.dm b/code/datums/status_effects/debuffs/fire_stacks.dm index ae7f73d4e0de0..a575d2619fe7d 100644 --- a/code/datums/status_effects/debuffs/fire_stacks.dm +++ b/code/datums/status_effects/debuffs/fire_stacks.dm @@ -300,12 +300,45 @@ enemy_types = list(/datum/status_effect/fire_handler/fire_stacks) stack_modifier = -1 + ///If the mob has the TRAIT_SLIPPERY_WHEN_WET trait, the mob gets this component while it's wet + var/datum/component/slippery/slipperiness + +/datum/status_effect/fire_handler/wet_stacks/on_apply() + . = ..() + RegisterSignals(owner, list(SIGNAL_ADDTRAIT(TRAIT_WET_FOR_LONGER), SIGNAL_REMOVETRAIT(TRAIT_WET_FOR_LONGER)), PROC_REF(update_wet_stack_modifier)) + update_wet_stack_modifier() + RegisterSignal(owner, SIGNAL_ADDTRAIT(TRAIT_SLIPPERY_WHEN_WET), PROC_REF(become_slippery)) + RegisterSignal(owner, SIGNAL_REMOVETRAIT(TRAIT_SLIPPERY_WHEN_WET), PROC_REF(no_longer_slippery)) + if(HAS_TRAIT(owner, TRAIT_SLIPPERY_WHEN_WET)) + become_slippery() + ADD_TRAIT(owner, TRAIT_IS_WET, TRAIT_STATUS_EFFECT(id)) + +/datum/status_effect/fire_handler/wet_stacks/on_remove() + . = ..() + REMOVE_TRAIT(owner, TRAIT_IS_WET, TRAIT_STATUS_EFFECT(id)) + if(HAS_TRAIT(owner, TRAIT_SLIPPERY_WHEN_WET)) + no_longer_slippery() + +/datum/status_effect/fire_handler/wet_stacks/proc/update_wet_stack_modifier() + SIGNAL_HANDLER + stack_modifier = HAS_TRAIT(owner, TRAIT_WET_FOR_LONGER) ? -3.5 : -1 + +/datum/status_effect/fire_handler/wet_stacks/proc/become_slippery() + SIGNAL_HANDLER + slipperiness = owner.AddComponent(/datum/component/slippery, 5 SECONDS, lube_flags = SLIPPERY_WHEN_LYING_DOWN) + ADD_TRAIT(owner, TRAIT_NO_SLIP_WATER, TRAIT_STATUS_EFFECT(id)) + +/datum/status_effect/fire_handler/wet_stacks/proc/no_longer_slippery() + SIGNAL_HANDLER + QDEL_NULL(slipperiness) + REMOVE_TRAIT(owner, TRAIT_NO_SLIP_WATER, TRAIT_STATUS_EFFECT(id)) /datum/status_effect/fire_handler/wet_stacks/get_examine_text() return "[owner.p_They()] look[owner.p_s()] a little soaked." /datum/status_effect/fire_handler/wet_stacks/tick(seconds_between_ticks) - adjust_stacks(-0.5 * seconds_between_ticks) + var/decay = HAS_TRAIT(owner, TRAIT_WET_FOR_LONGER) ? -0.035 : -0.5 + adjust_stacks(decay * seconds_between_ticks) if(stacks <= 0) qdel(src) diff --git a/code/datums/status_effects/neutral.dm b/code/datums/status_effects/neutral.dm index 6fd10943b7edf..8737cacede317 100644 --- a/code/datums/status_effects/neutral.dm +++ b/code/datums/status_effects/neutral.dm @@ -609,3 +609,38 @@ /datum/status_effect/gutted/proc/stop_gutting() SIGNAL_HANDLER qdel(src) + +/atom/movable/screen/alert/status_effect/shower_regen + name = "Washing" + desc = "A good wash fills me with energy!" + icon_state = "shower_regen" + +/atom/movable/screen/alert/status_effect/shower_regen/hater + name = "Washing" + desc = "Waaater... Fuck this WATER!!" + icon_state = "shower_regen_hater" + +/datum/status_effect/shower_regen + id = "shower_regen" + duration = -1 + status_type = STATUS_EFFECT_UNIQUE + alert_type = /atom/movable/screen/alert/status_effect/shower_regen + /// How many heals from washing. + var/stamina_heal_per_tick = 4 + +/datum/status_effect/shower_regen/on_apply() + . = ..() + if(HAS_TRAIT(owner, TRAIT_WATER_HATER) && !HAS_TRAIT(owner, TRAIT_WATER_ADAPTATION)) + alert_type = /atom/movable/screen/alert/status_effect/shower_regen/hater + +/datum/status_effect/shower_regen/tick(seconds_between_ticks) + . = ..() + var/water_adaptation = HAS_TRAIT(owner, TRAIT_WATER_ADAPTATION) + var/heal_or_deal = HAS_TRAIT(owner, TRAIT_WATER_HATER) && !water_adaptation ? 1 : -1 + if(water_adaptation) //very mild healing for those with the water adaptation trait (fish infusion) + owner.adjustOxyLoss(-1 * seconds_between_ticks, updating_health = FALSE, required_biotype = MOB_ORGANIC) + owner.adjustFireLoss(-0.6 * seconds_between_ticks, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC) + owner.adjustToxLoss(-0.6 * seconds_between_ticks, updating_health = FALSE, required_biotype = MOB_ORGANIC) + owner.adjustBruteLoss(-0.6 * seconds_between_ticks, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC) + heal_or_deal *= 1.5 + owner.adjustStaminaLoss(stamina_heal_per_tick * heal_or_deal * seconds_between_ticks) diff --git a/code/datums/status_effects/stacking_effect.dm b/code/datums/status_effects/stacking_effect.dm index b54734155ad92..b0d00a92ba0c2 100644 --- a/code/datums/status_effects/stacking_effect.dm +++ b/code/datums/status_effects/stacking_effect.dm @@ -123,9 +123,9 @@ var/icon_height = I.Height() status_overlay.pixel_x = -owner.pixel_x status_overlay.pixel_y = FLOOR(icon_height * 0.25, 1) - status_overlay.transform = matrix() * (icon_height/world.icon_size) //scale the status's overlay size based on the target's icon size + status_overlay.transform = matrix() * (icon_height/ICON_SIZE_Y) //scale the status's overlay size based on the target's icon size status_underlay.pixel_x = -owner.pixel_x - status_underlay.transform = matrix() * (icon_height/world.icon_size) * 3 + status_underlay.transform = matrix() * (icon_height/ICON_SIZE_Y) * 3 status_underlay.alpha = 40 owner.add_overlay(status_overlay) owner.underlays += status_underlay diff --git a/code/datums/status_effects/wound_effects.dm b/code/datums/status_effects/wound_effects.dm index fc3f3140593ea..30361dc9cf1a1 100644 --- a/code/datums/status_effects/wound_effects.dm +++ b/code/datums/status_effects/wound_effects.dm @@ -124,19 +124,6 @@ //////// WOUNDS ///////// ///////////////////////// -// wound alert -/atom/movable/screen/alert/status_effect/wound - name = "Wounded" - desc = "Your body has sustained serious damage, click here to inspect yourself." - -/atom/movable/screen/alert/status_effect/wound/Click() - . = ..() - if(!.) - return - - var/mob/living/carbon/carbon_owner = owner - carbon_owner.check_self_for_injuries() - // wound status effect base /datum/status_effect/wound id = "wound" diff --git a/code/datums/storage/subtypes/drone.dm b/code/datums/storage/subtypes/drone.dm new file mode 100644 index 0000000000000..2df8f4c627966 --- /dev/null +++ b/code/datums/storage/subtypes/drone.dm @@ -0,0 +1,26 @@ +/datum/storage/drone + max_total_storage = 40 + max_specific_storage = WEIGHT_CLASS_NORMAL + max_slots = 10 + do_rustle = FALSE + +/datum/storage/drone/New(atom/parent, max_slots, max_specific_storage, max_total_storage) + . = ..() + + var/static/list/drone_builtins = list( + /obj/item/crowbar/drone, + /obj/item/screwdriver/drone, + /obj/item/wrench/drone, + /obj/item/weldingtool/drone, + /obj/item/wirecutters/drone, + /obj/item/multitool/drone, + /obj/item/pipe_dispenser/drone, + /obj/item/t_scanner/drone, + /obj/item/analyzer/drone, + /obj/item/soap/drone, + ) + + set_holdable(drone_builtins) + +/datum/storage/drone/dump_content_at(atom/dest_object, dump_loc, mob/user) + return //no dumping of contents allowed diff --git a/code/datums/view.dm b/code/datums/view.dm index 90d07c667967c..702550a4e1874 100644 --- a/code/datums/view.dm +++ b/code/datums/view.dm @@ -134,7 +134,7 @@ _y = -offset if(WEST) _x = -offset - animate(chief, pixel_x = world.icon_size*_x, pixel_y = world.icon_size*_y, 0, FALSE, LINEAR_EASING, ANIMATION_END_NOW) + animate(chief, pixel_x = ICON_SIZE_X*_x, pixel_y = ICON_SIZE_Y*_y, 0, FALSE, LINEAR_EASING, ANIMATION_END_NOW) //Ready for this one? setTo(radius) diff --git a/code/datums/votes/map_vote.dm b/code/datums/votes/map_vote.dm index abe452ce4fedf..b4f938a42e451 100644 --- a/code/datums/votes/map_vote.dm +++ b/code/datums/votes/map_vote.dm @@ -2,29 +2,18 @@ name = "Map" default_message = "Vote for next round's map!" count_method = VOTE_COUNT_METHOD_SINGLE - winner_method = VOTE_WINNER_METHOD_WEIGHTED_RANDOM + winner_method = VOTE_WINNER_METHOD_NONE display_statistics = FALSE /datum/vote/map_vote/New() . = ..() - - default_choices = list() - - // Fill in our default choices with all of the maps in our map config, if they are votable and not blocked. - var/list/maps = shuffle(global.config.maplist) - for(var/map in maps) - var/datum/map_config/possible_config = config.maplist[map] - if(!possible_config.votable || (possible_config.map_name in SSpersistence.blocked_maps)) - continue - - default_choices += possible_config.map_name + default_choices = SSmap_vote.get_valid_map_vote_choices() /datum/vote/map_vote/create_vote() . = ..() if(!.) return FALSE - choices -= get_choices_invalid_for_population() if(length(choices) == 1) // Only one choice, no need to vote. Let's just auto-rotate it to the only remaining map because it would just happen anyways. var/datum/map_config/change_me_out = global.config.maplist[choices[1]] finalize_vote(choices[1])// voted by not voting, very sad. @@ -48,35 +37,16 @@ . = ..() if(. != VOTE_AVAILABLE) return . - if(forced) - return VOTE_AVAILABLE - var/num_choices = length(default_choices - get_choices_invalid_for_population()) + + var/num_choices = length(default_choices) if(num_choices <= 1) return "There [num_choices == 1 ? "is only one map" : "are no maps"] to choose from." - if(SSmapping.map_vote_rocked) - return VOTE_AVAILABLE - if(SSmapping.map_voted) + if(SSmap_vote.next_map_config) return "The next map has already been selected." return VOTE_AVAILABLE -/// Returns a list of all map options that are invalid for the current population. -/datum/vote/map_vote/proc/get_choices_invalid_for_population() - var/filter_threshold = 0 - if(SSticker.HasRoundStarted()) - filter_threshold = get_active_player_count(alive_check = FALSE, afk_check = TRUE, human_check = FALSE) - else - filter_threshold = GLOB.clients.len - - var/list/invalid_choices = list() - for(var/map in default_choices) - var/datum/map_config/possible_config = config.maplist[map] - if(possible_config.config_min_users > 0 && filter_threshold < possible_config.config_min_users) - invalid_choices += map - - else if(possible_config.config_max_users > 0 && filter_threshold > possible_config.config_max_users) - invalid_choices += map - - return invalid_choices +/datum/vote/map_vote/get_result_text(list/all_winners, real_winner, list/non_voters) + return null /datum/vote/map_vote/get_vote_result(list/non_voters) // Even if we have default no vote off, @@ -97,20 +67,4 @@ return ..() /datum/vote/map_vote/finalize_vote(winning_option) - var/datum/map_config/winning_map = global.config.maplist[winning_option] - if(!istype(winning_map)) - CRASH("[type] wasn't passed a valid winning map choice. (Got: [winning_option || "null"] - [winning_map || "null"])") - - SSmapping.changemap(winning_map) - SSmapping.map_voted = TRUE - if(SSmapping.map_vote_rocked) - SSmapping.map_vote_rocked = FALSE - -/proc/revert_map_vote() - var/datum/map_config/override_map = SSmapping.config - if(isnull(override_map)) - return - - SSmapping.changemap(override_map) - log_game("The next map has been reset to [override_map.map_name].") - send_to_playing_players(span_boldannounce("The next map is: [override_map.map_name].")) + SSmap_vote.finalize_map_vote(src) diff --git a/code/datums/votes/restart_vote.dm b/code/datums/votes/restart_vote.dm index 3c74d7e518e28..ba0fdf78083b1 100644 --- a/code/datums/votes/restart_vote.dm +++ b/code/datums/votes/restart_vote.dm @@ -57,10 +57,10 @@ return // If there was a previous map vote, we revert the change. - if(!isnull(SSmapping.next_map_config)) + if(!isnull(SSmap_vote.next_map_config)) log_game("The next map has been reset due to successful restart vote.") send_to_playing_players(span_boldannounce("The next map has been reset due to successful restart vote.")) - revert_map_vote() + SSmap_vote.revert_next_map() SSticker.force_ending = FORCE_END_ROUND log_game("End round forced by successful restart vote.") diff --git a/code/datums/votes/rock_the_vote.dm b/code/datums/votes/rock_the_vote.dm deleted file mode 100644 index 6c7ac4ff2572e..0000000000000 --- a/code/datums/votes/rock_the_vote.dm +++ /dev/null @@ -1,62 +0,0 @@ -#define CHOICE_TO_ROCK "Yes, re-do the map vote." -#define CHOICE_NOT_TO_ROCK "No, keep the currently selected map." - -/// If a map vote is called before the emergency shuttle leaves the station, the players can call another vote to re-run the vote on the shuttle leaving. -/datum/vote/rock_the_vote - name = "Rock the Vote" - override_question = "Rock the Vote?" - contains_vote_in_name = TRUE //lol - default_choices = list( - CHOICE_TO_ROCK, - CHOICE_NOT_TO_ROCK, - ) - default_message = "Override the current map vote." - /// The number of times we have rocked the vote thus far. - var/rocking_votes = 0 - -/datum/vote/rock_the_vote/toggle_votable() - CONFIG_SET(flag/allow_rock_the_vote, !CONFIG_GET(flag/allow_rock_the_vote)) - -/datum/vote/rock_the_vote/is_config_enabled() - return CONFIG_GET(flag/allow_rock_the_vote) - -/datum/vote/rock_the_vote/can_be_initiated(forced) - . = ..() - if(. != VOTE_AVAILABLE) - return . - - if(SSticker.current_state == GAME_STATE_FINISHED) - return "The game is finished, no map votes can be initiated." - - if(rocking_votes >= CONFIG_GET(number/max_rocking_votes)) - return "The maximum number of times to rock the vote has been reached." - - if(SSmapping.map_vote_rocked) - return "The vote has already been rocked! Initiate a map vote!" - - if(!SSmapping.map_voted) - return "Rocking the vote is disabled because no map has been voted on yet!" - - if(SSmapping.map_force_chosen) - return "Rocking the vote is disabled because an admin has forcibly set the map!" - - if(EMERGENCY_ESCAPED_OR_ENDGAMED && SSmapping.map_voted) - return "The emergency shuttle has already left the station and the next map has already been chosen!" - - return VOTE_AVAILABLE - -/datum/vote/rock_the_vote/finalize_vote(winning_option) - rocking_votes++ - if(winning_option == CHOICE_NOT_TO_ROCK) - return - - if(winning_option == CHOICE_TO_ROCK) - to_chat(world, span_boldannounce("The vote has been rocked! Players are now able to re-run the map vote once more.")) - message_admins("The players have successfully rocked the vote.") - SSmapping.map_vote_rocked = TRUE - return - - CRASH("[type] wasn't passed a valid winning choice. (Got: [winning_option || "null"])") - -#undef CHOICE_TO_ROCK -#undef CHOICE_NOT_TO_ROCK diff --git a/code/datums/weather/weather.dm b/code/datums/weather/weather.dm index df2518b4322c6..85e5e74b02fba 100644 --- a/code/datums/weather/weather.dm +++ b/code/datums/weather/weather.dm @@ -59,7 +59,7 @@ /// Since it's above everything else, this is the layer used by default. var/overlay_layer = AREA_LAYER /// Plane for the overlay - var/overlay_plane = AREA_PLANE + var/overlay_plane = WEATHER_PLANE /// If the weather has no purpose other than looks var/aesthetic = FALSE /// Used by mobs (or movables containing mobs, such as enviro bags) to prevent them from being affected by the weather. @@ -99,7 +99,7 @@ /datum/weather/proc/telegraph() if(stage == STARTUP_STAGE) return - SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_TELEGRAPH(type)) + SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_TELEGRAPH(type), src) stage = STARTUP_STAGE var/list/affectareas = list() for(var/V in get_areas(area_type)) @@ -129,14 +129,14 @@ /datum/weather/proc/start() if(stage >= MAIN_STAGE) return - SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_START(type)) + SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_START(type), src) stage = MAIN_STAGE update_areas() send_alert(weather_message, weather_sound) if(!perpetual) addtimer(CALLBACK(src, PROC_REF(wind_down)), weather_duration) for(var/area/impacted_area as anything in impacted_areas) - SEND_SIGNAL(impacted_area, COMSIG_WEATHER_BEGAN_IN_AREA(type)) + SEND_SIGNAL(impacted_area, COMSIG_WEATHER_BEGAN_IN_AREA(type), src) /** * Weather enters the winding down phase, stops effects @@ -148,7 +148,7 @@ /datum/weather/proc/wind_down() if(stage >= WIND_DOWN_STAGE) return - SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_WINDDOWN(type)) + SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_WINDDOWN(type), src) stage = WIND_DOWN_STAGE update_areas() send_alert(end_message, end_sound) @@ -164,12 +164,12 @@ /datum/weather/proc/end() if(stage == END_STAGE) return - SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_END(type)) + SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_END(type), src) stage = END_STAGE SSweather.processing -= src update_areas() for(var/area/impacted_area as anything in impacted_areas) - SEND_SIGNAL(impacted_area, COMSIG_WEATHER_ENDED_IN_AREA(type)) + SEND_SIGNAL(impacted_area, COMSIG_WEATHER_ENDED_IN_AREA(type), src) // handles sending all alerts /datum/weather/proc/send_alert(alert_msg, alert_sfx) @@ -260,12 +260,12 @@ // I prefer it to creating 2 extra plane masters however, so it's a cost I'm willing to pay // LU if(use_glow) - var/mutable_appearance/glow_overlay = mutable_appearance('icons/effects/glow_weather.dmi', weather_state, overlay_layer, null, ABOVE_LIGHTING_PLANE, 100, offset_const = offset) + var/mutable_appearance/glow_overlay = mutable_appearance('icons/effects/glow_weather.dmi', weather_state, overlay_layer, null, WEATHER_GLOW_PLANE, 100, offset_const = offset) glow_overlay.color = weather_color gen_overlay_cache += glow_overlay - var/mutable_appearance/weather_overlay = mutable_appearance('icons/effects/weather_effects.dmi', weather_state, overlay_layer, plane = overlay_plane, offset_const = offset) - weather_overlay.color = weather_color - gen_overlay_cache += weather_overlay + var/mutable_appearance/new_weather_overlay = mutable_appearance('icons/effects/weather_effects.dmi', weather_state, overlay_layer, plane = overlay_plane, offset_const = offset) + new_weather_overlay.color = weather_color + gen_overlay_cache += new_weather_overlay return gen_overlay_cache diff --git a/code/datums/world_topic.dm b/code/datums/world_topic.dm index f2bf896bb10b3..a9971f6068c98 100644 --- a/code/datums/world_topic.dm +++ b/code/datums/world_topic.dm @@ -212,7 +212,7 @@ .["admins"] = presentmins.len + afkmins.len //equivalent to the info gotten from adminwho .["gamestate"] = SSticker.current_state - .["map_name"] = SSmapping.config?.map_name || "Loading..." + .["map_name"] = SSmapping.current_map.map_name || "Loading..." if(key_valid) .["active_players"] = get_active_player_count() diff --git a/code/datums/wounds/_wounds.dm b/code/datums/wounds/_wounds.dm index 5e5258c86deb9..fdecc89680a54 100644 --- a/code/datums/wounds/_wounds.dm +++ b/code/datums/wounds/_wounds.dm @@ -203,8 +203,7 @@ if(status_effect_type) victim.apply_status_effect(status_effect_type, src) SEND_SIGNAL(victim, COMSIG_CARBON_GAIN_WOUND, src, limb) - if(!victim.alerts[ALERT_WOUNDED]) // only one alert is shared between all of the wounds - victim.throw_alert(ALERT_WOUNDED, /atom/movable/screen/alert/status_effect/wound) + victim.update_health_hud() var/demoted if(old_wound) @@ -348,13 +347,13 @@ if (ismob(old_victim)) var/mob/mob_victim = old_victim SEND_SIGNAL(mob_victim, COMSIG_CARBON_POST_LOSE_WOUND, src, old_limb, ignore_limb, replaced) + if(!replaced && !limb) + mob_victim.update_health_hud() /datum/wound/proc/remove_wound_from_victim() if(!victim) return LAZYREMOVE(victim.all_wounds, src) - if(!victim.all_wounds) - victim.clear_alert(ALERT_WOUNDED) SEND_SIGNAL(victim, COMSIG_CARBON_LOSE_WOUND, src, limb) /** diff --git a/code/game/area/areas/ruins/icemoon.dm b/code/game/area/areas/ruins/icemoon.dm index 061bd8f06d209..fa87fa832a1fb 100644 --- a/code/game/area/areas/ruins/icemoon.dm +++ b/code/game/area/areas/ruins/icemoon.dm @@ -57,6 +57,11 @@ /area/ruin/planetengi name = "\improper Engineering Outpost" +/area/ruin/huntinglodge + name = "\improper Hunting Lodge" + mood_bonus = -5 + mood_message = "Something feels off..." + /area/ruin/smoking_room/house name = "\improper Tobacco House" sound_environment = SOUND_ENVIRONMENT_CITY diff --git a/code/game/atom/_atom.dm b/code/game/atom/_atom.dm index ca4ae5635797a..691badb31c1d0 100644 --- a/code/game/atom/_atom.dm +++ b/code/game/atom/_atom.dm @@ -879,10 +879,18 @@ var/shift_lmb_ctrl_shift_lmb_line = "" var/extra_lines = 0 var/extra_context = "" + var/used_name = name if(isliving(user) || isovermind(user) || isaicamera(user) || (ghost_screentips && isobserver(user))) var/obj/item/held_item = user.get_active_held_item() + if (user.mob_flags & MOB_HAS_SCREENTIPS_NAME_OVERRIDE) + var/list/returned_name = list(used_name) + + var/name_override_returns = SEND_SIGNAL(user, COMSIG_MOB_REQUESTING_SCREENTIP_NAME_FROM_USER, returned_name, held_item, src) + if (name_override_returns & SCREENTIP_NAME_SET) + used_name = returned_name[1] + if (flags_1 & HAS_CONTEXTUAL_SCREENTIPS_1 || held_item?.item_flags & ITEM_HAS_CONTEXTUAL_SCREENTIPS) var/list/context = list() @@ -948,9 +956,9 @@ new_maptext = "" else //We inline a MAPTEXT() here, because there's no good way to statically add to a string like this - new_maptext = "[name][extra_context]" + new_maptext = "[used_name][extra_context]" - if (length(name) * 10 > active_hud.screentip_text.maptext_width) + if (length(used_name) * 10 > active_hud.screentip_text.maptext_width) INVOKE_ASYNC(src, PROC_REF(set_hover_maptext), client, active_hud, new_maptext) return diff --git a/code/game/atom/atom_materials.dm b/code/game/atom/atom_materials.dm index 345a8486dd60a..cb88c83f3eb8c 100644 --- a/code/game/atom/atom_materials.dm +++ b/code/game/atom/atom_materials.dm @@ -7,23 +7,276 @@ ///Modifier that raises/lowers the effect of the amount of a material, prevents small and easy to get items from being death machines. var/material_modifier = 1 -/// Sets the custom materials for an item. +/// Sets the custom materials for an atom. This is what you want to call, since most of the ones below are mainly internal. /atom/proc/set_custom_materials(list/materials, multiplier = 1) - if(custom_materials && material_flags & MATERIAL_EFFECTS) //Only runs if custom materials existed at first and affected src. - for(var/current_material in custom_materials) - var/datum/material/custom_material = GET_MATERIAL_REF(current_material) - custom_material.on_removed(src, OPTIMAL_COST(custom_materials[current_material] * material_modifier), material_flags) //Remove the current materials + SHOULD_NOT_OVERRIDE(TRUE) + if(length(custom_materials)) + remove_material_effects() if(!length(materials)) custom_materials = null return - if(material_flags & MATERIAL_EFFECTS) + initialize_materials(materials, multiplier) + +/** + * The second part of set_custom_materials(), which handles applying the new materials + * It is a separate proc because Initialize calls may make use of this since they should've no prior materials to remove. + */ +/atom/proc/initialize_materials(list/materials, multiplier = 1) + SHOULD_NOT_OVERRIDE(TRUE) + if(multiplier != 1) + materials = materials.Copy() //avoid editing the list that was originally used as argument if it's ever going to be used again. for(var/current_material in materials) - var/datum/material/custom_material = GET_MATERIAL_REF(current_material) - custom_material.on_applied(src, OPTIMAL_COST(materials[current_material] * multiplier * material_modifier), material_flags) + materials[current_material] *= multiplier + + apply_material_effects(materials) + custom_materials = SSmaterials.FindOrCreateMaterialCombo(materials) + +///proc responsible for applying material effects when setting materials. +/atom/proc/apply_material_effects(list/materials) + SHOULD_CALL_PARENT(TRUE) + if(!materials || !(material_flags & MATERIAL_EFFECTS)) + return + var/list/material_effects = get_material_effects_list(materials) + finalize_material_effects(material_effects) + +/// Proc responsible for removing material effects when setting materials. +/atom/proc/remove_material_effects() + SHOULD_CALL_PARENT(TRUE) + //Only runs if custom materials existed at first and affected src. + if(!custom_materials || !(material_flags & MATERIAL_EFFECTS)) + return + var/list/material_effects = get_material_effects_list(custom_materials) + finalize_remove_material_effects(material_effects) + +/atom/proc/get_material_effects_list(list/materials) + SHOULD_NOT_OVERRIDE(TRUE) + var/list/material_effects = list() + var/index = 1 + for(var/current_material in materials) + var/datum/material/material = GET_MATERIAL_REF(current_material) + material_effects[material] = list( + MATERIAL_LIST_OPTIMAL_AMOUNT = OPTIMAL_COST(materials[current_material] * material_modifier), + MATERIAL_LIST_MULTIPLIER = get_material_multiplier(material, materials, index), + ) + index++ + return material_effects + +/** + * A proc that can be used to selectively control the stat changes and effects from a material without affecting the others. + * + * For example, we can have items made of two different materials, with the primary contributing a good 1.2 multiplier + * and the second a meager 0.3. + * + * The GET_MATERIAL_MODIFIER macro will handles some modifications where the minimum should be 1 if above 1 and the maximum + * be 1 if below 1. Just don't return negative values. + */ +/atom/proc/get_material_multiplier(datum/material/custom_material, list/materials, index) + return 1/length(materials) + +///Called by apply_material_effects(). It ACTUALLY handles applying effects common to all atoms (depending on material flags) +/atom/proc/finalize_material_effects(list/materials) + SHOULD_CALL_PARENT(TRUE) + var/total_alpha = 0 + var/list/colors = list() + var/mat_length = length(materials) + var/datum/material/main_material //the material with the highest amount (after calculations) + var/main_mat_amount + var/main_mat_mult + for(var/datum/material/custom_material as anything in materials) + var/list/deets = materials[custom_material] + var/mat_amount = deets[MATERIAL_LIST_OPTIMAL_AMOUNT] + var/multiplier = deets[MATERIAL_LIST_MULTIPLIER] + if(mat_amount > main_mat_amount) + main_material = custom_material + main_mat_amount = mat_amount + main_mat_mult = multiplier + + apply_single_mat_effect(custom_material, mat_amount, multiplier) + custom_material.on_applied(src, mat_amount, multiplier) + + //Prevent changing things with pre-set colors, to keep colored toolboxes their looks for example + if(material_flags & (MATERIAL_COLOR|MATERIAL_GREYSCALE)) + gather_material_color(custom_material, colors, mat_amount, multicolor = mat_length > 1) + var/added_alpha = custom_material.alpha * (custom_material.alpha / 255) + total_alpha += GET_MATERIAL_MODIFIER(added_alpha, multiplier) + if(custom_material.beauty_modifier) + AddElement(/datum/element/beauty, custom_material.beauty_modifier * mat_amount) + + apply_main_material_effects(main_material, main_mat_amount, main_mat_mult) + + if(material_flags & (MATERIAL_COLOR|MATERIAL_GREYSCALE)) + var/init_alpha = initial(alpha) + var/alpha_value = (total_alpha / length(materials)) * init_alpha + + if(alpha_value < init_alpha * 0.9) + opacity = FALSE + + if(material_flags & MATERIAL_GREYSCALE) + var/config_path = get_material_greyscale_config(main_material.type, greyscale_config) + //Make sure that we've no less than the expected amount + //expected_colors is zero for paths, the value is assigned when reading the json files. + var/datum/greyscale_config/config = SSgreyscale.configurations["[config_path || greyscale_config]"] + var/colors_len = length(colors) + if(config.expected_colors > colors_len) + var/list/filled_colors = colors.Copy() + for(var/index in colors_len to config.expected_colors - 1) + filled_colors += pick(colors) + colors = filled_colors + set_greyscale(colors, config_path) + else if(length(colors)) + mix_material_colors(colors) + + if(material_flags & MATERIAL_ADD_PREFIX) + var/prefixes = get_material_prefixes(materials) + name = "[prefixes] [name]" + +/** + * A proc used by both finalize_material_effects() and finalize_remove_material_effects() to get the colors + * that will later be applied to or removed from the atom + */ +/atom/proc/gather_material_color(datum/material/material, list/colors, amount, multicolor = FALSE) + SHOULD_CALL_PARENT(TRUE) + if(!material.color) //the material has no color. Nevermind + return + var/color_to_add = material.color + var/istext = istext(color_to_add) + if(istext) + if(material.alpha != 255) + color_to_add += num2hex(material.alpha, 2) + else + if(multicolor || material_flags & MATERIAL_GREYSCALE) + color_to_add = material.greyscale_color || color_matrix2color_hex(material.color) + if(material.greyscale_color) + color_to_add += num2hex(material.alpha, 2) + else + color_to_add = color_to_full_rgba_matrix(color_to_add) + color_to_add[20] *= (material.alpha / 255) // multiply the constant alpha of the color matrix + + colors[color_to_add] += amount + +/// Manages mixing, adding or removing the material colors from the atom in absence of the MATERIAL_GREYSCALE flag. +/atom/proc/mix_material_colors(list/colors, remove = FALSE) + SHOULD_NOT_OVERRIDE(TRUE) + var/color_len = length(colors) + if(!color_len) + return + var/mixcolor = colors[1] + var/amount_divisor = colors[mixcolor] + for(var/i in 2 to length(colors)) + var/color_to_add = colors[i] + if(islist(color_to_add)) + color_to_add = color_matrix2color_hex(color_to_add) + var/mix_amount = colors[color_to_add] + amount_divisor += mix_amount + mixcolor = BlendRGB(mixcolor, color_to_add, mix_amount/amount_divisor) + if(remove) + remove_atom_colour(FIXED_COLOUR_PRIORITY, mixcolor) + else + add_atom_colour(mixcolor, FIXED_COLOUR_PRIORITY) + +///Returns the prefixes to attach to the atom when setting materials, from a list argument. +/atom/proc/get_material_prefixes(list/materials) + var/list/mat_names = list() + for(var/datum/material/material as anything in materials) + mat_names |= material.name + return mat_names.Join("-") + +///Returns a string like "plasma, paper and glass" from a list of materials +/atom/proc/get_material_english_list(list/materials) + var/list/mat_names = list() + for(var/datum/material/material as anything in materials) + mat_names += material.name + return english_list(mat_names) + +///Searches for a subtype of config_type that is to be used in its place for specific materials (like shimmering gold for cleric maces) +/atom/proc/get_material_greyscale_config(mat_type, config_type) + SHOULD_NOT_OVERRIDE(TRUE) + if(!config_type) + return + for(var/datum/greyscale_config/path as anything in subtypesof(config_type)) + if(mat_type != initial(path.material_skin)) + continue + return path + +///Apply material effects of a single material. +/atom/proc/apply_single_mat_effect(datum/material/custom_material, amount, multipier) + SHOULD_CALL_PARENT(TRUE) + return + +///A proc for material effects that only the main material (which the atom's primarly composed of) should apply. +/atom/proc/apply_main_material_effects(datum/material/main_material, amount, multipier) + SHOULD_CALL_PARENT(TRUE) + if(main_material.texture_layer_icon_state && material_flags & MATERIAL_COLOR) + ADD_KEEP_TOGETHER(src, MATERIAL_SOURCE(main_material)) + add_filter("material_texture_[main_material.name]", 1, layering_filter(icon = main_material.cached_texture_filter_icon, blend_mode = BLEND_INSET_OVERLAY)) + + main_material.on_main_applied(src, amount, multipier) + +///Called by remove_material_effects(). It ACTUALLY handles removing effects common to all atoms (depending on material flags) +/atom/proc/finalize_remove_material_effects(list/materials) + var/list/colors = list() + var/datum/material/main_material = get_master_material() + var/mat_length = length(materials) + var/main_mat_amount + var/main_mat_mult + for(var/datum/material/custom_material as anything in materials) + var/list/deets = materials[custom_material] + var/mat_amount = deets[MATERIAL_LIST_OPTIMAL_AMOUNT] + var/multiplier = deets[MATERIAL_LIST_MULTIPLIER] + if(custom_material == main_material) + main_mat_amount = mat_amount + main_mat_mult = multiplier + + remove_single_mat_effect(custom_material, mat_amount, multiplier) + custom_material.on_removed(src, mat_amount, multiplier) + if(material_flags & MATERIAL_COLOR) + gather_material_color(custom_material, colors, mat_amount, multicolor = mat_length > 1) + if(custom_material.beauty_modifier) + RemoveElement(/datum/element/beauty, custom_material.beauty_modifier * mat_amount) + + remove_main_material_effects(main_material, main_mat_amount, main_mat_mult) + + if(material_flags & (MATERIAL_GREYSCALE|MATERIAL_COLOR)) + if(material_flags & MATERIAL_COLOR) + mix_material_colors(colors, remove = TRUE) + else + set_greyscale(initial(greyscale_colors), initial(greyscale_config)) + alpha = initial(alpha) + opacity = initial(opacity) + + if(material_flags & MATERIAL_ADD_PREFIX) + name = initial(name) + +///Remove material effects of a single material. +/atom/proc/remove_single_mat_effect(datum/material/custom_material, amount, multipier) + SHOULD_CALL_PARENT(TRUE) + return + +///A proc to remove the material effects previously applied by the (ex-)main material +/atom/proc/remove_main_material_effects(datum/material/main_material, amount, multipier) + SHOULD_CALL_PARENT(TRUE) + if(main_material.texture_layer_icon_state) + remove_filter("material_texture_[main_material.name]") + REMOVE_KEEP_TOGETHER(src, MATERIAL_SOURCE(main_material)) + main_material.on_main_removed(src, amount, multipier) + +///Remove the old effects, change the material_modifier variable, and then reapply all the effects. +/atom/proc/change_material_modifier(new_value) + SHOULD_NOT_OVERRIDE(TRUE) + remove_material_effects() + material_modifier = new_value + apply_material_effects(custom_materials) - custom_materials = SSmaterials.FindOrCreateMaterialCombo(materials, multiplier) +///For enabling and disabling material effects from an item (mainly VV) +/atom/proc/toggle_material_flags(new_flags) + SHOULD_NOT_OVERRIDE(TRUE) + if(material_flags & MATERIAL_EFFECTS && !(new_flags & MATERIAL_EFFECTS)) + remove_material_effects() + else if(!(material_flags & MATERIAL_EFFECTS) && new_flags & MATERIAL_EFFECTS) + apply_material_effects() + material_flags = new_flags /** * Returns the material composition of the atom. diff --git a/code/game/atom/atom_vv.dm b/code/game/atom/atom_vv.dm index 10a6cbff24a92..7a7dc8d3a877d 100644 --- a/code/game/atom/atom_vv.dm +++ b/code/game/atom/atom_vv.dm @@ -270,6 +270,12 @@ if(NAMEOF(src, base_pixel_y)) set_base_pixel_y(var_value) . = TRUE + if(NAMEOF(src, material_flags)) + toggle_material_flags(var_value) + . = TRUE + if(NAMEOF(src, material_modifier)) + change_material_modifier(var_value) + . = TRUE light_flags = old_light_flags if(!isnull(.)) diff --git a/code/game/atom/atoms_initializing_EXPENSIVE.dm b/code/game/atom/atoms_initializing_EXPENSIVE.dm index 205617fdbc8f9..b73504fb137b8 100644 --- a/code/game/atom/atoms_initializing_EXPENSIVE.dm +++ b/code/game/atom/atoms_initializing_EXPENSIVE.dm @@ -142,7 +142,8 @@ // This MUST come after atom_integrity is set above, as if old materials get removed, // atom_integrity is checked against max_integrity and can BREAK the atom. // The integrity to max_integrity ratio is still preserved. - set_custom_materials(custom_materials) + if(custom_materials) + initialize_materials(custom_materials) if(ispath(ai_controller)) ai_controller = new ai_controller(src) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index f4ba6dd1968cb..2611ee2386166 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -468,7 +468,7 @@ var/static/list/not_falsey_edits = list(NAMEOF_STATIC(src, bound_width) = TRUE, NAMEOF_STATIC(src, bound_height) = TRUE) if(banned_edits[var_name]) return FALSE //PLEASE no. - if(careful_edits[var_name] && (var_value % world.icon_size) != 0) + if(careful_edits[var_name] && (var_value % ICON_SIZE_ALL) != 0) return FALSE if(not_falsey_edits[var_name] && !var_value) return FALSE @@ -1130,7 +1130,7 @@ RESOLVE_ACTIVE_MOVEMENT var/atom/oldloc = loc - var/is_multi_tile = bound_width > world.icon_size || bound_height > world.icon_size + var/is_multi_tile = bound_width > ICON_SIZE_X || bound_height > ICON_SIZE_Y SET_ACTIVE_MOVEMENT(oldloc, NONE, TRUE, null) @@ -1153,8 +1153,8 @@ var/list/new_locs = block( destination, locate( - min(world.maxx, destination.x + ROUND_UP(bound_width / 32)), - min(world.maxy, destination.y + ROUND_UP(bound_height / 32)), + 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 ) ) @@ -1633,8 +1633,14 @@ /* End language procs */ -//Returns an atom's power cell, if it has one. Overload for individual items. -/atom/movable/proc/get_cell() +/** + * Returns an atom's power cell, if it has one. Overload for individual items. + * Args + * + * * /atom/movable/interface - the atom that is trying to interact with this cell + * * mob/user - the mob that is holding the interface + */ +/atom/movable/proc/get_cell(atom/movable/interface, mob/user) return /atom/movable/proc/can_be_pulled(user, grab_state, force) diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index 4aae21dd7f14b..6d05f03687f49 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -175,7 +175,7 @@ Medical HUD! Basic mode needs suit sensors on. holder.icon_state = "hud[RoundHealth(src)]" var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - world.icon_size + holder.pixel_y = I.Height() - ICON_SIZE_Y //for carbon suit sensors /mob/living/carbon/med_hud_set_health() @@ -188,7 +188,7 @@ Medical HUD! Basic mode needs suit sensors on. return var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - world.icon_size + holder.pixel_y = I.Height() - ICON_SIZE_Y if(stat == DEAD || (HAS_TRAIT(src, TRAIT_FAKEDEATH))) holder.icon_state = "huddead" else @@ -201,7 +201,7 @@ Medical HUD! Basic mode needs suit sensors on. var/icon/I = icon(icon, icon_state, dir) var/virus_threat = check_virus() - holder.pixel_y = I.Height() - world.icon_size + holder.pixel_y = I.Height() - ICON_SIZE_Y if(HAS_TRAIT(src, TRAIT_XENO_HOST)) holder.icon_state = "hudxeno" else if(stat == DEAD || (HAS_TRAIT(src, TRAIT_FAKEDEATH))) @@ -244,7 +244,7 @@ FAN HUDs! For identifying other fans on-sight. /mob/living/carbon/human/proc/fan_hud_set_fandom() var/image/holder = hud_list[FAN_HUD] var/icon/hud_icon = icon(icon, icon_state, dir) - holder.pixel_y = hud_icon.Height() - world.icon_size + holder.pixel_y = hud_icon.Height() - ICON_SIZE_Y holder.icon_state = "hudfan_no" var/obj/item/clothing/under/undershirt = w_uniform @@ -275,7 +275,7 @@ Security HUDs! Basic mode shows only the job. /mob/living/carbon/human/proc/sec_hud_set_ID() var/image/holder = hud_list[ID_HUD] var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - world.icon_size + holder.pixel_y = I.Height() - ICON_SIZE_Y var/sechud_icon_state = wear_id?.get_sechud_job_icon_state() if(!sechud_icon_state || HAS_TRAIT(src, TRAIT_UNKNOWN)) sechud_icon_state = "hudno_id" @@ -296,7 +296,7 @@ Security HUDs! Basic mode shows only the job. if(1) holder = hud_list[IMPSEC_FIRST_HUD] var/icon/IC = icon(icon, icon_state, dir) - holder.pixel_y = IC.Height() - world.icon_size + holder.pixel_y = IC.Height() - ICON_SIZE_Y holder.icon_state = current_implant.hud_icon_state set_hud_image_active(IMPSEC_FIRST_HUD) security_slot++ @@ -304,22 +304,26 @@ Security HUDs! Basic mode shows only the job. if(2) //Theoretically if we somehow get multiple sec implants, whatever the most recently implanted implant is will take over the 2nd position holder = hud_list[IMPSEC_SECOND_HUD] var/icon/IC = icon(icon, icon_state, dir) - holder.pixel_y = IC.Height() - world.icon_size - holder.pixel_x = initial(holder.pixel_x) + 7 //Adds an offset that mirrors the hud blip to the other side of the mob. + holder.pixel_y = IC.Height() - ICON_SIZE_Y + holder.pixel_x = initial(holder.pixel_x) + (ICON_SIZE_X / 4 - 1) //Adds an offset that mirrors the hud blip to the other side of the mob. holder.icon_state = current_implant.hud_icon_state set_hud_image_active(IMPSEC_SECOND_HUD) if(HAS_TRAIT(src, TRAIT_MINDSHIELD)) holder = hud_list[IMPLOYAL_HUD] var/icon/IC = icon(icon, icon_state, dir) - holder.pixel_y = IC.Height() - world.icon_size + holder.pixel_y = IC.Height() - ICON_SIZE_Y holder.icon_state = "hud_imp_loyal" set_hud_image_active(IMPLOYAL_HUD) /mob/living/carbon/human/proc/sec_hud_set_security_status() + if(!hud_list) + // We haven't finished initializing yet, huds will be updated once we are + return + var/image/holder = hud_list[WANTED_HUD] var/icon/sec_icon = icon(icon, icon_state, dir) - holder.pixel_y = sec_icon.Height() - world.icon_size + holder.pixel_y = sec_icon.Height() - ICON_SIZE_Y if (HAS_TRAIT(src, TRAIT_ALWAYS_WANTED)) holder.icon_state = "hudwanted" @@ -396,7 +400,7 @@ Diagnostic HUDs! /mob/living/silicon/proc/diag_hud_set_health() var/image/holder = hud_list[DIAG_HUD] var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - world.icon_size + holder.pixel_y = I.Height() - ICON_SIZE_Y if(stat == DEAD) holder.icon_state = "huddiagdead" else @@ -405,7 +409,7 @@ Diagnostic HUDs! /mob/living/silicon/proc/diag_hud_set_status() var/image/holder = hud_list[DIAG_STAT_HUD] var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - world.icon_size + holder.pixel_y = I.Height() - ICON_SIZE_Y switch(stat) if(CONSCIOUS) holder.icon_state = "hudstat" @@ -418,7 +422,7 @@ Diagnostic HUDs! /mob/living/silicon/robot/proc/diag_hud_set_borgcell() var/image/holder = hud_list[DIAG_BATT_HUD] var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - world.icon_size + holder.pixel_y = I.Height() - ICON_SIZE_Y if(cell) var/chargelvl = (cell.charge/cell.maxcharge) holder.icon_state = "hudbatt[RoundDiagBar(chargelvl)]" @@ -429,7 +433,7 @@ Diagnostic HUDs! /mob/living/silicon/robot/proc/diag_hud_set_aishell() //Shows tracking beacons on the mech var/image/holder = hud_list[DIAG_TRACK_HUD] var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - world.icon_size + holder.pixel_y = I.Height() - ICON_SIZE_Y if(!shell) //Not an AI shell holder.icon_state = null set_hud_image_inactive(DIAG_TRACK_HUD) @@ -444,7 +448,7 @@ Diagnostic HUDs! /mob/living/silicon/ai/proc/diag_hud_set_deployed() //Shows tracking beacons on the mech var/image/holder = hud_list[DIAG_TRACK_HUD] var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - world.icon_size + holder.pixel_y = I.Height() - ICON_SIZE_Y if(!deployed_shell) holder.icon_state = null set_hud_image_inactive(DIAG_TRACK_HUD) @@ -458,14 +462,14 @@ Diagnostic HUDs! /obj/vehicle/sealed/mecha/proc/diag_hud_set_mechhealth() var/image/holder = hud_list[DIAG_MECH_HUD] var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - world.icon_size + holder.pixel_y = I.Height() - ICON_SIZE_Y holder.icon_state = "huddiag[RoundDiagBar(atom_integrity/max_integrity)]" /obj/vehicle/sealed/mecha/proc/diag_hud_set_mechcell() var/image/holder = hud_list[DIAG_BATT_HUD] var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - world.icon_size + holder.pixel_y = I.Height() - ICON_SIZE_Y if(cell) var/chargelvl = cell.charge/cell.maxcharge holder.icon_state = "hudbatt[RoundDiagBar(chargelvl)]" @@ -475,7 +479,7 @@ Diagnostic HUDs! /obj/vehicle/sealed/mecha/proc/diag_hud_set_mechstat() var/image/holder = hud_list[DIAG_STAT_HUD] var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - world.icon_size + holder.pixel_y = I.Height() - ICON_SIZE_Y if(internal_damage) holder.icon_state = "hudwarn" set_hud_image_active(DIAG_STAT_HUD) @@ -487,7 +491,7 @@ Diagnostic HUDs! /obj/vehicle/sealed/mecha/proc/diag_hud_set_mechtracking() var/image/holder = hud_list[DIAG_TRACK_HUD] var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - world.icon_size + holder.pixel_y = I.Height() - ICON_SIZE_Y var/new_icon_state //This var exists so that the holder's icon state is set only once in the event of multiple mech beacons. for(var/obj/item/mecha_parts/mecha_tracking/T in trackers) if(T.ai_beacon) //Beacon with AI uplink @@ -501,7 +505,7 @@ Diagnostic HUDs! /obj/vehicle/sealed/mecha/proc/diag_hud_set_camera() var/image/holder = hud_list[DIAG_CAMERA_HUD] var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - world.icon_size + holder.pixel_y = I.Height() - ICON_SIZE_Y if(chassis_camera?.is_emp_scrambled) holder.icon_state = "hudcamera_empd" return @@ -513,13 +517,13 @@ Diagnostic HUDs! /mob/living/simple_animal/bot/proc/diag_hud_set_bothealth() var/image/holder = hud_list[DIAG_HUD] var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - world.icon_size + holder.pixel_y = I.Height() - ICON_SIZE_Y holder.icon_state = "huddiag[RoundDiagBar(health/maxHealth)]" /mob/living/simple_animal/bot/proc/diag_hud_set_botstat() //On (With wireless on or off), Off, EMP'ed var/image/holder = hud_list[DIAG_STAT_HUD] var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - world.icon_size + holder.pixel_y = I.Height() - ICON_SIZE_Y if(bot_mode_flags & BOT_MODE_ON) holder.icon_state = "hudstat" else if(stat) //Generally EMP causes this @@ -530,7 +534,7 @@ Diagnostic HUDs! /mob/living/simple_animal/bot/proc/diag_hud_set_botmode() //Shows a bot's current operation var/image/holder = hud_list[DIAG_BOT_HUD] var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - world.icon_size + holder.pixel_y = I.Height() - ICON_SIZE_Y if(client) //If the bot is player controlled, it will not be following mode logic! holder.icon_state = "hudsentient" return @@ -552,7 +556,7 @@ Diagnostic HUDs! /mob/living/simple_animal/bot/mulebot/proc/diag_hud_set_mulebotcell() var/image/holder = hud_list[DIAG_BATT_HUD] var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - world.icon_size + holder.pixel_y = I.Height() - ICON_SIZE_Y if(cell) var/chargelvl = (cell.charge/cell.maxcharge) holder.icon_state = "hudbatt[RoundDiagBar(chargelvl)]" diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 34b8612c2d4be..282e7f6a34ae2 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -648,6 +648,11 @@ if(interaction_flags_machine & INTERACT_MACHINE_REQUIRES_SILICON) //if the user was a silicon, we'd have returned out earlier, so the user must not be a silicon return FALSE + if(interaction_flags_machine & INTERACT_MACHINE_REQUIRES_STANDING) + var/mob/living/living_user = user + if(!(living_user.mobility_flags & MOBILITY_MOVE)) + return FALSE + return TRUE // If we passed all of those checks, woohoo! We can interact with this machine. /obj/machinery/proc/check_nap_violations() diff --git a/code/game/machinery/airlock_control.dm b/code/game/machinery/airlock_control.dm index f4d1b29da186f..9e089eeaf2be8 100644 --- a/code/game/machinery/airlock_control.dm +++ b/code/game/machinery/airlock_control.dm @@ -18,9 +18,9 @@ update_appearance() /// Forces the airlock to close and bolt -/obj/machinery/door/airlock/proc/secure_close() +/obj/machinery/door/airlock/proc/secure_close(force_crush = FALSE) locked = FALSE - close(forced = TRUE) + close(forced = TRUE, force_crush = force_crush) locked = TRUE stoplag(0.2 SECONDS) diff --git a/code/game/machinery/announcement_system.dm b/code/game/machinery/announcement_system.dm index 07c12c28760ff..029f4a17ea99b 100644 --- a/code/game/machinery/announcement_system.dm +++ b/code/game/machinery/announcement_system.dm @@ -97,12 +97,12 @@ GLOBAL_LIST_EMPTY(announcement_systems) switch(message_type) if(AUTO_ANNOUNCE_ARRIVAL) if(!arrival_toggle) - message = CompileText(arrival, target, rank) return + message = CompileText(arrival, target, rank) if(AUTO_ANNOUNCE_NEWHEAD) if(!newhead_toggle) - message = CompileText(newhead, target, rank) return + message = CompileText(newhead, target, rank) if(AUTO_ANNOUNCE_ARRIVALS_BROKEN) message = "The arrivals shuttle has been damaged. Docking for repairs..." if(AUTO_ANNOUNCE_NODE) diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 0a89c4e8b5b08..06c88f4749e1f 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -112,7 +112,7 @@ highest_mat = present_mat highest_mat_ref = mat - flick_overlay_view(material_insertion_animation(highest_mat_ref.greyscale_colors), 1 SECONDS) + flick_overlay_view(material_insertion_animation(highest_mat_ref), 1 SECONDS) /obj/machinery/autolathe/ui_interact(mob/user, datum/tgui/ui) if(!is_operational) @@ -255,7 +255,7 @@ if(istext(material)) // category var/list/choices = list() for(var/datum/material/valid_candidate as anything in SSmaterials.materials_by_category[material]) - if(materials.get_material_amount(valid_candidate) < amount_needed) + if(materials.get_material_amount(valid_candidate) < (amount_needed + materials_needed[material])) continue choices[valid_candidate.name] = valid_candidate if(!length(choices)) @@ -274,7 +274,7 @@ if(isnull(material)) stack_trace("got passed an invalid material id: [material]") return - materials_needed[material] = amount_needed + materials_needed[material] += amount_needed //checks for available materials var/material_cost_coefficient = ispath(design.build_path, /obj/item/stack) ? 1 : creation_efficiency diff --git a/code/game/machinery/computer/atmos_computers/_air_sensor.dm b/code/game/machinery/computer/atmos_computers/_air_sensor.dm index 91a616cc5f678..1f4a8bf834098 100644 --- a/code/game/machinery/computer/atmos_computers/_air_sensor.dm +++ b/code/game/machinery/computer/atmos_computers/_air_sensor.dm @@ -15,6 +15,8 @@ var/inlet_id /// The outlet[vent pump] controlled by this sensor var/outlet_id + /// The air alarm connected to this sensor + var/obj/machinery/airalarm/connected_airalarm /obj/machinery/air_sensor/Initialize(mapload) id_tag = assign_random_name() @@ -57,7 +59,7 @@ /obj/machinery/air_sensor/examine(mob/user) . = ..() - . += span_notice("Use multitool to link it to an injector/vent or reset its ports") + . += span_notice("Use a multitool to link it to an injector, vent, or air alarm, or reset its ports.") . += span_notice("Click with hand to turn it off.") /obj/machinery/air_sensor/attack_hand(mob/living/user, list/modifiers) @@ -78,6 +80,11 @@ /obj/machinery/air_sensor/proc/reset() inlet_id = null outlet_id = null + if(connected_airalarm) + connected_airalarm.disconnect_sensor() + // if air alarm and sensor were linked at roundstart we allow them to link to new devices + connected_airalarm.allow_link_change = TRUE + connected_airalarm = null ///right click with multi tool to disconnect everything /obj/machinery/air_sensor/multitool_act_secondary(mob/living/user, obj/item/tool) diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 76701eca0d852..abbfb055e1647 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -672,7 +672,7 @@ /// Returns TRUE if the user can buy shuttles. /// If they cannot, returns FALSE or a string detailing why. /obj/machinery/computer/communications/proc/can_buy_shuttles(mob/user) - if (!SSmapping.config.allow_custom_shuttles) + if (!SSmapping.current_map.allow_custom_shuttles) return FALSE if (HAS_SILICON_ACCESS(user)) return FALSE diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm index 910489999e04c..8cca5ff9b6c81 100644 --- a/code/game/machinery/computer/dna_console.dm +++ b/code/game/machinery/computer/dna_console.dm @@ -440,7 +440,7 @@ // GUARD CHECK - Can we genetically modify the occupant? Includes scanner // operational guard checks. // GUARD CHECK - Is scramble DNA actually ready? - if(!can_modify_occupant() || !(scramble_ready < world.time)) + if(!can_modify_occupant() || !(scramble_ready < world.time) || HAS_TRAIT(scanner_occupant, TRAIT_NO_DNA_SCRAMBLE)) return scanner_occupant.dna.remove_all_mutations(list(MUT_NORMAL, MUT_EXTRA)) diff --git a/code/game/machinery/computer/operating_computer.dm b/code/game/machinery/computer/operating_computer.dm index 0354806d85ebd..83a2a08d986c3 100644 --- a/code/game/machinery/computer/operating_computer.dm +++ b/code/game/machinery/computer/operating_computer.dm @@ -7,6 +7,7 @@ icon_screen = "crew" icon_keyboard = "med_key" circuit = /obj/item/circuitboard/computer/operating + interaction_flags_machine = parent_type::interaction_flags_machine | INTERACT_MACHINE_REQUIRES_STANDING var/obj/structure/table/optable/table var/list/advanced_surgeries = list() @@ -77,7 +78,7 @@ break /obj/machinery/computer/operating/ui_state(mob/user) - return GLOB.not_incapacitated_state + return GLOB.standing_state /obj/machinery/computer/operating/ui_interact(mob/user, datum/tgui/ui) . = ..() diff --git a/code/game/machinery/computer/orders/order_items/mining/order_consumables.dm b/code/game/machinery/computer/orders/order_items/mining/order_consumables.dm index c8cfa12f9abfe..a91a34b46f2da 100644 --- a/code/game/machinery/computer/orders/order_items/mining/order_consumables.dm +++ b/code/game/machinery/computer/orders/order_items/mining/order_consumables.dm @@ -46,3 +46,9 @@ item_path = /obj/item/stack/spacecash/c1000 desc = "A stack of space cash worth 1000 credits." cost_per_order = 2000 + +/datum/orderable_item/consumables/rescue_hook + name = "Rescue Fishing Rod" + item_path = /obj/item/fishing_rod/rescue + desc = "For when your fellow miner has inevitably fallen into a chasm, and it's up to you to save them." + cost_per_order = 600 diff --git a/code/game/machinery/computer/records/records.dm b/code/game/machinery/computer/records/records.dm index a30c11c3abefa..7d01d973549b3 100644 --- a/code/game/machinery/computer/records/records.dm +++ b/code/game/machinery/computer/records/records.dm @@ -142,7 +142,7 @@ playsound(src, 'sound/machines/terminal/terminal_error.ogg', 70, TRUE) return FALSE - if(mugshot.picture.psize_x > world.icon_size || mugshot.picture.psize_y > world.icon_size) + if(mugshot.picture.psize_x > ICON_SIZE_X || mugshot.picture.psize_y > ICON_SIZE_Y) balloon_alert(user, "photo too large!") playsound(src, 'sound/machines/terminal/terminal_error.ogg', 70, TRUE) return FALSE diff --git a/code/game/machinery/dna_infuser/dna_infuser.dm b/code/game/machinery/dna_infuser/dna_infuser.dm index 961092c635b33..ccc24d44f6e7e 100644 --- a/code/game/machinery/dna_infuser/dna_infuser.dm +++ b/code/game/machinery/dna_infuser/dna_infuser.dm @@ -210,7 +210,6 @@ /// Verify that the given infusion source/mob is a dead creature. /obj/machinery/dna_infuser/proc/is_valid_infusion(atom/movable/target, mob/user) - var/datum/component/edible/food_comp = IS_EDIBLE(target) if(infusing_from) balloon_alert(user, "empty the machine first!") return FALSE @@ -219,11 +218,8 @@ if(living_target.stat != DEAD) balloon_alert(user, "only dead creatures!") return FALSE - else if(food_comp) - if(!(food_comp.foodtypes & GORE)) - balloon_alert(user, "only creatures!") - return FALSE - else + else if(!HAS_TRAIT(target, TRAIT_VALID_DNA_INFUSION)) + balloon_alert(user, "only creatures!") return FALSE return TRUE diff --git a/code/game/machinery/dna_infuser/dna_infusion.dm b/code/game/machinery/dna_infuser/dna_infusion.dm index c902240404ca7..86a8a5f41e9f3 100644 --- a/code/game/machinery/dna_infuser/dna_infusion.dm +++ b/code/game/machinery/dna_infuser/dna_infusion.dm @@ -47,6 +47,8 @@ // Valid organ successfully picked. new_organ = new new_organ() new_organ.replace_into(src) + //make sure bodypart overlays are correctly displayed. + update_body_parts() return TRUE /// Picks a random mutated organ from the given infuser entry which is also compatible with this human. diff --git a/code/game/machinery/dna_infuser/infuser_actions.dm b/code/game/machinery/dna_infuser/infuser_actions.dm new file mode 100644 index 0000000000000..1b55059bb9899 --- /dev/null +++ b/code/game/machinery/dna_infuser/infuser_actions.dm @@ -0,0 +1,61 @@ +///Action from the inky tongue, from fish with the ink production trait. +/datum/action/cooldown/ink_spit + name = "Spit Ink" + desc = "Spits ink at someone, blinding them temporarily." + button_icon = 'icons/hud/radial_fishing.dmi' + button_icon_state = "oil" + base_background_icon_state = "bg_default" + active_background_icon_state = "bg_default_on" + check_flags = AB_CHECK_IMMOBILE | AB_CHECK_CONSCIOUS | AB_CHECK_INCAPACITATED + click_to_activate = TRUE + unset_after_click = TRUE + cooldown_time = 21 SECONDS + +/datum/action/cooldown/ink_spit/IsAvailable(feedback = FALSE) + var/mob/living/carbon/as_carbon = owner + if(istype(as_carbon) && as_carbon.is_mouth_covered(ITEM_SLOT_MASK)) + return FALSE + if(!isturf(owner.loc)) + return FALSE + return ..() + +/datum/action/cooldown/ink_spit/set_click_ability(mob/on_who) + . = ..() + if(!.) + return + + to_chat(on_who, span_notice("You prepare your ink glands. Right-click to fire at a target!")) + build_all_button_icons() + +/datum/action/cooldown/ink_spit/unset_click_ability(mob/on_who, refund_cooldown = TRUE) + . = ..() + if(!.) + return + + build_all_button_icons() + +// We do this in InterceptClickOn() instead of Activate() +// because we use the click parameters for aiming the projectile +// (or something like that) +/datum/action/cooldown/ink_spit/InterceptClickOn(mob/living/caller, params, atom/target) + if(!LAZYACCESS(params2list(params), RIGHT_CLICK)) + return + . = ..() + + var/modifiers = params2list(params) + caller.visible_message( + span_danger("[caller] spits ink!"), + span_bold("You spit ink."), + ) + var/obj/projectile/ink_spit/ink = new /obj/projectile/ink_spit(caller.loc) + ink.preparePixelProjectile(target, caller, modifiers) + ink.firer = caller + ink.fire() + playsound(caller, 'sound/items/weapons/pierce.ogg', 20, TRUE, -1) + caller.newtonian_move(get_angle(target, caller)) + StartCooldown() + return TRUE + +// Has to return TRUE, otherwise is skipped. +/datum/action/cooldown/ink_spit/Activate(atom/target) + return TRUE diff --git a/code/game/machinery/dna_infuser/infuser_entries/infuser_tier_one_entries.dm b/code/game/machinery/dna_infuser/infuser_entries/infuser_tier_one_entries.dm index bd8734643f898..faa3683b9a27b 100644 --- a/code/game/machinery/dna_infuser/infuser_entries/infuser_tier_one_entries.dm +++ b/code/game/machinery/dna_infuser/infuser_entries/infuser_tier_one_entries.dm @@ -105,3 +105,86 @@ infusion_desc = "kafkaesque" // Gregor Samsa !! tier = DNA_MUTANT_TIER_ONE status_effect_type = /datum/status_effect/organ_set_bonus/roach + +/datum/infuser_entry/fish + name = "Fish" + infuse_mob_name = "fish" + desc = "Aquatic life comes in several forms. A fisherman could tell you more about it, but that's beside the point. \ + This infusion comes with many benefits and one potential major drawback being fish-mutated lungs, with \ + additional organs depending on the traits of the fish used for the infusion." + threshold_desc = "While wet, you're slightly sturdier, immune to slips, and both slippery and faster while crawling. \ + Drinking water and showers heal you, and it takes longer to dry out, however you're weaker when dry. \ + Finally, you resist high pressures and are better at fishing. " + qualities = list( + "faster in water", + "resistant to food diseases", + "enjoy eating raw fish", + "flopping and waddling", + "fishing is easier", + "Need water. badly!", + "possibly more", + ) + input_obj_or_mob = list( + /obj/item/fish, + ) + output_organs = list( + /obj/item/organ/internal/lungs/fish, + /obj/item/organ/internal/stomach/fish, + /obj/item/organ/external/tail/fish, + ) + infusion_desc = "piscine" + tier = DNA_MUTANT_TIER_ONE + status_effect_type = /datum/status_effect/organ_set_bonus/fish + +/datum/infuser_entry/squid + name = "Ink Production" + infuse_mob_name = "ink-producing sealife" + desc = "Some marine mollusks like cuttlefish, squids and octopus release ink when threatened as a smokescreen for their escape. \ + This kind of infusion enhances the salivary glands, producing excessive quantities of ink which can later be spat to blind foes." + threshold_desc = DNA_INFUSION_NO_THRESHOLD + qualities = list( + "spit ink to blind foes", + ) + output_organs = list( + /obj/item/organ/internal/tongue/inky + ) + tier = DNA_MUTANT_TIER_ONE + +/datum/infuser_entry/ttx_healing + name = "TTX healing" + infuse_mob_name = "Tetraodontiformes" + desc = "Fish of the Tetraodontiformes (pufferfish etc.) order are known for the highly poisonous tetrodotoxin (TTX) in their bodies. \ + Extracting their DNA can provide a way to utilize it for healing instead. It also enables better alcohol metabolization." + threshold_desc = DNA_INFUSION_NO_THRESHOLD + qualities = list( + "TTX healing", + "drink like a fish", + ) + output_organs = list( + /obj/item/organ/internal/liver/fish + ) + tier = DNA_MUTANT_TIER_ONE + unreachable_effect = TRUE + status_effect_type = /datum/status_effect/organ_set_bonus/fish + +/datum/infuser_entry/amphibious + name = "Amphibious" + infuse_mob_name = "Semi-aquatic critters" + desc = "Some animals breathe air, some breath water, a few can breath both, even if none (at least on Earth) can breathe in space." + threshold_desc = DNA_INFUSION_NO_THRESHOLD + qualities = list( + "no need to breathe while wet", + "can beathe water vapor", + ) + input_obj_or_mob = list( + /mob/living/basic/frog, + /mob/living/basic/axolotl, + /mob/living/basic/crab, + ) + output_organs = list( + /obj/item/organ/internal/lungs/fish/amphibious, + ) + infusion_desc = "semi-aquatic" + tier = DNA_MUTANT_TIER_ONE + unreachable_effect = TRUE + status_effect_type = /datum/status_effect/organ_set_bonus/fish diff --git a/code/game/machinery/dna_infuser/infuser_entry.dm b/code/game/machinery/dna_infuser/infuser_entry.dm index 8b0bcfb3f790d..55ac43d1bf4e6 100644 --- a/code/game/machinery/dna_infuser/infuser_entry.dm +++ b/code/game/machinery/dna_infuser/infuser_entry.dm @@ -28,8 +28,16 @@ GLOBAL_LIST_INIT(infuser_entries, prepare_infuser_entries()) ) /// status effect type of the corresponding bonus, if it has one. tier zero won't ever set this. var/status_effect_type - /// essentially how difficult it is to get this infusion, and if it will be locked behind some progression. see defines for more info - /// ...overwrite this, please + /** + * This var clarifies that while the infuser entry has organs that contribute towards an organ set bonus + * It cannot reach the organ threshold of the bonus on its own, meaning it relies on some other infuser entry for that. + * This is mainly the case for fish organs from fish with specific traits, for example. We don't want the unit test to bith about it. + */ + var/unreachable_effect = FALSE + /** + * essentially how difficult it is to get this infusion, and if it will be locked behind some progression. see defines for more info + * ...overwrite this, please + */ var/tier = DNA_MUTANT_UNOBTAINABLE //-- Vars for DNA Infuser Machine --// diff --git a/code/game/machinery/dna_infuser/organ_sets/carp_organs.dm b/code/game/machinery/dna_infuser/organ_sets/carp_organs.dm index 10fcae90a9591..c551ce0c4e964 100644 --- a/code/game/machinery/dna_infuser/organ_sets/carp_organs.dm +++ b/code/game/machinery/dna_infuser/organ_sets/carp_organs.dm @@ -10,6 +10,7 @@ bonus_activate_text = span_notice("Carp DNA is deeply infused with you! You've learned how to propel yourself through space!") bonus_deactivate_text = span_notice("Your DNA is once again mostly yours, and so fades your ability to space-swim...") bonus_traits = list(TRAIT_SPACEWALK) + limb_overlay = /datum/bodypart_overlay/texture/carpskin ///Carp lungs! You can breathe in space! Oh... you can't breathe on the station, you need low oxygen environments. /// Inverts behavior of lungs. Bypasses suffocation due to space / lack of gas, but also allows Oxygen to suffocate. diff --git a/code/game/machinery/dna_infuser/organ_sets/fish_organs.dm b/code/game/machinery/dna_infuser/organ_sets/fish_organs.dm new file mode 100644 index 0000000000000..1c2802138f77f --- /dev/null +++ b/code/game/machinery/dna_infuser/organ_sets/fish_organs.dm @@ -0,0 +1,388 @@ +#define FISH_ORGAN_COLOR "#875652" //dark moderate magenta +#define FISH_SCLERA_COLOR COLOR_WHITE +#define FISH_PUPIL_COLOR COLOR_BLUE +#define FISH_COLORS FISH_ORGAN_COLOR + FISH_SCLERA_COLOR + FISH_PUPIL_COLOR + +///bonus of the observing gondola: you can ignore environmental hazards +/datum/status_effect/organ_set_bonus/fish + id = "organ_set_bonus_fish" + tick_interval = 1 SECONDS + organs_needed = 3 + bonus_activate_text = span_notice("Fish DNA is deeply infused with you! While wet, you crawl faster, are slippery, and cannot slip, and it takes longer to dry out. \ + You're also more resistant to high pressure, better at fishing, but less resilient when dry, especially against burns.") + bonus_deactivate_text = span_notice("You no longer feel as fishy. The moisture around your body begins to dissipate faster...") + bonus_traits = list( + TRAIT_RESISTHIGHPRESSURE, + TRAIT_EXPERT_FISHER, + TRAIT_EXAMINE_FISH, + TRAIT_EXAMINE_DEEPER_FISH, + TRAIT_REVEAL_FISH, + TRAIT_EXAMINE_FISHING_SPOT, + TRAIT_WET_FOR_LONGER, + TRAIT_SLIPPERY_WHEN_WET, + TRAIT_EXPANDED_FOV, //fish vision + TRAIT_WATER_ADAPTATION, + ) + +/datum/status_effect/organ_set_bonus/fish/enable_bonus() + . = ..() + if(!.) + return + RegisterSignals(owner, list(COMSIG_CARBON_GAIN_ORGAN, COMSIG_CARBON_LOSE_ORGAN), PROC_REF(check_tail)) + RegisterSignals(owner, list(SIGNAL_ADDTRAIT(TRAIT_IS_WET), SIGNAL_REMOVETRAIT(TRAIT_IS_WET)), PROC_REF(update_wetness)) + RegisterSignals(owner, COMSIG_LIVING_GET_PERCEIVED_FOOD_QUALITY, PROC_REF(get_perceived_food_quality)) + + if(ishuman(owner)) + var/mob/living/carbon/human/human = owner + human.physiology.damage_resistance += 8 //base 8% damage resistance, much wow. + if(!HAS_TRAIT(owner, TRAIT_IS_WET)) + apply_debuff() + else + ADD_TRAIT(owner, TRAIT_GRABRESISTANCE, REF(src)) + owner.add_mood_event("fish_organs_bonus", /datum/mood_event/fish_water) + if(HAS_TRAIT(owner, TRAIT_IS_WET) && istype(owner.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL), /obj/item/organ/external/tail/fish)) + add_speed_buff() + owner.mind?.adjust_experience(/datum/skill/fishing, SKILL_EXP_JOURNEYMAN, silent = TRUE) + +/datum/status_effect/organ_set_bonus/fish/disable_bonus() + . = ..() + UnregisterSignal(owner, list( + COMSIG_CARBON_GAIN_ORGAN, + COMSIG_CARBON_LOSE_ORGAN, + SIGNAL_ADDTRAIT(TRAIT_IS_WET), + SIGNAL_REMOVETRAIT(TRAIT_IS_WET), + COMSIG_LIVING_TREAT_MESSAGE, + COMSIG_LIVING_GET_PERCEIVED_FOOD_QUALITY, + )) + if(!HAS_TRAIT(owner, TRAIT_IS_WET)) + remove_debuff() + else + REMOVE_TRAIT(owner, TRAIT_GRABRESISTANCE, REF(src)) + owner.clear_mood_event("fish_organs_bonus") + if(ishuman(owner)) + var/mob/living/carbon/human/human = owner + human.physiology.damage_resistance -= 8 + if(HAS_TRAIT(owner, TRAIT_IS_WET) && istype(owner.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL), /obj/item/organ/external/tail/fish)) + remove_speed_buff() + owner.mind?.adjust_experience(/datum/skill/fishing, -SKILL_EXP_JOURNEYMAN, silent = TRUE) + +/datum/status_effect/organ_set_bonus/fish/proc/get_perceived_food_quality(datum/source, datum/component/edible/edible, list/extra_quality) + SIGNAL_HANDLER + if(HAS_TRAIT(edible.parent, TRAIT_GREAT_QUALITY_BAIT)) + extra_quality += LIKED_FOOD_QUALITY_CHANGE * 3 + else if(HAS_TRAIT(edible.parent, TRAIT_GOOD_QUALITY_BAIT)) + extra_quality += LIKED_FOOD_QUALITY_CHANGE * 2 + else if(HAS_TRAIT(edible.parent, TRAIT_BASIC_QUALITY_BAIT)) + extra_quality += LIKED_FOOD_QUALITY_CHANGE + +/datum/status_effect/organ_set_bonus/fish/tick(seconds_between_ticks) + . = ..() + if(!bonus_active || !HAS_TRAIT(owner, TRAIT_IS_WET)) + return + owner.adjust_bodytemperature(-2 * seconds_between_ticks, min_temp = owner.get_body_temp_normal()) + owner.adjustStaminaLoss(-1.5 * seconds_between_ticks) + +/datum/status_effect/organ_set_bonus/fish/proc/update_wetness(datum/source) + SIGNAL_HANDLER + if(HAS_TRAIT(owner, TRAIT_IS_WET)) //remove the debuffs from being dry + remove_debuff() + if(istype(owner.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL), /obj/item/organ/external/tail/fish)) + add_speed_buff() + return + apply_debuff() + if(istype(owner.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL), /obj/item/organ/external/tail/fish)) + remove_speed_buff() + +/datum/status_effect/organ_set_bonus/fish/proc/apply_debuff() + REMOVE_TRAIT(owner, TRAIT_GRABRESISTANCE, REF(src)) + owner.add_movespeed_modifier(/datum/movespeed_modifier/fish_waterless) + owner.add_mood_event("fish_organs_bonus", /datum/mood_event/fish_waterless) + if(!ishuman(owner)) + return + var/mob/living/carbon/human/human = owner + human.physiology.burn_mod *= 1.5 + human.physiology.heat_mod *= 1.2 + human.physiology.brute_mod *= 1.1 + human.physiology.stun_mod *= 1.1 + human.physiology.knockdown_mod *= 1.1 + human.physiology.stamina_mod *= 1.1 + human.physiology.damage_resistance -= 16 //from +8% to -8% + +/datum/status_effect/organ_set_bonus/fish/proc/remove_debuff() + ADD_TRAIT(owner, TRAIT_GRABRESISTANCE, REF(src)) //harder to grab when wet. + owner.remove_movespeed_modifier(/datum/movespeed_modifier/fish_waterless) + owner.add_mood_event("fish_organs_bonus", /datum/mood_event/fish_water) + if(!ishuman(owner)) + return + var/mob/living/carbon/human/human = owner + human.physiology.burn_mod /= 1.5 + human.physiology.heat_mod /= 1.2 + human.physiology.brute_mod /= 1.1 + human.physiology.stun_mod /= 1.1 + human.physiology.knockdown_mod /= 1.1 + human.physiology.stamina_mod /= 1.1 + human.physiology.damage_resistance += 16 //from -8% to +8% + +/datum/status_effect/organ_set_bonus/fish/proc/check_tail(mob/living/carbon/source, obj/item/organ/organ, special) + SIGNAL_HANDLER + if(!HAS_TRAIT(owner, TRAIT_IS_WET) || !istype(organ, /obj/item/organ/external/tail/fish)) + return + var/obj/item/organ/tail = owner.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL) + if(tail != organ) + remove_speed_buff() + return + add_speed_buff() + +/datum/status_effect/organ_set_bonus/fish/proc/add_speed_buff(datum/source) + SIGNAL_HANDLER + RegisterSignal(owner, COMSIG_LIVING_SET_BODY_POSITION, PROC_REF(check_body_position)) + check_body_position() + +/datum/status_effect/organ_set_bonus/fish/proc/remove_speed_buff(datum/source) + SIGNAL_HANDLER + UnregisterSignal(owner, COMSIG_LIVING_SET_BODY_POSITION) + owner.remove_movespeed_modifier(/datum/movespeed_modifier/fish_flopping) + +/datum/status_effect/organ_set_bonus/fish/proc/check_body_position(datum/source) + SIGNAL_HANDLER + if(owner.body_position == LYING_DOWN) + owner.add_movespeed_modifier(/datum/movespeed_modifier/fish_flopping) + else + owner.remove_movespeed_modifier(/datum/movespeed_modifier/fish_flopping) + + +///Tail for fish DNA-infused spacemen. It provides a speed buff while in water. It's also needed for the crawl speed bonus once the threshold is reached. +/obj/item/organ/external/tail/fish + name = "fish tail" + desc = "A severed tail from some sort of marine creature... or a fish-infused spaceman. It's smooth, faintly wet and definitely not flopping." + icon = 'icons/obj/medical/organs/infuser_organs.dmi' + icon_state = "fish_tail" + greyscale_config = /datum/greyscale_config/fish_tail + greyscale_colors = FISH_ORGAN_COLOR + + bodypart_overlay = /datum/bodypart_overlay/mutant/tail/fish + dna_block = DNA_FISH_TAIL_BLOCK + wag_flags = WAG_ABLE + organ_traits = list(TRAIT_FLOPPING) + +/obj/item/organ/external/tail/fish/Initialize(mapload) + . = ..() + AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/fish) + +/obj/item/organ/external/tail/fish/on_mob_insert(mob/living/carbon/owner) + . = ..() + owner.AddElementTrait(TRAIT_WADDLING, type, /datum/element/waddling/flopping_only) // DOPPLER EDIT, old code: owner.AddElementTrait(TRAIT_WADDLING, type, /datum/element/waddling) + RegisterSignal(owner, COMSIG_MOVABLE_MOVED, PROC_REF(check_location)) + check_location(owner, null) + +/obj/item/organ/external/tail/fish/on_mob_remove(mob/living/carbon/owner) + . = ..() + owner.remove_traits(list(TRAIT_WADDLING, TRAIT_NO_STAGGER), type) + owner.remove_movespeed_modifier(/datum/movespeed_modifier/fish_on_water) + owner.remove_actionspeed_modifier(/datum/actionspeed_modifier/fish_on_water) + UnregisterSignal(owner, COMSIG_MOVABLE_MOVED) + +/obj/item/organ/external/tail/fish/get_greyscale_color_from_draw_color() + set_greyscale(bodypart_overlay.draw_color) + +/obj/item/organ/external/tail/fish/proc/check_location(mob/living/carbon/source, atom/movable/old_loc, dir, forced) + SIGNAL_HANDLER + var/was_water = istype(old_loc, /turf/open/water) + var/is_water = istype(source.loc, /turf/open/water) && !HAS_TRAIT(source.loc, TRAIT_TURF_IGNORE_SLOWDOWN) + if(was_water && !is_water) + source.remove_movespeed_modifier(/datum/movespeed_modifier/fish_on_water) + source.remove_actionspeed_modifier(/datum/actionspeed_modifier/fish_on_water) + source.add_traits(list(TRAIT_OFF_BALANCE_TACKLER, TRAIT_NO_STAGGER, TRAIT_NO_THROW_HITPUSH), type) + else if(!was_water && is_water) + source.add_movespeed_modifier(/datum/movespeed_modifier/fish_on_water) + source.add_actionspeed_modifier(/datum/actionspeed_modifier/fish_on_water) + source.add_traits(list(TRAIT_OFF_BALANCE_TACKLER, TRAIT_NO_STAGGER, TRAIT_NO_THROW_HITPUSH), type) + +/datum/bodypart_overlay/mutant/tail/fish + feature_key = "fish_tail" + color_source = ORGAN_COLOR_HAIR + +/datum/bodypart_overlay/mutant/tail/fish/on_mob_insert(obj/item/organ/parent, mob/living/carbon/receiver) + //Initialize the related dna feature block if we don't have any so it doesn't error out. + //This isn't tied to any species, but I kinda want it to be mutable instead of having a fixed sprite accessory. + if(imprint_on_next_insertion && !receiver.dna.features["fish_tail"]) + receiver.dna.features["fish_tail"] = /datum/sprite_accessory/tails/fish/none::name // DOPPLER EDIT, old code: receiver.dna.features["fish_tail"] = pick(SSaccessories.tails_list_fish) + receiver.dna.update_uf_block(DNA_FISH_TAIL_BLOCK) + + return ..() + +/datum/bodypart_overlay/mutant/tail/fish/get_global_feature_list() + return SSaccessories.tails_list_fish + + +///Lungs that replace the need of oxygen with water vapor or being wet +/obj/item/organ/internal/lungs/fish + name = "mutated gills" + desc = "Fish DNA infused on what once was a normal pair of lungs that now require spacemen to breathe water vapor, or keep themselves covered in water." + icon = 'icons/obj/medical/organs/infuser_organs.dmi' + icon_state = "gills" + + safe_oxygen_min = 0 //We don't breathe this + ///The required partial pressure of water_vapor for not drowing + var/safe_water_level = 29 + + /// Bodypart overlay applied to the chest where the lungs are in + var/datum/bodypart_overlay/simple/gills/gills + + var/has_gills = TRUE + +/obj/item/organ/internal/lungs/fish/Initialize(mapload) + . = ..() + add_gas_reaction(/datum/gas/water_vapor, always = PROC_REF(breathe_water)) + respiration_type |= RESPIRATION_OXYGEN //after all, we get oxygen from water + AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/fish) + if(has_gills) + gills = new() + AddElement(/datum/element/noticable_organ, "%PRONOUN_Theyve a set of gills on %PRONOUN_their neck.", BODY_ZONE_PRECISE_MOUTH) + AddComponent(/datum/component/bubble_icon_override, "fish", BUBBLE_ICON_PRIORITY_ORGAN) + +/obj/item/organ/internal/lungs/fish/Destroy() + QDEL_NULL(gills) + return ..() + +/obj/item/organ/internal/lungs/fish/on_bodypart_insert(obj/item/bodypart/limb) + . = ..() + if(gills) + limb.add_bodypart_overlay(gills) + +/obj/item/organ/internal/lungs/fish/on_bodypart_remove(obj/item/bodypart/limb) + . = ..() + if(gills) + limb.remove_bodypart_overlay(gills) + +/obj/item/organ/internal/lungs/fish/on_mob_remove(mob/living/carbon/owner) + . = ..() + owner.clear_alert(ALERT_NOT_ENOUGH_WATER) + +/// Requires the spaceman to have either water vapor or be wet. +/obj/item/organ/internal/lungs/fish/proc/breathe_water(mob/living/carbon/breather, datum/gas_mixture/breath, water_pp, old_water_pp) + var/need_to_breathe = !HAS_TRAIT(src, TRAIT_SPACEBREATHING) && !HAS_TRAIT(breather, TRAIT_IS_WET) + if(water_pp < safe_water_level && need_to_breathe) + on_low_water(breather, breath, water_pp) + return + + if(old_water_pp < safe_water_level || breather.failed_last_breath) + breather.failed_last_breath = FALSE + breather.clear_alert(ALERT_NOT_ENOUGH_WATER) + + if(need_to_breathe) + breathe_gas_volume(breath, /datum/gas/water_vapor, /datum/gas/carbon_dioxide) + // Heal mob if not in crit. + if(breather.health >= breather.crit_threshold && breather.oxyloss) + breather.adjustOxyLoss(-5) + +/// Called when there isn't enough water to breath +/obj/item/organ/internal/lungs/fish/proc/on_low_water(mob/living/carbon/breather, datum/gas_mixture/breath, water_pp) + breather.throw_alert(ALERT_NOT_ENOUGH_WATER, /atom/movable/screen/alert/not_enough_water) + var/gas_breathed = handle_suffocation(breather, water_pp, safe_water_level, breath.gases[/datum/gas/water_vapor][MOLES]) + if(water_pp) + breathe_gas_volume(breath, /datum/gas/water_vapor, /datum/gas/carbon_dioxide, volume = gas_breathed) + +// Simple overlay so we can add gills to those with fish lungs +/datum/bodypart_overlay/simple/gills + icon = 'icons/mob/human/fish_features.dmi' + icon_state = "gills" + layers = EXTERNAL_ADJACENT + +/datum/bodypart_overlay/simple/gills/get_image(image_layer, obj/item/bodypart/limb) + return image( + icon = icon, + icon_state = "[icon_state]_[mutant_bodyparts_layertext(image_layer)]", + layer = image_layer, + ) + +/// Subtype of gills that allow the mob to optionally breathe water. +/obj/item/organ/internal/lungs/fish/amphibious + name = "mutated semi-aquatic lungs" + desc = "DNA from an amphibious or semi-aquatic creature infused on a pair lungs. Enjoy breathing underwater without drowning outside water." + safe_oxygen_min = /obj/item/organ/internal/lungs::safe_oxygen_min + safe_water_level = 19 + has_gills = FALSE + /** + * If false, we don't breathe air since we've got water instead. + * Set to FALSE at the start of each cycle and TRUE on on_low_water() + */ + var/should_breathe_oxygen = FALSE + +/obj/item/organ/internal/lungs/fish/amphibious/Initialize(mapload) + . = ..() + /** + * We're setting the gas reaction for breathing oxygen here, + * since gas reation procs are run in the order they're added, + * and we want breathe_water() to run before breathe_oxygen, + * so that if we're breathing water vapor (or are wet), we won't have to breathe oxygen. + */ + safe_oxygen_min = /obj/item/organ/internal/lungs::safe_oxygen_min + add_gas_reaction(/datum/gas/oxygen, always = PROC_REF(breathe_oxygen)) + +/obj/item/organ/internal/lungs/fish/amphibious/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/breather) + should_breathe_oxygen = FALSE //assume we don't have to breathe oxygen until we fail to breathe water + return ..() + +/obj/item/organ/internal/lungs/fish/amphibious/on_low_water(mob/living/carbon/breather, datum/gas_mixture/breath, water_pp) + should_breathe_oxygen = TRUE + return + +/obj/item/organ/internal/lungs/fish/amphibious/breathe_oxygen(mob/living/carbon/breather, datum/gas_mixture/breath, o2_pp, old_o2_pp) + if(!should_breathe_oxygen) + if(breather.failed_last_breath) //in case we had neither oxygen nor water last tick. + breather.clear_alert(ALERT_NOT_ENOUGH_OXYGEN) + return + return ..() + +///Fish infuser organ, allows mobs to safely eat raw fish. +/obj/item/organ/internal/stomach/fish + name = "mutated fish-stomach" + desc = "Fish DNA infused into a stomach now parmated by the faint smell of salt and slightly putrified fish." + icon = 'icons/obj/medical/organs/infuser_organs.dmi' + icon_state = "stomach" + greyscale_config = /datum/greyscale_config/mutant_organ + greyscale_colors = FISH_COLORS + + organ_traits = list(TRAIT_STRONG_STOMACH, TRAIT_FISH_EATER) + disgust_metabolism = 2.5 + +/obj/item/organ/internal/stomach/fish/Initialize(mapload) + . = ..() + AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/fish) + + +///Organ from fish with the ink production trait. Doesn't count toward the organ set bonus but is buffed once it's active. +/obj/item/organ/internal/tongue/inky + name = "ink-secreting tongue" + desc = "A black tongue linked to two swollen black sacs underneath the palate." + icon = 'icons/obj/medical/organs/infuser_organs.dmi' + icon_state = "inky_tongue" + actions_types = list(/datum/action/cooldown/ink_spit) + +/obj/item/organ/internal/tongue/inky/Initialize(mapload) + . = ..() + AddElement(/datum/element/noticable_organ, "Slick black ink seldom rivulets from %PRONOUN_their mouth.", BODY_ZONE_PRECISE_MOUTH) + +///Organ from fish with the toxic trait. Allows the user to use tetrodotoxin as a healing chem instead of a toxin. +/obj/item/organ/internal/liver/fish + name = "mutated fish-liver" + desc = "Fish DNA infused into a stomach that now uses tetrodotoxin as regenerative material. It also processes alcohol quite well." + icon = 'icons/obj/medical/organs/infuser_organs.dmi' + icon_state = "liver" + greyscale_config = /datum/greyscale_config/mutant_organ + greyscale_colors = FISH_COLORS + + organ_traits = list(TRAIT_TETRODOTOXIN_HEALING, TRAIT_ALCOHOL_TOLERANCE) //drink like a fish :^) + liver_resistance = parent_type::liver_resistance * 1.5 + food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/iron = 5, /datum/reagent/toxin/tetrodotoxin = 5) + grind_results = list(/datum/reagent/consumable/nutriment/peptides = 5, /datum/reagent/toxin/tetrodotoxin = 5) + +/obj/item/organ/internal/liver/fish/Initialize(mapload) + . = ..() + AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/fish) + +#undef FISH_ORGAN_COLOR +#undef FISH_SCLERA_COLOR +#undef FISH_PUPIL_COLOR +#undef FISH_COLORS diff --git a/code/game/machinery/droneDispenser.dm b/code/game/machinery/drone_dispenser.dm similarity index 77% rename from code/game/machinery/droneDispenser.dm rename to code/game/machinery/drone_dispenser.dm index 03a5c4c6cf93b..414746dcb1923 100644 --- a/code/game/machinery/droneDispenser.dm +++ b/code/game/machinery/drone_dispenser.dm @@ -14,40 +14,58 @@ integrity_failure = 0.33 // These allow for different icons when creating custom dispensers + /// Icon string to use when the drone dispenser is not processing. var/icon_off = "off" + /// Icon string to use when the drone dispenser is processing. var/icon_on = "on" + /// Icon string to use when the drone dispenser is on cooldown. var/icon_recharging = "recharge" + /// Icon string to use when the drone dispenser is making a new shell. var/icon_creating = "make" + /// The quantity of materials used when generating a new drone shell. var/list/using_materials + /// Quantity of materials to automatically insert when the drone dispenser is spawned. var/starting_amount = 0 var/iron_cost = HALF_SHEET_MATERIAL_AMOUNT var/glass_cost = HALF_SHEET_MATERIAL_AMOUNT + /// Energy to draw when processing a new drone shell fresh. var/energy_used = 1 KILO JOULES + /// What operation the drone shell dispenser is currently in, checked in process() to determine behavior var/mode = DRONE_READY + /// Reference to world.time to use for calculation of cooldowns and production of a new drone dispenser. var/timer + /// How long should the drone dispenser be on cooldown after operating var/cooldownTime = 3 MINUTES - var/production_time = 30 + /// How long does it the drone dispenser take to generate a new drone shell? + var/production_time = 3 SECONDS //The item the dispenser will create - var/dispense_type = /obj/effect/mob_spawn/ghost_role/drone + var/list/dispense_type = list(/obj/effect/mob_spawn/ghost_role/drone) - // The maximum number of "idle" drone shells it will make before - // ceasing production. Set to 0 for infinite. + /// The maximum number of "idle" drone shells it will make before ceasing production. Set to 0 for infinite. var/maximum_idle = 3 + /// Sound that the drone dispnser plays when it's ready to start making more drones. var/work_sound = 'sound/items/tools/rped.ogg' + /// Sound that the drone dispnser plays when it's created a new drone. var/create_sound = 'sound/items/deconstruct.ogg' + /// Sound that the drone dispnser plays when it's recharged it's cooldown. var/recharge_sound = 'sound/machines/ping.ogg' + /// String that's displayed for when the drone dispenser start working. var/begin_create_message = "whirs to life!" + /// String that's displayed for when the drone dispenser stops working. var/end_create_message = "dispenses a drone shell." + /// String that's displayed for when the drone dispenser finished it's cooldown. var/recharge_message = "pings." + /// String that's displayed for when the drone dispenser is still on cooldown. var/recharging_text = "It is whirring and clicking. It seems to be recharging." - + /// String that's displayed for when the drone dispenser is broken. var/break_message = "lets out a tinny alarm before falling dark." + /// Sound that the drone dispnser plays when it's broken. var/break_sound = 'sound/machines/warning-buzzer.ogg' - + /// Reference to the object's internal storage for materials. var/datum/component/material_container/materials /obj/machinery/drone_dispenser/Initialize(mapload) @@ -75,7 +93,7 @@ /obj/machinery/drone_dispenser/syndrone //Please forgive me name = "syndrone shell dispenser" desc = "A suspicious machine that will create Syndicate exterminator drones when supplied with iron and glass. Disgusting." - dispense_type = /obj/effect/mob_spawn/ghost_role/drone/syndrone + dispense_type = list(/obj/effect/mob_spawn/ghost_role/drone/syndrone) //If we're gonna be a jackass, go the full mile - 10 second recharge timer cooldownTime = 100 end_create_message = "dispenses a suspicious drone shell." @@ -84,14 +102,14 @@ /obj/machinery/drone_dispenser/syndrone/badass //Please forgive me name = "badass syndrone shell dispenser" desc = "A suspicious machine that will create Syndicate exterminator drones when supplied with iron and glass. Disgusting. This one seems ominous." - dispense_type = /obj/effect/mob_spawn/ghost_role/drone/syndrone/badass + dispense_type = list(/obj/effect/mob_spawn/ghost_role/drone/syndrone/badass) end_create_message = "dispenses an ominous suspicious drone shell." // I don't need your forgiveness, this is awesome. /obj/machinery/drone_dispenser/snowflake name = "snowflake drone shell dispenser" desc = "A hefty machine that, when supplied with iron and glass, will periodically create a snowflake drone shell. Does not need to be manually operated." - dispense_type = /obj/effect/mob_spawn/ghost_role/drone/snowflake + dispense_type = list(/obj/effect/mob_spawn/ghost_role/drone/snowflake) end_create_message = "dispenses a snowflake drone shell." // Those holoprojectors aren't cheap iron_cost = SHEET_MATERIAL_AMOUNT @@ -103,7 +121,7 @@ /obj/machinery/drone_dispenser/derelict name = "derelict drone shell dispenser" desc = "A rusty machine that, when supplied with iron and glass, will periodically create a derelict drone shell. Does not need to be manually operated." - dispense_type = /obj/effect/mob_spawn/ghost_role/drone/derelict + dispense_type = list(/obj/effect/mob_spawn/ghost_role/drone/derelict) end_create_message = "dispenses a derelict drone shell." iron_cost = SHEET_MATERIAL_AMOUNT * 5 glass_cost = SHEET_MATERIAL_AMOUNT * 2.5 @@ -113,7 +131,7 @@ /obj/machinery/drone_dispenser/classic name = "classic drone shell dispenser" desc = "A hefty machine that, when supplied with iron and glass, will periodically create a classic drone shell. Does not need to be manually operated." - dispense_type = /obj/effect/mob_spawn/ghost_role/drone/classic + dispense_type = list(/obj/effect/mob_spawn/ghost_role/drone/classic) end_create_message = "dispenses a classic drone shell." // An example of a custom drone dispenser. @@ -131,7 +149,7 @@ glass_cost = 0 energy_used = 0 cooldownTime = 10 //Only 1 second - hivebots are extremely weak - dispense_type = /mob/living/basic/hivebot + dispense_type = list(/mob/living/basic/hivebot) begin_create_message = "closes and begins fabricating something within." end_create_message = "slams open, revealing a hivebot!" recharge_sound = null @@ -141,7 +159,7 @@ /obj/machinery/drone_dispenser/binoculars name = "binoculars fabricator" desc = "A hefty machine that periodically creates a pair of binoculars. Really, Nanotrasen? We're getting this lazy?" - dispense_type = /obj/item/binoculars + dispense_type = list(/obj/item/binoculars) starting_amount = SHEET_MATERIAL_AMOUNT * 2.5 //Redudant maximum_idle = 1 cooldownTime = 5 SECONDS @@ -194,8 +212,9 @@ if(energy_used) use_energy(energy_used) - var/atom/A = new dispense_type(loc) - A.flags_1 |= (flags_1 & ADMIN_SPAWNED_1) + for(var/spawnable_item as anything in dispense_type) + var/atom/spawned_atom = new spawnable_item(loc) + spawned_atom.flags_1 |= (flags_1 & ADMIN_SPAWNED_1) if(create_sound) playsound(src, create_sound, 50, TRUE) @@ -217,9 +236,10 @@ /obj/machinery/drone_dispenser/proc/count_shells() . = 0 - for(var/a in loc) - if(istype(a, dispense_type)) - .++ + for(var/actual_shell in loc) + for(var/potential_item as anything in dispense_type) + if(istype(actual_shell, potential_item)) + .++ /obj/machinery/drone_dispenser/update_icon_state() if(machine_stat & (BROKEN|NOPOWER)) diff --git a/code/game/machinery/flatpacker.dm b/code/game/machinery/flatpacker.dm index 56fcc8a8ae74c..6c90e45e4f67b 100644 --- a/code/game/machinery/flatpacker.dm +++ b/code/game/machinery/flatpacker.dm @@ -124,7 +124,7 @@ highest_mat = present_mat highest_mat_ref = mat - flick_overlay_view(material_insertion_animation(highest_mat_ref.greyscale_colors), 1 SECONDS) + flick_overlay_view(material_insertion_animation(highest_mat_ref), 1 SECONDS) /** * Attempts to find the total material cost of a typepath (including our creation efficiency), modifying a list diff --git a/code/game/machinery/nebula_shielding.dm b/code/game/machinery/nebula_shielding.dm index 10306177ebf5a..6473c1b1bfc46 100644 --- a/code/game/machinery/nebula_shielding.dm +++ b/code/game/machinery/nebula_shielding.dm @@ -140,7 +140,7 @@ /obj/item/paper/fluff/radiation_nebula name = "radioactive nebula shielding" default_raw_text = {"EXTREME IMPORTANCE!!!!
- Set up these radioactive nebula shielding units before the gravity generators native shielding is overwhelmed!
+ Set up these radioactive nebula shielding units before the gravity generator's native shielding is overwhelmed!
Shielding units passively generate tritium, so make sure to properly ventilate/isolate the area before setting up a shielding unit! More circuit boards can be ordered through cargo. Consider setting up auxillary shielding units in-case of destruction, power loss or sabotage. "} @@ -149,6 +149,6 @@ /obj/item/paper/fluff/radiation_nebula_virologist name = "radioactive resonance" default_raw_text = {"EXTREME IMPORTANCE!!!!
- During routine bloodscreening on employees working in the nebula, we found no traces of the sympton called 'Radioactive Resonance'.
- Something inside the nebula is interfering with it, be wary of a more shallow viral genepool. + During routine blood screening on employees working within the nebula, we have found no traces of the symptom called 'Radioactive Resonance'.
+ Something inside the nebula is interfering with it; be wary of a more shallow viral genepool. "} diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm index c9ed74caa02a9..97ac006bcd500 100644 --- a/code/game/machinery/syndicatebeacon.dm +++ b/code/game/machinery/syndicatebeacon.dm @@ -11,10 +11,12 @@ density = TRUE layer = BELOW_MOB_LAYER //so people can't hide it and it's REALLY OBVIOUS verb_say = "states" - var/cooldown = 0 + /// Cooldown each time singularity is pulled in our direction + COOLDOWN_DECLARE(singularity_beacon_cd) var/active = FALSE var/icontype = "beacon" + var/energy_used = 1.5 KILO JOULES /obj/machinery/power/singularity_beacon/proc/Activate(mob/user = null) @@ -42,11 +44,9 @@ if(user) to_chat(user, span_notice("You deactivate the beacon.")) - /obj/machinery/power/singularity_beacon/attack_ai(mob/user) return - /obj/machinery/power/singularity_beacon/attack_hand(mob/user, list/modifiers) . = ..() if(.) @@ -93,10 +93,10 @@ if(!active) return - if(surplus() >= 1500) - add_load(1500) - if(cooldown <= world.time) - cooldown = world.time + 80 + if(surplus() >= energy_used) + add_load(energy_used) + if(COOLDOWN_FINISHED(src, singularity_beacon_cd)) + COOLDOWN_START(src, singularity_beacon_cd, 8 SECONDS) for(var/_singulo_component in GLOB.singularities) var/datum/component/singularity/singulo_component = _singulo_component var/atom/singulo = singulo_component.parent @@ -106,6 +106,95 @@ Deactivate() say("Insufficient charge detected - powering down") +// Used for the No Escape final objective that attracts a singularity to the escape shuttle +// needs to be charged with an inducer to work +/obj/machinery/power/singularity_beacon/syndicate/no_escape + name = "ominous beacon" + desc = "This looks very suspicious..." + processing_flags = START_PROCESSING_MANUALLY + /// The cell we spawn with + var/obj/item/stock_parts/power_store/cell/cell = /obj/item/stock_parts/power_store/cell/super/empty + /// The black hole shuttle event that is triggered + var/datum/shuttle_event/simple_spawner/black_hole/no_escape/no_escape_event + +/obj/machinery/power/singularity_beacon/syndicate/no_escape/Initialize(mapload) + . = ..() + cell = new cell(src) + +/obj/machinery/power/singularity_beacon/syndicate/no_escape/Destroy() + if(active) + Deactivate() + QDEL_NULL(cell) + // destroying the beacon doesn't automatically stop the event + no_escape_event = null + return ..() + +/obj/machinery/power/singularity_beacon/syndicate/no_escape/examine(mob/user) + . = ..() + . += "\The [src] is [active ? "on" : "off"]." + if(cell) + . += "The charge meter reads [cell ? round(cell.percent(), 1) : 0]%." + +/obj/machinery/power/singularity_beacon/syndicate/no_escape/get_cell() + return cell + +/obj/machinery/power/singularity_beacon/syndicate/no_escape/attack_hand(mob/user, list/modifiers) + return active ? Deactivate(user) : Activate(user) + +/obj/machinery/power/singularity_beacon/syndicate/no_escape/Activate(mob/user = null) + if(!cell.charge()) + say("Insufficient charge detected") + return + + icon_state = "[icontype]1" + active = TRUE + begin_processing() + if(user) + to_chat(user, span_notice("You activate the beacon.")) + +/obj/machinery/power/singularity_beacon/syndicate/no_escape/Deactivate(mob/user = null) + icon_state = "[icontype]0" + active = FALSE + end_processing() + if(user) + to_chat(user, span_notice("You deactivate the beacon.")) + +/obj/machinery/power/singularity_beacon/syndicate/no_escape/wrench_act(mob/living/user, obj/item/tool) + . = TRUE + + tool.play_tool_sound(src, 50) + if(anchored) + set_anchored(FALSE) + to_chat(user, span_notice("You unbolt \the [src] from the floor.")) + return + else + set_anchored(TRUE) + to_chat(user, span_notice("You bolt \the [src] to the floor.")) + return + +/obj/machinery/power/singularity_beacon/syndicate/no_escape/screwdriver_act(mob/living/user, obj/item/tool) + return + +/obj/machinery/power/singularity_beacon/syndicate/no_escape/emp_act(severity) + . = ..() + if(machine_stat & (NOPOWER|BROKEN) || . & EMP_PROTECT_CONTENTS) + return + cell?.emp_act(severity) + +/obj/machinery/power/singularity_beacon/syndicate/no_escape/process() + if(cell.charge()) + cell.use(energy_used, force = TRUE) + + if(!no_escape_event) + var/area/escape_shuttle_area = get_area(src) + // beacon must be on the traveling escape shuttle (not a pod) + if(istype(escape_shuttle_area, /area/shuttle/escape) && (SSshuttle.emergency.mode == SHUTTLE_ESCAPE) && SSshuttle.emergency.is_in_shuttle_bounds(src)) + var/obj/docking_port/mobile/port = SSshuttle.emergency + no_escape_event = port.add_shuttle_event(/datum/shuttle_event/simple_spawner/black_hole/no_escape) + no_escape_event.beacon = src + else + Deactivate() + say("Insufficient charge detected - powering down") /obj/machinery/power/singularity_beacon/syndicate icontype = "beaconsynd" @@ -131,6 +220,10 @@ qdel(src) return +/obj/item/sbeacondrop/no_escape + name = "very suspicious beacon" + droptype = /obj/machinery/power/singularity_beacon/syndicate/no_escape + /obj/item/sbeacondrop/bomb desc = "A label on it reads: Warning: Activating this device will send a high-ordinance explosive to your location." droptype = /obj/machinery/syndicatebomb diff --git a/code/game/objects/effects/anomalies/anomalies_dimensional_themes.dm b/code/game/objects/effects/anomalies/anomalies_dimensional_themes.dm index 2d92eaabb929c..8f10717c771e9 100644 --- a/code/game/objects/effects/anomalies/anomalies_dimensional_themes.dm +++ b/code/game/objects/effects/anomalies/anomalies_dimensional_themes.dm @@ -36,7 +36,7 @@ /datum/dimension_theme/New() if (material) var/datum/material/using_mat = GET_MATERIAL_REF(material) - window_colour = using_mat.greyscale_colors + window_colour = using_mat.color /** * Applies themed transformation to the provided turf. diff --git a/code/game/objects/effects/cursor_catcher.dm b/code/game/objects/effects/cursor_catcher.dm index a8c19e40be80d..366ab0556248c 100644 --- a/code/game/objects/effects/cursor_catcher.dm +++ b/code/game/objects/effects/cursor_catcher.dm @@ -60,8 +60,8 @@ var/icon_y = text2num(LAZYACCESS(modifiers, VIS_Y)) if(isnull(icon_y)) icon_y = text2num(LAZYACCESS(modifiers, ICON_Y)) - var/our_x = round(icon_x / world.icon_size) - var/our_y = round(icon_y / world.icon_size) + var/our_x = round(icon_x / ICON_SIZE_X) + var/our_y = round(icon_y / ICON_SIZE_Y) given_turf = locate(owner.x + our_x - round(view_list[1]/2), owner.y + our_y - round(view_list[2]/2), owner.z) - given_x = round(icon_x - world.icon_size * our_x, 1) - given_y = round(icon_y - world.icon_size * our_y, 1) + given_x = round(icon_x - ICON_SIZE_X * our_x, 1) + given_y = round(icon_y - ICON_SIZE_Y * our_y, 1) diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index b6837df6f9546..21eff5028b57e 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -1,6 +1,5 @@ /obj/effect/decal/cleanable gender = PLURAL - plane = GAME_PLANE layer = FLOOR_CLEAN_LAYER var/list/random_icon_states = null ///I'm sorry but cleanable/blood code is ass, and so is blood_DNA diff --git a/code/game/objects/effects/decals/cleanable/aliens.dm b/code/game/objects/effects/decals/cleanable/aliens.dm index bf826e207db37..bc7923ac0ed47 100644 --- a/code/game/objects/effects/decals/cleanable/aliens.dm +++ b/code/game/objects/effects/decals/cleanable/aliens.dm @@ -23,7 +23,8 @@ desc = "Gnarly..." icon = 'icons/effects/blood.dmi' icon_state = "xgib1" - layer = LOW_OBJ_LAYER + plane = GAME_PLANE + layer = BELOW_OBJ_LAYER random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6") mergeable_decal = FALSE diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm index 808357df1d8d3..c3bdfbdb89543 100644 --- a/code/game/objects/effects/decals/cleanable/humans.dm +++ b/code/game/objects/effects/decals/cleanable/humans.dm @@ -111,7 +111,7 @@ desc = "They look bloody and gruesome." icon = 'icons/effects/blood.dmi' icon_state = "gib1" - layer = LOW_OBJ_LAYER + layer = BELOW_OBJ_LAYER plane = GAME_PLANE random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6") mergeable_decal = FALSE @@ -354,6 +354,8 @@ GLOBAL_LIST_EMPTY(bloody_footprints_cache) pass_flags = PASSTABLE | PASSGRILLE icon_state = "hitsplatter1" random_icon_states = list("hitsplatter1", "hitsplatter2", "hitsplatter3") + plane = GAME_PLANE + layer = ABOVE_WINDOW_LAYER /// The turf we just came from, so we can back up when we hit a wall var/turf/prev_loc /// The cached info about the blood diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm index 1124e32983f31..caf7428ef01fa 100644 --- a/code/game/objects/effects/decals/cleanable/misc.dm +++ b/code/game/objects/effects/decals/cleanable/misc.dm @@ -10,6 +10,8 @@ desc = "Ashes to ashes, dust to dust, and into space." icon = 'icons/obj/debris.dmi' icon_state = "ash" + plane = GAME_PLANE + layer = GAME_CLEAN_LAYER mergeable_decal = FALSE beauty = -50 decal_reagent = /datum/reagent/ash @@ -144,6 +146,7 @@ name = "cobweb" desc = "Somebody should remove that." gender = NEUTER + plane = GAME_PLANE layer = WALL_OBJ_LAYER icon = 'icons/effects/web.dmi' icon_state = "cobweb1" @@ -160,6 +163,8 @@ gender = NEUTER icon = 'icons/effects/effects.dmi' icon_state = "molten" + plane = GAME_PLANE + layer = GAME_CLEAN_LAYER mergeable_decal = FALSE beauty = -150 clean_type = CLEAN_TYPE_HARD_DECAL @@ -245,6 +250,8 @@ name = "chemical pile" desc = "A pile of chemicals. You can't quite tell what's inside it." gender = NEUTER + plane = GAME_PLANE + layer = GAME_CLEAN_LAYER icon = 'icons/obj/debris.dmi' icon_state = "ash" @@ -322,6 +329,8 @@ desc = "Torn pieces of cardboard and paper, left over from a package." icon = 'icons/obj/debris.dmi' icon_state = "paper_shreds" + plane = GAME_PLANE + layer = GAME_CLEAN_LAYER /obj/effect/decal/cleanable/wrapping/pinata name = "pinata shreds" @@ -340,7 +349,7 @@ icon = 'icons/obj/debris.dmi' icon_state = "garbage" plane = GAME_PLANE - layer = FLOOR_CLEAN_LAYER //To display the decal over wires. + layer = GAME_CLEAN_LAYER beauty = -150 clean_type = CLEAN_TYPE_HARD_DECAL @@ -443,7 +452,6 @@ name = "pool of fuel" desc = "A pool of flammable fuel. Its probably wise to clean this off before something ignites it..." icon_state = "fuel_pool" - layer = LOW_OBJ_LAYER beauty = -50 clean_type = CLEAN_TYPE_BLOOD mouse_opacity = MOUSE_OPACITY_OPAQUE @@ -558,6 +566,8 @@ icon_state = "rubble" mergeable_decal = FALSE beauty = -10 + plane = GAME_PLANE + layer = BELOW_OBJ_LAYER /obj/effect/decal/cleanable/rubble/Initialize(mapload) . = ..() diff --git a/code/game/objects/effects/decals/cleanable/robots.dm b/code/game/objects/effects/decals/cleanable/robots.dm index 808a68d6f5eb0..3f2957a9c9e16 100644 --- a/code/game/objects/effects/decals/cleanable/robots.dm +++ b/code/game/objects/effects/decals/cleanable/robots.dm @@ -5,7 +5,8 @@ desc = "It's a useless heap of junk... or is it?" icon = 'icons/mob/silicon/robots.dmi' icon_state = "gib1" - layer = LOW_OBJ_LAYER + plane = GAME_PLANE + layer = BELOW_OBJ_LAYER random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7") blood_state = BLOOD_STATE_OIL bloodiness = BLOOD_AMOUNT_PER_DECAL diff --git a/code/game/objects/effects/decals/crayon.dm b/code/game/objects/effects/decals/crayon.dm index eced2fb66f1ee..e27e6f91337fe 100644 --- a/code/game/objects/effects/decals/crayon.dm +++ b/code/game/objects/effects/decals/crayon.dm @@ -4,7 +4,6 @@ icon = 'icons/effects/crayondecal.dmi' icon_state = "rune1" gender = NEUTER - plane = GAME_PLANE //makes the graffiti visible over a wall. mergeable_decal = FALSE flags_1 = ALLOW_DARK_PAINTS_1 var/do_icon_rotate = TRUE @@ -13,6 +12,10 @@ /obj/effect/decal/cleanable/crayon/Initialize(mapload, main, type, e_name, graf_rot, alt_icon = null, desc_override = null) . = ..() + if(isclosedturf(loc) && loc.density) + // allows for wall graffiti to be seen + SET_PLANE_IMPLICIT(src, GAME_PLANE) + layer = GAME_CLEAN_LAYER if(e_name) name = e_name if(desc_override) diff --git a/code/game/objects/effects/forcefields.dm b/code/game/objects/effects/forcefields.dm index 4445815a422be..60ce9d7662b81 100644 --- a/code/game/objects/effects/forcefields.dm +++ b/code/game/objects/effects/forcefields.dm @@ -84,7 +84,7 @@ icon = 'icons/effects/eldritch.dmi' icon_state = "cosmic_carpet" anchored = TRUE - layer = LOW_SIGIL_LAYER + layer = BELOW_OBJ_LAYER density = FALSE can_atmos_pass = ATMOS_PASS_NO initial_duration = 30 SECONDS diff --git a/code/game/objects/effects/material_insert.dm b/code/game/objects/effects/material_insert.dm index 9ca86226b24b9..3dcdd904a01d5 100644 --- a/code/game/objects/effects/material_insert.dm +++ b/code/game/objects/effects/material_insert.dm @@ -2,21 +2,18 @@ * Creates a mutable appearance with the material color applied for its insertion animation into an autolathe or techfab * Arguments * - * * color - the material color that will be applied + * * material - the material used to generate the overlay */ -/proc/material_insertion_animation(color) +/proc/material_insertion_animation(datum/material/material) RETURN_TYPE(/mutable_appearance) var/static/list/mutable_appearance/apps = list() - var/mutable_appearance/cached_app = apps[color] + var/mutable_appearance/cached_app = apps[material] if(isnull(cached_app)) - var/icon/modified_icon = icon('icons/obj/machines/research.dmi', "material_insertion") + cached_app = mutable_appearance('icons/obj/machines/research.dmi', "material_insertion") + cached_app.color = material.color + cached_app.alpha = material.alpha - //assuming most of the icon is white we find what ratio to scale the intensity of each part roughly - var/list/rgb_list = rgb2num(color) - modified_icon.SetIntensity(rgb_list[1] / 255, rgb_list[2] / 255, rgb_list[3] / 255) - cached_app = mutable_appearance(modified_icon, "material_insertion") - - apps[color] = cached_app + apps[material] = cached_app return cached_app diff --git a/code/game/objects/effects/step_triggers.dm b/code/game/objects/effects/step_triggers.dm index 1467a7854be52..68a49b8a3031b 100644 --- a/code/game/objects/effects/step_triggers.dm +++ b/code/game/objects/effects/step_triggers.dm @@ -220,3 +220,9 @@ if(happens_once) qdel(src) + +/obj/effect/step_trigger/sound_effect/lavaland_cult_altar + happens_once = 1 + name = "a grave mistake"; + sound = 'sound/effects/hallucinations/i_see_you1.ogg' + triggerer_only = 1 diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index 6e7df14b7c564..033f83edfc739 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -402,7 +402,12 @@ duration = 6 /obj/effect/temp_visual/impact_effect/neurotoxin - icon_state = "impact_neurotoxin" + icon_state = "impact_spit" + color = "#5BDD04" + +/obj/effect/temp_visual/impact_effect/ink_spit + icon_state = "impact_spit" + color = COLOR_NEARLY_ALL_BLACK /obj/effect/temp_visual/heart name = "heart" @@ -441,7 +446,7 @@ if(size_calc_target) layer = size_calc_target.layer + 0.01 var/icon/I = icon(size_calc_target.icon, size_calc_target.icon_state, size_calc_target.dir) - size_matrix = matrix() * (I.Height()/world.icon_size) + size_matrix = matrix() * (I.Height()/ICON_SIZE_Y) transform = size_matrix //scale the bleed overlay's size based on the target's icon size var/matrix/M = transform if(shrink) diff --git a/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm b/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm index 14b7f43a82280..8c4ea163232e1 100644 --- a/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm +++ b/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm @@ -5,7 +5,7 @@ var/obj/effect/projectile/tracer/PB = new beam_type if(isnull(light_color_override)) light_color_override = color - PB.apply_vars(angle_between_points(starting, ending), midpoint.return_px(), midpoint.return_py(), color, pixel_length_between_points(starting, ending) / world.icon_size, midpoint.return_turf(), 0) + PB.apply_vars(angle_between_points(starting, ending), midpoint.return_px(), midpoint.return_py(), color, pixel_length_between_points(starting, ending) / ICON_SIZE_ALL, midpoint.return_turf(), 0) . = PB if(light_range > 0 && light_intensity > 0) var/list/turf/line = get_line(starting.return_turf(), ending.return_turf()) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 03f6754eb9951..fddfc5b591306 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -161,7 +161,7 @@ var/slowdown = 0 ///percentage of armour effectiveness to remove var/armour_penetration = 0 - ///Whether or not our object is easily hindered by the presence of armor + ///Whether or not our object doubles the value of affecting armour var/weak_against_armour = FALSE /// The click cooldown given after attacking. Lower numbers means faster attacks var/attack_speed = CLICK_CD_MELEE @@ -1796,6 +1796,56 @@ embed_data = ispath(embed) ? get_embed_by_type(embed) : embed SEND_SIGNAL(src, COMSIG_ITEM_EMBEDDING_UPDATE) +/obj/item/apply_main_material_effects(datum/material/main_material, amount, multipier) + . = ..() + if(material_flags & MATERIAL_GREYSCALE) + var/main_mat_type = main_material.type + var/worn_path = get_material_greyscale_config(main_mat_type, greyscale_config_worn) + var/lefthand_path = get_material_greyscale_config(main_mat_type, greyscale_config_inhand_left) + var/righthand_path = get_material_greyscale_config(main_mat_type, greyscale_config_inhand_right) + set_greyscale( + new_worn_config = worn_path, + new_inhand_left = lefthand_path, + new_inhand_right = righthand_path + ) + if(!main_material.item_sound_override) + return + hitsound = main_material.item_sound_override + usesound = main_material.item_sound_override + mob_throw_hit_sound = main_material.item_sound_override + equip_sound = main_material.item_sound_override + pickup_sound = main_material.item_sound_override + drop_sound = main_material.item_sound_override + +/obj/item/remove_main_material_effects(datum/material/main_material, amount, multipier) + . = ..() + if(material_flags & MATERIAL_GREYSCALE) + set_greyscale( + new_worn_config = initial(greyscale_config_worn), + new_inhand_left = initial(greyscale_config_inhand_left), + new_inhand_right = initial(greyscale_config_inhand_right) + ) + if(!main_material.item_sound_override) + return + hitsound = initial(hitsound) + usesound = initial(usesound) + mob_throw_hit_sound = initial(mob_throw_hit_sound) + equip_sound = initial(equip_sound) + pickup_sound = initial(pickup_sound) + drop_sound = initial(drop_sound) + +/obj/item/apply_single_mat_effect(datum/material/material, mat_amount, multiplier) + . = ..() + if(!(material_flags & MATERIAL_AFFECT_STATISTICS) || !slowdown) + return + slowdown += GET_MATERIAL_MODIFIER(material.added_slowdown * mat_amount, multiplier) + +/obj/item/remove_single_mat_effect(datum/material/material, mat_amount, multiplier) + . = ..() + if(!(material_flags & MATERIAL_AFFECT_STATISTICS) || !slowdown) + return + slowdown -= GET_MATERIAL_MODIFIER(material.added_slowdown * mat_amount, multiplier) + /** * Returns the atom(either itself or an internal module) that will interact/attack the target on behalf of us * For example an object can have different `tool_behaviours` (e.g borg omni tool) but will return an internal reference of that tool to attack for us @@ -1836,9 +1886,20 @@ var/list/special_identifier = identifier switch(special_identifier[FISH_BAIT_TYPE]) if(FISH_BAIT_FOODTYPE) - var/obj/item/food/food_bait = bait - return istype(food_bait) && food_bait.foodtypes & special_identifier[FISH_BAIT_VALUE] + var/datum/component/edible/edible = bait.GetComponent(/datum/component/edible) + return edible?.foodtypes & special_identifier[FISH_BAIT_VALUE] if(FISH_BAIT_REAGENT) return bait.reagents?.has_reagent(special_identifier[FISH_BAIT_VALUE], special_identifier[FISH_BAIT_AMOUNT], check_subtypes = TRUE) else CRASH("Unknown bait identifier in fish favourite/disliked list") + +/obj/item/vv_get_header() + . = ..() + . += {" +
+ DAMTYPE: [uppertext(damtype)] + FORCE: [force] + WOUND: [wound_bonus] + BARE WOUND: [bare_wound_bonus] + + "} diff --git a/code/game/objects/items/cardboard_cutouts.dm b/code/game/objects/items/cardboard_cutouts.dm index 960363685b1e8..e46bb676a8caf 100644 --- a/code/game/objects/items/cardboard_cutouts.dm +++ b/code/game/objects/items/cardboard_cutouts.dm @@ -360,3 +360,34 @@ applied_name = "Private Security Officer" applied_desc = "A cardboard cutout of a private security officer." mob_spawner = /obj/effect/mob_spawn/corpse/human/nanotrasensoldier + +/datum/cardboard_cutout/heretic + name = "Heretic" + applied_name = "Unknown" + applied_desc = "A cardboard cutout of a Heretic." + outfit = /datum/outfit/heretic_hallucination + +/datum/cardboard_cutout/changeling + name = "Changeling" + applied_name = "Unknown" + applied_desc = "A cardboard cutout of a Changeling." + outfit = /datum/outfit/changeling + +/datum/cardboard_cutout/pirate + name = "Pirate" + applied_name = "Unknown" + applied_desc = "A cardboard cutout of a space pirate." + outfit = /datum/outfit/pirate/space/captain/cardboard + +/datum/cardboard_cutout/ninja + name = "Space Ninja" + applied_name = "Unknown" + applied_desc = "A cardboard cutout of a space ninja." + outfit = /datum/outfit/ninja + +/datum/cardboard_cutout/abductor + name = "Abductor Agent" + applied_name = "Unknown" + applied_desc = "A cardboard cutout of an abductor agent." + species = /datum/species/abductor + outfit = /datum/outfit/abductor/agent/cardboard diff --git a/code/game/objects/items/chainsaw.dm b/code/game/objects/items/chainsaw.dm index 00ca25985bfee..dad44d69e7ea7 100644 --- a/code/game/objects/items/chainsaw.dm +++ b/code/game/objects/items/chainsaw.dm @@ -26,6 +26,8 @@ var/on = FALSE ///The looping sound for our chainsaw when running var/datum/looping_sound/chainsaw/chainsaw_loop + ///how long it takes to behead someone with this chainsaw. + var/behead_time = 15 SECONDS /obj/item/chainsaw/apply_fantasy_bonuses(bonus) . = ..() @@ -98,8 +100,9 @@ desc = span_warning("VRRRRRRR!!!") armour_penetration = 100 force_on = 30 + behead_time = 2 SECONDS -/obj/item/chainsaw/doomslayer/attack(mob/living/target_mob, mob/living/user, params) +/obj/item/chainsaw/attack(mob/living/target_mob, mob/living/user, params) if (target_mob.stat != DEAD) return ..() @@ -113,7 +116,7 @@ playsound(user, 'sound/items/weapons/slice.ogg', vol = 80, vary = TRUE) target_mob.balloon_alert(user, "cutting off head...") - if (!do_after(user, 2 SECONDS, target_mob, extra_checks = CALLBACK(src, PROC_REF(has_same_head), target_mob, head))) + if (!do_after(user, behead_time, target_mob, extra_checks = CALLBACK(src, PROC_REF(has_same_head), target_mob, head))) return TRUE head.dismember(silent = FALSE) @@ -128,7 +131,7 @@ return TRUE return FALSE -/obj/item/chainsaw/doomslayer/proc/has_same_head(mob/living/target_mob, obj/item/bodypart/head) +/obj/item/chainsaw/proc/has_same_head(mob/living/target_mob, obj/item/bodypart/head) return target_mob.get_bodypart(BODY_ZONE_HEAD) == head /obj/item/chainsaw/mounted_chainsaw diff --git a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm index 36ab3de00c60d..b47d97bcf6607 100644 --- a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm @@ -344,6 +344,23 @@ /datum/stock_part/capacitor = 1) def_components = list(/obj/item/stock_parts/power_store/battery = /obj/item/stock_parts/power_store/battery/high/empty) +/obj/item/circuitboard/machine/smes/connector + name = "power connector" + build_path = /obj/machinery/power/smes/connector + req_components = list( + /obj/item/stack/cable_coil = 5, + /datum/stock_part/capacitor = 1,) + +/obj/item/circuitboard/machine/smesbank + name = "portable SMES" + greyscale_colors = CIRCUIT_COLOR_ENGINEERING + needs_anchored = FALSE + build_path = /obj/machinery/power/smesbank + req_components = list( + /obj/item/stack/cable_coil = 5, + /obj/item/stock_parts/power_store/battery = 5,) + def_components = list(/obj/item/stock_parts/power_store/battery = /obj/item/stock_parts/power_store/battery/high/empty) + /obj/item/circuitboard/machine/techfab/department/engineering name = "\improper Departmental Techfab - Engineering" greyscale_colors = CIRCUIT_COLOR_ENGINEERING @@ -352,6 +369,9 @@ /obj/item/circuitboard/machine/smes/super def_components = list(/obj/item/stock_parts/power_store/battery = /obj/item/stock_parts/power_store/battery/super/empty) +/obj/item/circuitboard/machine/smesbank/super + def_components = list(/obj/item/stock_parts/power_store/battery = /obj/item/stock_parts/power_store/battery/super/empty) + /obj/item/circuitboard/machine/thermomachine name = "Thermomachine" greyscale_colors = CIRCUIT_COLOR_ENGINEERING @@ -1392,7 +1412,7 @@ /obj/item/circuitboard/machine/fishing_portal_generator/emagged name = "Emagged Fishing Portal Generator" - build_path = /obj/machinery/fishing_portal_generator + build_path = /obj/machinery/fishing_portal_generator/emagged //Supply /obj/item/circuitboard/machine/ore_redemption @@ -1720,3 +1740,65 @@ req_components = list( /datum/stock_part/servo = 1, ) + +/obj/item/circuitboard/machine/manucrafter + name = /obj/machinery/power/manufacturing/crafter::name + greyscale_colors = CIRCUIT_COLOR_ENGINEERING + build_path = /obj/machinery/power/manufacturing/crafter + req_components = list( + /obj/item/stack/sheet/iron = 5, + /datum/stock_part/servo = 1, + ) + +/obj/item/circuitboard/machine/manulathe + name = /obj/machinery/power/manufacturing/lathe::name + greyscale_colors = CIRCUIT_COLOR_ENGINEERING + build_path = /obj/machinery/power/manufacturing/lathe + req_components = list( + /obj/item/stack/sheet/iron = 5, + /datum/stock_part/servo = 1, + ) + +/obj/item/circuitboard/machine/manucrusher + name = /obj/machinery/power/manufacturing/crusher::name + greyscale_colors = CIRCUIT_COLOR_ENGINEERING + build_path = /obj/machinery/power/manufacturing/crusher + req_components = list( + /obj/item/stack/sheet/iron = 5, + /datum/stock_part/servo = 1, + ) + +/obj/item/circuitboard/machine/manuunloader + name = /obj/machinery/power/manufacturing/unloader::name + greyscale_colors = CIRCUIT_COLOR_ENGINEERING + build_path = /obj/machinery/power/manufacturing/unloader + req_components = list( + /obj/item/stack/sheet/iron = 5, + /datum/stock_part/servo = 1, + ) + +/obj/item/circuitboard/machine/manusorter + name = /obj/machinery/power/manufacturing/sorter::name + greyscale_colors = CIRCUIT_COLOR_ENGINEERING + build_path = /obj/machinery/power/manufacturing/sorter + req_components = list( + /obj/item/stack/sheet/iron = 5, + /datum/stock_part/scanning_module = 1, + ) + +/obj/item/circuitboard/machine/manusmelter + name = /obj/machinery/power/manufacturing/smelter::name + greyscale_colors = CIRCUIT_COLOR_ENGINEERING + build_path = /obj/machinery/power/manufacturing/smelter + req_components = list( + /obj/item/stack/sheet/iron = 5, + /datum/stock_part/micro_laser = 1, + ) + +/obj/item/circuitboard/machine/manurouter + name = /obj/machinery/power/manufacturing/router::name + greyscale_colors = CIRCUIT_COLOR_ENGINEERING + build_path = /obj/machinery/power/manufacturing/router + req_components = list( + /obj/item/stack/sheet/iron = 5, + ) diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 808b37c54722e..78b150ed89c62 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -504,8 +504,8 @@ var/clicky if(LAZYACCESS(modifiers, ICON_X) && LAZYACCESS(modifiers, ICON_Y)) - clickx = clamp(text2num(LAZYACCESS(modifiers, ICON_X)) - 16, -(world.icon_size/2), world.icon_size/2) - clicky = clamp(text2num(LAZYACCESS(modifiers, ICON_Y)) - 16, -(world.icon_size/2), world.icon_size/2) + clickx = clamp(text2num(LAZYACCESS(modifiers, ICON_X)) - 16, -(ICON_SIZE_X/2), ICON_SIZE_X/2) + clicky = clamp(text2num(LAZYACCESS(modifiers, ICON_Y)) - 16, -(ICON_SIZE_Y/2), ICON_SIZE_Y/2) if(!instant) to_chat(user, span_notice("You start drawing a [temp] on the [target.name]...")) diff --git a/code/game/objects/items/dehy_carp.dm b/code/game/objects/items/dehy_carp.dm index 88a3a98a5bb26..e863f09ecde5b 100644 --- a/code/game/objects/items/dehy_carp.dm +++ b/code/game/objects/items/dehy_carp.dm @@ -71,3 +71,6 @@ UnregisterSignal(owner, COMSIG_QDELETING) owner = null + +/obj/item/toy/plush/carpplushie/dehy_carp/peaceful + mobtype = /mob/living/basic/carp/passive diff --git a/code/game/objects/items/devices/aicard_evil.dm b/code/game/objects/items/devices/aicard_evil.dm index 852a105de350f..bb23779fafec6 100644 --- a/code/game/objects/items/devices/aicard_evil.dm +++ b/code/game/objects/items/devices/aicard_evil.dm @@ -35,7 +35,7 @@ balloon_alert(user, "invalid access!") return var/mob/chosen_one = SSpolling.poll_ghosts_for_target( - check_jobban = ROLE_OPERATIVE, + check_jobban = list(ROLE_OPERATIVE, JOB_AI), poll_time = 20 SECONDS, checked_target = src, ignore_category = POLL_IGNORE_SYNDICATE, @@ -47,12 +47,12 @@ /// Poll has concluded with a ghost, create the AI /obj/item/aicard/syndie/loaded/proc/on_poll_concluded(mob/user, datum/antagonist/nukeop/op_datum, mob/dead/observer/ghost) - if(isnull(ghost)) + if(!ismob(ghost)) to_chat(user, span_warning("Unable to connect to S.E.L.F. dispatch. Please wait and try again later or use the intelliCard on your uplink to get your points refunded.")) return // pick ghost, create AI and transfer - var/mob/living/silicon/ai/weak_syndie/new_ai = new /mob/living/silicon/ai/weak_syndie(get_turf(src), new /datum/ai_laws/syndicate_override, ghost) + var/mob/living/silicon/ai/weak_syndie/new_ai = new /mob/living/silicon/ai/weak_syndie(null, new /datum/ai_laws/syndicate_override, ghost) // create and apply syndie datum var/datum/antagonist/nukeop/nuke_datum = new() nuke_datum.send_to_spawnpoint = FALSE diff --git a/code/game/objects/items/devices/pressureplates.dm b/code/game/objects/items/devices/pressureplates.dm index 18bb026745ac0..17f324d109f99 100644 --- a/code/game/objects/items/devices/pressureplates.dm +++ b/code/game/objects/items/devices/pressureplates.dm @@ -7,7 +7,8 @@ lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' icon_state = "pressureplate" - layer = LOW_OBJ_LAYER + plane = FLOOR_PLANE + layer = HIGH_TURF_LAYER var/trigger_mob = TRUE var/trigger_item = FALSE var/specific_item = null diff --git a/code/game/objects/items/devices/scanners/health_analyzer.dm b/code/game/objects/items/devices/scanners/health_analyzer.dm index 270c070d6dc5e..5b7ee4f7026b8 100644 --- a/code/game/objects/items/devices/scanners/health_analyzer.dm +++ b/code/game/objects/items/devices/scanners/health_analyzer.dm @@ -280,7 +280,7 @@ var/list/missing_organs = list() if(!humantarget.get_organ_slot(ORGAN_SLOT_BRAIN)) missing_organs[ORGAN_SLOT_BRAIN] = "Brain" - if(!humantarget.needs_heart() && !humantarget.get_organ_slot(ORGAN_SLOT_HEART)) + if(humantarget.needs_heart() && !humantarget.get_organ_slot(ORGAN_SLOT_HEART)) missing_organs[ORGAN_SLOT_HEART] = "Heart" if(!HAS_TRAIT_FROM(humantarget, TRAIT_NOBREATH, SPECIES_TRAIT) && !isnull(humantarget.dna.species.mutantlungs) && !humantarget.get_organ_slot(ORGAN_SLOT_LUNGS)) missing_organs[ORGAN_SLOT_LUNGS] = "Lungs" diff --git a/code/game/objects/items/extinguisher.dm b/code/game/objects/items/extinguisher.dm index 9c4192116a003..b4150ecb72fea 100644 --- a/code/game/objects/items/extinguisher.dm +++ b/code/game/objects/items/extinguisher.dm @@ -6,6 +6,8 @@ worn_icon_state = "fire_extinguisher" inhand_icon_state = "fire_extinguisher" hitsound = 'sound/items/weapons/smash.ogg' + pickup_sound = 'sound/items/handling/gas_tank/gas_tank_pick_up.ogg' + drop_sound = 'sound/items/handling/gas_tank/gas_tank_drop.ogg' obj_flags = CONDUCTS_ELECTRICITY throwforce = 10 w_class = WEIGHT_CLASS_NORMAL @@ -47,6 +49,9 @@ var/cooling_power = 2 /// Icon state when inside a tank holder. var/tank_holder_icon_state = "holder_extinguisher" + ///The sound a fire extinguisher makes when picked up, dropped if there is liquid inside. + var/fire_extinguisher_reagent_sloshing_sound = SFX_DEFAULT_LIQUID_SLOSH + /obj/item/extinguisher/Initialize(mapload) . = ..() @@ -66,6 +71,17 @@ context[SCREENTIP_CONTEXT_ALT_LMB] = "Empty" return CONTEXTUAL_SCREENTIP_SET +/obj/item/extinguisher/dropped(mob/user, silent) + . = ..() + if(fire_extinguisher_reagent_sloshing_sound && reagents.total_volume > 0) + playsound(src, fire_extinguisher_reagent_sloshing_sound, LIQUID_SLOSHING_SOUND_VOLUME, vary = TRUE, ignore_walls = FALSE) + +/obj/item/extinguisher/equipped(mob/user, slot, initial = FALSE) + . = ..() + if((slot & ITEM_SLOT_HANDS) && fire_extinguisher_reagent_sloshing_sound && reagents.total_volume > 0) + playsound(src, fire_extinguisher_reagent_sloshing_sound, LIQUID_SLOSHING_SOUND_VOLUME, vary = TRUE, ignore_walls = FALSE) + + /obj/item/extinguisher/empty starting_water = FALSE diff --git a/code/game/objects/items/food/egg.dm b/code/game/objects/items/food/egg.dm index d731d8c4978dc..bbb7d6784e2e0 100644 --- a/code/game/objects/items/food/egg.dm +++ b/code/game/objects/items/food/egg.dm @@ -130,9 +130,9 @@ GLOBAL_VAR_INIT(chicks_from_eggs, 0) return ITEM_INTERACT_BLOCKING var/atom/broken_egg = new /obj/item/food/rawegg(interacting_with.loc) if(LAZYACCESS(modifiers, ICON_X)) - broken_egg.pixel_x = clamp(text2num(LAZYACCESS(modifiers, ICON_X)) - 16, -(world.icon_size/2), world.icon_size/2) + broken_egg.pixel_x = clamp(text2num(LAZYACCESS(modifiers, ICON_X)) - 16, -(ICON_SIZE_X/2), ICON_SIZE_X/2) if(LAZYACCESS(modifiers, ICON_Y)) - broken_egg.pixel_y = clamp(text2num(LAZYACCESS(modifiers, ICON_Y)) - 16, -(world.icon_size/2), world.icon_size/2) + broken_egg.pixel_y = clamp(text2num(LAZYACCESS(modifiers, ICON_Y)) - 16, -(ICON_SIZE_Y/2), ICON_SIZE_Y/2) playsound(user, 'sound/items/sheath.ogg', 40, TRUE) reagents.copy_to(broken_egg, reagents.total_volume) diff --git a/code/game/objects/items/food/meatdish.dm b/code/game/objects/items/food/meatdish.dm index 9bda586b2693f..770b6f8bf3124 100644 --- a/code/game/objects/items/food/meatdish.dm +++ b/code/game/objects/items/food/meatdish.dm @@ -88,6 +88,13 @@ cell_line = null starting_reagent_purity = 0.3 +///carp fillet, but without the toxin. Used by baby carps (fish item), which have a trait that handles the toxin already. +/obj/item/food/fishmeat/carp/no_tox + +/obj/item/food/fishmeat/carp/no_tox/Initialize(mapload) + food_reagents -= /datum/reagent/toxin/carpotoxin + return ..() + /obj/item/food/fishmeat/moonfish name = "moonfish fillet" desc = "A fillet of moonfish." diff --git a/code/game/objects/items/inducer.dm b/code/game/objects/items/inducer.dm index 2404974d69970..0f66cd4b6d108 100644 --- a/code/game/objects/items/inducer.dm +++ b/code/game/objects/items/inducer.dm @@ -7,212 +7,219 @@ lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' force = 7 + /// Multiplier that determines the speed at which this inducer works at. var/power_transfer_multiplier = 1 + /// Is the battery hatch opened var/opened = FALSE - var/cell_type = /obj/item/stock_parts/power_store/battery/high - var/obj/item/stock_parts/power_store/powerdevice + /// The cell for used in recharging cycles + var/obj/item/stock_parts/power_store/powerdevice = /obj/item/stock_parts/power_store/battery/high + /// Are we in the process of recharging something var/recharging = FALSE /obj/item/inducer/Initialize(mapload) . = ..() - if(!powerdevice && cell_type) - powerdevice = new cell_type -/obj/item/inducer/proc/induce(obj/item/stock_parts/power_store/target, coefficient) - var/obj/item/stock_parts/power_store/our_cell = get_cell() - var/rating_base = target.rating_base - var/totransfer = min(our_cell.charge, (rating_base * coefficient * power_transfer_multiplier)) - var/transferred = target.give(totransfer) + if(ispath(powerdevice)) + powerdevice = new powerdevice(src) - our_cell.use(transferred) - our_cell.update_appearance() - target.update_appearance() + register_context() -/obj/item/inducer/get_cell() - return powerdevice + update_appearance(UPDATE_OVERLAYS) -/obj/item/inducer/emp_act(severity) +/obj/item/inducer/Destroy(force) + QDEL_NULL(powerdevice) . = ..() - var/obj/item/stock_parts/power_store/our_cell = get_cell() - if(!isnull(our_cell) && !(. & EMP_PROTECT_CONTENTS)) - our_cell.emp_act(severity) -/obj/item/inducer/attack_atom(obj/target, mob/living/carbon/user, params) - if(user.combat_mode) - return ..() +/obj/item/inducer/Exited(atom/movable/gone, direction) + . = ..() + if(gone == powerdevice) + powerdevice = null - if(cantbeused(user)) - return +/obj/item/inducer/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = NONE - if(recharge(target, user)) + if(isnull(held_item)) + if(opened && !QDELETED(powerdevice)) + context[SCREENTIP_CONTEXT_LMB] = "Remove Cell" + . = CONTEXTUAL_SCREENTIP_SET return - return ..() + if(opened) + if(istype(held_item, /obj/item/stock_parts/power_store) && QDELETED(powerdevice)) + context[SCREENTIP_CONTEXT_LMB] = "Insert cell" + return CONTEXTUAL_SCREENTIP_SET -/obj/item/inducer/proc/cantbeused(mob/user) - if(!ISADVANCEDTOOLUSER(user)) - to_chat(user, span_warning("You don't have the dexterity to use [src]!")) - return TRUE + if(istype(held_item, /obj/item/stack/sheet/mineral/plasma) && !QDELETED(powerdevice)) + context[SCREENTIP_CONTEXT_LMB] = "Charge cell" + return CONTEXTUAL_SCREENTIP_SET - var/obj/item/stock_parts/power_store/our_cell = get_cell() + if(held_item.tool_behaviour == TOOL_SCREWDRIVER) + context[SCREENTIP_CONTEXT_LMB] = "[opened ? "Close" : "Open"] Panel" + return CONTEXTUAL_SCREENTIP_SET - if(isnull(our_cell)) - balloon_alert(user, "no cell installed!") - return TRUE +/obj/item/inducer/examine(mob/living/user) + . = ..() - if(!our_cell.charge) - balloon_alert(user, "no charge!") - return TRUE - return FALSE + if(!QDELETED(powerdevice)) + . += span_notice("Its display shows: [display_energy(powerdevice.charge)].") + if(opened) + . += span_notice("The cell can be removed with an empty hand.") + . += span_notice("Plasma sheets can be used to recharge the cell.") + else + . += span_warning("It's missing a power cell.") -/obj/item/inducer/screwdriver_act(mob/living/user, obj/item/tool) - . = TRUE - tool.play_tool_sound(src) + . += span_notice("Its battery compartment can be [EXAMINE_HINT("screwed")] [opened ? "shut" : "open"].") + +/obj/item/inducer/update_overlays() + . = ..() if(!opened) - to_chat(user, span_notice("You unscrew the battery compartment.")) - opened = TRUE - update_appearance() return - else - to_chat(user, span_notice("You close the battery compartment.")) - opened = FALSE - update_appearance() + . += "inducer-[!QDELETED(powerdevice) ? "bat" : "nobat"]" + +/obj/item/inducer/get_cell() + return powerdevice + +/obj/item/inducer/emp_act(severity) + . = ..() + if(!QDELETED(powerdevice) && !(. & EMP_PROTECT_CONTENTS)) + powerdevice.emp_act(severity) + +/obj/item/inducer/screwdriver_act(mob/living/user, obj/item/tool) + . = NONE + + if(!tool.use_tool(src, user, delay = 0)) return -/obj/item/inducer/attackby(obj/item/used_item, mob/user) - var/obj/item/stock_parts/power_store/our_cell = get_cell() - if(istype(used_item, /obj/item/stock_parts/power_store)) - if(opened) - if(isnull(our_cell)) - if(!user.transferItemToLoc(used_item, src)) - return - to_chat(user, span_notice("You insert [used_item] into [src].")) - powerdevice = used_item - update_appearance() - return - else - to_chat(user, span_warning("[src] already has \a [our_cell] installed!")) - return - - if (istype(used_item, /obj/item/stack/sheet/mineral/plasma) && !isnull(our_cell)) - if(our_cell.charge == our_cell.maxcharge) - balloon_alert(user, "already fully charged!") - return - used_item.use(1) - our_cell.give(1.5 * STANDARD_CELL_CHARGE) + opened = !opened + to_chat(user, span_notice("You [opened ? "open" : "close"] the battery compartment.")) + update_appearance(UPDATE_OVERLAYS) + + return ITEM_INTERACT_SUCCESS + +/obj/item/inducer/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + . = NONE + if(user.combat_mode || !istype(tool) || tool.flags_1 & HOLOGRAM_1 || tool.item_flags & ABSTRACT) + return ITEM_INTERACT_SKIP_TO_ATTACK + + if(!opened) + balloon_alert(user, "open first!") + return ITEM_INTERACT_FAILURE + + if(istype(tool, /obj/item/stock_parts/power_store)) + if(!QDELETED(powerdevice)) + balloon_alert(user, "cell already installed!") + return ITEM_INTERACT_FAILURE + + if(!user.transferItemToLoc(tool, src)) + balloon_alert(user, "stuck in hand!") + return ITEM_INTERACT_FAILURE + + powerdevice = tool + return ITEM_INTERACT_SUCCESS + + if(istype(tool, /obj/item/stack/sheet/mineral/plasma) && !QDELETED(powerdevice)) + if(!powerdevice.used_charge()) + balloon_alert(user, "fully charged!") + return ITEM_INTERACT_FAILURE + + tool.use(1) + powerdevice.give(1.5 * STANDARD_CELL_CHARGE) balloon_alert(user, "cell recharged") - return - if(cantbeused(user)) - return + return ITEM_INTERACT_SUCCESS - if(recharge(used_item, user)) - return +/obj/item/inducer/interact_with_atom(atom/movable/interacting_with, mob/living/user, list/modifiers) + . = NONE + if(user.combat_mode || !istype(interacting_with) || interacting_with.flags_1 & HOLOGRAM_1) + return ITEM_INTERACT_SKIP_TO_ATTACK + + //basic checks + if(opened) + balloon_alert(user, "close first!") + return ITEM_INTERACT_FAILURE - return ..() + if(recharging || (!isturf(interacting_with) && user.loc == interacting_with)) + return ITEM_INTERACT_FAILURE -/obj/item/inducer/proc/recharge(atom/movable/target, mob/user) - if(!isturf(target) && user.loc == target) - return FALSE - if(recharging) - return TRUE + if(!ISADVANCEDTOOLUSER(user)) + to_chat(user, span_warning("You don't have the dexterity to use [src]!")) + return ITEM_INTERACT_FAILURE + if(QDELETED(powerdevice)) + balloon_alert(user, "no cell installed!") + return ITEM_INTERACT_FAILURE + + if(!powerdevice.charge) + balloon_alert(user, "no charge!") + return ITEM_INTERACT_FAILURE + + var/obj/item/stock_parts/power_store/target_cell = interacting_with.get_cell(src, user) + + if(QDELETED(target_cell)) + return ITEM_INTERACT_FAILURE + + if(!target_cell.used_charge()) + balloon_alert(user, "fully charged!") + return ITEM_INTERACT_FAILURE + + //begin recharging recharging = TRUE - var/obj/item/stock_parts/power_store/our_cell = get_cell() - var/obj/item/stock_parts/power_store/target_cell = target.get_cell() - var/obj/target_as_object = target - var/coefficient = 1 - - if(istype(target, /obj/item/gun/energy) || istype(target, /obj/item/clothing/suit/space)) - to_chat(user, span_alert("Error: unable to interface with device.")) - return FALSE - - if(target_cell) - var/done_any = FALSE - if(target_cell.charge >= target_cell.maxcharge) - balloon_alert(user, "it's fully charged!") - recharging = FALSE - return TRUE - - user.visible_message(span_notice("[user] starts recharging [target] with [src]."), span_notice("You start recharging [target] with [src].")) - - while(target_cell.charge < target_cell.maxcharge) - if(do_after(user, 1 SECONDS, target = user) && our_cell.charge) - done_any = TRUE - induce(target_cell, coefficient) - do_sparks(1, FALSE, target) - if(istype(target_as_object)) - target_as_object.update_appearance() - else - break - if(done_any) // Only show a message if we succeeded at least once - user.visible_message(span_notice("[user] recharged [target]!"), span_notice("You recharged [target]!")) - recharging = FALSE - return TRUE - recharging = FALSE + user.visible_message(span_notice("[user] starts recharging [interacting_with] with [src]."), span_notice("You start recharging [interacting_with] with [src].")) + var/done_any = FALSE + while(target_cell.used_charge()) + if(!do_after(user, 1 SECONDS, target = user)) + break -/obj/item/inducer/attack(mob/target, mob/living/user) - if(user.combat_mode) - return ..() + //transfer of charge + var/transferred = min(powerdevice.charge, target_cell.used_charge(), (target_cell.rating_base * target_cell.rating * power_transfer_multiplier)) + if(!transferred) + break + powerdevice.use(target_cell.give(transferred)) - if(cantbeused(user)) - return + //update all appearances + powerdevice.update_appearance() + target_cell.update_appearance() + interacting_with.update_appearance() - if(recharge(target, user)) - return + //sparks & update + do_sparks(1, FALSE, interacting_with) + done_any = TRUE - return ..() + recharging = FALSE + // Only show a message if we succeeded at least once + if(done_any) + user.visible_message(span_notice("[user] recharges [interacting_with]!"), span_notice("You recharge [interacting_with]!")) + + return ITEM_INTERACT_SUCCESS /obj/item/inducer/attack_self(mob/user) - if(opened && powerdevice) + if(opened && !QDELETED(powerdevice)) user.visible_message(span_notice("[user] removes [powerdevice] from [src]!"), span_notice("You remove [powerdevice].")) powerdevice.update_appearance() user.put_in_hands(powerdevice) - powerdevice = null - update_appearance() - - -/obj/item/inducer/examine(mob/living/user) - . = ..() - var/obj/item/stock_parts/power_store/our_cell = get_cell() - if(!isnull(our_cell)) - . += span_notice("Its display shows: [display_energy(our_cell.charge)].") - else - . += span_notice("Its display is dark.") - if(opened) - . += span_notice("Its battery compartment is open.") - -/obj/item/inducer/update_overlays() - . = ..() - if(!opened) - return - . += "inducer-[!isnull(get_cell()) ? "bat" : "nobat"]" + update_appearance(UPDATE_OVERLAYS) /obj/item/inducer/empty - cell_type = null + powerdevice = null opened = TRUE /obj/item/inducer/orderable - cell_type = /obj/item/stock_parts/power_store/battery/upgraded + powerdevice = /obj/item/stock_parts/power_store/battery/upgraded opened = FALSE /obj/item/inducer/sci icon_state = "inducer-sci" inhand_icon_state = "inducer-sci" desc = "A tool for inductively charging internal power cells. This one has a science color scheme, and is less potent than its engineering counterpart." - cell_type = null + powerdevice = null opened = TRUE -/obj/item/inducer/sci/Initialize(mapload) - . = ..() - update_appearance() - /obj/item/inducer/syndicate icon_state = "inducer-syndi" inhand_icon_state = "inducer-syndi" desc = "A tool for inductively charging internal power cells. This one has a suspicious colour scheme, and seems to be rigged to transfer charge at a much faster rate." power_transfer_multiplier = 2 // 2x the base speed - cell_type = /obj/item/stock_parts/power_store/cell/super + powerdevice = /obj/item/stock_parts/power_store/battery/super diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index 813ace6ced89e..9a1b8bed101f0 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -515,10 +515,10 @@ greyscale_config_inhand_left = /datum/greyscale_config/cleric_mace_lefthand greyscale_config_inhand_right = /datum/greyscale_config/cleric_mace_righthand greyscale_config_worn = /datum/greyscale_config/cleric_mace - greyscale_colors = COLOR_WHITE + greyscale_colors = COLOR_WHITE + COLOR_BROWN material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_GREYSCALE | MATERIAL_AFFECT_STATISTICS //Material type changes the prefix as well as the color. - custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT*6) //Defaults to an Iron Mace. + custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 4.5, /datum/material/wood = SHEET_MATERIAL_AMOUNT * 1.5) //Defaults to an Iron Mace. slot_flags = ITEM_SLOT_BELT force = 14 w_class = WEIGHT_CLASS_BULKY @@ -529,6 +529,26 @@ attack_verb_continuous = list("smacks", "strikes", "cracks", "beats") attack_verb_simple = list("smack", "strike", "crack", "beat") +///Cleric maces are made of two custom materials: one is handle, and the other is the mace itself. +/obj/item/melee/cleric_mace/get_material_multiplier(datum/material/custom_material, list/materials, index) + if(length(materials) <= 1) + return 1.2 + if(index == 1) + return 1 + else + return 0.3 + +/obj/item/melee/cleric_mace/get_material_prefixes(list/materials) + var/datum/material/material = materials[1] + return material.name //It only inherits the name of the main material it's made of. The secondary is in the description. + +/obj/item/melee/cleric_mace/finalize_material_effects(list/materials) + . = ..() + if(length(materials) == 1) + return + var/datum/material/material = materials[2] + desc = "[initial(desc)] Its handle is made of [material.name]." + /obj/item/melee/cleric_mace/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK, damage_type = BRUTE) if(attack_type == PROJECTILE_ATTACK || attack_type == LEAP_ATTACK) final_block_chance = 0 //Don't bring a...mace to a gunfight, and also you aren't going to really block someone full body tackling you with a mace diff --git a/code/game/objects/items/pet_carrier.dm b/code/game/objects/items/pet_carrier.dm index 0148076f529ec..2d700cf3ff0c0 100644 --- a/code/game/objects/items/pet_carrier.dm +++ b/code/game/objects/items/pet_carrier.dm @@ -11,6 +11,10 @@ inhand_icon_state = "pet_carrier" lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' righthand_file = 'icons/mob/inhands/items_righthand.dmi' + greyscale_config = /datum/greyscale_config/pet_carrier + greyscale_config_inhand_left = /datum/greyscale_config/pet_carrier_inhands_left + greyscale_config_inhand_right = /datum/greyscale_config/pet_carrier_inhands_right + greyscale_colors = COLOR_BLUE force = 5 attack_verb_continuous = list("bashes", "carries") attack_verb_simple = list("bash", "carry") @@ -19,7 +23,6 @@ throw_range = 3 custom_materials = list(/datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT * 7.5, /datum/material/glass = SMALL_MATERIAL_AMOUNT) interaction_flags_mouse_drop = NEED_DEXTERITY - var/open = TRUE var/locked = FALSE var/list/occupants = list() @@ -147,14 +150,9 @@ if(open) icon_state = initial(icon_state) return ..() - icon_state = "[base_icon_state]_[!occupants.len ? "closed" : "occupied"]" + icon_state = "[base_icon_state]_[!occupants.len ? "closed" : "occupied"]_[locked ? "locked" : "unlocked"]" return ..() -/obj/item/pet_carrier/update_overlays() - . = ..() - if(!open) - . += "[base_icon_state]_[locked ? "" : "un"]locked" - /obj/item/pet_carrier/mouse_drop_dragged(atom/over_atom, mob/user, src_location, over_location, params) if(isopenturf(over_atom) && open && occupants.len) user.visible_message(span_notice("[user] unloads [src]."), \ @@ -202,5 +200,9 @@ base_icon_state = "biopod" icon_state = "biopod_open" inhand_icon_state = "biopod" + greyscale_config = null + greyscale_config_inhand_left = null + greyscale_config_inhand_right = null + greyscale_colors = null #undef pet_carrier_full diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 4b210c47e9fca..2e7682eda1fd1 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -648,7 +648,7 @@ name = "Internal inducer" icon = 'icons/obj/tools.dmi' icon_state = "inducer-engi" - cell_type = null + powerdevice = null /obj/item/inducer/cyborg/get_cell() var/obj/item/robot_model/possible_model = loc @@ -657,7 +657,7 @@ . = silicon_friend.cell /obj/item/inducer/cyborg/screwdriver_act(mob/living/user, obj/item/tool) - return FALSE + return NONE /obj/item/borg/upgrade/pinpointer name = "medical cyborg crew pinpointer" diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index e2a8e10c4df49..18891ebdd9306 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -77,18 +77,19 @@ amount = new_amount while(amount > max_amount) amount -= max_amount - new type(loc, max_amount, FALSE) + new type(loc, max_amount, FALSE, mat_override, mat_amt) if(!merge_type) merge_type = type + . = ..() + + var/materials_mult = amount if(LAZYLEN(mat_override)) - set_mats_per_unit(mat_override, mat_amt) - else if(LAZYLEN(mats_per_unit)) - set_mats_per_unit(mats_per_unit, 1) - else if(LAZYLEN(custom_materials)) - set_mats_per_unit(custom_materials, amount ? 1/amount : 1) + materials_mult *= mat_amt + mats_per_unit = mat_override + if(LAZYLEN(mats_per_unit)) + initialize_materials(mats_per_unit, materials_mult) - . = ..() if(merge) for(var/obj/item/stack/item_stack in loc) if(item_stack == src) @@ -118,26 +119,15 @@ if(is_path_in_list(merge_type, GLOB.golem_stack_food_directory)) AddComponent(/datum/component/golem_food, golem_food_key = merge_type) -/** Sets the amount of materials per unit for this stack. - * - * Arguments: - * - [mats][/list]: The value to set the mats per unit to. - * - multiplier: The amount to multiply the mats per unit by. Defaults to 1. - */ -/obj/item/stack/proc/set_mats_per_unit(list/mats, multiplier=1) - mats_per_unit = SSmaterials.FindOrCreateMaterialCombo(mats, multiplier) - update_custom_materials() - -/** Updates the custom materials list of this stack. - */ +///Called to lazily update the materials of the item whenever the used or if more is added /obj/item/stack/proc/update_custom_materials() - set_custom_materials(mats_per_unit, amount, is_update=TRUE) + if(length(mats_per_unit)) + set_custom_materials(mats_per_unit, amount) -/** - * Override to make things like metalgen accurately set custom materials - */ -/obj/item/stack/set_custom_materials(list/materials, multiplier=1, is_update=FALSE) - return is_update ? ..() : set_mats_per_unit(materials, multiplier/(amount || 1)) +/obj/item/stack/apply_material_effects(list/materials) + . = ..() + if(amount) + mats_per_unit = SSmaterials.FindOrCreateMaterialCombo(materials, 1/amount) /obj/item/stack/blend_requirements() if(is_cyborg) @@ -437,7 +427,7 @@ if((recipe.crafting_flags & CRAFT_APPLIES_MATS) && LAZYLEN(mats_per_unit)) if(isstack(created)) var/obj/item/stack/crafted_stack = created - crafted_stack.set_mats_per_unit(mats_per_unit, recipe.req_amount / recipe.res_amount) + crafted_stack.set_custom_materials(mats_per_unit, (recipe.req_amount / recipe.res_amount) * crafted_stack.amount) else created.set_custom_materials(mats_per_unit, recipe.req_amount / recipe.res_amount) @@ -540,8 +530,7 @@ amount -= used if(check && is_zero_amount(delete_if_zero = TRUE)) return TRUE - if(length(mats_per_unit)) - update_custom_materials() + update_custom_materials() update_appearance() update_weight() return TRUE @@ -588,8 +577,7 @@ source.add_charge(_amount * cost) else amount += _amount - if(length(mats_per_unit)) - update_custom_materials() + update_custom_materials() update_appearance() update_weight() diff --git a/code/game/objects/items/storage/boxes/clothes_boxes.dm b/code/game/objects/items/storage/boxes/clothes_boxes.dm index 582b611186c56..86cd3931f1e20 100644 --- a/code/game/objects/items/storage/boxes/clothes_boxes.dm +++ b/code/game/objects/items/storage/boxes/clothes_boxes.dm @@ -38,8 +38,8 @@ new /obj/item/stack/sticky_tape(src) /obj/item/storage/box/fakesyndiesuit - name = "boxed space suit and helmet" - desc = "A sleek, sturdy box used to hold replica spacesuits." + name = "boxed replica space suit and helmet" + desc = "A sleek, sturdy box used to hold toy spacesuits." icon_state = "syndiebox" illustration = "syndiesuit" diff --git a/code/game/objects/items/storage/briefcase.dm b/code/game/objects/items/storage/briefcase.dm index bd474808446af..a0b6e892e0591 100644 --- a/code/game/objects/items/storage/briefcase.dm +++ b/code/game/objects/items/storage/briefcase.dm @@ -110,3 +110,12 @@ new /obj/item/clothing/mask/balaclava(src) new /obj/item/bodybag(src) new /obj/item/soap/nanotrasen(src) + +/obj/item/storage/briefcase/hitchiker/PopulateContents() + new /obj/item/food/sandwich/peanut_butter_jelly(src) + new /obj/item/food/sandwich/peanut_butter_jelly(src) + new /obj/item/reagent_containers/cup/glass/waterbottle/large(src) + new /obj/item/soap(src) + new /obj/item/pillow/random(src) + new /obj/item/tank/internals/emergency_oxygen(src) + new /obj/item/tank/internals/emergency_oxygen(src) diff --git a/code/game/objects/items/storage/holsters.dm b/code/game/objects/items/storage/holsters.dm index 010cc7ffd7f5a..b1bdc86b39db8 100644 --- a/code/game/objects/items/storage/holsters.dm +++ b/code/game/objects/items/storage/holsters.dm @@ -198,7 +198,7 @@ /obj/item/storage/belt/holster/nukie/cowboy/full/PopulateContents() generate_items_inside(list( /obj/item/ammo_box/a357 = 2, - /obj/item/gun/ballistic/revolver/syndicate/cowboy/nuclear = 1, + /obj/item/gun/ballistic/revolver/cowboy/nuclear = 1, ), src) diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm index c939e3d0dd9f4..5f08747e60c92 100644 --- a/code/game/objects/items/storage/toolbox.dm +++ b/code/game/objects/items/storage/toolbox.dm @@ -19,7 +19,7 @@ hitsound = 'sound/items/weapons/smash.ogg' drop_sound = 'sound/items/handling/toolbox/toolbox_drop.ogg' pickup_sound = 'sound/items/handling/toolbox/toolbox_pickup.ogg' - material_flags = MATERIAL_EFFECTS | MATERIAL_COLOR + material_flags = MATERIAL_EFFECTS | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS var/latches = "single_latch" var/has_latches = TRUE wound_bonus = 5 @@ -381,7 +381,7 @@ /obj/item/storage/toolbox/guncase/revolver name = "revolver gun case" - weapon_to_spawn = /obj/item/gun/ballistic/revolver/syndicate/nuclear + weapon_to_spawn = /obj/item/gun/ballistic/revolver/badass/nuclear extra_to_spawn = /obj/item/ammo_box/a357 /obj/item/storage/toolbox/guncase/sword_and_board diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm index 05b8a5a0e8ab0..9e5ae3ba74b1c 100644 --- a/code/game/objects/items/storage/uplink_kits.dm +++ b/code/game/objects/items/storage/uplink_kits.dm @@ -78,7 +78,7 @@ new /obj/item/jammer(src) // 5 tc if(KIT_GUN) - new /obj/item/gun/ballistic/revolver/syndicate(src) // 13 tc + new /obj/item/gun/ballistic/revolver(src) // 13 tc new /obj/item/ammo_box/a357(src) // 4tc new /obj/item/ammo_box/a357(src) new /obj/item/storage/belt/holster/chameleon(src) // 1 tc diff --git a/code/game/objects/items/syndie_spraycan.dm b/code/game/objects/items/syndie_spraycan.dm index fb6192c6e3990..5690ecb7a28cc 100644 --- a/code/game/objects/items/syndie_spraycan.dm +++ b/code/game/objects/items/syndie_spraycan.dm @@ -157,7 +157,8 @@ mergeable_decal = FALSE resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF clean_type = CLEAN_TYPE_HARD_DECAL - layer = SIGIL_LAYER + plane = FLOOR_PLANE + layer = RUNE_LAYER var/slip_time = 6 SECONDS var/slip_flags = NO_SLIP_WHEN_WALKING diff --git a/code/game/objects/items/tail_pin.dm b/code/game/objects/items/tail_pin.dm index df191da845aa4..dc2ffaefea0a9 100644 --- a/code/game/objects/items/tail_pin.dm +++ b/code/game/objects/items/tail_pin.dm @@ -44,6 +44,6 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/poster/party_game, 32) var/list/modifiers = params2list(params) if(!LAZYACCESS(modifiers, ICON_X) || !LAZYACCESS(modifiers, ICON_Y)) return - I.pixel_x = clamp(text2num(LAZYACCESS(modifiers, ICON_X)) - 16, -(world.icon_size/2), world.icon_size/2) - I.pixel_y = clamp(text2num(LAZYACCESS(modifiers, ICON_Y)) - 16, -(world.icon_size/2), world.icon_size/2) + I.pixel_x = clamp(text2num(LAZYACCESS(modifiers, ICON_X)) - 16, -(ICON_SIZE_X/2), ICON_SIZE_X/2) + I.pixel_y = clamp(text2num(LAZYACCESS(modifiers, ICON_Y)) - 16, -(ICON_SIZE_Y/2), ICON_SIZE_Y/2) return TRUE diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm index 8634336504d54..6fca04c7a3f40 100644 --- a/code/game/objects/items/teleportation.dm +++ b/code/game/objects/items/teleportation.dm @@ -110,10 +110,12 @@ w_class = WEIGHT_CLASS_SMALL throw_speed = 3 throw_range = 5 - custom_materials = list(/datum/material/iron= SHEET_MATERIAL_AMOUNT * 5) + custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 5) armor_type = /datum/armor/item_hand_tele resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF - var/list/active_portal_pairs + ///List of portal pairs created by this hand tele + var/list/active_portal_pairs = list() + ///Maximum concurrent active portal pairs allowed var/max_portal_pairs = 3 /** @@ -130,10 +132,7 @@ fire = 100 acid = 100 -/obj/item/hand_tele/Initialize(mapload) - . = ..() - active_portal_pairs = list() - +///Checks if the targeted portal was created by us, then causes it to expire, removing it /obj/item/hand_tele/proc/try_dispel_portal(atom/target, mob/user) if(is_parent_of_portal(target)) to_chat(user, span_notice("You dispel [target] with [src]!")) @@ -262,6 +261,9 @@ RegisterSignal(portal2, COMSIG_QDELETING, PROC_REF(on_portal_destroy)) try_move_adjacent(portal1, user.dir) + if(QDELETED(portal1) || QDELETED(portal2)) //in the event that something managed to delete the portal objects, i.e. something teleported them + to_chat(user, span_notice("[src] vibrates, but no portal seems to appear. Maybe you should try something else.")) + return active_portal_pairs[portal1] = portal2 investigate_log("was used by [key_name(user)] at [AREACOORD(user)] to create a portal pair with destinations [AREACOORD(portal1)] and [AREACOORD(portal2)].", INVESTIGATE_PORTAL) @@ -271,6 +273,9 @@ return TRUE +///Checks for whether creating a portal in our area is allowed or not, +///returning FALSE when in a NOTELEPORT area, an away mission or when the user is not on a turf. +///Is, for some reason, separate from the teleport target's check in try_create_portal_to() /obj/item/hand_tele/proc/can_teleport_notifies(mob/user) var/turf/current_location = get_turf(user) var/area/current_area = current_location.loc @@ -280,6 +285,7 @@ return TRUE +///Clears last teleport location when the teleporter providing our target location changes its target /obj/item/hand_tele/proc/on_teleporter_new_target(datum/source) SIGNAL_HANDLER @@ -287,6 +293,7 @@ last_portal_location = null UnregisterSignal(source, COMSIG_TELEPORTER_NEW_TARGET) +///Removes a destroyed portal from active_portal_pairs list /obj/item/hand_tele/proc/on_portal_destroy(obj/effect/portal/P) SIGNAL_HANDLER @@ -339,6 +346,8 @@ var/maximum_teleport_distance = 8 //How far the emergency teleport checks for a safe position var/parallel_teleport_distance = 3 + // How much blood lost per teleport (out of base 560 blood) + var/bleed_amount = 20 /obj/item/syndicate_teleporter/Initialize(mapload) . = ..() @@ -427,7 +436,10 @@ charges = max(charges - 1, 0) new /obj/effect/temp_visual/teleport_abductor/syndi_teleporter(current_location) new /obj/effect/temp_visual/teleport_abductor/syndi_teleporter(destination) - make_bloods(current_location, destination, user) + if(make_bloods(current_location, destination, user)) + new /obj/effect/temp_visual/circle_wave/syndi_teleporter/bloody(destination) + else + new /obj/effect/temp_visual/circle_wave/syndi_teleporter(destination) playsound(current_location, SFX_PORTAL_ENTER, 50, 1, SHORT_RANGE_SOUND_EXTRARANGE) playsound(destination, 'sound/effects/phasein.ogg', 25, 1, SHORT_RANGE_SOUND_EXTRARANGE) playsound(destination, SFX_PORTAL_ENTER, 50, 1, SHORT_RANGE_SOUND_EXTRARANGE) @@ -463,11 +475,14 @@ new /obj/effect/temp_visual/teleport_abductor/syndi_teleporter(mobloc) new /obj/effect/temp_visual/teleport_abductor/syndi_teleporter(emergency_destination) balloon_alert(user, "emergency teleport triggered!") - if (!HAS_TRAIT(user, TRAIT_NOBLOOD)) - make_bloods(mobloc, emergency_destination, user) + if(make_bloods(destination, emergency_destination, user)) + new /obj/effect/temp_visual/circle_wave/syndi_teleporter/bloody(destination) + else + new /obj/effect/temp_visual/circle_wave/syndi_teleporter(destination) playsound(mobloc, SFX_PORTAL_ENTER, 50, 1, SHORT_RANGE_SOUND_EXTRARANGE) playsound(emergency_destination, 'sound/effects/phasein.ogg', 25, 1, SHORT_RANGE_SOUND_EXTRARANGE) playsound(emergency_destination, SFX_PORTAL_ENTER, 50, 1, SHORT_RANGE_SOUND_EXTRARANGE) + playsound(src, 'sound/machines/warning-buzzer.ogg', 25, TRUE) else //We tried to save. We failed. Death time. get_fragged(user, destination) @@ -495,16 +510,45 @@ victim.apply_damage(20, BRUTE) victim.Paralyze(6 SECONDS) to_chat(victim, span_warning("[user] teleports into you, knocking you to the floor with the bluespace wave!")) + victim.throw_at(get_step_rand(victim), 1, 1, user, spin = TRUE) ///Bleed and make blood splatters at tele start and end points /obj/item/syndicate_teleporter/proc/make_bloods(turf/old_location, turf/new_location, mob/living/user) + if(HAS_TRAIT(user, TRAIT_NOBLOOD)) + return FALSE user.add_splatter_floor(old_location) user.add_splatter_floor(new_location) if(!iscarbon(user)) - return + return FALSE var/mob/living/carbon/carbon_user = user - carbon_user.bleed(10) + // always lose a bit + carbon_user.bleed(bleed_amount * 0.25) + // sometimes lose a lot + // average evens out to 10 per teleport, but the randomness spices things up + if(prob(25) && bleed_amount) + playsound(src, 'sound/effects/wounds/pierce1.ogg', 40, vary = TRUE) + visible_message(span_warning("Blood visibly spurts out of [user] as [src] fails to teleport [user.p_their()] body properly!"), \ + span_boldwarning("Blood visibly spurts out of you as [src] fails to teleport your body properly!")) + carbon_user.bleed(bleed_amount * 0.75) + carbon_user.spray_blood(pick(GLOB.alldirs), rand(1, 3)) + return TRUE + + return FALSE + // retval used for picking wave type + +/// Visual effect spawned when teleporting +/obj/effect/temp_visual/circle_wave/syndi_teleporter + duration = 0.25 SECONDS + color = COLOR_SYNDIE_RED + max_alpha = 100 + amount_to_scale = 0.8 + +/obj/effect/temp_visual/circle_wave/syndi_teleporter/bloody + duration = 0.25 SECONDS + color = COLOR_VIVID_RED + max_alpha = 160 + amount_to_scale = 1 /obj/item/paper/syndicate_teleporter name = "Teleporter Guide" diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 065f4929e4089..c9270b1f67ef6 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -1360,6 +1360,11 @@ toysay = "EI NATH!" toysound = 'sound/effects/magic/disintegrate.ogg' +/obj/item/toy/figure/wizard/special + name = "\improper Wizard action figure special edition" + toysay = "CLANG!"; + toysound = 'sound/effects/clang.ogg' + /obj/item/toy/figure/rd name = "\improper Research Director action figure" icon_state = "rd" @@ -1562,7 +1567,7 @@ GLOBAL_LIST_EMPTY(intento_players) #define DISARM "disarm" #define GRAB "grab" #define HARM "harm" -#define ICON_SPLIT world.icon_size/2 +#define ICON_SPLIT ICON_SIZE_ALL/2 // These states do not have any associated processing. #define STATE_AWAITING_PLAYER_INPUT "awaiting_player_input" diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 7015e403141c4..bddc056b99ef8 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -1200,8 +1200,8 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 user.do_attack_animation(target, "nothing") var/list/modifiers = params2list(params) var/damage_mod = 1 - var/x_slashed = text2num(modifiers[ICON_X]) || world.icon_size/2 //in case we arent called by a client - var/y_slashed = text2num(modifiers[ICON_Y]) || world.icon_size/2 //in case we arent called by a client + var/x_slashed = text2num(modifiers[ICON_X]) || ICON_SIZE_X/2 //in case we arent called by a client + var/y_slashed = text2num(modifiers[ICON_Y]) || ICON_SIZE_Y/2 //in case we arent called by a client new /obj/effect/temp_visual/slash(get_turf(target), target, x_slashed, y_slashed, slash_color) if(target == previous_target?.resolve()) //if the same target, we calculate a damage multiplier if you swing your mouse around var/x_mod = previous_x - x_slashed @@ -1249,7 +1249,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 var/matrix/new_transform = matrix() new_transform.Turn(rand(1, 360)) // Random slash angle var/datum/decompose_matrix/decomp = target.transform.decompose() - new_transform.Translate((x_slashed - world.icon_size/2) * decomp.scale_x, (y_slashed - world.icon_size/2) * decomp.scale_y) // Move to where we clicked + new_transform.Translate((x_slashed - ICON_SIZE_X/2) * decomp.scale_x, (y_slashed - ICON_SIZE_Y/2) * decomp.scale_y) // Move to where we clicked //Follow target's transform while ignoring scaling new_transform.Turn(decomp.rotation) new_transform.Translate(decomp.shift_x, decomp.shift_y) diff --git a/code/game/objects/items/wiki_manuals.dm b/code/game/objects/items/wiki_manuals.dm index 7209d76cc5735..d64c565f04adf 100644 --- a/code/game/objects/items/wiki_manuals.dm +++ b/code/game/objects/items/wiki_manuals.dm @@ -1,31 +1,5 @@ // Wiki books that are linked to the configured wiki link. -/// The size of the window that the wiki books open in. -#define BOOK_WINDOW_BROWSE_SIZE "970x710" -/// This macro will resolve to code that will open up the associated wiki page in the window. -#define WIKI_PAGE_IFRAME(wikiurl, link_identifier) {" - - - - - - - -

You start skimming through the manual...

- - - - "} - // A book that links to the wiki /obj/item/book/manual/wiki starting_content = "Nanotrasen presently does not have any resources on this topic. If you would like to know more, contact your local Central Command representative." // safety @@ -37,9 +11,10 @@ if(!wiki_url) user.balloon_alert(user, "this book is empty!") return - credit_book_to_reader(user) - DIRECT_OUTPUT(user, browse(WIKI_PAGE_IFRAME(wiki_url, page_link), "window=manual;size=[BOOK_WINDOW_BROWSE_SIZE]")) // if you change this GUARANTEE that it works. + if(tgui_alert(user, "This book's page will open in your browser. Are you sure?", "Open The Wiki", list("Yes", "No")) != "Yes") + return + usr << link("[wiki_url]/[page_link]") /obj/item/book/manual/wiki/chemistry name = "Chemistry Textbook" @@ -223,6 +198,3 @@ starting_author = "Nanotrasen Edu-tainment Division" starting_title = "Tactical Game Cards - Player's Handbook" page_link = "Tactical_Game_Cards" - -#undef BOOK_WINDOW_BROWSE_SIZE -#undef WIKI_PAGE_IFRAME diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 0a88aade6978f..c51adf91b3b10 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -291,3 +291,28 @@ GLOBAL_LIST_EMPTY(objects_by_id_tag) pixel_z = anchored_tabletop_offset else pixel_z = initial(pixel_z) + +/obj/apply_single_mat_effect(datum/material/material, mat_amount, multiplier) + . = ..() + if(!(material_flags & MATERIAL_AFFECT_STATISTICS)) + return + var/integrity_mod = GET_MATERIAL_MODIFIER(material.integrity_modifier, multiplier) + modify_max_integrity(ceil(max_integrity * integrity_mod)) + var/strength_mod = GET_MATERIAL_MODIFIER(material.strength_modifier, multiplier) + force *= strength_mod + throwforce *= strength_mod + var/list/armor_mods = material.get_armor_modifiers(multiplier) + set_armor(get_armor().generate_new_with_multipliers(armor_mods)) + +///This proc is called when the material is removed from an object specifically. +/obj/remove_single_mat_effect(datum/material/material, mat_amount, multiplier) + . = ..() + if(!(material_flags & MATERIAL_AFFECT_STATISTICS)) + return + var/integrity_mod = GET_MATERIAL_MODIFIER(material.integrity_modifier, multiplier) + modify_max_integrity(floor(max_integrity / integrity_mod)) + var/strength_mod = GET_MATERIAL_MODIFIER(material.strength_modifier, multiplier) + force /= strength_mod + throwforce /= strength_mod + var/list/armor_mods = material.get_armor_modifiers(1 / multiplier) + set_armor(get_armor().generate_new_with_multipliers(armor_mods)) diff --git a/code/game/objects/structures/bonfire.dm b/code/game/objects/structures/bonfire.dm index a26a2f9278437..e6f7edd939628 100644 --- a/code/game/objects/structures/bonfire.dm +++ b/code/game/objects/structures/bonfire.dm @@ -73,8 +73,8 @@ if(!LAZYACCESS(modifiers, ICON_X) || !LAZYACCESS(modifiers, ICON_Y)) return //Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf) - used_item.pixel_x = used_item.base_pixel_x + clamp(text2num(LAZYACCESS(modifiers, ICON_X)) - 16, -(world.icon_size/2), world.icon_size/2) - used_item.pixel_y = used_item.base_pixel_y + clamp(text2num(LAZYACCESS(modifiers, ICON_Y)) - 16, -(world.icon_size/2), world.icon_size/2) + used_item.pixel_x = used_item.base_pixel_x + clamp(text2num(LAZYACCESS(modifiers, ICON_X)) - 16, -(ICON_SIZE_X/2), ICON_SIZE_X/2) + used_item.pixel_y = used_item.base_pixel_y + clamp(text2num(LAZYACCESS(modifiers, ICON_Y)) - 16, -(ICON_SIZE_Y/2), ICON_SIZE_Y/2) else return ..() @@ -185,6 +185,13 @@ /obj/structure/bonfire/dense density = TRUE +/obj/structure/bonfire/dense/prelit/Initialize(mapload) + . = ..() + return INITIALIZE_HINT_LATELOAD + +/obj/structure/bonfire/dense/prelit/LateInitialize() + start_burning() + /obj/structure/bonfire/prelit/Initialize(mapload) . = ..() return INITIALIZE_HINT_LATELOAD diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 58e99dc8839aa..7a3fcef368ada 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -134,7 +134,7 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) if(isnull(card_reader_choices)) card_reader_choices = list( "Personal", - "Departmental", + "Job", "None" ) if(access_choices) @@ -800,11 +800,11 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) switch(choice) if("Personal") //only the player who swiped their id has access. id_card = WEAKREF(id) - name = "[id.registered_name] locker" - desc = "now owned by [id.registered_name]. [initial(desc)]" - if("Departmental") //anyone who has the same access permissions as this id has access - name = "[id.assignment] closet" - desc = "Its a [id.assignment] closet. [initial(desc)]" + name = "[id.registered_name]'s locker" + desc += " It has been ID locked to [id.registered_name]." + if("Job") //anyone who has the same access permissions as this id has access. Does NOT apply to the whole department. + name = "[id.assignment]'s locker" + desc += " It has been access locked to [id.assignment]s." set_access(id.GetAccess()) if("None") //free for all name = initial(name) diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index f01fe56431d94..f7a0ccd66dfdd 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -305,22 +305,16 @@ base_icon_state = "food" /obj/structure/closet/crate/freezer/donk - name = "donk co. fridge" - desc = "A Donk Co. brand fridge, keeps your donkpcokets and foam ammunition fresh!" + name = "\improper Donk Co. fridge" + desc = "A Donk Co. brand fridge, keeps your donkpockets and foam ammunition fresh!" icon_state = "donkcocrate" base_icon_state = "donkcocrate" -/obj/structure/closet/crate/freezer/interdyne - name = "interdyne freezer" - desc = "Interdyne Pharmauceutics branded freezer. Might or might not contain cold steel, or fresh organs." - icon_state = "interdynefreezer" - base_icon_state = "interdynefreezer" - -/obj/structure/closet/crate/freezer/blood/interdyne - name = "interdyne blood freezer" - desc = "Interdyne Pharmauceutics branded freezer. Only freshly harvested- I mean, freshly kept blood inside!" - icon_state = "interdynefreezer" - base_icon_state = "interdynefreezer" +/obj/structure/closet/crate/self + name = "\improper S.E.L.F. crate" + desc = "A robust-looking crate with a seemingly decorative holographic display. The front of the crate proudly declares its allegiance to the notorious terrorist group 'S.E.L.F'." + icon_state = "selfcrate" + base_icon_state = "selfcrate" /obj/structure/closet/crate/radiation desc = "A crate with a radiation sign on it." diff --git a/code/game/objects/structures/crates_lockers/crates/secure.dm b/code/game/objects/structures/crates_lockers/crates/secure.dm index e93591f1d596c..b0b6cfaae0016 100644 --- a/code/game/objects/structures/crates_lockers/crates/secure.dm +++ b/code/game/objects/structures/crates_lockers/crates/secure.dm @@ -44,17 +44,6 @@ icon_state = "weaponcrate" base_icon_state = "weaponcrate" -/obj/structure/closet/crate/secure/gorlex_weapons - desc = "A secure weapons crate of Gorlex Marauders." - name = "weapons crate" - icon_state = "gorlex_weaponcrate" - base_icon_state = "gorlex_weaponcrate" - -/obj/structure/closet/crate/secure/gorlex_weapons/jammed - desc = "A beaten up, jammed open weapon crate of Gorlex Marauders." - name = "jammed weapons crate" - locked = FALSE - /obj/structure/closet/crate/secure/plasma desc = "A secure plasma crate." name = "plasma crate" @@ -204,64 +193,110 @@ to_chat(user, span_warning("[src] is broken!")) else ..() -/obj/structure/closet/crate/secure/interdyne - name = "interdyne crate" +/obj/structure/closet/crate/secure/freezer/interdyne + name = "\improper Interdyne freezer" + desc = "This is an Interdyne Pharmauceutics branded freezer. May or may not contain fresh organs." + icon_state = "interdynefreezer" + base_icon_state = "interdynefreezer" + req_access = list(ACCESS_SYNDICATE) + +/obj/structure/closet/crate/secure/freezer/interdyne/blood + name = "\improper Interdyne blood freezer" + desc = "This is an Interdyne Pharmauceutics branded freezer. It's made to contain fresh, high-quality blood." + +/obj/structure/closet/crate/secure/freezer/interdyne/blood/PopulateContents() + . = ..() + for(var/i in 1 to 13) + new /obj/item/reagent_containers/blood/random(src) + +/obj/structure/closet/crate/secure/freezer/donk + name = "\improper Donk Co. fridge" + desc = "A Donk Co. brand fridge, keeps your donkpockets and foam ammunition fresh!" + icon_state = "donkcocrate_secure" + base_icon_state = "donkcocrate_secure" + req_access = list(ACCESS_SYNDICATE) + +/obj/structure/closet/crate/secure/syndicate + name = "\improper Syndicate crate" + desc = "A secure crate with the Syndicate's branding on it." + icon_state = "syndicrate" + base_icon_state = "syndicrate" + req_access = list(ACCESS_SYNDICATE) + +/obj/structure/closet/crate/secure/syndicate/interdyne + name = "\improper Interdyne crate" desc = "Crate belonging to Interdyne Pharmaceutics. Hopefully doesn't have bioweapons inside..." icon_state = "interdynecrate" base_icon_state = "interdynecrate" -/obj/structure/closet/crate/secure/tiger - name = "tiger co-op crate" +/obj/structure/closet/crate/secure/syndicate/tiger + name = "\improper Tiger Co-Op crate" icon_state = "tigercrate" base_icon_state = "tigercrate" -/obj/structure/closet/crate/secure/self - name = "s.e.l.f. crate" +/obj/structure/closet/crate/secure/syndicate/self + name = "\improper S.E.L.F. crate" desc = "A secure crate locked from the inside with a scanning panel above it and holographic display of lock's status. Sentient Engine Liberation Front engineers are quite the show-offs." - icon_state = "selfcrate" - base_icon_state = "selfcrate" + icon_state = "selfcrate_secure" + base_icon_state = "selfcrate_secure" -/obj/structure/closet/crate/secure/m13 +/obj/structure/closet/crate/secure/syndicate/mi13 name = "mysterious secure crate" desc = "A secure crate. Lacks any obvious logos or even codes for where it arrived from, but looks like taken straight from a spy movie." icon_state = "mithirteencrate" base_icon_state = "mithirteencrate" + open_sound_volume = 15 + close_sound_volume = 20 -/obj/structure/closet/crate/secure/arc - name = "animal rights consortium crate" +/obj/structure/closet/crate/secure/syndicate/arc + name = "\improper Animal Rights Consortium crate" icon_state = "arccrate" base_icon_state = "arccrate" -/obj/structure/closet/crate/secure/cybersun - name = "cybersun crate" +/obj/structure/closet/crate/secure/syndicate/cybersun + name = "\improper Cybersun crate" -/obj/structure/closet/crate/secure/cybersun/dawn +/obj/structure/closet/crate/secure/syndicate/cybersun/dawn desc = "A secure crate from Cybersun Industries. It has distinct orange-green colouring, probably of some departament or division, but you cannot tell what is it." icon_state = "cyber_dawncrate" base_icon_state = "cyber_dawncrate" -/obj/structure/closet/crate/secure/cybersun/noon +/obj/structure/closet/crate/secure/syndicate/cybersun/noon desc = "A secure crate from Cybersun Industries. It has distinct yellow-orange colouring, probably of some departament or division, but you cannot tell what is it." icon_state = "cyber_nooncrate" base_icon_state = "cyber_nooncrate" -/obj/structure/closet/crate/secure/cybersun/dusk +/obj/structure/closet/crate/secure/syndicate/cybersun/dusk desc = "A secure crate from Cybersun Industries. It has distinct purple-green colouring, probably of some departament or division, but you cannot tell what is it." icon_state = "cyber_duskcrate" base_icon_state = "cyber_duskcrate" -/obj/structure/closet/crate/secure/cybersun/night +/obj/structure/closet/crate/secure/syndicate/cybersun/night desc = "A secure crate from Cybersun Industries. This one blatantly adorns syndicate colours. You can only guess it contains equipement for syndicate operatives." icon_state = "cyber_nightcrate" base_icon_state = "cyber_nightcrate" -/obj/structure/closet/crate/secure/wafflecorp - name = "wafflecorp crate" +/obj/structure/closet/crate/secure/syndicate/wafflecorp + name = "\improper Waffle corp. crate" desc = "A very outdated model and design of shipment crate with a modern lock strapped on it, how befitting of its brand owner, Waffle Corporation. Golden lettering written in cursive by the logo reads 'bringing you consecutively top five world-wide rated* breakfast since 2055. A much smaller fineprint, also in cursive, clarifies: '*in years 2099-2126'... It's year 2563 now, however." icon_state = "wafflecrate" base_icon_state = "wafflecrate" -/obj/structure/closet/crate/secure/gorlex - name = "gorlex marauders crate" +/obj/structure/closet/crate/secure/syndicate/gorlex + name = "\improper Gorlex Marauders crate" icon_state = "gorlexcrate" base_icon_state = "gorlexcrate" + +/obj/structure/closet/crate/secure/syndicate/gorlex/weapons + desc = "A secure weapons crate of Gorlex Marauders." + name = "weapons crate" + icon_state = "gorlex_weaponcrate" + base_icon_state = "gorlex_weaponcrate" + +/obj/structure/closet/crate/secure/syndicate/gorlex/weapons/bustedlock + desc = "A beaten up weapon crate with Gorlex Marauders branding. Its lock looks broken." + name = "damaged weapons crate" + secure = FALSE + locked = FALSE + max_integrity = 400 + damage_deflection = 15 diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm index a4d35f02e0c09..5c2f1972c33ef 100644 --- a/code/game/objects/structures/false_walls.dm +++ b/code/game/objects/structures/false_walls.dm @@ -392,8 +392,9 @@ var/datum/material/material_datum = material new material_datum.sheet_type(loc, FLOOR(custom_materials[material_datum] / SHEET_MATERIAL_AMOUNT, 1)) -/obj/structure/falsewall/material/mat_update_desc(mat) - desc = "A huge chunk of [mat] used to separate rooms." +/obj/structure/falsewall/material/finalize_material_effects(list/materials) + . = ..() + desc = "A huge chunk of [get_material_english_list(materials)] used to separate rooms." /obj/structure/falsewall/material/toggle_open() if(!QDELETED(src)) diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index a464f41827678..f5e63bcf23bba 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -452,6 +452,10 @@ desc = "A wondrous decorated Christmas tree." icon_state = "pine_c" +/obj/structure/flora/tree/pine/xmas/presentless + icon_state = "pinepresents" + desc = "A wondrous decorated Christmas tree. It has presents, though none of them seem to have your name on them." + /obj/structure/flora/tree/pine/xmas/presents icon_state = "pinepresents" desc = "A wondrous decorated Christmas tree. It has presents!" diff --git a/code/game/objects/structures/plaques/static_plaques.dm b/code/game/objects/structures/plaques/static_plaques.dm index 3ae3b66b71b66..4b53ae0437301 100644 --- a/code/game/objects/structures/plaques/static_plaques.dm +++ b/code/game/objects/structures/plaques/static_plaques.dm @@ -3,6 +3,12 @@ /obj/structure/plaque/static_plaque engraved = TRUE +/obj/structure/plaque/static_plaque/Initialize(mapload) + . = ..() + if(isopenturf(loc) && !isProbablyWallMounted(src)) + SET_PLANE_IMPLICIT(src, FLOOR_PLANE) + layer = HIGH_TURF_LAYER + /obj/structure/plaque/static_plaque/atmos name = "\improper FEA Atmospherics Division plaque" desc = "This plaque commemorates the fall of the Atmos FEA division. For all the charred, dizzy, and brittle men who have died in its hands." diff --git a/code/game/objects/structures/railings.dm b/code/game/objects/structures/railings.dm index fe2e4b06b4f10..af213603f6353 100644 --- a/code/game/objects/structures/railings.dm +++ b/code/game/objects/structures/railings.dm @@ -101,6 +101,10 @@ /obj/structure/railing/wirecutter_act(mob/living/user, obj/item/I) . = ..() + if(resistance_flags & INDESTRUCTIBLE) + to_chat(user, span_warning("You try to cut apart the railing, but it's too hard!")) + I.play_tool_sound(src, 100) + return TRUE to_chat(user, span_warning("You cut apart the railing.")) I.play_tool_sound(src, 100) deconstruct() diff --git a/code/game/objects/structures/shower.dm b/code/game/objects/structures/shower.dm index 1ae66f2f82f19..6c5435c1bfad8 100644 --- a/code/game/objects/structures/shower.dm +++ b/code/game/objects/structures/shower.dm @@ -90,6 +90,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/shower, (-16)) AddComponent(/datum/component/plumbing/simple_demand, extend_pipe_to_edge = TRUE) var/static/list/loc_connections = list( COMSIG_ATOM_ENTERED = PROC_REF(on_entered), + COMSIG_ATOM_EXITED = PROC_REF(on_exited), ) AddElement(/datum/element/connect_loc, loc_connections) @@ -233,18 +234,33 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/shower, (-16)) qdel(mist) -/obj/machinery/shower/proc/on_entered(datum/source, atom/movable/AM) +/obj/machinery/shower/proc/on_entered(datum/source, atom/movable/enterer) SIGNAL_HANDLER + if(actually_on && reagents.total_volume) - wash_atom(AM) + wash_atom(enterer) + +/obj/machinery/shower/proc/on_exited(datum/source, atom/movable/exiter) + SIGNAL_HANDLER + + if(!isliving(exiter)) + return + + var/obj/machinery/shower/locate_new_shower = locate() in get_turf(exiter) + if(locate_new_shower && isturf(exiter.loc)) + return + var/mob/living/take_his_status_effect = exiter + take_his_status_effect.remove_status_effect(/datum/status_effect/shower_regen) /obj/machinery/shower/proc/wash_atom(atom/target) target.wash(CLEAN_RAD | CLEAN_WASH) reagents.expose(target, (TOUCH), SHOWER_EXPOSURE_MULTIPLIER * SHOWER_SPRAY_VOLUME / max(reagents.total_volume, SHOWER_SPRAY_VOLUME)) - if(isliving(target)) - var/mob/living/living_target = target - check_heat(living_target) - living_target.add_mood_event("shower", /datum/mood_event/nice_shower) + if(!isliving(target)) + return + var/mob/living/living_target = target + check_heat(living_target) + living_target.add_mood_event("shower", /datum/mood_event/nice_shower) + living_target.apply_status_effect(/datum/status_effect/shower_regen) /** * Toggle whether shower is actually on and outputting water. diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 834347cc84f4f..ac7282f9386b6 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -309,8 +309,8 @@ // Items are centered by default, but we move them if click ICON_X and ICON_Y are available if(LAZYACCESS(modifiers, ICON_X) && LAZYACCESS(modifiers, ICON_Y)) // Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf) - tool.pixel_x = clamp(text2num(LAZYACCESS(modifiers, ICON_X)) - 16, -(world.icon_size*0.5), world.icon_size*0.5) - tool.pixel_y = clamp(text2num(LAZYACCESS(modifiers, ICON_Y)) - 16, -(world.icon_size*0.5), world.icon_size*0.5) + tool.pixel_x = clamp(text2num(LAZYACCESS(modifiers, ICON_X)) - 16, -(ICON_SIZE_X*0.5), ICON_SIZE_X*0.5) + tool.pixel_y = clamp(text2num(LAZYACCESS(modifiers, ICON_Y)) - 16, -(ICON_SIZE_Y*0.5), ICON_SIZE_Y*0.5) AfterPutItemOnTable(tool, user) return ITEM_INTERACT_SUCCESS @@ -361,13 +361,10 @@ material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS buildstack = null //No buildstack, so generate from mat datums -/obj/structure/table/greyscale/set_custom_materials(list/materials, multiplier) +/obj/structure/table/greyscale/finalize_material_effects(list/materials) . = ..() - var/list/materials_list = list() - for(var/custom_material in custom_materials) - var/datum/material/current_material = GET_MATERIAL_REF(custom_material) - materials_list += "[current_material.name]" - desc = "A square [(materials_list.len > 1) ? "amalgamation" : "piece"] of [english_list(materials_list)] on four legs. It can not move." + var/english_list = get_material_english_list(materials) + desc = "A square [(length(materials) > 1) ? "amalgamation" : "piece"] of [english_list] on four legs. It can not move." ///Table on wheels /obj/structure/table/rolling @@ -664,6 +661,9 @@ /obj/structure/table/reinforced/welder_act_secondary(mob/living/user, obj/item/tool) if(tool.tool_start_check(user, amount = 0)) + if(attempt_electrocution(user)) + return ITEM_INTERACT_BLOCKING + if(deconstruction_ready) to_chat(user, span_notice("You start strengthening the reinforced table...")) if (tool.use_tool(src, user, 50, volume = 50)) @@ -684,6 +684,40 @@ return ..() +/obj/structure/table/reinforced/screwdriver_act_secondary(mob/living/user, obj/item/tool) + if(deconstruction_ready && attempt_electrocution(user)) + return ITEM_INTERACT_BLOCKING + return ..() + +/obj/structure/table/reinforced/wrench_act_secondary(mob/living/user, obj/item/tool) + if(deconstruction_ready && attempt_electrocution(user)) + return ITEM_INTERACT_BLOCKING + return ..() + +/// Attempts to shock the user, given the table is hooked up and they're within range. +/// Returns TRUE on successful electrocution, FALSE otherwise. +/obj/structure/table/reinforced/proc/attempt_electrocution(mob/user) + if(!anchored) // If for whatever reason it's not anchored, it can't be shocked either. + return FALSE + if(!in_range(src, user)) // To prevent TK and mech users from getting shocked. + return FALSE + + var/turf/our_turf = get_turf(src) + if(our_turf.overfloor_placed) // Can't have a floor in the way. + return FALSE + + var/obj/structure/cable/cable_node = our_turf.get_cable_node() + if(isnull(cable_node)) + return FALSE + if(!electrocute_mob(user, cable_node, src, 1, TRUE)) + return FALSE + + var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread + sparks.set_up(3, TRUE, src) + sparks.start() + + return TRUE + /obj/structure/table/bronze name = "bronze table" desc = "A solid table made out of bronze." diff --git a/code/game/sound.dm b/code/game/sound.dm index fb9d70eb2cb03..d3553b1d6f926 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -43,6 +43,9 @@ if(isarea(source)) CRASH("playsound(): source is an area") + if(islist(soundin)) + CRASH("playsound(): soundin attempted to pass a list! Consider using pick()") + var/turf/turf_source = get_turf(source) if (!turf_source || !soundin || !vol) @@ -226,7 +229,10 @@ if(SFX_CLOWN_STEP) soundin = pick('sound/effects/footstep/clownstep1.ogg','sound/effects/footstep/clownstep2.ogg') if(SFX_SUIT_STEP) - soundin = pick('sound/effects/suitstep1.ogg','sound/effects/suitstep2.ogg') + soundin = pick( + 'sound/items/handling/armor_rustle/riot_armor/suitstep1.ogg', + 'sound/items/handling/armor_rustle/riot_armor/suitstep2.ogg', + ) if(SFX_SWING_HIT) soundin = pick('sound/items/weapons/genhit1.ogg', 'sound/items/weapons/genhit2.ogg', 'sound/items/weapons/genhit3.ogg') if(SFX_HISS) @@ -523,4 +529,60 @@ 'sound/effects/liquid_pour/liquid_pour2.ogg', 'sound/effects/liquid_pour/liquid_pour3.ogg', ) + if(SFX_SNORE_FEMALE) + soundin = pick_weight(list( + 'sound/mobs/humanoids/human/snore/snore_female1.ogg' = 33, + 'sound/mobs/humanoids/human/snore/snore_female2.ogg' = 33, + 'sound/mobs/humanoids/human/snore/snore_female3.ogg' = 33, + 'sound/mobs/humanoids/human/snore/snore_mimimi1.ogg' = 1, + )) + if(SFX_SNORE_MALE) + soundin = pick_weight(list( + 'sound/mobs/humanoids/human/snore/snore_male1.ogg' = 20, + 'sound/mobs/humanoids/human/snore/snore_male2.ogg' = 20, + 'sound/mobs/humanoids/human/snore/snore_male3.ogg' = 20, + 'sound/mobs/humanoids/human/snore/snore_male4.ogg' = 20, + 'sound/mobs/humanoids/human/snore/snore_male5.ogg' = 20, + 'sound/mobs/humanoids/human/snore/snore_mimimi2.ogg' = 1, + )) + if(SFX_CAT_MEOW) + soundin = pick_weight(list( + 'sound/creatures/cat/cat_meow1.ogg' = 33, + 'sound/creatures/cat/cat_meow2.ogg' = 33, + 'sound/creatures/cat/cat_meow3.ogg' = 33, + 'sound/creatures/cat/oranges_meow1.ogg' = 1, + )) + if(SFX_CAT_PURR) + soundin = pick( + 'sound/creatures/cat/cat_purr1.ogg', + 'sound/creatures/cat/cat_purr2.ogg', + 'sound/creatures/cat/cat_purr3.ogg', + 'sound/creatures/cat/cat_purr4.ogg', + ) + if(SFX_DEFAULT_LIQUID_SLOSH) + soundin = pick( + 'sound/items/handling/reagent_containers/default/default_liquid_slosh1.ogg', + 'sound/items/handling/reagent_containers/default/default_liquid_slosh2.ogg', + 'sound/items/handling/reagent_containers/default/default_liquid_slosh3.ogg', + 'sound/items/handling/reagent_containers/default/default_liquid_slosh4.ogg', + 'sound/items/handling/reagent_containers/default/default_liquid_slosh5.ogg', + ) + if(SFX_PLASTIC_BOTTLE_LIQUID_SLOSH) + soundin = pick( + 'sound/items/handling/reagent_containers/plastic_bottle/plastic_bottle_liquid_slosh1.ogg', + 'sound/items/handling/reagent_containers/plastic_bottle/plastic_bottle_liquid_slosh2.ogg', + ) + if(SFX_PLATE_ARMOR_RUSTLE) + soundin = pick_weight(list( + 'sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle1.ogg' = 8, //longest sound is rarer. + 'sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle2.ogg' = 23, + 'sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle3.ogg' = 23, + 'sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle4.ogg' = 23, + 'sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle5.ogg' = 23, + )) + if(SFX_PIG_OINK) + soundin = pick( + 'sound/mobs/non-humanoids/pig/pig1.ogg', + 'sound/mobs/non-humanoids/pig/pig2.ogg', + ) return soundin diff --git a/code/game/turfs/closed/wall/material_walls.dm b/code/game/turfs/closed/wall/material_walls.dm index 5f16a68584f3e..f8f9d58c220fb 100644 --- a/code/game/turfs/closed/wall/material_walls.dm +++ b/code/game/turfs/closed/wall/material_walls.dm @@ -22,6 +22,7 @@ var/datum/material/M = i new M.sheet_type(src, FLOOR(custom_materials[M] / SHEET_MATERIAL_AMOUNT, 1)) -/turf/closed/wall/material/mat_update_desc(mat) - desc = "A huge chunk of [mat] used to separate rooms." +/turf/closed/wall/material/finalize_material_effects(list/materials) + . = ..() + desc = "A huge chunk of [get_material_english_list(materials)] used to separate rooms." diff --git a/code/game/turfs/open/_open.dm b/code/game/turfs/open/_open.dm index b62de34f14690..c2b9963c5ed41 100644 --- a/code/game/turfs/open/_open.dm +++ b/code/game/turfs/open/_open.dm @@ -486,6 +486,15 @@ playsound(src, 'sound/items/weapons/genhit.ogg', 50, TRUE) new used_tiles.tile_type(src) +/turf/open/apply_main_material_effects(datum/material/main_material, amount, multipier) + . = ..() + if(!main_material.turf_sound_override) + return + footstep = main_material.turf_sound_override + barefootstep = main_material.turf_sound_override + "barefoot" + clawfootstep = main_material.turf_sound_override + "claw" + heavyfootstep = FOOTSTEP_GENERIC_HEAVY + /// Very similar to build_with_rods, this exists to allow building transport/tram girders on openspace /turf/open/proc/build_with_titanium(obj/item/stack/sheet/mineral/titanium/used_stack, user) var/obj/structure/transport/linear/platform = locate(/obj/structure/transport/linear, src) diff --git a/code/game/turfs/open/chasm.dm b/code/game/turfs/open/chasm.dm index f81ac4c7f536e..2699b4933626d 100644 --- a/code/game/turfs/open/chasm.dm +++ b/code/game/turfs/open/chasm.dm @@ -50,8 +50,8 @@ /turf/open/chasm/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) - underlay_appearance.icon = 'icons/turf/floors.dmi' - underlay_appearance.icon_state = "basalt" + underlay_appearance.icon = /turf/open/misc/asteroid/basalt::icon + underlay_appearance.icon_state = /turf/open/misc/asteroid/basalt::icon_state return TRUE /turf/open/chasm/attackby(obj/item/C, mob/user, params, area/area_restriction) @@ -100,6 +100,11 @@ light_power = 0.65 light_color = LIGHT_COLOR_PURPLE +/turf/open/chasm/icemoon/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) + underlay_appearance.icon = /turf/open/misc/asteroid/snow/icemoon::icon + underlay_appearance.icon_state = /turf/open/misc/asteroid/snow/icemoon::icon_state + return TRUE + // Chasms for the jungle, with planetary atmos and a different icon /turf/open/chasm/jungle icon = 'icons/turf/floors/junglechasm.dmi' @@ -109,8 +114,8 @@ baseturfs = /turf/open/chasm/jungle /turf/open/chasm/jungle/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) - underlay_appearance.icon = 'icons/turf/floors.dmi' - underlay_appearance.icon_state = "dirt" + underlay_appearance.icon = /turf/open/misc/dirt::icon + underlay_appearance.icon_state = /turf/open/misc/dirt::icon_state return TRUE // Chasm that doesn't do any z-level nonsense and just kills/stores whoever steps into it. diff --git a/code/game/turfs/open/floor.dm b/code/game/turfs/open/floor.dm index dad46fd8de6b6..c3ea369404331 100644 --- a/code/game/turfs/open/floor.dm +++ b/code/game/turfs/open/floor.dm @@ -382,4 +382,4 @@ . = ..() if(.) var/obj/item/stack/tile = . - tile.set_mats_per_unit(custom_materials, 1) + tile.set_custom_materials(custom_materials) diff --git a/code/game/turfs/open/lava.dm b/code/game/turfs/open/lava.dm index eebb74b72897b..1a9f24ce50ebd 100644 --- a/code/game/turfs/open/lava.dm +++ b/code/game/turfs/open/lava.dm @@ -178,11 +178,6 @@ /turf/open/lava/singularity_pull(S, current_size) return -/turf/open/lava/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) - underlay_appearance.icon = 'icons/turf/floors.dmi' - underlay_appearance.icon_state = "basalt" - return TRUE - /turf/open/lava/GetHeatCapacity() . = 700000 @@ -341,6 +336,12 @@ underfloor_accessibility = 2 //This avoids strangeness when routing pipes / wires along catwalks over lava immerse_overlay_color = "#F98511" +/// Smooth lava needs to take after basalt in order to blend better. If you make a /turf/open/lava/smooth subtype for an area NOT surrounded by basalt; you should override this proc. +/turf/open/lava/smooth/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) + underlay_appearance.icon = /turf/open/misc/asteroid/basalt::icon + underlay_appearance.icon_state = /turf/open/misc/asteroid/basalt::icon_state + return TRUE + /turf/open/lava/smooth/lava_land_surface initial_gas_mix = LAVALAND_DEFAULT_ATMOS planetary_atmos = TRUE diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 38976bcfdd6df..5b39caf571faa 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -270,7 +270,7 @@ GLOBAL_LIST_EMPTY(station_turfs) * * type_list - are we checking for types of atoms to ignore and not physical atoms */ /turf/proc/is_blocked_turf(exclude_mobs = FALSE, source_atom = null, list/ignore_atoms, type_list = FALSE) - if(density) + if((!isnull(source_atom) && !CanPass(source_atom, get_dir(src, source_atom))) || density) return TRUE for(var/atom/movable/movable_content as anything in contents) @@ -770,6 +770,23 @@ GLOBAL_LIST_EMPTY(station_turfs) inherent_explosive_resistance = explosion_block explosive_resistance += get_explosive_block() +/turf/apply_main_material_effects(datum/material/main_material, amount, multipier) + . = ..() + if(alpha < 255) + AddElement(/datum/element/turf_z_transparency) + main_material.setup_glow(src) + rust_resistance = main_material.mat_rust_resistance + +/turf/remove_main_material_effects(datum/material/custom_material, amount, multipier) + . = ..() + rust_resistance = initial(rust_resistance) + if(alpha == 255) + return + RemoveElement(/datum/element/turf_z_transparency) + // yeets glow + UnregisterSignal(SSdcs, COMSIG_STARLIGHT_COLOR_CHANGED) + set_light(0, 0, null) + /// Returns whether it is safe for an atom to move across this turf /turf/proc/can_cross_safely(atom/movable/crossing) return TRUE diff --git a/code/game/world.dm b/code/game/world.dm index 765aa7c18ef5d..184b13be6427f 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -399,10 +399,10 @@ GLOBAL_VAR(tracy_log) new_status += " | Shuttle: [SSshuttle.emergency.getModeStr()] [SSshuttle.emergency.getTimerStr()]" else if(SSticker.current_state == GAME_STATE_FINISHED) new_status += "
RESTARTING" - if(SSmapping.config) - new_status += "
Map: [SSmapping.config.map_path == CUSTOM_MAP_PATH ? "Uncharted Territory" : SSmapping.config.map_name]" - if(SSmapping.next_map_config) - new_status += "[SSmapping.config ? " | " : "
"]Next: [SSmapping.next_map_config.map_path == CUSTOM_MAP_PATH ? "Uncharted Territory" : SSmapping.next_map_config.map_name]" + if(SSmapping.current_map) + new_status += "
Map: [SSmapping.current_map.map_path == CUSTOM_MAP_PATH ? "Uncharted Territory" : SSmapping.current_map.map_name]" + if(SSmap_vote.next_map_config) + new_status += "[SSmapping.current_map ? " | " : "
"]Next: [SSmap_vote.next_map_config.map_path == CUSTOM_MAP_PATH ? "Uncharted Territory" : SSmap_vote.next_map_config.map_name]" status = new_status diff --git a/code/modules/actionspeed/modifiers/mobs.dm b/code/modules/actionspeed/modifiers/mobs.dm new file mode 100644 index 0000000000000..adc1a1d120750 --- /dev/null +++ b/code/modules/actionspeed/modifiers/mobs.dm @@ -0,0 +1,3 @@ +///speed bonus given by the fish tail organ when inside water. +/datum/actionspeed_modifier/fish_on_water + multiplicative_slowdown = -0.15 diff --git a/code/modules/admin/verbs/adminevents.dm b/code/modules/admin/verbs/adminevents.dm index b3c61e8e787f2..649ae3e3a34f8 100644 --- a/code/modules/admin/verbs/adminevents.dm +++ b/code/modules/admin/verbs/adminevents.dm @@ -121,103 +121,6 @@ ADMIN_VERB(cmd_admin_add_freeform_ai_law, R_ADMIN, "Add Custom AI Law", "Add a c BLACKBOX_LOG_ADMIN_VERB("Add Custom AI Law") -ADMIN_VERB(call_shuttle, R_ADMIN, "Call Shuttle", "Force a shuttle call with additional modifiers.", ADMIN_CATEGORY_EVENTS) - if(EMERGENCY_AT_LEAST_DOCKED) - return - - var/confirm = tgui_alert(user, "You sure?", "Confirm", list("Yes", "Yes (No Recall)", "No")) - switch(confirm) - if(null, "No") - return - if("Yes (No Recall)") - SSshuttle.admin_emergency_no_recall = TRUE - SSshuttle.emergency.mode = SHUTTLE_IDLE - - SSshuttle.emergency.request() - BLACKBOX_LOG_ADMIN_VERB("Call Shuttle") - log_admin("[key_name(user)] admin-called the emergency shuttle.") - message_admins(span_adminnotice("[key_name_admin(user)] admin-called the emergency shuttle[confirm == "Yes (No Recall)" ? " (non-recallable)" : ""].")) - -ADMIN_VERB(cancel_shuttle, R_ADMIN, "Cancel Shuttle", "Recall the shuttle, regardless of circumstances.", ADMIN_CATEGORY_EVENTS) - if(EMERGENCY_AT_LEAST_DOCKED) - return - - if(tgui_alert(user, "You sure?", "Confirm", list("Yes", "No")) != "Yes") - return - SSshuttle.admin_emergency_no_recall = FALSE - SSshuttle.emergency.cancel() - BLACKBOX_LOG_ADMIN_VERB("Cancel Shuttle") - log_admin("[key_name(user)] admin-recalled the emergency shuttle.") - message_admins(span_adminnotice("[key_name_admin(user)] admin-recalled the emergency shuttle.")) - -ADMIN_VERB(disable_shuttle, R_ADMIN, "Disable Shuttle", "Those fuckers aren't getting out.", ADMIN_CATEGORY_EVENTS) - if(SSshuttle.emergency.mode == SHUTTLE_DISABLED) - to_chat(user, span_warning("Error, shuttle is already disabled.")) - return - - if(tgui_alert(user, "You sure?", "Confirm", list("Yes", "No")) != "Yes") - return - - message_admins(span_adminnotice("[key_name_admin(user)] disabled the shuttle.")) - - SSshuttle.last_mode = SSshuttle.emergency.mode - SSshuttle.last_call_time = SSshuttle.emergency.timeLeft(1) - SSshuttle.admin_emergency_no_recall = TRUE - SSshuttle.emergency.setTimer(0) - SSshuttle.emergency.mode = SHUTTLE_DISABLED - priority_announce( - text = "Emergency Shuttle uplink failure, shuttle disabled until further notice.", - title = "Uplink Failure", - sound = 'sound/announcer/announcement/announce_dig.ogg', - sender_override = "Emergency Shuttle Uplink Alert", - color_override = "grey", - ) - -ADMIN_VERB(enable_shuttle, R_ADMIN, "Enable Shuttle", "Those fuckers ARE getting out.", ADMIN_CATEGORY_EVENTS) - if(SSshuttle.emergency.mode != SHUTTLE_DISABLED) - to_chat(user, span_warning("Error, shuttle not disabled.")) - return - - if(tgui_alert(user, "You sure?", "Confirm", list("Yes", "No")) != "Yes") - return - - message_admins(span_adminnotice("[key_name_admin(user)] enabled the emergency shuttle.")) - SSshuttle.admin_emergency_no_recall = FALSE - SSshuttle.emergency_no_recall = FALSE - if(SSshuttle.last_mode == SHUTTLE_DISABLED) //If everything goes to shit, fix it. - SSshuttle.last_mode = SHUTTLE_IDLE - - SSshuttle.emergency.mode = SSshuttle.last_mode - if(SSshuttle.last_call_time < 10 SECONDS && SSshuttle.last_mode != SHUTTLE_IDLE) - SSshuttle.last_call_time = 10 SECONDS //Make sure no insta departures. - SSshuttle.emergency.setTimer(SSshuttle.last_call_time) - priority_announce( - text = "Emergency Shuttle uplink reestablished, shuttle enabled.", - title = "Uplink Restored", - sound = 'sound/announcer/announcement/announce_dig.ogg', - sender_override = "Emergency Shuttle Uplink Alert", - color_override = "green", - ) - -ADMIN_VERB(hostile_environment, R_ADMIN, "Hostile Environment", "Disable the shuttle, naturally.", ADMIN_CATEGORY_EVENTS) - switch(tgui_alert(user, "Select an Option", "Hostile Environment Manager", list("Enable", "Disable", "Clear All"))) - if("Enable") - if (SSshuttle.hostile_environments["Admin"] == TRUE) - to_chat(user, span_warning("Error, admin hostile environment already enabled.")) - else - message_admins(span_adminnotice("[key_name_admin(user)] Enabled an admin hostile environment")) - SSshuttle.registerHostileEnvironment("Admin") - if("Disable") - if (!SSshuttle.hostile_environments["Admin"]) - to_chat(user, span_warning("Error, no admin hostile environment found.")) - else - message_admins(span_adminnotice("[key_name_admin(user)] Disabled the admin hostile environment")) - SSshuttle.clearHostileEnvironment("Admin") - if("Clear All") - message_admins(span_adminnotice("[key_name_admin(user)] Disabled all current hostile environment sources")) - SSshuttle.hostile_environments.Cut() - SSshuttle.checkHostileEnvironment() - ADMIN_VERB(toggle_nuke, R_DEBUG|R_ADMIN, "Toggle Nuke", "Arm or disarm a nuke.", ADMIN_CATEGORY_EVENTS) var/list/nukes = list() for (var/obj/machinery/nuclearbomb/bomb in world) diff --git a/code/modules/admin/verbs/adminshuttle.dm b/code/modules/admin/verbs/adminshuttle.dm new file mode 100644 index 0000000000000..6f2a0d42b190c --- /dev/null +++ b/code/modules/admin/verbs/adminshuttle.dm @@ -0,0 +1,196 @@ +ADMIN_VERB(change_shuttle_events, R_ADMIN|R_FUN, "Change Shuttle Events", "Change the events on a shuttle.", ADMIN_CATEGORY_SHUTTLE) + //At least for now, just letting admins modify the emergency shuttle is fine + var/obj/docking_port/mobile/port = SSshuttle.emergency + + if(!port) + to_chat(user, span_admin("Uh oh, couldn't find the escape shuttle!")) + + var/list/options = list("Clear"="Clear") + + //Grab the active events so we know which ones we can Add or Remove + var/list/active = list() + for(var/datum/shuttle_event/event in port.event_list) + active[event.type] = event + + for(var/datum/shuttle_event/event as anything in subtypesof(/datum/shuttle_event)) + options[((event in active) ? "(Remove)" : "(Add)") + initial(event.name)] = event + + //Throw up an ugly menu with the shuttle events and the options to add or remove them, or clear them all + var/result = input(user, "Choose an event to add/remove", "Shuttle Events") as null|anything in sort_list(options) + + if(result == "Clear") + port.event_list.Cut() + message_admins("[key_name_admin(user)] has cleared the shuttle events on: [port]") + else if(options[result]) + var/typepath = options[result] + if(typepath in active) + port.event_list.Remove(active[options[result]]) + message_admins("[key_name_admin(user)] has removed '[active[result]]' from [port].") + else + message_admins("[key_name_admin(user)] has added '[typepath]' to [port].") + port.add_shuttle_event(typepath) + +ADMIN_VERB(call_shuttle, R_ADMIN, "Call Shuttle", "Force a shuttle call with additional modifiers.", ADMIN_CATEGORY_SHUTTLE) + if(EMERGENCY_AT_LEAST_DOCKED) + return + + var/confirm = tgui_alert(user, "You sure?", "Confirm", list("Yes", "Yes (No Recall)", "No")) + switch(confirm) + if(null, "No") + return + if("Yes (No Recall)") + SSshuttle.admin_emergency_no_recall = TRUE + SSshuttle.emergency.mode = SHUTTLE_IDLE + + SSshuttle.emergency.request() + BLACKBOX_LOG_ADMIN_VERB("Call Shuttle") + log_admin("[key_name(user)] admin-called the emergency shuttle.") + message_admins(span_adminnotice("[key_name_admin(user)] admin-called the emergency shuttle[confirm == "Yes (No Recall)" ? " (non-recallable)" : ""].")) + +ADMIN_VERB(cancel_shuttle, R_ADMIN, "Cancel Shuttle", "Recall the shuttle, regardless of circumstances.", ADMIN_CATEGORY_SHUTTLE) + if(EMERGENCY_AT_LEAST_DOCKED) + return + + if(tgui_alert(user, "You sure?", "Confirm", list("Yes", "No")) != "Yes") + return + SSshuttle.admin_emergency_no_recall = FALSE + SSshuttle.emergency.cancel() + BLACKBOX_LOG_ADMIN_VERB("Cancel Shuttle") + log_admin("[key_name(user)] admin-recalled the emergency shuttle.") + message_admins(span_adminnotice("[key_name_admin(user)] admin-recalled the emergency shuttle.")) + +ADMIN_VERB(disable_shuttle, R_ADMIN, "Disable Shuttle", "Those fuckers aren't getting out.", ADMIN_CATEGORY_SHUTTLE) + if(SSshuttle.emergency.mode == SHUTTLE_DISABLED) + to_chat(user, span_warning("Error, shuttle is already disabled.")) + return + + if(tgui_alert(user, "You sure?", "Confirm", list("Yes", "No")) != "Yes") + return + + message_admins(span_adminnotice("[key_name_admin(user)] disabled the shuttle.")) + + SSshuttle.last_mode = SSshuttle.emergency.mode + SSshuttle.last_call_time = SSshuttle.emergency.timeLeft(1) + SSshuttle.admin_emergency_no_recall = TRUE + SSshuttle.emergency.setTimer(0) + SSshuttle.emergency.mode = SHUTTLE_DISABLED + priority_announce( + text = "Emergency Shuttle uplink failure, shuttle disabled until further notice.", + title = "Uplink Failure", + sound = 'sound/announcer/announcement/announce_dig.ogg', + sender_override = "Emergency Shuttle Uplink Alert", + color_override = "grey", + ) + +ADMIN_VERB(enable_shuttle, R_ADMIN, "Enable Shuttle", "Those fuckers ARE getting out.", ADMIN_CATEGORY_SHUTTLE) + if(SSshuttle.emergency.mode != SHUTTLE_DISABLED) + to_chat(user, span_warning("Error, shuttle not disabled.")) + return + + if(tgui_alert(user, "You sure?", "Confirm", list("Yes", "No")) != "Yes") + return + + message_admins(span_adminnotice("[key_name_admin(user)] enabled the emergency shuttle.")) + SSshuttle.admin_emergency_no_recall = FALSE + SSshuttle.emergency_no_recall = FALSE + if(SSshuttle.last_mode == SHUTTLE_DISABLED) //If everything goes to shit, fix it. + SSshuttle.last_mode = SHUTTLE_IDLE + + SSshuttle.emergency.mode = SSshuttle.last_mode + if(SSshuttle.last_call_time < 10 SECONDS && SSshuttle.last_mode != SHUTTLE_IDLE) + SSshuttle.last_call_time = 10 SECONDS //Make sure no insta departures. + SSshuttle.emergency.setTimer(SSshuttle.last_call_time) + priority_announce( + text = "Emergency Shuttle uplink reestablished, shuttle enabled.", + title = "Uplink Restored", + sound = 'sound/announcer/announcement/announce_dig.ogg', + sender_override = "Emergency Shuttle Uplink Alert", + color_override = "green", + ) + +ADMIN_VERB(hostile_environment, R_ADMIN, "Hostile Environment", "Disable the shuttle, naturally.", ADMIN_CATEGORY_SHUTTLE) + switch(tgui_alert(user, "Select an Option", "Hostile Environment Manager", list("Enable", "Disable", "Clear All"))) + if("Enable") + if (SSshuttle.hostile_environments["Admin"] == TRUE) + to_chat(user, span_warning("Error, admin hostile environment already enabled.")) + else + message_admins(span_adminnotice("[key_name_admin(user)] Enabled an admin hostile environment")) + SSshuttle.registerHostileEnvironment("Admin") + if("Disable") + if (!SSshuttle.hostile_environments["Admin"]) + to_chat(user, span_warning("Error, no admin hostile environment found.")) + else + message_admins(span_adminnotice("[key_name_admin(user)] Disabled the admin hostile environment")) + SSshuttle.clearHostileEnvironment("Admin") + if("Clear All") + message_admins(span_adminnotice("[key_name_admin(user)] Disabled all current hostile environment sources")) + SSshuttle.hostile_environments.Cut() + SSshuttle.checkHostileEnvironment() + +ADMIN_VERB(shuttle_panel, R_ADMIN, "Shuttle Manipulator", "Opens the shuttle manipulator UI.", ADMIN_CATEGORY_SHUTTLE) + SSshuttle.ui_interact(user.mob) + +/obj/docking_port/mobile/proc/admin_fly_shuttle(mob/user) + var/list/options = list() + + for(var/port in SSshuttle.stationary_docking_ports) + if (istype(port, /obj/docking_port/stationary/transit)) + continue // please don't do this + var/obj/docking_port/stationary/S = port + if (canDock(S) == SHUTTLE_CAN_DOCK) + options[S.name || S.shuttle_id] = S + + options += "--------" + options += "Infinite Transit" + options += "Delete Shuttle" + options += "Into The Sunset (delete & greentext 'escape')" + + var/selection = tgui_input_list(user, "Select where to fly [name || shuttle_id]:", "Fly Shuttle", options) + if(isnull(selection)) + return + + switch(selection) + if("Infinite Transit") + destination = null + mode = SHUTTLE_IGNITING + setTimer(ignitionTime) + + if("Delete Shuttle") + if(tgui_alert(user, "Really delete [name || shuttle_id]?", "Delete Shuttle", list("Cancel", "Really!")) != "Really!") + return + jumpToNullSpace() + + if("Into The Sunset (delete & greentext 'escape')") + if(tgui_alert(user, "Really delete [name || shuttle_id] and greentext escape objectives?", "Delete Shuttle", list("Cancel", "Really!")) != "Really!") + return + intoTheSunset() + + else + if(options[selection]) + request(options[selection]) + +/obj/docking_port/mobile/emergency/admin_fly_shuttle(mob/user) + return // use the existing verbs for this + +/obj/docking_port/mobile/arrivals/admin_fly_shuttle(mob/user) + switch(tgui_alert(user, "Would you like to fly the arrivals shuttle once or change its destination?", "Fly Shuttle", list("Fly", "Retarget", "Cancel"))) + if("Cancel") + return + if("Fly") + return ..() + + var/list/options = list() + + for(var/port in SSshuttle.stationary_docking_ports) + if (istype(port, /obj/docking_port/stationary/transit)) + continue // please don't do this + var/obj/docking_port/stationary/S = port + if (canDock(S) == SHUTTLE_CAN_DOCK) + options[S.name || S.shuttle_id] = S + + var/selection = tgui_input_list(user, "New arrivals destination", "Fly Shuttle", options) + if(isnull(selection)) + return + target_dock = options[selection] + if(!QDELETED(target_dock)) + destination = target_dock diff --git a/code/modules/admin/verbs/change_shuttle_events.dm b/code/modules/admin/verbs/change_shuttle_events.dm deleted file mode 100644 index 90f7e03672e73..0000000000000 --- a/code/modules/admin/verbs/change_shuttle_events.dm +++ /dev/null @@ -1,31 +0,0 @@ -ADMIN_VERB(change_shuttle_events, R_ADMIN|R_FUN, "Change Shuttle Events", "Change the events on a shuttle.", ADMIN_CATEGORY_EVENTS) - //At least for now, just letting admins modify the emergency shuttle is fine - var/obj/docking_port/mobile/port = SSshuttle.emergency - - if(!port) - to_chat(user, span_admin("Uh oh, couldn't find the escape shuttle!")) - - var/list/options = list("Clear"="Clear") - - //Grab the active events so we know which ones we can Add or Remove - var/list/active = list() - for(var/datum/shuttle_event/event in port.event_list) - active[event.type] = event - - for(var/datum/shuttle_event/event as anything in subtypesof(/datum/shuttle_event)) - options[((event in active) ? "(Remove)" : "(Add)") + initial(event.name)] = event - - //Throw up an ugly menu with the shuttle events and the options to add or remove them, or clear them all - var/result = input(user, "Choose an event to add/remove", "Shuttle Events") as null|anything in sort_list(options) - - if(result == "Clear") - port.event_list.Cut() - message_admins("[key_name_admin(user)] has cleared the shuttle events on: [port]") - else if(options[result]) - var/typepath = options[result] - if(typepath in active) - port.event_list.Remove(active[options[result]]) - message_admins("[key_name_admin(user)] has removed '[active[result]]' from [port].") - else - port.event_list.Add(new typepath (port)) - message_admins("[key_name_admin(user)] has added '[typepath]' to [port].") diff --git a/code/modules/admin/verbs/ert.dm b/code/modules/admin/verbs/ert.dm index 23f1627503e06..71722eb6d64ab 100644 --- a/code/modules/admin/verbs/ert.dm +++ b/code/modules/admin/verbs/ert.dm @@ -77,6 +77,8 @@ else ertemplate = new /datum/ert/centcom_official + var/human_authority_setting = CONFIG_GET(string/human_authority) + var/list/settings = list( "preview_callback" = CALLBACK(src, PROC_REF(makeERTPreviewIcon)), "mainsettings" = list( @@ -84,7 +86,7 @@ "teamsize" = list("desc" = "Team Size", "type" = "number", "value" = ertemplate.teamsize), "mission" = list("desc" = "Mission", "type" = "string", "value" = ertemplate.mission), "polldesc" = list("desc" = "Ghost poll description", "type" = "string", "value" = ertemplate.polldesc), - "enforce_human" = list("desc" = "Enforce human authority", "type" = "boolean", "value" = "[(CONFIG_GET(flag/enforce_human_authority) ? "Yes" : "No")]"), + "enforce_human" = list("desc" = "Enforce human authority", "type" = "boolean", "value" = "[(human_authority_setting == HUMAN_AUTHORITY_ENFORCED ? "Yes" : "No")]"), "open_armory" = list("desc" = "Open armory doors", "type" = "boolean", "value" = "[(ertemplate.opendoors ? "Yes" : "No")]"), "leader_experience" = list("desc" = "Pick an experienced leader", "type" = "boolean", "value" = "[(ertemplate.leader_experience ? "Yes" : "No")]"), "random_names" = list("desc" = "Randomize names", "type" = "boolean", "value" = "[(ertemplate.random_names ? "Yes" : "No")]"), diff --git a/code/modules/admin/verbs/grant_dna_infusion.dm b/code/modules/admin/verbs/grant_dna_infusion.dm index 06cfa8110d60d..2e087a160574d 100644 --- a/code/modules/admin/verbs/grant_dna_infusion.dm +++ b/code/modules/admin/verbs/grant_dna_infusion.dm @@ -19,7 +19,7 @@ // This is necessary because list propererties are not defined until initialization picked_infusion = infusions[picked_infusion] - picked_infusion = new picked_infusion + picked_infusion = new picked_infusion() if(!length(picked_infusion.output_organs)) return FALSE @@ -27,7 +27,8 @@ . = picked_infusion for(var/obj/item/organ/infusion_organ as anything in picked_infusion.output_organs) var/obj/item/organ/new_organ = new infusion_organ() - if(!new_organ.replace_into(target)) + new_organ.replace_into(target) + if(new_organ.owner != target) to_chat(usr, span_notice("[target] is unable to carry [new_organ]!")) qdel(new_organ) . = FALSE diff --git a/code/modules/admin/verbs/lawpanel.dm b/code/modules/admin/verbs/lawpanel.dm index 6de3ff70182b8..32815b73cbd8f 100644 --- a/code/modules/admin/verbs/lawpanel.dm +++ b/code/modules/admin/verbs/lawpanel.dm @@ -48,7 +48,8 @@ ADMIN_VERB(law_panel, R_ADMIN, "Law Panel", "View the AI laws.", ADMIN_CATEGORY_ borgo.laws.add_inherent_law(lawtext) if(LAW_SUPPLIED) borgo.laws.add_supplied_law(length(borgo.laws.supplied), lawtext) // Just goes to the end of the list - + log_admin("[key_name(user)] has UPLOADED a [lawtype] law to [key_name(borgo)] stating: [lawtext]") + message_admins("[key_name(user)] has UPLOADED a [lawtype] law to [key_name(borgo)] stating: [lawtext]") return TRUE /datum/law_panel/proc/move_law_helper(mob/living/user, mob/living/silicon/borgo, direction, law) @@ -104,6 +105,9 @@ ADMIN_VERB(law_panel, R_ADMIN, "Law Panel", "View the AI laws.", ADMIN_CATEGORY_ return FALSE relevant_laws[lawindex] = newlaw + log_admin("[key_name(user)] has EDITED [key_name(borgo)] [lawtype] law. OLD LAW: [oldlaw] \ + NEW LAW: [newlaw]") + message_admins("[key_name(user)] has EDITED a [lawtype] law on [key_name(borgo)]") return TRUE /datum/law_panel/proc/edit_law_priority_helper(mob/living/user, mob/living/silicon/borgo, law) @@ -145,10 +149,12 @@ ADMIN_VERB(law_panel, R_ADMIN, "Law Panel", "View the AI laws.", ADMIN_CATEGORY_ if(swap_or_remove == "Swap") borgo.laws.supplied.Swap(old_prio, new_prio) + log_admin("[key_name(user)] has SWAPPED [key_name(borgo)] law [old_prio] and [new_prio]") return TRUE if(swap_or_remove == "Replace") borgo.laws.remove_supplied_law_by_num(new_prio, law) borgo.laws.add_supplied_law(new_prio, law) + log_admin("[key_name(user)] has REPLACED [key_name(borgo)] law: [law] with priority [new_prio]") return TRUE var/new_prio_for_old_law = new_prio + (swap_or_remove == "Move up" ? 1 : -1) @@ -157,6 +163,7 @@ ADMIN_VERB(law_panel, R_ADMIN, "Law Panel", "View the AI laws.", ADMIN_CATEGORY_ borgo.laws.remove_supplied_law_by_num(new_prio) borgo.laws.add_supplied_law(new_prio, law) borgo.laws.add_supplied_law(new_prio_for_old_law, existing_law) + log_admin("[key_name(user)] has changed the priority of an existing law on [key_name(borgo)]. LAW: [law] PRIORITY: [new_prio]") return TRUE // Sanity @@ -167,6 +174,8 @@ ADMIN_VERB(law_panel, R_ADMIN, "Law Panel", "View the AI laws.", ADMIN_CATEGORY_ // At this point the slot is free, insert it as normal borgo.laws.remove_supplied_law_by_num(old_prio) borgo.laws.add_supplied_law(new_prio, law) + log_admin("[key_name(user)] has UPLOADED a supplied law to [key_name(borgo)] stating: [law]") // Normal insertion, I.E upload + message_admins("[key_name(user)] has UPLOADED a supplied law to [key_name(borgo)] stating: [law]") return TRUE /datum/law_panel/proc/remove_law_helper(mob/living/user, mob/living/silicon/borgo, lawtype, law) @@ -184,7 +193,8 @@ ADMIN_VERB(law_panel, R_ADMIN, "Law Panel", "View the AI laws.", ADMIN_CATEGORY_ borgo.laws.protected_zeroth = FALSE else return FALSE - + log_admin("[key_name(user)] has REMOVED a law from [key_name(borgo)]. LAW: [law]") + message_admins("[key_name(user)] has REMOVED a law from [key_name(borgo)]. LAW: [law]") return TRUE /datum/law_panel/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) diff --git a/code/modules/admin/verbs/maprotation.dm b/code/modules/admin/verbs/maprotation.dm index 09d6d93bee632..38d7535758fc7 100644 --- a/code/modules/admin/verbs/maprotation.dm +++ b/code/modules/admin/verbs/maprotation.dm @@ -1,12 +1,3 @@ - -ADMIN_VERB(force_random_rotate, R_SERVER, "Trigger 'Random' Map Rotation", "Force a map vote.", ADMIN_CATEGORY_SERVER) - var/rotate = tgui_alert(user,"Force a random map rotation to trigger?", "Rotate map?", list("Yes", "Cancel")) - if (rotate != "Yes") - return - message_admins("[key_name_admin(user)] is forcing a random map rotation.") - log_admin("[key_name(user)] is forcing a random map rotation.") - SSmapping.maprotate() - ADMIN_VERB(admin_change_map, R_SERVER, "Change Map", "Set the next map.", ADMIN_CATEGORY_SERVER) var/list/maprotatechoices = list() for (var/map in config.maplist) @@ -119,14 +110,14 @@ ADMIN_VERB(admin_change_map, R_SERVER, "Change Map", "Set the next map.", ADMIN_ fdel(PATH_TO_NEXT_MAP_JSON) text2file(json_encode(json_value), PATH_TO_NEXT_MAP_JSON) - if(SSmapping.changemap(virtual_map)) + if(SSmap_vote.set_next_map(virtual_map)) message_admins("[key_name_admin(user)] has changed the map to [virtual_map.map_name]") - SSmapping.map_force_chosen = TRUE + SSmap_vote.admin_override = TRUE fdel("data/custom_map_json/[config_file]") else var/datum/map_config/virtual_map = maprotatechoices[chosenmap] message_admins("[key_name_admin(user)] is changing the map to [virtual_map.map_name]") log_admin("[key_name(user)] is changing the map to [virtual_map.map_name]") - if (SSmapping.changemap(virtual_map)) + if (SSmap_vote.set_next_map(virtual_map)) message_admins("[key_name_admin(user)] has changed the map to [virtual_map.map_name]") - SSmapping.map_force_chosen = TRUE + SSmap_vote.admin_override = TRUE diff --git a/code/modules/admin/verbs/shuttlepanel.dm b/code/modules/admin/verbs/shuttlepanel.dm deleted file mode 100644 index ae0ad4dcde3c5..0000000000000 --- a/code/modules/admin/verbs/shuttlepanel.dm +++ /dev/null @@ -1,68 +0,0 @@ -ADMIN_VERB(shuttle_panel, R_ADMIN, "Shuttle Manipulator", "Opens the shuttle manipulator UI.", ADMIN_CATEGORY_EVENTS) - SSshuttle.ui_interact(user.mob) - -/obj/docking_port/mobile/proc/admin_fly_shuttle(mob/user) - var/list/options = list() - - for(var/port in SSshuttle.stationary_docking_ports) - if (istype(port, /obj/docking_port/stationary/transit)) - continue // please don't do this - var/obj/docking_port/stationary/S = port - if (canDock(S) == SHUTTLE_CAN_DOCK) - options[S.name || S.shuttle_id] = S - - options += "--------" - options += "Infinite Transit" - options += "Delete Shuttle" - options += "Into The Sunset (delete & greentext 'escape')" - - var/selection = tgui_input_list(user, "Select where to fly [name || shuttle_id]:", "Fly Shuttle", options) - if(isnull(selection)) - return - - switch(selection) - if("Infinite Transit") - destination = null - mode = SHUTTLE_IGNITING - setTimer(ignitionTime) - - if("Delete Shuttle") - if(tgui_alert(user, "Really delete [name || shuttle_id]?", "Delete Shuttle", list("Cancel", "Really!")) != "Really!") - return - jumpToNullSpace() - - if("Into The Sunset (delete & greentext 'escape')") - if(tgui_alert(user, "Really delete [name || shuttle_id] and greentext escape objectives?", "Delete Shuttle", list("Cancel", "Really!")) != "Really!") - return - intoTheSunset() - - else - if(options[selection]) - request(options[selection]) - -/obj/docking_port/mobile/emergency/admin_fly_shuttle(mob/user) - return // use the existing verbs for this - -/obj/docking_port/mobile/arrivals/admin_fly_shuttle(mob/user) - switch(tgui_alert(user, "Would you like to fly the arrivals shuttle once or change its destination?", "Fly Shuttle", list("Fly", "Retarget", "Cancel"))) - if("Cancel") - return - if("Fly") - return ..() - - var/list/options = list() - - for(var/port in SSshuttle.stationary_docking_ports) - if (istype(port, /obj/docking_port/stationary/transit)) - continue // please don't do this - var/obj/docking_port/stationary/S = port - if (canDock(S) == SHUTTLE_CAN_DOCK) - options[S.name || S.shuttle_id] = S - - var/selection = tgui_input_list(user, "New arrivals destination", "Fly Shuttle", options) - if(isnull(selection)) - return - target_dock = options[selection] - if(!QDELETED(target_dock)) - destination = target_dock - diff --git a/code/modules/admin/view_variables/topic.dm b/code/modules/admin/view_variables/topic.dm index 75ed4aab4a59c..4fde1e30d1a0e 100644 --- a/code/modules/admin/view_variables/topic.dm +++ b/code/modules/admin/view_variables/topic.dm @@ -113,10 +113,51 @@ admin_ticket_log(L, "[log_msg]") vv_update_display(L, Text, "[newamt]") + else if(href_list["item_to_tweak"] && href_list["var_tweak"]) + if(!check_rights(NONE)) + return + + var/obj/item/editing = locate(href_list["item_to_tweak"]) + if(!istype(editing) || QDELING(editing)) + return + + var/existing_val = -1 + switch(href_list["var_tweak"]) + if("damtype") + existing_val = editing.damtype + if("force") + existing_val = editing.force + if("wound") + existing_val = editing.wound_bonus + if("bare wound") + existing_val = editing.bare_wound_bonus + else + CRASH("Invalid var_tweak passed to item vv set var: [href_list["var_tweak"]]") + + var/new_val + if(href_list["var_tweak"] == "damtype") + new_val = input("Enter the new damage type for [editing]","Set Damtype", existing_val) in list(BRUTE, BURN, TOX, OXY, STAMINA, BRAIN) + else + new_val = input("Enter the new value for [editing]'s [href_list["var_tweak"]]","Set [href_list["var_tweak"]]", existing_val) as num|null + if(isnull(new_val) || new_val == existing_val || QDELETED(editing) || !check_rights(NONE)) + return + + switch(href_list["var_tweak"]) + if("damtype") + editing.damtype = new_val + if("force") + editing.force = new_val + if("wound") + editing.wound_bonus = new_val + if("bare wound") + editing.bare_wound_bonus = new_val + + message_admins("[key_name(usr)] set [editing]'s [href_list["var_tweak"]] to [new_val] (was [existing_val])") + log_admin("[key_name(usr)] set [editing]'s [href_list["var_tweak"]] to [new_val] (was [existing_val])") + vv_update_display(editing, href_list["var_tweak"], istext(new_val) ? uppertext(new_val) : new_val) //Finally, refresh if something modified the list. if(href_list["datumrefresh"]) var/datum/DAT = locate(href_list["datumrefresh"]) if(isdatum(DAT) || istype(DAT, /client) || islist(DAT)) debug_variables(DAT) - diff --git a/code/modules/antagonists/_common/antag_spawner.dm b/code/modules/antagonists/_common/antag_spawner.dm index 27c1fd5a0ea89..741bdeeed7b7c 100644 --- a/code/modules/antagonists/_common/antag_spawner.dm +++ b/code/modules/antagonists/_common/antag_spawner.dm @@ -381,7 +381,10 @@ if(ishuman(spawned_mob)) var/mob/living/carbon/human/human_mob = spawned_mob - human_mob.set_species(species_type) + // ignore if it's already the same + if(human_mob.dna.species != species_type) + human_mob.set_species(species_type) + human_mob.equipOutfit(outfit) op_mind.special_role = role_to_play @@ -411,6 +414,7 @@ desc = "Call up some backup from ARC for monkey mayhem." icon = 'icons/obj/devices/voice.dmi' icon_state = "walkietalkie" + spawn_type = /mob/living/carbon/human/species/monkey species_type = /datum/species/monkey outfit = /datum/outfit/syndicate_monkey antag_datum = /datum/antagonist/syndicate_monkey @@ -424,13 +428,26 @@ monkey_man.fully_replace_character_name(monkey_man.real_name, pick(GLOB.syndicate_monkey_names)) - monkey_man.make_clever_and_no_dna_scramble() + monkey_man.crewlike_monkify() + + // fuck you i am no longer playing around. this goes against the entire soul of the item + RegisterSignal(monkey_man, COMSIG_SPECIES_GAIN, PROC_REF(allergy)) + monkey_man.mind.enslave_mind_to_creator(user) var/obj/item/implant/explosive/imp = new(src) imp.implant(monkey_man, user) +/obj/item/antag_spawner/loadout/monkey_man/proc/allergy(mob/living/second_lifer, datum/species/folly_species) + SIGNAL_HANDLER + if(is_simian(second_lifer)) + return + // timer is long to let them panic and consider their folly, and because allergies take a while + second_lifer.visible_message(span_bolddanger("[second_lifer] starts swelling unhealthily in size. It looks like they had an allergic reaction to becoming a [folly_species]!"), span_userdanger("As your monkey features morph, you feel your allergies coming in. Oh no.")) + // no brain or items. organs are funny though + second_lifer.inflate_gib(drop_bitflags = DROP_ORGANS|DROP_BODYPARTS, gib_time = 25 SECONDS, anim_time = 40 SECONDS) + /datum/outfit/syndicate_monkey name = "Syndicate Monkey Agent Kit" diff --git a/code/modules/antagonists/abductor/equipment/abduction_outfits.dm b/code/modules/antagonists/abductor/equipment/abduction_outfits.dm index 109f27e82225f..8739a9de74950 100644 --- a/code/modules/antagonists/abductor/equipment/abduction_outfits.dm +++ b/code/modules/antagonists/abductor/equipment/abduction_outfits.dm @@ -50,6 +50,13 @@ /obj/item/abductor/silencer = 1 ) +/datum/outfit/abductor/agent/cardboard + name = "Abductor Agent" + head = /obj/item/clothing/head/helmet/abductor + suit = /obj/item/clothing/suit/armor/abductor/vest + l_hand = /obj/item/melee/baton/abductor + belt = /obj/item/storage/belt/military/abductor/full + /datum/outfit/abductor/scientist name = "Abductor Scientist" diff --git a/code/modules/antagonists/abductor/equipment/gland.dm b/code/modules/antagonists/abductor/equipment/gland.dm index f4fe0fb1875f8..d1f240b7f6821 100644 --- a/code/modules/antagonists/abductor/equipment/gland.dm +++ b/code/modules/antagonists/abductor/equipment/gland.dm @@ -51,7 +51,7 @@ return var/image/holder = owner.hud_list[GLAND_HUD] var/icon/I = icon(owner.icon, owner.icon_state, owner.dir) - holder.pixel_y = I.Height() - world.icon_size + holder.pixel_y = I.Height() - ICON_SIZE_Y if(active_mind_control) holder.icon_state = "hudgland_active" else if(mind_control_uses) diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm index 59610861756e6..297437e0bc65f 100644 --- a/code/modules/antagonists/changeling/changeling.dm +++ b/code/modules/antagonists/changeling/changeling.dm @@ -15,6 +15,7 @@ default_custom_objective = "Consume the station's most valuable genomes." hardcore_random_bonus = TRUE stinger_sound = 'sound/music/antag/ling_alert.ogg' + /// Whether to give this changeling objectives or not var/give_objectives = TRUE /// Weather we assign objectives which compete with other lings @@ -996,11 +997,11 @@ var/icon/final_icon = render_preview_outfit(/datum/outfit/changeling) var/icon/split_icon = render_preview_outfit(/datum/outfit/job/engineer) - final_icon.Shift(WEST, world.icon_size / 2) - final_icon.Shift(EAST, world.icon_size / 2) + final_icon.Shift(WEST, ICON_SIZE_X / 2) + final_icon.Shift(EAST, ICON_SIZE_X / 2) - split_icon.Shift(EAST, world.icon_size / 2) - split_icon.Shift(WEST, world.icon_size / 2) + split_icon.Shift(EAST, ICON_SIZE_X / 2) + split_icon.Shift(WEST, ICON_SIZE_X / 2) final_icon.Blend(split_icon, ICON_OVERLAY) diff --git a/code/modules/antagonists/changeling/powers/transform.dm b/code/modules/antagonists/changeling/powers/transform.dm index 852e8fca53c8c..733e0495118bc 100644 --- a/code/modules/antagonists/changeling/powers/transform.dm +++ b/code/modules/antagonists/changeling/powers/transform.dm @@ -142,7 +142,7 @@ if(hud_icon) var/image/holder = user.hud_list[ID_HUD] var/icon/I = icon(user.icon, user.icon_state, user.dir) - holder.pixel_y = I.Height() - world.icon_size + holder.pixel_y = I.Height() - ICON_SIZE_Y holder.icon_state = hud_icon /** diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm index 6c3135fbe4b32..d4350a9c67966 100644 --- a/code/modules/antagonists/cult/blood_magic.dm +++ b/code/modules/antagonists/cult/blood_magic.dm @@ -41,7 +41,7 @@ if(!moving_button) continue var/first_available_slot = position_list[1] - var/our_x = position[1] + first_available_slot * world.icon_size // Offset any new buttons into our list + var/our_x = position[1] + first_available_slot * ICON_SIZE_X // Offset any new buttons into our list hud.position_action(moving_button, offset_to_screen_loc(our_x, position[2], our_view)) blood_spell.positioned = first_available_slot diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index e7cde6d1425c2..e334b17e3603a 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -34,7 +34,8 @@ Runes can either be invoked by one's self or with many different cultists. Each icon = 'icons/obj/antags/cult/rune.dmi' icon_state = "1" resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF - layer = SIGIL_LAYER + plane = FLOOR_PLANE + layer = RUNE_LAYER color = RUNE_COLOR_RED /// The name of the rune to cultists diff --git a/code/modules/antagonists/fugitive/hunters/hunter_outfits.dm b/code/modules/antagonists/fugitive/hunters/hunter_outfits.dm index 5491251d1aa53..20eccc6977900 100644 --- a/code/modules/antagonists/fugitive/hunters/hunter_outfits.dm +++ b/code/modules/antagonists/fugitive/hunters/hunter_outfits.dm @@ -249,7 +249,7 @@ /obj/item/clothing/mask/chameleon = 20, /obj/item/language_manual/codespeak_manual/unlimited = 10, /obj/item/storage/mail_counterfeit_device = 10, - /obj/item/traitor_machine_trapper = 10, + /obj/item/clothing/glasses/thermal = 10, /obj/item/gun/ballistic/automatic/pistol/clandestine/fisher = 10, )) diff --git a/code/modules/antagonists/heretic/heretic_antag.dm b/code/modules/antagonists/heretic/heretic_antag.dm index 4c9c25945c9e8..d6e21bed03bea 100644 --- a/code/modules/antagonists/heretic/heretic_antag.dm +++ b/code/modules/antagonists/heretic/heretic_antag.dm @@ -27,6 +27,7 @@ default_custom_objective = "Turn a department into a testament for your dark knowledge." hardcore_random_bonus = TRUE stinger_sound = 'sound/music/antag/heretic/heretic_gain.ogg' + /// Whether we give this antagonist objectives on gain. var/give_objectives = TRUE /// Whether we've ascended! (Completed one of the final rituals) diff --git a/code/modules/antagonists/heretic/items/unfathomable_curio.dm b/code/modules/antagonists/heretic/items/unfathomable_curio.dm index 716b0927f54c6..eff1fa7ea2fe2 100644 --- a/code/modules/antagonists/heretic/items/unfathomable_curio.dm +++ b/code/modules/antagonists/heretic/items/unfathomable_curio.dm @@ -21,6 +21,7 @@ atom_storage.max_total_storage = 21 atom_storage.set_holdable(list( /obj/item/ammo_box/strilka310/lionhunter, + /obj/item/heretic_labyrinth_handbook, /obj/item/bodypart, // Bodyparts are often used in rituals. /obj/item/clothing/neck/eldritch_amulet, /obj/item/clothing/neck/heretic_focus, diff --git a/code/modules/antagonists/heretic/magic/cosmic_runes.dm b/code/modules/antagonists/heretic/magic/cosmic_runes.dm index 1003920dfa9ad..be8f103678e09 100644 --- a/code/modules/antagonists/heretic/magic/cosmic_runes.dm +++ b/code/modules/antagonists/heretic/magic/cosmic_runes.dm @@ -57,7 +57,8 @@ icon = 'icons/obj/service/hand_of_god_structures.dmi' icon_state = "cosmic_rune" resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF - layer = SIGIL_LAYER + plane = FLOOR_PLANE + layer = RUNE_LAYER /// The other rune this rune is linked with var/datum/weakref/linked_rune /// Effect for when someone teleports @@ -133,7 +134,8 @@ name = "cosmic rune" icon = 'icons/obj/service/hand_of_god_structures.dmi' icon_state = "cosmic_rune_fade" - layer = SIGIL_LAYER + plane = FLOOR_PLANE + layer = RUNE_LAYER anchored = TRUE duration = 5 @@ -147,7 +149,8 @@ name = "cosmic rune" icon = 'icons/obj/service/hand_of_god_structures.dmi' icon_state = "cosmic_rune_light" - layer = SIGIL_LAYER + plane = FLOOR_PLANE + layer = RUNE_LAYER anchored = TRUE duration = 5 diff --git a/code/modules/antagonists/heretic/magic/space_crawl.dm b/code/modules/antagonists/heretic/magic/space_crawl.dm index 6a96403872f11..cce9f46085bc6 100644 --- a/code/modules/antagonists/heretic/magic/space_crawl.dm +++ b/code/modules/antagonists/heretic/magic/space_crawl.dm @@ -1,3 +1,5 @@ +#define SPACE_PHASING "space-phasing" + /** * ### Space Crawl * @@ -16,6 +18,8 @@ invocation_type = INVOCATION_NONE spell_requirements = NONE + ///List of traits that are added to the heretic while in space phase jaunt + var/static/list/jaunting_traits = list(TRAIT_RESISTLOWPRESSURE, TRAIT_RESISTCOLD, TRAIT_NOBREATH) /datum/action/cooldown/spell/jaunt/space_crawl/Grant(mob/grant_to) . = ..() @@ -82,6 +86,7 @@ jaunter.put_in_hands(left_hand) jaunter.put_in_hands(right_hand) + jaunter.add_traits(jaunting_traits, SPACE_PHASING) RegisterSignal(jaunter, SIGNAL_REMOVETRAIT(TRAIT_ALLOW_HERETIC_CASTING), PROC_REF(on_focus_lost)) playsound(our_turf, 'sound/effects/magic/cosmic_energy.ogg', 50, TRUE, -1) our_turf.visible_message(span_warning("[jaunter] sinks into [our_turf]!")) @@ -101,6 +106,7 @@ if(!exit_jaunt(jaunter, our_turf)) return FALSE + jaunter.remove_traits(jaunting_traits, SPACE_PHASING) our_turf.visible_message(span_boldwarning("[jaunter] rises out of [our_turf]!")) return TRUE @@ -131,3 +137,5 @@ /obj/item/space_crawl/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) + +#undef SPACE_PHASING diff --git a/code/modules/antagonists/heretic/rust_effect.dm b/code/modules/antagonists/heretic/rust_effect.dm index ad86fa5a747f5..9af6c4f6d89a0 100644 --- a/code/modules/antagonists/heretic/rust_effect.dm +++ b/code/modules/antagonists/heretic/rust_effect.dm @@ -3,9 +3,9 @@ icon = 'icons/effects/eldritch.dmi' icon_state = "small_rune_1" anchored = TRUE - layer = LOW_SIGIL_LAYER + plane = FLOOR_PLANE + layer = LOWER_RUNE_LAYER mouse_opacity = MOUSE_OPACITY_TRANSPARENT - plane = GAME_PLANE /obj/effect/glowing_rune/Initialize(mapload) . = ..() diff --git a/code/modules/antagonists/heretic/status_effects/buffs.dm b/code/modules/antagonists/heretic/status_effects/buffs.dm index d60129ae3d930..387301f2c489d 100644 --- a/code/modules/antagonists/heretic/status_effects/buffs.dm +++ b/code/modules/antagonists/heretic/status_effects/buffs.dm @@ -254,13 +254,13 @@ var/static/list/caretaking_traits = list(TRAIT_GODMODE, TRAIT_HANDS_BLOCKED, TRAIT_IGNORESLOWDOWN, TRAIT_SECLUDED_LOCATION) /datum/status_effect/caretaker_refuge/on_apply() - owner.add_traits(caretaking_traits, TRAIT_STATUS_EFFECT(id)) animate(owner, alpha = 45,time = 0.5 SECONDS) owner.density = FALSE RegisterSignal(owner, SIGNAL_REMOVETRAIT(TRAIT_ALLOW_HERETIC_CASTING), PROC_REF(on_focus_lost)) RegisterSignal(owner, COMSIG_MOB_BEFORE_SPELL_CAST, PROC_REF(prevent_spell_usage)) RegisterSignal(owner, COMSIG_ATOM_HOLYATTACK, PROC_REF(nullrod_handler)) RegisterSignal(owner, COMSIG_CARBON_CUFF_ATTEMPTED, PROC_REF(prevent_cuff)) + owner.add_traits(caretaking_traits, TRAIT_STATUS_EFFECT(id)) return TRUE /datum/status_effect/caretaker_refuge/on_remove() @@ -288,7 +288,7 @@ /datum/status_effect/caretaker_refuge/proc/on_focus_lost() SIGNAL_HANDLER to_chat(owner, span_danger("Without a focus, your refuge weakens and dissipates!")) - owner.remove_status_effect(type) + qdel(src) /datum/status_effect/caretaker_refuge/proc/prevent_spell_usage(datum/source, datum/spell) SIGNAL_HANDLER diff --git a/code/modules/antagonists/heretic/structures/carving_knife.dm b/code/modules/antagonists/heretic/structures/carving_knife.dm index 72b224d117dd4..b93b52eb8e8e9 100644 --- a/code/modules/antagonists/heretic/structures/carving_knife.dm +++ b/code/modules/antagonists/heretic/structures/carving_knife.dm @@ -175,7 +175,7 @@ /obj/structure/trap/eldritch/on_entered(datum/source, atom/movable/entering_atom) if(!isliving(entering_atom)) - return ..() + return var/mob/living/living_mob = entering_atom if(WEAKREF(living_mob) == owner) return diff --git a/code/modules/antagonists/heretic/transmutation_rune.dm b/code/modules/antagonists/heretic/transmutation_rune.dm index 02c27c353a90e..a2bf4af77f4fa 100644 --- a/code/modules/antagonists/heretic/transmutation_rune.dm +++ b/code/modules/antagonists/heretic/transmutation_rune.dm @@ -7,7 +7,8 @@ anchored = TRUE interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF - layer = SIGIL_LAYER + plane = FLOOR_PLANE + layer = RUNE_LAYER ///Used mainly for summoning ritual to prevent spamming the rune to create millions of monsters. var/is_in_use = FALSE @@ -222,8 +223,8 @@ pixel_x = -30 pixel_y = 18 pixel_z = -48 - plane = GAME_PLANE - layer = SIGIL_LAYER + plane = FLOOR_PLANE + layer = RUNE_LAYER greyscale_config = /datum/greyscale_config/heretic_rune /// We only set this state after setting the colour, otherwise the animation doesn't colour correctly var/animation_state = "transmutation_rune_draw" diff --git a/code/modules/antagonists/ninja/ninja_clothing.dm b/code/modules/antagonists/ninja/ninja_clothing.dm index 54ed46c9c3ec0..4eaf40f9c79cb 100644 --- a/code/modules/antagonists/ninja/ninja_clothing.dm +++ b/code/modules/antagonists/ninja/ninja_clothing.dm @@ -15,7 +15,8 @@ resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF flags_inv = HIDEFACIALHAIR | HIDEFACE | HIDESNOUT flags_cover = MASKCOVERSMOUTH | PEPPERPROOF - has_fov = FALSE + pepper_tint = FALSE + /obj/item/clothing/under/syndicate/ninja name = "ninja suit" diff --git a/code/modules/antagonists/nukeop/datums/operative.dm b/code/modules/antagonists/nukeop/datums/operative.dm index 859cee578b265..ebaaf8692b2f4 100644 --- a/code/modules/antagonists/nukeop/datums/operative.dm +++ b/code/modules/antagonists/nukeop/datums/operative.dm @@ -9,6 +9,7 @@ hijack_speed = 2 //If you can't take out the station, take the shuttle instead. suicide_cry = "FOR THE SYNDICATE!!" stinger_sound = 'sound/music/antag/ops.ogg' + /// Which nukie team are we on? var/datum/team/nuclear/nuke_team /// If not assigned a team by default ops will try to join existing ones, set this to TRUE to always create new team. @@ -114,8 +115,8 @@ var/icon/teammate = render_preview_outfit(preview_outfit_behind) teammate.Blend(rgb(128, 128, 128, 128), ICON_MULTIPLY) - final_icon.Blend(teammate, ICON_UNDERLAY, -world.icon_size / 4, 0) - final_icon.Blend(teammate, ICON_UNDERLAY, world.icon_size / 4, 0) + final_icon.Blend(teammate, ICON_UNDERLAY, -ICON_SIZE_X / 4, 0) + final_icon.Blend(teammate, ICON_UNDERLAY, ICON_SIZE_X / 4, 0) if (!isnull(nuke_icon_state)) var/icon/nuke = icon('icons/obj/machines/nuke.dmi', nuke_icon_state) diff --git a/code/modules/antagonists/pirate/pirate_outfits.dm b/code/modules/antagonists/pirate/pirate_outfits.dm index 14729908e65be..8976e212c5475 100644 --- a/code/modules/antagonists/pirate/pirate_outfits.dm +++ b/code/modules/antagonists/pirate/pirate_outfits.dm @@ -57,6 +57,10 @@ id_trim = /datum/id_trim/pirate/captain +/datum/outfit/pirate/space/captain/cardboard + name = "Space Pirate Captain (EVA)" + l_hand = /obj/item/nullrod/claymore/saber/pirate + /datum/outfit/pirate/silverscale name = "Silver Scale Member" diff --git a/code/modules/antagonists/sentient_creature/sentient_creature.dm b/code/modules/antagonists/sentient_creature/sentient_creature.dm index d1197265ced5d..9fbafdfe2cce9 100644 --- a/code/modules/antagonists/sentient_creature/sentient_creature.dm +++ b/code/modules/antagonists/sentient_creature/sentient_creature.dm @@ -10,11 +10,11 @@ var/icon/pandora = icon('icons/mob/simple/lavaland/lavaland_elites.dmi', "pandora") pandora.Blend(rgb(128, 128, 128, 128), ICON_MULTIPLY) - final_icon.Blend(pandora, ICON_UNDERLAY, -world.icon_size / 4, 0) + final_icon.Blend(pandora, ICON_UNDERLAY, -ICON_SIZE_X / 4, 0) var/icon/rat = icon('icons/mob/simple/animal.dmi', "regalrat") rat.Blend(rgb(128, 128, 128, 128), ICON_MULTIPLY) - final_icon.Blend(rat, ICON_UNDERLAY, world.icon_size / 4, 0) + final_icon.Blend(rat, ICON_UNDERLAY, ICON_SIZE_X / 4, 0) final_icon.Scale(ANTAGONIST_PREVIEW_ICON_SIZE, ANTAGONIST_PREVIEW_ICON_SIZE) return final_icon diff --git a/code/modules/antagonists/space_dragon/carp_rift.dm b/code/modules/antagonists/space_dragon/carp_rift.dm index 6038c5e6820b7..6299bde9275cd 100644 --- a/code/modules/antagonists/space_dragon/carp_rift.dm +++ b/code/modules/antagonists/space_dragon/carp_rift.dm @@ -111,6 +111,8 @@ healing_color = COLOR_BLUE, \ ) + AddComponent(/datum/component/fishing_spot, /datum/fish_source/carp_rift) + gravity_aura = new( /* host = */src, /* range = */15, diff --git a/code/modules/antagonists/space_dragon/space_dragon.dm b/code/modules/antagonists/space_dragon/space_dragon.dm index 090c8f66dc82e..74b0c60a872ce 100644 --- a/code/modules/antagonists/space_dragon/space_dragon.dm +++ b/code/modules/antagonists/space_dragon/space_dragon.dm @@ -112,7 +112,7 @@ var/icon/icon = icon('icons/mob/nonhuman-player/spacedragon.dmi', "spacedragon") icon.Blend(COLOR_STRONG_VIOLET, ICON_MULTIPLY) - icon.Blend(icon('icons/mob/nonhuman-player/spacedragon.dmi', "overlay_base"), ICON_OVERLAY) + icon.Blend(icon('icons/mob/nonhuman-player/spacedragon.dmi', "spacedragon_overlay_base"), ICON_OVERLAY) icon.Crop(10, 9, 54, 53) icon.Scale(ANTAGONIST_PREVIEW_ICON_SIZE, ANTAGONIST_PREVIEW_ICON_SIZE) diff --git a/code/modules/antagonists/traitor/objectives/final_objective/final_objective.dm b/code/modules/antagonists/traitor/objectives/final_objective/final_objective.dm index 6e722b1515eb4..3367540239703 100644 --- a/code/modules/antagonists/traitor/objectives/final_objective/final_objective.dm +++ b/code/modules/antagonists/traitor/objectives/final_objective/final_objective.dm @@ -7,6 +7,7 @@ /datum/traitor_objective/ultimate/infect_ai = 1, /datum/traitor_objective/ultimate/romerol = 1, /datum/traitor_objective/ultimate/supermatter_cascade = 1, + /datum/traitor_objective/ultimate/no_escape = 1, ) weight = 100 diff --git a/code/modules/antagonists/traitor/objectives/final_objective/no_escape.dm b/code/modules/antagonists/traitor/objectives/final_objective/no_escape.dm new file mode 100644 index 0000000000000..12cbdcf2d01fa --- /dev/null +++ b/code/modules/antagonists/traitor/objectives/final_objective/no_escape.dm @@ -0,0 +1,48 @@ +/datum/traitor_objective/ultimate/no_escape + name = "Attach a beacon to the escape shuttle that will attract a singularity to consume everything." + description = "Go to %AREA%, and receive the smuggled beacon. Set up the beacon anywhere on the shuttle, \ + and charge it using an inducer then, IT COMES. Warning: The singularity will consume all in it's path, you included." + + ///area type the objective owner must be in to receive the satellites + var/area/beacon_spawn_area_type + ///checker on whether we have sent the beacon yet + var/sent_beacon = FALSE + +/datum/traitor_objective/ultimate/no_escape/generate_objective(datum/mind/generating_for, list/possible_duplicates) + var/list/possible_areas = GLOB.the_station_areas.Copy() + for(var/area/possible_area as anything in possible_areas) + if(!ispath(possible_area, /area/station/maintenance/solars) && !ispath(possible_area, /area/station/solars)) + possible_areas -= possible_area + if(length(possible_areas) == 0) + return FALSE + beacon_spawn_area_type = pick(possible_areas) + replace_in_name("%AREA%", initial(beacon_spawn_area_type.name)) + return TRUE + +/datum/traitor_objective/ultimate/no_escape/generate_ui_buttons(mob/user) + var/list/buttons = list() + if(!sent_beacon) + buttons += add_ui_button("", "Pressing this will call down a pod with the smuggled beacon.", "beacon", "beacon") + return buttons + +/datum/traitor_objective/ultimate/no_escape/ui_perform_action(mob/living/user, action) + . = ..() + switch(action) + if("beacon") + if(sent_beacon) + return + var/area/delivery_area = get_area(user) + if(delivery_area.type != beacon_spawn_area_type) + to_chat(user, span_warning("You must be in [initial(beacon_spawn_area_type.name)] to receive the smuggled beacon.")) + return + sent_beacon = TRUE + podspawn(list( + "target" = get_turf(user), + "style" = /datum/pod_style/syndicate, + "spawn" = list( + /obj/item/sbeacondrop/no_escape, + /obj/item/inducer/syndicate, + /obj/item/wrench + ) + )) + diff --git a/code/modules/antagonists/wizard/grand_ritual/finales/armageddon.dm b/code/modules/antagonists/wizard/grand_ritual/finales/armageddon.dm index 9b67aa24a5380..3716a684c6a3d 100644 --- a/code/modules/antagonists/wizard/grand_ritual/finales/armageddon.dm +++ b/code/modules/antagonists/wizard/grand_ritual/finales/armageddon.dm @@ -38,7 +38,7 @@ var/static/list/doom_options = list() if (!length(doom_options)) doom_options = list(DOOM_SINGULARITY, DOOM_TESLA) - if (!SSmapping.config.planetary) + if (!SSmapping.is_planetary()) doom_options += DOOM_METEORS switch(pick(doom_options)) diff --git a/code/modules/antagonists/wizard/grand_ritual/grand_ritual.dm b/code/modules/antagonists/wizard/grand_ritual/grand_ritual.dm index 2134e2862a461..e5611411a67e8 100644 --- a/code/modules/antagonists/wizard/grand_ritual/grand_ritual.dm +++ b/code/modules/antagonists/wizard/grand_ritual/grand_ritual.dm @@ -299,8 +299,8 @@ pixel_y = 16 pixel_z = -48 anchored = TRUE - layer = SIGIL_LAYER - plane = GAME_PLANE + plane = FLOOR_PLANE + layer = RUNE_LAYER duration = 0 SECONDS /obj/effect/temp_visual/wizard_rune/Initialize(mapload) diff --git a/code/modules/antagonists/wizard/grand_ritual/grand_rune.dm b/code/modules/antagonists/wizard/grand_ritual/grand_rune.dm index 009853bed22d1..6d08cd539fed5 100644 --- a/code/modules/antagonists/wizard/grand_ritual/grand_rune.dm +++ b/code/modules/antagonists/wizard/grand_ritual/grand_rune.dm @@ -21,7 +21,8 @@ anchored = TRUE interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_ATTACK_PAW resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF - layer = SIGIL_LAYER + plane = FLOOR_PLANE + layer = RUNE_LAYER /// How many prior grand rituals have been completed? var/potency = 0 /// Time to take per invocation of rune. @@ -393,7 +394,7 @@ mergeable_decal = FALSE resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF clean_type = CLEAN_TYPE_HARD_DECAL - layer = SIGIL_LAYER + layer = RUNE_LAYER /obj/effect/decal/cleanable/grand_remains/cheese name = "cheese soot marks" diff --git a/code/modules/antagonists/wizard/wizard.dm b/code/modules/antagonists/wizard/wizard.dm index 67b9a971bad5b..d0c99f03bbf06 100644 --- a/code/modules/antagonists/wizard/wizard.dm +++ b/code/modules/antagonists/wizard/wizard.dm @@ -15,6 +15,7 @@ GLOBAL_LIST_EMPTY(wizard_spellbook_purchases_by_key) can_assign_self_objectives = TRUE default_custom_objective = "Demonstrate your incredible and destructive magical powers." hardcore_random_bonus = TRUE + var/give_objectives = TRUE var/strip = TRUE //strip before equipping var/allow_rename = TRUE diff --git a/code/modules/art/statues.dm b/code/modules/art/statues.dm index ff5cbc38f850d..eeb0cfa9cb432 100644 --- a/code/modules/art/statues.dm +++ b/code/modules/art/statues.dm @@ -348,7 +348,7 @@ Moving interrupts //How long whole process takes var/sculpting_time = 30 SECONDS //Single interruptible progress period - var/sculpting_period = round(sculpting_time / world.icon_size) //this is just so it reveals pixels line by line for each. + var/sculpting_period = round(sculpting_time / ICON_SIZE_Y) //this is just so it reveals pixels line by line for each. var/interrupted = FALSE var/remaining_time = sculpting_time - (prepared_block.completion * sculpting_time) @@ -473,7 +473,7 @@ Moving interrupts return FALSE //No big icon things var/list/icon_dimensions = get_icon_dimensions(target.icon) - if(icon_dimensions["width"] != world.icon_size || icon_dimensions["height"] != world.icon_size) + if(icon_dimensions["width"] != ICON_SIZE_X || icon_dimensions["height"] != ICON_SIZE_Y) user.balloon_alert(user, "sculpt target is too big!") return FALSE return TRUE @@ -509,7 +509,7 @@ Moving interrupts remove_filter("partial_uncover") target_appearance_with_filters = null else - var/mask_offset = min(world.icon_size,round(completion * world.icon_size)) + var/mask_offset = min(ICON_SIZE_Y,round(completion * ICON_SIZE_Y)) remove_filter("partial_uncover") add_filter("partial_uncover", 1, alpha_mask_filter(icon = white, y = -mask_offset)) target_appearance_with_filters.filters = filter(type="alpha",icon=white,y=-mask_offset,flags=MASK_INVERSE) diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index 16a33b2a9a344..f0e9b5136ee8d 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -255,15 +255,15 @@ var/x_move = 0 var/y_move = 0 if(movement_dir & NORTH) - y_move = -32 + y_move = -ICON_SIZE_Y else if(movement_dir & SOUTH) - y_move = 32 + y_move = ICON_SIZE_Y if(movement_dir & WEST) - x_move = 32 + x_move = ICON_SIZE_X else if(movement_dir & EAST) - x_move = -32 + x_move = -ICON_SIZE_X - var/fake_glide_time = round(world.icon_size / glide_size * world.tick_lag, world.tick_lag) + var/fake_glide_time = round(ICON_SIZE_ALL / glide_size * world.tick_lag, world.tick_lag) for(var/obj/effect/ebeam/beam as anything in active_beam?.elements) var/matrix/base_transform = matrix(beam.transform) beam.transform = beam.transform.Translate(x_move, y_move) diff --git a/code/modules/asset_cache/asset_list.dm b/code/modules/asset_cache/asset_list.dm index bc302a188d825..39e9cf925da62 100644 --- a/code/modules/asset_cache/asset_list.dm +++ b/code/modules/asset_cache/asset_list.dm @@ -391,6 +391,11 @@ GLOBAL_LIST_EMPTY(asset_datums) to_generate += list(args.Copy()) /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 + stack_trace("Tried to insert nonexistent icon_state '[icon_state]' from [I] into spritesheet [name] ([type])") + return +#endif I = icon(I, icon_state=icon_state, dir=dir, frame=frame, moving=moving) if (!I || !length(icon_states(I))) // that direction or state doesn't exist return diff --git a/code/modules/asset_cache/assets/plumbing.dm b/code/modules/asset_cache/assets/plumbing.dm index 73b1dfc7df57d..980a85e83b040 100644 --- a/code/modules/asset_cache/assets/plumbing.dm +++ b/code/modules/asset_cache/assets/plumbing.dm @@ -17,7 +17,6 @@ "synthesizer", "reaction_chamber", "grinder_chemical", - "growing_vat", "fermenter", "pump", "disposal", diff --git a/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm b/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm index 5f073d17fc1e2..1e9045d82279c 100644 --- a/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm +++ b/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm @@ -99,13 +99,14 @@ GLOBAL_LIST_EMPTY_TYPED(air_alarms, /obj/machinery/airalarm) tlv_collection = list() tlv_collection["pressure"] = new /datum/tlv/pressure tlv_collection["temperature"] = new /datum/tlv/temperature - var/list/meta_info = GLOB.meta_gas_info // shorthand - for(var/gas_path in meta_info) + + var/list/cached_gas_info = GLOB.meta_gas_info + for(var/datum/gas/gas_path as anything in cached_gas_info) if(ispath(gas_path, /datum/gas/oxygen)) tlv_collection[gas_path] = new /datum/tlv/oxygen else if(ispath(gas_path, /datum/gas/carbon_dioxide)) tlv_collection[gas_path] = new /datum/tlv/carbon_dioxide - else if(meta_info[gas_path][META_GAS_DANGER]) + else if(cached_gas_info[gas_path][META_GAS_DANGER]) tlv_collection[gas_path] = new /datum/tlv/dangerous else tlv_collection[gas_path] = new /datum/tlv/no_checks @@ -137,6 +138,12 @@ GLOBAL_LIST_EMPTY_TYPED(air_alarms, /obj/machinery/airalarm) /obj/machinery/airalarm/Destroy() if(my_area) my_area = null + if(connected_sensor) + UnregisterSignal(connected_sensor, COMSIG_QDELETING) + UnregisterSignal(connected_sensor.loc, COMSIG_TURF_EXPOSE) + connected_sensor.connected_airalarm = null + connected_sensor = null + QDEL_NULL(alarm_manager) GLOB.air_alarms -= src return ..() @@ -201,10 +208,16 @@ GLOBAL_LIST_EMPTY_TYPED(air_alarms, /obj/machinery/airalarm) return . if(istype(multi_tool.buffer, /obj/machinery/air_sensor)) + var/obj/machinery/air_sensor/sensor = multi_tool.buffer + if(!allow_link_change) balloon_alert(user, "linking disabled") return ITEM_INTERACT_BLOCKING - connect_sensor(multi_tool.buffer) + if(connected_sensor || sensor.connected_airalarm) + balloon_alert(user, "sensor already connected!") + return ITEM_INTERACT_BLOCKING + + connect_sensor(sensor) balloon_alert(user, "connected sensor") return ITEM_INTERACT_SUCCESS @@ -568,34 +581,40 @@ GLOBAL_LIST_EMPTY_TYPED(air_alarms, /obj/machinery/airalarm) danger_level = max(danger_level, tlv_collection["pressure"].check_value(pressure)) danger_level = max(danger_level, tlv_collection["temperature"].check_value(temp)) if(total_moles) - for(var/gas_path in GLOB.meta_gas_info) + var/list/cached_gas_info = GLOB.meta_gas_info + for(var/datum/gas/gas_path as anything in cached_gas_info) var/moles = environment.gases[gas_path] ? environment.gases[gas_path][MOLES] : 0 danger_level = max(danger_level, tlv_collection[gas_path].check_value(pressure * moles / total_moles)) if(danger_level) alarm_manager.send_alarm(ALARM_ATMOS) - if(pressure <= tlv_collection["pressure"].hazard_min && temp <= tlv_collection["temperature"].hazard_min) + var/is_high_pressure = tlv_collection["pressure"].hazard_max != TLV_VALUE_IGNORE && pressure >= tlv_collection["pressure"].hazard_max + var/is_high_temp = tlv_collection["temperature"].hazard_max != TLV_VALUE_IGNORE && temp >= tlv_collection["temperature"].hazard_max + var/is_low_pressure = tlv_collection["pressure"].hazard_min != TLV_VALUE_IGNORE && pressure <= tlv_collection["pressure"].hazard_min + var/is_low_temp = tlv_collection["temperature"].hazard_min != TLV_VALUE_IGNORE && temp <= tlv_collection["temperature"].hazard_min + + if(is_low_pressure && is_low_temp) warning_message = "Danger! Low pressure and temperature detected." return - if(pressure <= tlv_collection["pressure"].hazard_min && temp >= tlv_collection["temperature"].hazard_max) + if(is_low_pressure && is_high_temp) warning_message = "Danger! Low pressure and high temperature detected." return - if(pressure >= tlv_collection["pressure"].hazard_max && temp >= tlv_collection["temperature"].hazard_max) + if(is_high_pressure && is_high_temp) warning_message = "Danger! High pressure and temperature detected." return - if(pressure >= tlv_collection["pressure"].hazard_max && temp <= tlv_collection["temperature"].hazard_min) + if(is_high_pressure && is_low_temp) warning_message = "Danger! High pressure and low temperature detected." return - if(pressure <= tlv_collection["pressure"].hazard_min) + if(is_low_pressure) warning_message = "Danger! Low pressure detected." return - if(pressure >= tlv_collection["pressure"].hazard_max) + if(is_high_pressure) warning_message = "Danger! High pressure detected." return - if(temp <= tlv_collection["temperature"].hazard_min) + if(is_low_temp) warning_message = "Danger! Low temperature detected." return - if(temp >= tlv_collection["temperature"].hazard_max) + if(is_high_temp) warning_message = "Danger! High temperature detected." return else @@ -686,14 +705,22 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/airalarm, 27) if(isnull(sensor)) log_mapping("[src] at [AREACOORD(src)] tried to connect to a sensor, but no sensor with chamber_id:[air_sensor_chamber_id] found!") return + if(connected_sensor) + log_mapping("[src] at [AREACOORD(src)] tried to connect to more than one sensor!") + return connect_sensor(sensor) ///Used to connect air alarm with a sensor /obj/machinery/airalarm/proc/connect_sensor(obj/machinery/air_sensor/sensor) - if(!isnull(connected_sensor)) - UnregisterSignal(connected_sensor, COMSIG_QDELETING) + sensor.connected_airalarm = src connected_sensor = sensor + RegisterSignal(connected_sensor, COMSIG_QDELETING, PROC_REF(disconnect_sensor)) + + // Transfer signal from air alarm to sensor + UnregisterSignal(loc, COMSIG_TURF_EXPOSE) + RegisterSignal(connected_sensor.loc, COMSIG_TURF_EXPOSE, PROC_REF(check_danger), override=TRUE) + my_area = get_area(connected_sensor) check_enviroment() @@ -704,6 +731,12 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/airalarm, 27) ///Used to reset the air alarm to default configuration after disconnecting from air sensor /obj/machinery/airalarm/proc/disconnect_sensor() UnregisterSignal(connected_sensor, COMSIG_QDELETING) + + // Transfer signal from sensor to air alarm + UnregisterSignal(connected_sensor.loc, COMSIG_TURF_EXPOSE) + RegisterSignal(loc, COMSIG_TURF_EXPOSE, PROC_REF(check_danger), override=TRUE) + + connected_sensor.connected_airalarm = null connected_sensor = null my_area = get_area(src) diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm index 95758c22707c6..186ef8ea9aace 100644 --- a/code/modules/atmospherics/machinery/atmosmachinery.dm +++ b/code/modules/atmospherics/machinery/atmosmachinery.dm @@ -614,8 +614,8 @@ our_client.set_eye(target_move) // Let's smooth out that movement with an animate yeah? // If the new x is greater (move is left to right) we get a negative offset. vis versa - our_client.pixel_x = (x - target_move.x) * world.icon_size - our_client.pixel_y = (y - target_move.y) * world.icon_size + our_client.pixel_x = (x - target_move.x) * ICON_SIZE_X + our_client.pixel_y = (y - target_move.y) * ICON_SIZE_Y animate(our_client, pixel_x = 0, pixel_y = 0, time = 0.05 SECONDS) our_client.move_delay = world.time + 0.05 SECONDS diff --git a/code/modules/atmospherics/machinery/components/tank.dm b/code/modules/atmospherics/machinery/components/tank.dm index f76f3dc470f57..6aa23f84e934b 100644 --- a/code/modules/atmospherics/machinery/components/tank.dm +++ b/code/modules/atmospherics/machinery/components/tank.dm @@ -88,7 +88,6 @@ air_contents = new air_contents.temperature = T20C air_contents.volume = volume - refresh_pressure_limit() if(gas_type) fill_to_pressure(gas_type) @@ -121,7 +120,7 @@ . += span_notice("The pipe port can be moved or closed with a [wrench_hint].") . += span_notice("A holographic sticker on it says that its maximum safe pressure is: [siunit_pressure(max_pressure, 0)].") -/obj/machinery/atmospherics/components/tank/set_custom_materials(list/materials, multiplier) +/obj/machinery/atmospherics/components/tank/finalize_material_effects(list/materials) . = ..() refresh_pressure_limit() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/airlock_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/airlock_pump.dm index 804f868e9c189..2cde2acd0ace8 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/airlock_pump.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/airlock_pump.dm @@ -48,6 +48,8 @@ var/allowed_pressure_error = ONE_ATMOSPHERE / 100 ///Minimal distro pressure to start cycling var/min_distro_pressure = ONE_ATMOSPHERE / 10 + ///Which pressure holds docked vessel\station for override of external_pressure_target + var/docked_side_pressure ///Rate of the pump to remove gases from the air var/volume_rate = 1000 ///The start time of the current cycle to calculate cycle duration @@ -125,7 +127,31 @@ /obj/machinery/atmospherics/components/unary/airlock_pump/post_machine_initialize() . = ..() set_links() + // If we are on docked shuttle - setup docking variables + // Example - 'build your own shuttle' evac vessel + var/turf/local_turf = get_turf(src) + if (!cycling_set_up || !isshuttleturf(local_turf)) + return + var/tile_air_pressure + for(var/obj/machinery/door/airlock/external_airlock in external_airlocks) + var/current_area = get_area(external_airlock) + for(var/obj/machinery/door/airlock/other_airlock in orange(2, external_airlock)) // does not include src, extended because some escape pods have 1 plating turf exposed to space + if(get_area(other_airlock) != current_area) // does not include double-wide airlocks unless actually docked + // Cycle linking is only disabled if we are actually adjacent to another airlock + external_airlock.shuttledocked = TRUE + other_airlock.shuttledocked = TRUE + if (other_airlock.cycle_pump) + INVOKE_ASYNC(other_airlock.cycle_pump, TYPE_PROC_REF(/obj/machinery/atmospherics/components/unary/airlock_pump, on_dock_request), internal_pressure_target) // Only case when airlock pumps speaking to each other directly + // Save external airlocks turf in case our own docking purpouses + local_turf = get_turf(other_airlock) + + if (local_turf) + local_turf = get_step(local_turf, REVERSE_DIR(dir)) + tile_air_pressure = 0 + if (local_turf) + tile_air_pressure = max(0, local_turf.return_air().return_pressure()) + on_dock_request(tile_air_pressure) /obj/machinery/atmospherics/components/unary/airlock_pump/New() . = ..() @@ -239,6 +265,22 @@ airlock.say("Airlock pair not found.") return if(airlock in external_airlocks) + // If it's not null - we shuttledocked + // (it may be 0. Maybe badmin set internal pressure to 0 as well, who knows) + if(docked_side_pressure != null) + // Space-faced airlock detection + var/turf/external_tile = get_step(airlock, REVERSE_DIR(dir)) + // Map edge or space turf + if (external_tile == null || is_space_or_openspace(external_tile)) + airlock.run_animation(DOOR_DENY_ANIMATION) + return + var/tile_air_pressure = max(0, external_tile.return_air().return_pressure()) + var/pressure_delta = docked_side_pressure - tile_air_pressure + if (pressure_delta > 0 ? (pressure_delta > allowed_pressure_error*10) : (pressure_delta*-1 > allowed_pressure_error*10)) + // Disabled to avoid airlocks close-open spam + airlock.run_animation(DOOR_DENY_ANIMATION) + return + start_cycle(ATMOS_DIRECTION_SIPHONING, airlock) else if(airlock in internal_airlocks) start_cycle(ATMOS_DIRECTION_RELEASING, airlock) @@ -281,17 +323,12 @@ if(is_cycling_audible) source_airlock.say("Pressurizing airlock.") else - cycle_pressure_target = external_pressure_target + cycle_pressure_target = docked_side_pressure != null ? docked_side_pressure : external_pressure_target var/pressure_delta = tile_air_pressure - cycle_pressure_target if(pressure_delta <= allowed_pressure_error) stop_cycle("Pressure nominal, cycle skipped.") return TRUE - for(var/obj/machinery/door/airlock/airlock as anything in external_airlocks) - if(airlock.shuttledocked) - stop_cycle("Shuttle docked, cycle skipped.") - return TRUE - if(!source_airlock) source_airlock = external_airlocks[1] if(is_cycling_audible) @@ -307,6 +344,11 @@ return FALSE on = FALSE + // In case we can open both sides safe_dock will do it for us + // it also handles its own messages. If we can't - procceed + if (docked_side_pressure != null && safe_dock(unbolt_only)) + return TRUE + var/list/obj/machinery/door/airlock/unlocked_airlocks = pump_direction == ATMOS_DIRECTION_RELEASING ? internal_airlocks : external_airlocks for(var/obj/machinery/door/airlock/airlock as anything in unlocked_airlocks) airlock.unbolt() @@ -323,6 +365,106 @@ update_appearance() return TRUE +/obj/machinery/atmospherics/components/unary/airlock_pump/proc/on_dock_request(requester_pressure = 0) + if (docked_side_pressure != null) + return + + docked_side_pressure = requester_pressure + + if (!powered() || !cycling_set_up) + return + + // We just finishing previous cycle + if (airlocks_animating) + say("Docking request queued.") + stoplag(1.1 SECONDS) // Wait for opening animation + if (airlocks_animating) // Should (almost) never happened + say("ERROR: D11. Please re-initiate docking sequence.") + return + + if (on) + // You can't go there, there is a shuttle now + if (pump_direction == ATMOS_DIRECTION_SIPHONING) + stop_cycle("Cycling sequence overriden by docking sequence.", TRUE) + start_cycle(ATMOS_DIRECTION_RELEASING) + // If cycling inside, docking will be handled by stop_cycle proc + return + + // Check if we need cycle in + var/turf/local_turf = get_turf(src) + var/tile_air_pressure = max(0, local_turf.return_air().return_pressure()) + var/pressure_delta = internal_pressure_target - tile_air_pressure + if(pressure_delta <= allowed_pressure_error) + // We fine + safe_dock() + else + var/obj/machinery/door/airlock/source_airlock = pick(internal_airlocks) + source_airlock.say("Docking sequence initiated") + start_cycle(ATMOS_DIRECTION_RELEASING) + + +/obj/machinery/atmospherics/components/unary/airlock_pump/proc/safe_dock(unbolt_only = FALSE) + var/pressure_delta = internal_pressure_target - docked_side_pressure + // Docked vessel has pressure higher then our internal + if ((pressure_delta + allowed_pressure_error) < 0) + return FALSE + // Pressure is too different, its unsafe to open both sides + else if (pressure_delta > allowed_pressure_error * 10) + return FALSE + // No power handles by stop_cycle pretty good + else if (!powered()) + return FALSE + + var/turf/local_turf = get_turf(src) + var/tile_air_pressure = max(0, local_turf.return_air().return_pressure()) + pressure_delta = internal_pressure_target - tile_air_pressure + // Chamber is not pressurised + if(pressure_delta > allowed_pressure_error) + return FALSE + + for(var/obj/machinery/door/airlock/airlock as anything in (external_airlocks + internal_airlocks)) + if (airlock in external_airlocks) + airlock.air_tight = TRUE + local_turf = get_step(airlock, REVERSE_DIR(dir)) + // Map edge or space turf + if (local_turf == null || is_space_or_openspace(local_turf)) + continue + + tile_air_pressure = max(0, local_turf.return_air().return_pressure()) + pressure_delta = docked_side_pressure - tile_air_pressure + // Do not open airlocks leading in space + // If docked entity now has pressure lower or higher then was declared on docking + // We will keep airlocks closed until redocking or fixing atmos + if (pressure_delta > 0 ? (pressure_delta > allowed_pressure_error*10) : (pressure_delta*-1 > allowed_pressure_error*10)) + continue + + airlock.unbolt() + if(open_airlock_on_cycle && !unbolt_only) + INVOKE_ASYNC(airlock, TYPE_PROC_REF(/obj/machinery/door/airlock, secure_open)) + + airlocks_animating = TRUE + stoplag(1 SECONDS) // Wait for closing animation + airlocks_animating = FALSE + update_appearance() + say("Docking complete.") + return TRUE + + +/obj/machinery/atmospherics/components/unary/airlock_pump/proc/undock() + if (docked_side_pressure == null) + return + docked_side_pressure = null + if(!powered()) + return + + for(var/obj/machinery/door/airlock/airlock as anything in external_airlocks) + INVOKE_ASYNC(airlock, TYPE_PROC_REF(/obj/machinery/door/airlock, secure_close), TRUE) + + say("Docking connection terminated.") + airlocks_animating = TRUE + stoplag(1 SECONDS) // Wait for closing animation + airlocks_animating = FALSE + ///Update adjacent_turfs with atmospherically adjacent tiles /obj/machinery/atmospherics/components/unary/airlock_pump/proc/check_turfs() diff --git a/code/modules/awaymissions/away_props.dm b/code/modules/awaymissions/away_props.dm index 843e55b963fe4..90fc3031088f2 100644 --- a/code/modules/awaymissions/away_props.dm +++ b/code/modules/awaymissions/away_props.dm @@ -137,3 +137,16 @@ if(!istype(mover)) return return isnull(mover.ckey) == reverse + +/obj/effect/invisible_wall // why didnt we have this already + name = "invisible wall" + desc = "You shall not pass" + icon = 'icons/effects/mapping_helpers.dmi' + icon_state = "blocker" + color = COLOR_BLUE_LIGHT + invisibility = INVISIBILITY_MAXIMUM + anchored = TRUE + +/obj/effect/invisible_wall/CanAllowThrough(mob/living/mover, border_dir) + ..() + return FALSE // NO diff --git a/code/modules/balloon_alert/balloon_alert.dm b/code/modules/balloon_alert/balloon_alert.dm index db8c529198631..cf890c0130807 100644 --- a/code/modules/balloon_alert/balloon_alert.dm +++ b/code/modules/balloon_alert/balloon_alert.dm @@ -44,7 +44,7 @@ if (isnull(viewer_client)) return - var/bound_width = world.icon_size + var/bound_width = ICON_SIZE_X if (ismovable(src)) var/atom/movable/movable_source = src bound_width = movable_source.bound_width @@ -64,7 +64,7 @@ animate( balloon_alert, - pixel_y = world.icon_size * 1.2, + pixel_y = ICON_SIZE_Y * 1.2, time = BALLOON_TEXT_TOTAL_LIFETIME(length_mult), easing = SINE_EASING | EASE_OUT, ) diff --git a/code/modules/bitrunning/objects/clothing.dm b/code/modules/bitrunning/objects/clothing.dm index de2b6789d5812..731b7dc2cca58 100644 --- a/code/modules/bitrunning/objects/clothing.dm +++ b/code/modules/bitrunning/objects/clothing.dm @@ -8,3 +8,4 @@ name = "trenchcoat" desc = "A long, black trenchcoat. Makes you feel like you're the one, but you're not." icon_state = "trenchcoat" + flags_inv = HIDEBELT diff --git a/code/modules/cargo/materials_market.dm b/code/modules/cargo/materials_market.dm index 4037a51c6916b..dd3093a0aafec 100644 --- a/code/modules/cargo/materials_market.dm +++ b/code/modules/cargo/materials_market.dm @@ -143,7 +143,7 @@ trend_string = "down" //get mat color - var/initial_colors = initial(traded_mat.greyscale_colors) + var/initial_colors = initial(traded_mat.greyscale_color) || initial(traded_mat.color) if(initial_colors) color_string = splicetext(initial_colors, 7, length(initial_colors), "") //slice it to a standard 6 char hex else diff --git a/code/modules/cargo/packs/imports.dm b/code/modules/cargo/packs/imports.dm index fc35e473f5ada..8720cb554fd43 100644 --- a/code/modules/cargo/packs/imports.dm +++ b/code/modules/cargo/packs/imports.dm @@ -143,7 +143,7 @@ /obj/item/gun/ballistic/automatic/wt550 = 2, /obj/item/ammo_box/magazine/wt550m9 = 2, ) - crate_type = /obj/structure/closet/crate/secure/gorlex_weapons/jammed + crate_type = /obj/structure/closet/crate/secure/syndicate/gorlex/weapons/bustedlock /datum/supply_pack/imports/wt550ammo name = "Smuggled WT-550 Ammo Crate" @@ -156,7 +156,7 @@ /obj/item/ammo_box/magazine/wt550m9/wtic = 2, ) crate_name = "emergency crate" - crate_type = /obj/structure/closet/crate/secure/gorlex_weapons/jammed + crate_type = /obj/structure/closet/crate/secure/syndicate/gorlex/weapons/bustedlock /datum/supply_pack/imports/shocktrooper name = "Shocktrooper Crate" @@ -172,7 +172,7 @@ /obj/item/clothing/suit/armor/vest, /obj/item/clothing/head/helmet, ) - crate_type = /obj/structure/closet/crate/secure/gorlex_weapons/jammed + crate_type = /obj/structure/closet/crate/secure/syndicate/gorlex/weapons/bustedlock /datum/supply_pack/imports/specialops name = "Special Ops Crate" @@ -188,7 +188,7 @@ /obj/item/switchblade, /obj/item/grenade/mirage = 5, ) - crate_type = /obj/structure/closet/crate/secure/gorlex_weapons/jammed + crate_type = /obj/structure/closet/crate/secure/syndicate/gorlex/weapons/bustedlock /datum/supply_pack/imports/russian name = "Russian Surplus Military Gear Crate" diff --git a/code/modules/client/preferences/README.md b/code/modules/client/preferences/README.md index fabfb779c902b..674f234d48ef6 100644 --- a/code/modules/client/preferences/README.md +++ b/code/modules/client/preferences/README.md @@ -398,11 +398,11 @@ For inspiration, here is changeling's: var/icon/final_icon = render_preview_outfit(/datum/outfit/changeling) var/icon/split_icon = render_preview_outfit(/datum/outfit/job/engineer) - final_icon.Shift(WEST, world.icon_size / 2) - final_icon.Shift(EAST, world.icon_size / 2) + final_icon.Shift(WEST, ICON_SIZE_X / 2) + final_icon.Shift(EAST, ICON_SIZE_X / 2) - split_icon.Shift(EAST, world.icon_size / 2) - split_icon.Shift(WEST, world.icon_size / 2) + split_icon.Shift(EAST, ICON_SIZE_X / 2) + split_icon.Shift(WEST, ICON_SIZE_X / 2) final_icon.Blend(split_icon, ICON_OVERLAY) diff --git a/code/modules/client/preferences/species_features/felinid.dm b/code/modules/client/preferences/species_features/felinid.dm index be90d806323d3..5910e42894f02 100644 --- a/code/modules/client/preferences/species_features/felinid.dm +++ b/code/modules/client/preferences/species_features/felinid.dm @@ -1,32 +1,32 @@ -/datum/preference/choiced/tail_human - savefile_key = "feature_human_tail" +/datum/preference/choiced/tail_felinid + savefile_key = "feature_human_tail" //savefile keys cannot be changed, blame whoever named them this way. savefile_identifier = PREFERENCE_CHARACTER category = PREFERENCE_CATEGORY_SECONDARY_FEATURES can_randomize = FALSE relevant_external_organ = /obj/item/organ/external/tail/cat -/datum/preference/choiced/tail_human/init_possible_values() - return assoc_to_keys_features(SSaccessories.tails_list_human) +/datum/preference/choiced/tail_felinid/init_possible_values() + return assoc_to_keys_features(SSaccessories.tails_list_felinid) -/datum/preference/choiced/tail_human/apply_to_human(mob/living/carbon/human/target, value) +/datum/preference/choiced/tail_felinid/apply_to_human(mob/living/carbon/human/target, value) target.dna.features["tail_cat"] = value -/datum/preference/choiced/tail_human/create_default_value() - var/datum/sprite_accessory/tails/human/cat/tail = /datum/sprite_accessory/tails/human/cat +/datum/preference/choiced/tail_felinid/create_default_value() + var/datum/sprite_accessory/tails/felinid/cat/tail = /datum/sprite_accessory/tails/felinid/cat return initial(tail.name) -/datum/preference/choiced/ears - savefile_key = "feature_human_ears" +/datum/preference/choiced/felinid_ears + savefile_key = "feature_human_ears" //savefile keys cannot be changed, blame whoever named them this way. savefile_identifier = PREFERENCE_CHARACTER category = PREFERENCE_CATEGORY_SECONDARY_FEATURES can_randomize = FALSE relevant_external_organ = /obj/item/organ/internal/ears/cat -/datum/preference/choiced/ears/init_possible_values() +/datum/preference/choiced/felinid_ears/init_possible_values() return assoc_to_keys_features(SSaccessories.ears_list) -/datum/preference/choiced/ears/apply_to_human(mob/living/carbon/human/target, value) +/datum/preference/choiced/felinid_ears/apply_to_human(mob/living/carbon/human/target, value) target.dna.features["ears"] = value -/datum/preference/choiced/ears/create_default_value() +/datum/preference/choiced/felinid_ears/create_default_value() return /datum/sprite_accessory/ears/cat::name diff --git a/code/modules/client/preferences/ui_style.dm b/code/modules/client/preferences/ui_style.dm index 64a82b592c60a..fa002fd71b0e7 100644 --- a/code/modules/client/preferences/ui_style.dm +++ b/code/modules/client/preferences/ui_style.dm @@ -12,8 +12,8 @@ var/icon/icons = GLOB.available_ui_styles[value] var/icon/icon = icon(icons, "hand_r") - icon.Crop(1, 1, world.icon_size * 2, world.icon_size) - icon.Blend(icon(icons, "hand_l"), ICON_OVERLAY, world.icon_size) + icon.Crop(1, 1, ICON_SIZE_X * 2, ICON_SIZE_Y) + icon.Blend(icon(icons, "hand_l"), ICON_OVERLAY, ICON_SIZE_X) return icon diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm index bd915cdf37a14..127840631d631 100644 --- a/code/modules/client/verbs/ooc.dm +++ b/code/modules/client/verbs/ooc.dm @@ -367,7 +367,7 @@ ADMIN_VERB(reset_ooc_color, R_FUN, "Reset Player OOC Color", "Returns player OOC var/desired_width = 0 if(zoom_value) - desired_width = round(view_size[1] * zoom_value * world.icon_size) + desired_width = round(view_size[1] * zoom_value * ICON_SIZE_X) else // Looks like we expect mapwindow.size to be "ixj" where i and j are numbers. @@ -456,3 +456,9 @@ ADMIN_VERB(reset_ooc_color, R_FUN, "Reset Player OOC Color", "Returns player OOC ASSERT(prefs, "User attempted to export preferences while preferences were null!") // what the fuck prefs.savefile.export_json_to_client(usr, ckey) + +/client/verb/map_vote_tally_count() + set name = "Show Map Vote Tallies" + set desc = "View the current map vote tally counts." + set category = "Server" + to_chat(mob, SSmap_vote.tally_printout) diff --git a/code/modules/clothing/masks/costume.dm b/code/modules/clothing/masks/costume.dm index 844b823880ac4..ff980442565a4 100644 --- a/code/modules/clothing/masks/costume.dm +++ b/code/modules/clothing/masks/costume.dm @@ -38,6 +38,7 @@ icon_state = "kitsune" inhand_icon_state = null w_class = WEIGHT_CLASS_SMALL + adjusted_flags = ITEM_SLOT_HEAD flags_inv = HIDEFACE|HIDEFACIALHAIR custom_price = PAYCHECK_CREW greyscale_colors = "#EEEEEE#AA0000" @@ -45,6 +46,18 @@ greyscale_config_worn = /datum/greyscale_config/kitsune/worn flags_1 = IS_PLAYER_COLORABLE_1 +/obj/item/clothing/mask/kitsune/examine(mob/user) + . = ..() + if(up) + . += "Use in-hand to wear as a mask!" + return + else + . += "Use in-hand to tie it up to wear as a hat!" + +/obj/item/clothing/mask/kitsune/attack_self(mob/user) + adjust_visor(user) + alternate_worn_layer = up ? ABOVE_BODY_FRONT_HEAD_LAYER : null + /obj/item/clothing/mask/rebellion name = "rebellion mask" desc = "Mask that is usually used during rebellions by insurgents. It covers the entire face and makes you unrecognizable." diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index 6d92b80ebfd47..89d9a68530acb 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -25,19 +25,21 @@ GLOBAL_LIST_INIT(clown_mask_options, list( var/list/gas_filters ///Type of filter that spawns on roundstart var/starting_filter_type = /obj/item/gas_filter - ///Does the mask have an FOV? - var/has_fov = TRUE ///Cigarette in the mask var/obj/item/cigarette/cig ///How much does this mask affect fishing difficulty var/fishing_modifier = 2 + ///Applies clothing_dirt component to the pepperproof mask if true + var/pepper_tint = TRUE /datum/armor/mask_gas bio = 100 /obj/item/clothing/mask/gas/Initialize(mapload) . = ..() - init_fov() + + if((flags_cover & PEPPERPROOF) && pepper_tint) + AddComponent(/datum/component/clothing_dirt) if(fishing_modifier) AddComponent(/datum/component/adjust_fishing_difficulty, fishing_modifier) @@ -160,11 +162,6 @@ GLOBAL_LIST_INIT(clown_mask_options, list( has_filter = FALSE return filtered_breath -/// Initializes the FoV component for the gas mask -/obj/item/clothing/mask/gas/proc/init_fov() - if (has_fov) - AddComponent(/datum/component/clothing_fov_visor, FOV_90_DEGREES) - /** * Getter for overall filter durability, takes into consideration all filters filter_status */ @@ -267,7 +264,6 @@ GLOBAL_LIST_INIT(clown_mask_options, list( icon_state = "plaguedoctor" flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEFACIALHAIR|HIDESNOUT|HIDEHAIR inhand_icon_state = "gas_mask" - has_fov = FALSE clothing_flags = BLOCK_GAS_SMOKE_EFFECT|MASKINTERNALS /obj/item/clothing/mask/gas/syndicate @@ -278,8 +274,8 @@ GLOBAL_LIST_INIT(clown_mask_options, list( resistance_flags = FIRE_PROOF | ACID_PROOF strip_delay = 60 w_class = WEIGHT_CLASS_SMALL - has_fov = FALSE fishing_modifier = 0 + pepper_tint = FALSE /obj/item/clothing/mask/gas/clown_hat name = "clown wig and mask" @@ -296,7 +292,6 @@ GLOBAL_LIST_INIT(clown_mask_options, list( resistance_flags = FLAMMABLE actions_types = list(/datum/action/item_action/adjust) dog_fashion = /datum/dog_fashion/head/clown - has_fov = FALSE var/list/clownmask_designs = list() voice_filter = null // performer masks expect to be talked through fishing_modifier = 0 @@ -341,7 +336,6 @@ GLOBAL_LIST_INIT(clown_mask_options, list( righthand_file = 'icons/mob/inhands/clothing/hats_righthand.dmi' flags_cover = MASKCOVERSEYES resistance_flags = FLAMMABLE - has_fov = FALSE fishing_modifier = 0 /obj/item/clothing/mask/gas/mime @@ -355,7 +349,6 @@ GLOBAL_LIST_INIT(clown_mask_options, list( resistance_flags = FLAMMABLE actions_types = list(/datum/action/item_action/adjust) species_exception = list(/datum/species/golem) - has_fov = FALSE fishing_modifier = 0 var/list/mimemask_designs = list() @@ -400,7 +393,6 @@ GLOBAL_LIST_INIT(clown_mask_options, list( inhand_icon_state = "owl_mask" flags_cover = MASKCOVERSEYES resistance_flags = FLAMMABLE - has_fov = FALSE fishing_modifier = 0 /obj/item/clothing/mask/gas/sexymime @@ -412,7 +404,6 @@ GLOBAL_LIST_INIT(clown_mask_options, list( flags_cover = MASKCOVERSEYES resistance_flags = FLAMMABLE species_exception = list(/datum/species/golem) - has_fov = FALSE fishing_modifier = 0 /obj/item/clothing/mask/gas/cyborg @@ -420,7 +411,6 @@ GLOBAL_LIST_INIT(clown_mask_options, list( desc = "Beep boop." icon_state = "death" resistance_flags = FLAMMABLE - has_fov = FALSE flags_cover = MASKCOVERSEYES fishing_modifier = 0 @@ -432,7 +422,6 @@ GLOBAL_LIST_INIT(clown_mask_options, list( clothing_flags = MASKINTERNALS flags_cover = MASKCOVERSEYES resistance_flags = FLAMMABLE - has_fov = FALSE fishing_modifier = -1 /obj/item/clothing/mask/gas/carp @@ -440,7 +429,6 @@ GLOBAL_LIST_INIT(clown_mask_options, list( desc = "Gnash gnash." icon_state = "carp_mask" inhand_icon_state = null - has_fov = FALSE flags_cover = MASKCOVERSEYES fishing_modifier = -3 @@ -451,7 +439,6 @@ GLOBAL_LIST_INIT(clown_mask_options, list( inhand_icon_state = null custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT * 1.25) resistance_flags = FLAMMABLE - has_fov = FALSE flags_cover = MASKCOVERSEYES max_integrity = 100 actions_types = list(/datum/action/item_action/adjust) @@ -498,7 +485,6 @@ GLOBAL_LIST_INIT(clown_mask_options, list( inhand_icon_state = "gas_atmos" resistance_flags = FIRE_PROOF | ACID_PROOF flags_inv = HIDEFACIALHAIR|HIDEFACE|HIDEEYES|HIDEEARS|HIDEHAIR|HIDESNOUT - has_fov = FALSE fishing_modifier = -2 /obj/item/clothing/mask/gas/prop @@ -509,7 +495,6 @@ GLOBAL_LIST_INIT(clown_mask_options, list( clothing_flags = NONE flags_cover = MASKCOVERSMOUTH resistance_flags = FLAMMABLE - has_fov = FALSE fishing_modifier = 0 /obj/item/clothing/mask/gas/atmosprop @@ -521,7 +506,6 @@ GLOBAL_LIST_INIT(clown_mask_options, list( clothing_flags = NONE flags_cover = MASKCOVERSMOUTH resistance_flags = FLAMMABLE - has_fov = FALSE fishing_modifier = 0 /obj/item/clothing/mask/gas/driscoll diff --git a/code/modules/clothing/masks/hailer.dm b/code/modules/clothing/masks/hailer.dm index aee1ac17b1b3e..182bc3ace7669 100644 --- a/code/modules/clothing/masks/hailer.dm +++ b/code/modules/clothing/masks/hailer.dm @@ -56,7 +56,6 @@ GLOBAL_LIST_INIT(hailer_phrases, list( flags_cover = MASKCOVERSMOUTH visor_flags_cover = MASKCOVERSMOUTH tint = 0 - has_fov = FALSE fishing_modifier = 0 unique_death = 'sound/items/sec_hailer/sec_death.ogg' COOLDOWN_DECLARE(hailer_cooldown) @@ -88,6 +87,7 @@ GLOBAL_LIST_INIT(hailer_phrases, list( flags_cover = MASKCOVERSMOUTH | MASKCOVERSEYES | PEPPERPROOF visor_flags_cover = MASKCOVERSMOUTH | MASKCOVERSEYES | PEPPERPROOF fishing_modifier = 2 + pepper_tint = FALSE /obj/item/clothing/mask/gas/sechailer/swat/spacepol name = "spacepol mask" diff --git a/code/modules/clothing/outfits/plasmaman.dm b/code/modules/clothing/outfits/plasmaman.dm index a0e927c631938..d6ab89cb8a855 100644 --- a/code/modules/clothing/outfits/plasmaman.dm +++ b/code/modules/clothing/outfits/plasmaman.dm @@ -4,7 +4,7 @@ uniform = /obj/item/clothing/under/plasmaman gloves = /obj/item/clothing/gloves/color/plasmaman head = /obj/item/clothing/head/helmet/space/plasmaman - r_hand= /obj/item/tank/internals/plasmaman/belt/full + r_hand = /obj/item/tank/internals/plasmaman/belt/full internals_slot = ITEM_SLOT_HANDS /datum/outfit/plasmaman/security diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index 88b388b47264d..53ab86b07718e 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -88,7 +88,7 @@ /obj/item/clothing/shoes/proc/restore_offsets(mob/user) equipped_before_drop = FALSE user.pixel_y -= offset - worn_y_dimension = world.icon_size + worn_y_dimension = ICON_SIZE_Y /obj/item/clothing/shoes/dropped(mob/user) var/atom/movable/screen/alert/our_alert = our_alert_ref?.resolve() diff --git a/code/modules/clothing/spacesuits/_spacesuits.dm b/code/modules/clothing/spacesuits/_spacesuits.dm index 124dfcee41c0b..cd646d1df9ac2 100644 --- a/code/modules/clothing/spacesuits/_spacesuits.dm +++ b/code/modules/clothing/spacesuits/_spacesuits.dm @@ -93,6 +93,12 @@ if(fishing_modifier) AddComponent(/datum/component/adjust_fishing_difficulty, fishing_modifier) +/obj/item/clothing/suit/space/on_outfit_equip(mob/living/carbon/human/outfit_wearer, visuals_only, item_slot) + . = ..() + if(isnull(cell)) + return + toggle_spacesuit(toggler = null, manual_toggle = FALSE) //turn on the thermal regulator by default. + /// Start Processing on the space suit when it is worn to heat the wearer /obj/item/clothing/suit/space/equipped(mob/living/user, slot) . = ..() @@ -161,7 +167,10 @@ thermal_on = FALSE // support for items that interact with the cell -/obj/item/clothing/suit/space/get_cell() +/obj/item/clothing/suit/space/get_cell(atom/movable/interface, mob/user) + if(istype(interface, /obj/item/inducer)) + to_chat(user, span_alert("Error: unable to interface with [interface].")) + return null return cell // Show the status of the suit and the cell diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm index 88767b84b66d5..3de75657d337c 100644 --- a/code/modules/clothing/spacesuits/plasmamen.dm +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -9,11 +9,10 @@ icon_state = "plasmaman_suit" inhand_icon_state = "plasmaman_suit" fishing_modifier = 0 - var/next_extinguish = 0 + COOLDOWN_DECLARE(extinguish_timer) var/extinguish_cooldown = 100 var/extinguishes_left = 10 - /datum/armor/eva_plasmaman bio = 100 fire = 100 @@ -23,21 +22,52 @@ . = ..() . += span_notice("There [extinguishes_left == 1 ? "is" : "are"] [extinguishes_left] extinguisher charge\s left in this suit.") +/obj/item/clothing/suit/space/eva/plasmaman/equipped(mob/living/user, slot) + . = ..() + if (slot & ITEM_SLOT_OCLOTHING) + RegisterSignals(user, list(COMSIG_MOB_EQUIPPED_ITEM, COMSIG_LIVING_IGNITED, SIGNAL_ADDTRAIT(TRAIT_HEAD_ATMOS_SEALED)), PROC_REF(check_fire_state)) + check_fire_state() + +/obj/item/clothing/suit/space/eva/plasmaman/dropped(mob/living/user) + . = ..() + UnregisterSignal(user, list(COMSIG_MOB_EQUIPPED_ITEM, COMSIG_LIVING_IGNITED, SIGNAL_ADDTRAIT(TRAIT_HEAD_ATMOS_SEALED))) + +/obj/item/clothing/suit/space/eva/plasmaman/proc/check_fire_state(datum/source) + SIGNAL_HANDLER + + if (!ishuman(loc)) + return + + // This is weird but basically we're calling this proc once the cooldown ends in case our wearer gets set on fire again during said cooldown + // This is why we're ignoring source and instead checking by loc + var/mob/living/carbon/human/owner = loc + if (!owner.on_fire || !owner.is_atmos_sealed(additional_flags = PLASMAMAN_PREVENT_IGNITION, check_hands = TRUE, ignore_chest_pressureprot = TRUE)) + return -/obj/item/clothing/suit/space/eva/plasmaman/proc/Extinguish(mob/living/carbon/human/H) - if(!istype(H)) + if (!extinguishes_left || !COOLDOWN_FINISHED(src, extinguish_timer)) return - if(H.fire_stacks > 0) - if(extinguishes_left) - if(next_extinguish > world.time) - return - next_extinguish = world.time + extinguish_cooldown - extinguishes_left-- - H.visible_message(span_warning("[H]'s suit automatically extinguishes [H.p_them()]!"),span_warning("Your suit automatically extinguishes you.")) - H.extinguish_mob() - new /obj/effect/particle_effect/water(get_turf(H)) + extinguishes_left -= 1 + COOLDOWN_START(src, extinguish_timer, extinguish_cooldown) + // Check if our (possibly other) wearer is on fire once the cooldown ends + addtimer(CALLBACK(src, PROC_REF(check_fire_state)), extinguish_cooldown) + owner.visible_message(span_warning("[owner]'s suit automatically extinguishes [owner.p_them()]!"), span_warning("Your suit automatically extinguishes you.")) + owner.extinguish_mob() + new /obj/effect/particle_effect/water(get_turf(owner)) + +/obj/item/clothing/suit/space/eva/plasmaman/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if (!istype(tool, /obj/item/extinguisher_refill)) + return + if (extinguishes_left == 5) + to_chat(user, span_notice("The inbuilt extinguisher is full.")) + return ITEM_INTERACT_BLOCKING + + extinguishes_left = 5 + to_chat(user, span_notice("You refill the suit's built-in extinguisher, using up the cartridge.")) + check_fire_state() + qdel(tool) + return ITEM_INTERACT_SUCCESS //I just want the light feature of helmets /obj/item/clothing/head/helmet/space/plasmaman diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 23e4d89ff2dbb..4569171c19a42 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -145,6 +145,10 @@ inhand_icon_state = "armor" dog_fashion = null +/obj/item/clothing/suit/armor/vest/cuirass/Initialize(mapload) + . = ..() + AddComponent(/datum/component/item_equipped_movement_rustle, SFX_PLATE_ARMOR_RUSTLE, 8) + /obj/item/clothing/suit/armor/hos name = "armored greatcoat" desc = "A greatcoat enhanced with a special alloy for some extra protection and style for those with a commanding presence." @@ -297,6 +301,10 @@ /obj/item/clothing/suit/armor/riot/Initialize(mapload) . = ..() AddComponent(/datum/component/adjust_fishing_difficulty, 5) + init_rustle_component() + +/obj/item/clothing/suit/armor/riot/proc/init_rustle_component() + AddComponent(/datum/component/item_equipped_movement_rustle) /datum/armor/armor_riot melee = 50 @@ -420,6 +428,10 @@ /obj/item/clothing/suit/armor/swat/Initialize(mapload) . = ..() AddComponent(/datum/component/adjust_fishing_difficulty, 5) + init_rustle_component() + +/obj/item/clothing/suit/armor/swat/proc/init_rustle_component() + AddComponent(/datum/component/item_equipped_movement_rustle) //All of the armor below is mostly unused @@ -519,6 +531,8 @@ /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, ) +/obj/item/clothing/suit/armor/riot/knight/init_rustle_component() + AddComponent(/datum/component/item_equipped_movement_rustle, SFX_PLATE_ARMOR_RUSTLE, 8) /obj/item/clothing/suit/armor/riot/knight/yellow icon_state = "knight_yellow" diff --git a/code/modules/clothing/suits/bio.dm b/code/modules/clothing/suits/bio.dm index 4fa5eeb5a90f7..25b28c74d1a7a 100644 --- a/code/modules/clothing/suits/bio.dm +++ b/code/modules/clothing/suits/bio.dm @@ -36,7 +36,7 @@ slowdown = 0.5 allowed = list(/obj/item/tank/internals, /obj/item/reagent_containers/dropper, /obj/item/flashlight/pen, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/reagent_containers/cup/beaker, /obj/item/gun/syringe) armor_type = /datum/armor/suit_bio_suit - flags_inv = HIDEGLOVES|HIDEJUMPSUIT + flags_inv = HIDEGLOVES|HIDEJUMPSUIT|HIDEBELT strip_delay = 70 equip_delay_other = 70 resistance_flags = ACID_PROOF diff --git a/code/modules/clothing/suits/costume.dm b/code/modules/clothing/suits/costume.dm index a720f49b9383f..d3918752056d1 100644 --- a/code/modules/clothing/suits/costume.dm +++ b/code/modules/clothing/suits/costume.dm @@ -121,7 +121,7 @@ icon_state = "imperium_monk" inhand_icon_state = "imperium_monk" body_parts_covered = CHEST|GROIN|LEGS|ARMS - flags_inv = HIDESHOES|HIDEJUMPSUIT + flags_inv = HIDESHOES|HIDEJUMPSUIT|HIDEBELT allowed = list(/obj/item/book/bible, /obj/item/nullrod, /obj/item/reagent_containers/cup/glass/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/flashlight/flare/candle, /obj/item/tank/internals/emergency_oxygen) /obj/item/clothing/suit/costume/chickensuit @@ -219,6 +219,7 @@ icon_state = "classicponcho" inhand_icon_state = null species_exception = list(/datum/species/golem) + flags_inv = HIDEBELT /obj/item/clothing/suit/costume/poncho/green name = "green poncho" @@ -248,7 +249,7 @@ icon_state = "white_dress" inhand_icon_state = "w_suit" body_parts_covered = CHEST|GROIN|LEGS|FEET - flags_inv = HIDEJUMPSUIT|HIDESHOES + flags_inv = HIDEJUMPSUIT|HIDESHOES|HIDEBELT /obj/item/clothing/suit/hooded/carp_costume name = "carp costume" @@ -503,6 +504,7 @@ desc = "Perfect for those who want to stalk around a corner of a bar." icon_state = "gothcoat" inhand_icon_state = null + flags_inv = HIDEBELT /obj/item/clothing/suit/costume/xenos name = "xenos suit" @@ -510,7 +512,7 @@ icon_state = "xenos" inhand_icon_state = "xenos_suit" body_parts_covered = CHEST|GROIN|LEGS|ARMS|HANDS - flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDEBELT allowed = list(/obj/item/clothing/mask/facehugger/toy) /obj/item/clothing/suit/costume/nemes diff --git a/code/modules/clothing/suits/ghostsheet.dm b/code/modules/clothing/suits/ghostsheet.dm index 965adc9b7e2ff..52c19be3bd160 100644 --- a/code/modules/clothing/suits/ghostsheet.dm +++ b/code/modules/clothing/suits/ghostsheet.dm @@ -7,7 +7,7 @@ throw_speed = 1 throw_range = 2 w_class = WEIGHT_CLASS_TINY - flags_inv = HIDEGLOVES|HIDEEARS|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT + flags_inv = HIDEGLOVES|HIDEEARS|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT|HIDEBELT|HIDEJUMPSUIT alternate_worn_layer = UNDER_HEAD_LAYER species_exception = list(/datum/species/golem) supports_variations_flags = CLOTHING_DIGITIGRADE_VARIATION_NO_NEW_ICON @@ -34,7 +34,7 @@ throw_speed = 1 throw_range = 2 w_class = WEIGHT_CLASS_TINY - flags_inv = HIDEGLOVES|HIDEEARS|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT + flags_inv = HIDEGLOVES|HIDEEARS|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT|HIDEBELT|HIDEJUMPSUIT species_exception = list(/datum/species/golem) supports_variations_flags = CLOTHING_DIGITIGRADE_VARIATION_NO_NEW_ICON alternate_worn_layer = ABOVE_BODY_FRONT_LAYER //so the bedsheet goes over everything but fire diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index 2ba150ab692ee..504558229639c 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -124,6 +124,7 @@ armor_type = /datum/armor/jacket_det_suit cold_protection = CHEST|GROIN|ARMS heat_protection = CHEST|GROIN|ARMS + flags_inv = HIDEBELT /datum/armor/jacket_det_suit melee = 25 diff --git a/code/modules/clothing/under/accessories/badges.dm b/code/modules/clothing/under/accessories/badges.dm index 335eded4d4c82..9d7d87a084687 100644 --- a/code/modules/clothing/under/accessories/badges.dm +++ b/code/modules/clothing/under/accessories/badges.dm @@ -4,6 +4,10 @@ desc = "Fills you with the conviction of JUSTICE. Lawyers tend to want to show it to everyone they meet." icon_state = "lawyerbadge" +/obj/item/clothing/accessory/lawyers_badge/Initialize(mapload) + . = ..() + AddComponent(/datum/component/bubble_icon_override, "lawyer", BUBBLE_ICON_PRIORITY_ACCESSORY) + /obj/item/clothing/accessory/lawyers_badge/interact(mob/user) . = ..() if(prob(1)) @@ -12,11 +16,9 @@ /obj/item/clothing/accessory/lawyers_badge/accessory_equipped(obj/item/clothing/under/clothes, mob/living/user) RegisterSignal(user, COMSIG_LIVING_SLAM_TABLE, PROC_REF(table_slam)) - user.bubble_icon = "lawyer" /obj/item/clothing/accessory/lawyers_badge/accessory_dropped(obj/item/clothing/under/clothes, mob/living/user) UnregisterSignal(user, COMSIG_LIVING_SLAM_TABLE) - user.bubble_icon = initial(user.bubble_icon) /obj/item/clothing/accessory/lawyers_badge/proc/table_slam(mob/living/source, obj/structure/table/the_table) SIGNAL_HANDLER diff --git a/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm b/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm index ee70fbb3d6ab6..1d2166653aef3 100644 --- a/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm +++ b/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm @@ -11,7 +11,7 @@ body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS can_adjust = FALSE strip_delay = 80 - var/next_extinguish = 0 + COOLDOWN_DECLARE(extinguish_timer) var/extinguish_cooldown = 100 var/extinguishes_left = 5 @@ -22,31 +22,54 @@ /obj/item/clothing/under/plasmaman/examine(mob/user) . = ..() - . += span_notice("There are [extinguishes_left] extinguisher charges left in this suit.") + . += span_notice("There [extinguishes_left == 1 ? "is" : "are"] [extinguishes_left] extinguisher charges left in this suit.") -/obj/item/clothing/under/plasmaman/proc/Extinguish(mob/living/carbon/human/H) - if(!istype(H)) +/obj/item/clothing/under/plasmaman/equipped(mob/living/user, slot) + . = ..() + if (slot & ITEM_SLOT_ICLOTHING) + RegisterSignals(user, list(COMSIG_MOB_EQUIPPED_ITEM, COMSIG_LIVING_IGNITED, SIGNAL_ADDTRAIT(TRAIT_HEAD_ATMOS_SEALED)), PROC_REF(check_fire_state)) + check_fire_state() + +/obj/item/clothing/under/plasmaman/dropped(mob/living/user) + . = ..() + UnregisterSignal(user, list(COMSIG_MOB_EQUIPPED_ITEM, COMSIG_LIVING_IGNITED, SIGNAL_ADDTRAIT(TRAIT_HEAD_ATMOS_SEALED))) + +/obj/item/clothing/under/plasmaman/proc/check_fire_state(datum/source) + SIGNAL_HANDLER + + if (!ishuman(loc)) + return + + // This is weird but basically we're calling this proc once the cooldown ends in case our wearer gets set on fire again during said cooldown + // This is why we're ignoring source and instead checking by loc + var/mob/living/carbon/human/owner = loc + if (!owner.on_fire || !owner.is_atmos_sealed(additional_flags = PLASMAMAN_PREVENT_IGNITION, check_hands = TRUE, ignore_chest_pressureprot = TRUE)) + return + + if (!extinguishes_left || !COOLDOWN_FINISHED(src, extinguish_timer)) return - if(H.on_fire) - if(extinguishes_left) - if(next_extinguish > world.time) - return - next_extinguish = world.time + extinguish_cooldown - extinguishes_left-- - H.visible_message(span_warning("[H]'s suit automatically extinguishes [H.p_them()]!"),span_warning("Your suit automatically extinguishes you.")) - H.extinguish_mob() - new /obj/effect/particle_effect/water(get_turf(H)) - -/obj/item/clothing/under/plasmaman/attackby(obj/item/E, mob/user, params) - ..() - if (istype(E, /obj/item/extinguisher_refill)) - if (extinguishes_left == 5) - to_chat(user, span_notice("The inbuilt extinguisher is full.")) - else - extinguishes_left = 5 - to_chat(user, span_notice("You refill the suit's built-in extinguisher, using up the cartridge.")) - qdel(E) + extinguishes_left -= 1 + COOLDOWN_START(src, extinguish_timer, extinguish_cooldown) + // Check if our (possibly other) wearer is on fire once the cooldown ends + addtimer(CALLBACK(src, PROC_REF(check_fire_state)), extinguish_cooldown) + owner.visible_message(span_warning("[owner]'s suit automatically extinguishes [owner.p_them()]!"), span_warning("Your suit automatically extinguishes you.")) + owner.extinguish_mob() + new /obj/effect/particle_effect/water(get_turf(owner)) + +/obj/item/clothing/under/plasmaman/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if (!istype(tool, /obj/item/extinguisher_refill)) + return + + if (extinguishes_left == 5) + to_chat(user, span_notice("The inbuilt extinguisher is full.")) + return ITEM_INTERACT_BLOCKING + + extinguishes_left = 5 + to_chat(user, span_notice("You refill the suit's built-in extinguisher, using up the cartridge.")) + check_fire_state() + qdel(tool) + return ITEM_INTERACT_SUCCESS /obj/item/extinguisher_refill name = "envirosuit extinguisher cartridge" @@ -54,7 +77,6 @@ icon_state = "plasmarefill" icon = 'icons/obj/canisters.dmi' - /obj/item/clothing/under/plasmaman/cargo name = "cargo plasma envirosuit" desc = "A joint envirosuit used by plasmamen quartermasters and cargo techs alike, due to the logistical problems of differenciating the two with the length of their pant legs." @@ -134,20 +156,27 @@ sensor_mode = SENSOR_COORDS random_sensor = FALSE -/obj/item/clothing/under/plasmaman/clown/Extinguish(mob/living/carbon/human/H) - if(!istype(H)) +/obj/item/clothing/under/plasmaman/clown/check_fire_state(datum/source, datum/status_effect/fire_handler/status_effect) + if (!ishuman(loc)) + return + + // This is weird but basically we're calling this proc once the cooldown ends in case our wearer gets set on fire again during said cooldown + // This is why we're ignoring source and instead checking by loc + var/mob/living/carbon/human/owner = loc + if (!owner.on_fire || !owner.is_atmos_sealed(additional_flags = PLASMAMAN_PREVENT_IGNITION, check_hands = TRUE, ignore_chest_pressureprot = TRUE)) + return + + if (!extinguishes_left || !COOLDOWN_FINISHED(src, extinguish_timer)) return - if(H.on_fire) - if(extinguishes_left) - if(next_extinguish > world.time) - return - next_extinguish = world.time + extinguish_cooldown - extinguishes_left-- - H.visible_message(span_warning("[H]'s suit spews space lube everywhere!"),span_warning("Your suit spews space lube everywhere!")) - H.extinguish_mob() - var/datum/effect_system/fluid_spread/foam/foam = new - var/datum/reagents/foamreagent = new /datum/reagents(15) - foamreagent.add_reagent(/datum/reagent/lube, 15) - foam.set_up(4, holder = src, location = H.loc, carry = foamreagent) - foam.start() //Truly terrifying. + extinguishes_left -= 1 + COOLDOWN_START(src, extinguish_timer, extinguish_cooldown) + // Check if our (possibly other) wearer is on fire once the cooldown ends + addtimer(CALLBACK(src, PROC_REF(check_fire_state)), extinguish_cooldown) + owner.visible_message(span_warning("[owner]'s suit spews space lube everywhere!"), span_warning("Your suit spews space lube everywhere!")) + owner.extinguish_mob() + var/datum/effect_system/fluid_spread/foam/foam = new + var/datum/reagents/foamreagent = new /datum/reagents(15) + foamreagent.add_reagent(/datum/reagent/lube, 15) + foam.set_up(4, holder = src, location = get_turf(owner), carry = foamreagent) + foam.start() //Truly terrifying. diff --git a/code/modules/deathmatch/deathmatch_loadouts.dm b/code/modules/deathmatch/deathmatch_loadouts.dm index 1e3d792f67b53..5670995512001 100644 --- a/code/modules/deathmatch/deathmatch_loadouts.dm +++ b/code/modules/deathmatch/deathmatch_loadouts.dm @@ -606,7 +606,7 @@ l_hand = /obj/item/melee/energy/sword r_pocket = /obj/item/reagent_containers/hypospray/medipen/stimulants l_pocket = /obj/item/soap/syndie - belt = /obj/item/gun/ballistic/revolver/syndicate + belt = /obj/item/gun/ballistic/revolver /datum/outfit/deathmatch_loadout/nukie name = "Deathmatch: Nuclear Operative" @@ -768,7 +768,7 @@ id_trim = /datum/id_trim/job/bridge_assistant // half tider half command id = /obj/item/card/id/advanced/chameleon uniform = /obj/item/clothing/under/trek/command/next - l_pocket = /obj/item/gun/energy/e_gun/mini + l_pocket = /obj/item/gun/energy/e_gun/mini // they are thej best race in the end. not as impactful as you may think r_pocket = /obj/item/extinguisher/mini gloves = /obj/item/clothing/gloves/fingerless belt = /obj/item/storage/belt/utility/full/inducer @@ -846,10 +846,11 @@ back = /obj/item/storage/backpack/science backpack_contents = list( - /obj/item/dnainjector/shock, /obj/item/etherealballdeployer, ) + mutations_to_add = list(/obj/item/dnainjector/shock) // pretend ethereals are interesting + /datum/outfit/deathmatch_loadout/plasmamen name = "Deathmatch: Plasmaman Species" display_name = "Plasmamen" @@ -907,16 +908,10 @@ uniform = /obj/item/clothing/under/pants/jeans suit = /obj/item/clothing/suit/costume/wellworn_shirt/graphic - back = /obj/item/storage/backpack + r_pocket = /obj/item/stack/rods/twentyfive + l_pocket = /obj/item/stack/rods/twentyfive r_hand = /obj/item/wirecutters - backpack_contents = list( - /obj/item/stack/rods/fifty, - /obj/item/stack/rods/fifty, - /obj/item/stack/rods/fifty, - /obj/item/stack/rods/fifty, - ) - // We don't want them to just punch each other to death /datum/outfit/deathmatch_loadout/lattice_battles/pre_equip(mob/living/carbon/human/user, visualsOnly) @@ -983,14 +978,12 @@ back = /obj/item/storage/backpack/cultpack backpack_contents = list( - /obj/item/cult_shift, /obj/item/reagent_containers/cup/beaker/unholywater, /obj/item/reagent_containers/cup/beaker/unholywater, /obj/item/reagent_containers/cup/beaker/unholywater, ) spells_to_add = list( - /datum/action/innate/cult/blood_spell/horror, /datum/action/innate/cult/blood_spell/horror, /datum/action/innate/cult/blood_spell/stun, /datum/action/innate/cult/blood_spell/stun, @@ -999,7 +992,7 @@ /datum/outfit/deathmatch_loadout/cultish/artificer/post_equip(mob/living/carbon/human/user, visualsOnly) . = ..() - var/datum/action/innate/cult/blood_spell/manipulation/magick = locate() in user + var/datum/action/innate/cult/blood_spell/manipulation/magick = locate() in user.get_all_contents() magick.charges = 300 /datum/outfit/deathmatch_loadout/heresy @@ -1018,13 +1011,10 @@ // Heretic Warrior -// Has spells of Ash, Blade, and Rust. Overall aggressive - /datum/outfit/deathmatch_loadout/heresy/warrior name = "Deathmatch: Heretic Warrior" display_name = "Heretic Warrior" - desc = "Prove the furious strength of the Mansus." - //species_override = /datum/species/plasmaman + desc = "Prove the furious strength of the Mansus!" head = /obj/item/clothing/head/hooded/cult_hoodie/eldritch neck = /obj/item/clothing/neck/heretic_focus @@ -1032,7 +1022,7 @@ suit_store = /obj/item/melee/sickly_blade/dark uniform = /obj/item/clothing/under/color/darkgreen id_trim = null - belt = /obj/item/melee/sickly_blade/ash + belt = /obj/item/melee/sickly_blade/rust gloves = null shoes = /obj/item/clothing/shoes/sandal l_pocket = /obj/item/flashlight/lantern/jade/on @@ -1061,16 +1051,12 @@ /datum/action/cooldown/spell/touch/mansus_grasp, /datum/action/cooldown/spell/realignment, /datum/action/cooldown/spell/pointed/projectile/furious_steel, - /datum/action/cooldown/spell/charged/beam/fire_blast, - /datum/action/cooldown/spell/aoe/fiery_rebirth, /datum/action/cooldown/spell/cone/staggered/entropic_plume, /datum/action/cooldown/spell/pointed/rust_construction, ) // Heretic Scribe -// Has spells of Void, Moon, and Cosmos. Overall defensive/mobile - /datum/outfit/deathmatch_loadout/heresy/scribe name = "Deathmatch: Heretic Scribe" display_name = "Heretic Scribe" @@ -1087,29 +1073,27 @@ gloves = null shoes = /obj/item/clothing/shoes/winterboots/ice_boots l_pocket = /obj/item/ammo_box/strilka310/lionhunter - r_pocket = /obj/item/codex_cicatrix + r_pocket = /obj/item/ammo_box/strilka310/lionhunter back = /obj/item/gun/ballistic/rifle/lionhunter // for his neutral b, he wields a gun belt_contents = list( /obj/item/heretic_labyrinth_handbook, /obj/item/heretic_labyrinth_handbook, - /obj/item/eldritch_potion/crucible_soul, - /obj/item/clothing/neck/heretic_focus/moon_amulet = 3, + /obj/item/eldritch_potion/duskndawn, + /obj/item/eldritch_potion/duskndawn, ) knowledge_to_grant = list( /datum/heretic_knowledge/cosmic_grasp, /datum/heretic_knowledge/moon_grasp, - /datum/heretic_knowledge/mark/moon_mark, ) spells_to_add = list( /datum/action/cooldown/spell/touch/mansus_grasp, - /datum/action/cooldown/spell/conjure/cosmic_expansion, /datum/action/cooldown/spell/pointed/projectile/star_blast, /datum/action/cooldown/spell/touch/star_touch, - /datum/action/cooldown/spell/cone/staggered/cone_of_cold/void, + /datum/action/cooldown/spell/pointed/mind_gate, /datum/action/cooldown/spell/aoe/void_pull, ) @@ -1127,7 +1111,7 @@ suit_store = /obj/item/book/bible/booze uniform = /obj/item/clothing/under/rank/civilian/chaplain id_trim = null - belt = /obj/item/nullrod // choose any! + belt = /obj/item/nullrod/non_station // choose any! gloves = /obj/item/clothing/gloves/plate shoes = /obj/item/clothing/shoes/plate l_pocket = /obj/item/flashlight/lantern/on @@ -1150,7 +1134,6 @@ name = "Deathmatch: Clock Cultist" display_name = "Rat'var Apostate" desc = "You're in a fight between the servants of gods, and yours is dead. Good luck?" - //species_override = /datum/species/plasmaman head = /obj/item/clothing/head/costume/bronze suit = /obj/item/clothing/suit/costume/bronze @@ -1160,5 +1143,5 @@ belt = /obj/item/brass_spear gloves = /obj/item/clothing/gloves/tinkerer shoes = /obj/item/clothing/shoes/bronze - l_pocket = /obj/item/reagent_containers/cup/beaker/synthflesh // they used to turn their dmg into tox with a spell. close enough - r_pocket = /obj/item/reagent_containers/cup/beaker/synthflesh + l_pocket = /obj/item/reagent_containers/cup/beaker/synthflesh/named // they used to turn their dmg into tox with a spell. close enough + r_pocket = /obj/item/reagent_containers/cup/beaker/synthflesh/named diff --git a/code/modules/deathmatch/deathmatch_mapping.dm b/code/modules/deathmatch/deathmatch_mapping.dm index b83419490be76..a0651f7da121b 100644 --- a/code/modules/deathmatch/deathmatch_mapping.dm +++ b/code/modules/deathmatch/deathmatch_mapping.dm @@ -31,3 +31,4 @@ icon_state = /turf/open/floor/wood::icon_state base_icon_state = /turf/open/floor/wood::base_icon_state icon = /turf/open/floor/wood::icon + smoothing_flags = NONE diff --git a/code/modules/discord/tgs_commands.dm b/code/modules/discord/tgs_commands.dm index 42d6d19ba99a7..8c6796bc1ea16 100644 --- a/code/modules/discord/tgs_commands.dm +++ b/code/modules/discord/tgs_commands.dm @@ -4,7 +4,7 @@ /datum/tgs_chat_command/tgscheck/Run(datum/tgs_chat_user/sender, params) var/server = CONFIG_GET(string/server) - return new /datum/tgs_message_content("[GLOB.round_id ? "Round #[GLOB.round_id]: " : ""][GLOB.clients.len] players on [SSmapping.config.map_name]; Round [SSticker.HasRoundStarted() ? (SSticker.IsRoundInProgress() ? "Active" : "Finishing") : "Starting"] -- [server ? server : "[world.internet_address]:[world.port]"]") + return new /datum/tgs_message_content("[GLOB.round_id ? "Round #[GLOB.round_id]: " : ""][GLOB.clients.len] players on [SSmapping.current_map.map_name]; Round [SSticker.HasRoundStarted() ? (SSticker.IsRoundInProgress() ? "Active" : "Finishing") : "Starting"] -- [server ? server : "[world.internet_address]:[world.port]"]") /datum/tgs_chat_command/gameversion name = "gameversion" diff --git a/code/modules/error_handler/error_handler.dm b/code/modules/error_handler/error_handler.dm index 1cf617ce4513e..6585f92f9b61c 100644 --- a/code/modules/error_handler/error_handler.dm +++ b/code/modules/error_handler/error_handler.dm @@ -26,7 +26,9 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0) Reboot(reason = 1) return - var/static/regex/stack_workaround = regex("[WORKAROUND_IDENTIFIER](.+?)[WORKAROUND_IDENTIFIER]") + var/static/regex/stack_workaround + if(isnull(stack_workaround)) + stack_workaround = regex("[WORKAROUND_IDENTIFIER](.+?)[WORKAROUND_IDENTIFIER]") var/static/list/error_last_seen = list() var/static/list/error_cooldown = list() /* Error_cooldown items will either be positive(cooldown time) or negative(silenced error) If negative, starts at -1, and goes down by 1 each time that error gets skipped*/ diff --git a/code/modules/escape_menu/details.dm b/code/modules/escape_menu/details.dm index 49bd19ce97fd7..ab6ff05d3ea46 100644 --- a/code/modules/escape_menu/details.dm +++ b/code/modules/escape_menu/details.dm @@ -35,7 +35,7 @@ GLOBAL_DATUM(escape_menu_details, /atom/movable/screen/escape_menu/details) Round ID: [GLOB.round_id || "Unset"]
Round Time: [ROUND_TIME()]
- Map: [SSmapping.config?.map_name || "Loading..."]
+ Map: [SSmapping.current_map.map_name || "Loading..."]
Time Dilation: [round(SStime_track.time_dilation_current,1)]%
"} diff --git a/code/modules/events/meteors/dark_matteor_event.dm b/code/modules/events/meteors/dark_matteor_event.dm index 412354b16f13d..a2352a1927e01 100644 --- a/code/modules/events/meteors/dark_matteor_event.dm +++ b/code/modules/events/meteors/dark_matteor_event.dm @@ -22,7 +22,7 @@ target = potential_target break //if target was never chosen the target is null aka the matteor will act as spacedust (and can technically miss) - spawn_meteor(list(/obj/effect/meteor/dark_matteor = 1), null, target) + spawn_meteor(list(/obj/effect/meteor/dark_matteor = 1), null, target, distance_from_edge = 10) /datum/round_event/dark_matteor/announce(fake) priority_announce("Warning. Excessive tampering of meteor satellites has attracted a dark matt-eor. Signature approaching [GLOB.station_name]. Please brace for impact.", "Meteor Alert", 'sound/announcer/alarm/airraid.ogg') diff --git a/code/modules/fishing/bait.dm b/code/modules/fishing/bait.dm index 9bd36daa7bebd..ec758be704201 100644 --- a/code/modules/fishing/bait.dm +++ b/code/modules/fishing/bait.dm @@ -147,7 +147,7 @@ name = "plastic dropping" desc = "A fishing lure to catch all sort of slimy, ratty, disgusting and/or junk-loving fish." icon_state = "dropping" - spin_frequency = list(1.5 SECONDS, 2.5 SECONDS) + spin_frequency = list(1.5 SECONDS, 2.8 SECONDS) /obj/item/fishing_lure/dropping/is_catchable_fish(obj/item/fish/fish_type, list/fish_properties) var/list/sources = list(/datum/fish_source/toilet, /datum/fish_source/moisture_trap) @@ -167,7 +167,7 @@ name = "\improper Indy spoon lure" desc = "A lustrous piece of metal mimicking the scales of a fish. Good for catching small to medium freshwater omnivore fish." icon_state = "spoon" - spin_frequency = list(1.25 SECONDS, 2.1 SECONDS) + spin_frequency = list(1.25 SECONDS, 2.25 SECONDS) /obj/item/fishing_lure/spoon/is_catchable_fish(obj/item/fish/fish_type, list/fish_properties) var/avg_size = initial(fish_type.average_size) @@ -187,7 +187,7 @@ name = "\improper Silkbuzz artificial fly" desc = "A fishing lure resembling a large wooly fly. Good for catching all sort of picky fish." icon_state = "artificial_fly" - spin_frequency = list(1.1 SECONDS, 1.9 SECONDS) + spin_frequency = list(1.1 SECONDS, 2 SECONDS) /obj/item/fishing_lure/artificial_fly/is_catchable_fish(obj/item/fish/fish_type, list/fish_properties) var/list/fish_traits = fish_properties[FISH_PROPERTIES_TRAITS] @@ -199,7 +199,7 @@ name = "\improper LED fishing lure" desc = "A heavy, waterproof and fish-looking LED stick, used to catch abyssal and demersal fish alike." icon_state = "led" - spin_frequency = list(3 SECONDS, 3.75 SECONDS) + spin_frequency = list(3 SECONDS, 3.8 SECONDS) /obj/item/fishing_lure/led/Initialize(mapload) . = ..() @@ -220,7 +220,7 @@ name = "\improper Maneki-Coin lure" desc = "A faux-gold lure used to attract shiny-loving fish." icon_state = "lucky_coin" - spin_frequency = list(1.5 SECONDS, 2.5 SECONDS) + spin_frequency = list(1.5 SECONDS, 2.7 SECONDS) /obj/item/fishing_lure/lucky_coin/is_catchable_fish(obj/item/fish/fish_type, list/fish_properties) var/list/fish_traits = fish_properties[FISH_PROPERTIES_TRAITS] @@ -244,7 +244,7 @@ name = "\improper Twister Worm lure" desc = "A soft plastic lure with the body of a grub and a twisting tail. Good for panfish and other small omnivore fish." icon_state = "grub" - spin_frequency = list(1 SECONDS, 2.5 SECONDS) + spin_frequency = list(1 SECONDS, 2.7 SECONDS) /obj/item/fishing_lure/grub/is_catchable_fish(obj/item/fish/fish_type, list/fish_properties) if(initial(fish_type.average_size) >= FISH_SIZE_SMALL_MAX) @@ -258,7 +258,7 @@ name = "\improper Electric-Buzz lure" desc = "A metallic, colored clanked attached to a series of cables that somehow attract shock-worthy fish." icon_state = "buzzbait" - spin_frequency = list(0.8 SECONDS, 1.6 SECONDS) + spin_frequency = list(0.8 SECONDS, 1.7 SECONDS) /obj/item/fishing_lure/buzzbait/is_catchable_fish(obj/item/fish/fish_type, list/fish_properties) var/list/fish_traits = fish_properties[FISH_PROPERTIES_TRAITS] diff --git a/code/modules/fishing/fish/_fish.dm b/code/modules/fishing/fish/_fish.dm index c97669c41155f..4a8efadcbcc9b 100644 --- a/code/modules/fishing/fish/_fish.dm +++ b/code/modules/fishing/fish/_fish.dm @@ -173,6 +173,9 @@ ADD_TRAIT(src, TRAIT_UNCOMPOSTABLE, REF(src)) //Composting a food that is not real food wouldn't work anyway. START_PROCESSING(SSobj, src) + //Adding this because not all fish have the gore foodtype that makes them automatically eligible for dna infusion. + ADD_TRAIT(src, TRAIT_VALID_DNA_INFUSION, INNATE_TRAIT) + //stops new fish from being able to reproduce right away. breeding_wait = world.time + (breeding_timeout * NEW_FISH_BREEDING_TIMEOUT_MULT) last_feeding = world.time - (feeding_frequency * NEW_FISH_LAST_FEEDING_MULT) @@ -181,7 +184,6 @@ apply_traits() //Make sure traits are applied before size and weight. update_size_and_weight() - register_evolutions() register_context() register_item_context() @@ -674,7 +676,9 @@ continue if(length(fish_traits & trait.incompatible_traits)) continue - if((trait_type in same_traits) ? prob(trait.inheritability) : prob(trait.diff_traits_inheritability)) + // If there's no partner, we've been reated through parthenogenesis or growth, therefore, traits are copied + // Otherwise, we do some probability checks. + if(!y_traits || ((trait_type in same_traits) ? prob(trait.inheritability) : prob(trait.diff_traits_inheritability))) fish_traits |= trait_type incompatible_traits |= trait.incompatible_traits @@ -685,11 +689,6 @@ var/datum/fish_trait/trait = GLOB.fish_traits[fish_trait_type] trait.apply_to_fish(src) -/obj/item/fish/proc/register_evolutions() - for(var/evolution_type in evolution_types) - var/datum/fish_evolution/evolution = GLOB.fish_evolutions[evolution_type] - evolution.register_fish(src) - /obj/item/fish/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change = TRUE) . = ..() check_flopping() @@ -718,17 +717,28 @@ /obj/item/fish/proc/feed(datum/reagents/fed_reagents) if(status != FISH_ALIVE) return - var/fed_reagent_type + + ///If one of the reagent with fish effects is also our food reagent this is set to TRUE + var/already_fed = FALSE + for(var/datum/reagent/reagent as anything in fed_reagents.reagent_list) + if(!fed_reagents.has_reagent(reagent.type, 0.1) || !reagent.used_on_fish(src)) + continue + fed_reagents.remove_reagent(reagent.type, 0.1) + if(reagent.type == food) + already_fed = TRUE + + if(already_fed) + sate_hunger() + return + if(fed_reagents.remove_reagent(food, 0.1)) - fed_reagent_type = food sate_hunger() - else - var/datum/reagent/wrong_reagent = pick(fed_reagents.reagent_list) - if(!wrong_reagent) - return - fed_reagent_type = wrong_reagent.type - fed_reagents.remove_reagent(fed_reagent_type, 0.1) - SEND_SIGNAL(src, COMSIG_FISH_FED, fed_reagents, fed_reagent_type) + return + + var/datum/reagent/wrong_reagent = pick(fed_reagents.reagent_list) + if(!wrong_reagent) + return + fed_reagents.remove_reagent(wrong_reagent.type, 0.1) /** * Base multiplier of the difference between current size and weight and their maximum value @@ -759,11 +769,14 @@ hunger_mult = 1 - (hunger - FISH_GROWTH_PEAK) * 4 if(hunger_mult <= 0) return + var/base_mult = FISH_GROWTH_MULT + if(HAS_TRAIT(src, TRAIT_FISH_QUICK_GROWTH)) + base_mult *= 2.5 if(size < maximum_size) - new_size += CEILING((maximum_size - size) * FISH_GROWTH_MULT / (w_class * FISH_SIZE_WEIGHT_GROWTH_MALUS) * hunger_mult, 1) + new_size += CEILING((maximum_size - size) * base_mult / (w_class * FISH_SIZE_WEIGHT_GROWTH_MALUS) * hunger_mult, 1) new_size = min(new_size, maximum_size) if(weight < maximum_weight) - new_weight += CEILING((maximum_weight - weight) * FISH_GROWTH_MULT / (get_weight_rank() * FISH_SIZE_WEIGHT_GROWTH_MALUS) * hunger_mult, 1) + new_weight += CEILING((maximum_weight - weight) * base_mult / (get_weight_rank() * FISH_SIZE_WEIGHT_GROWTH_MALUS) * hunger_mult, 1) new_weight = min(new_weight, maximum_weight) if(new_size != size || new_weight != weight) update_size_and_weight(new_size, new_weight) @@ -1012,6 +1025,9 @@ health_change_per_second -= 0.5 //Starving else health_change_per_second += 0.5 //Slowly healing + if(HAS_TRAIT(src, TRAIT_FISH_ON_TESLIUM)) + health_change_per_second -= 0.65 //This becomes - 0.15 if safe and not starving. + adjust_health(health + health_change_per_second * seconds_per_tick) /obj/item/fish/proc/adjust_health(amount) @@ -1221,6 +1237,8 @@ if(istype(loc, /obj/structure/aquarium/bioelec_gen)) fish_zap_range = 5 fish_zap_power = GET_FISH_ELECTROGENESIS(src) + if(HAS_TRAIT(src, TRAIT_FISH_ON_TESLIUM)) + fish_zap_power *= 0.5 fish_zap_flags |= (ZAP_GENERATES_POWER | ZAP_MOB_STUN) tesla_zap(source = get_turf(src), zap_range = fish_zap_range, power = fish_zap_power, cutoff = 1 MEGA JOULES, zap_flags = fish_zap_flags) @@ -1302,6 +1320,28 @@ /obj/item/fish/proc/undo_petted() fish_flags &= ~FISH_FLAG_PETTED +/obj/item/fish/update_atom_colour() + . = ..() + aquarium_vc_color = color || initial(aquarium_vc_color) + +/obj/item/fish/get_infusion_entry() + var/amphibious = required_fluid_type == AQUARIUM_FLUID_AIR || HAS_TRAIT(src, TRAIT_FISH_AMPHIBIOUS) + var/list/possible_infusions = list() + for(var/type in fish_traits) + var/datum/fish_trait/trait = GLOB.fish_traits[type] + if(!trait.infusion_entry) + continue + possible_infusions |= trait.infusion_entry + if(!length(possible_infusions) && !amphibious) + return GLOB.infuser_entries[/datum/infuser_entry/fish] + var/datum/infuser_entry/fish/entry = new + if(amphibious) + entry.output_organs -= /obj/item/organ/internal/lungs/fish + for(var/key in possible_infusions) + var/datum/infuser_entry/infusion = GLOB.infuser_entries[key] + entry.output_organs |= infusion.output_organs + return entry + /// Returns random fish, using random_case_rarity probabilities. /proc/random_fish_type(required_fluid) var/static/probability_table diff --git a/code/modules/fishing/fish/fish_evolution.dm b/code/modules/fishing/fish/fish_evolution.dm index 49eb3f46374bd..52708add566da 100644 --- a/code/modules/fishing/fish/fish_evolution.dm +++ b/code/modules/fishing/fish/fish_evolution.dm @@ -48,6 +48,8 @@ GLOBAL_LIST_EMPTY(fishes_by_fish_evolution) if(aquarium) //chances are halved if only one parent has this evolution. var/real_probability = (mate && (type in mate.evolution_types)) ? probability : probability/2 + if(HAS_TRAIT(source, TRAIT_FISH_MUTAGENIC) || (mate && HAS_TRAIT(mate, TRAIT_FISH_MUTAGENIC))) + real_probability *= 3 if(!prob(real_probability)) return FALSE if(!ISINRANGE(aquarium.fluid_temp, required_temperature_min, required_temperature_max)) @@ -82,25 +84,12 @@ GLOBAL_LIST_EMPTY(fishes_by_fish_evolution) . += " [conditions_note]" return . -///Proc called to let evolution register signals that are needed for various conditions. -/datum/fish_evolution/proc/register_fish(obj/item/fish/fish) - return - /datum/fish_evolution/lubefish probability = 25 new_fish_type = /obj/item/fish/clownfish/lube new_traits = list(/datum/fish_trait/lubed) conditions_note = "The fish must be fed lube beforehand." -/datum/fish_evolution/lubefish/register_fish(obj/item/fish/fish) - RegisterSignal(fish, COMSIG_FISH_FED, PROC_REF(check_for_lube)) - -/datum/fish_evolution/lubefish/proc/check_for_lube(obj/item/fish/source, datum/reagents/fed_reagents, wrong_reagent_type) - SIGNAL_HANDLER - if((wrong_reagent_type == /datum/reagent/lube) || fed_reagents.remove_reagent(/datum/reagent/lube, 0.1)) - ADD_TRAIT(source, TRAIT_FISH_FED_LUBE, FISH_EVOLUTION) - addtimer(TRAIT_CALLBACK_REMOVE(source, TRAIT_FISH_FED_LUBE, FISH_EVOLUTION), source.feeding_frequency) - /datum/fish_evolution/lubefish/check_conditions(obj/item/fish/source, obj/item/fish/mate, obj/structure/aquarium/aquarium) if(!HAS_TRAIT(source, TRAIT_FISH_FED_LUBE)) return FALSE @@ -167,6 +156,7 @@ GLOBAL_LIST_EMPTY(fishes_by_fish_evolution) /datum/fish_evolution/fritterish new_fish_type = /obj/item/fish/fryish/fritterish + removed_traits = list(/datum/fish_trait/no_mating) conditions_note = "Fryish will grow into it over time." /datum/fish_evolution/nessie diff --git a/code/modules/fishing/fish/fish_traits.dm b/code/modules/fishing/fish/fish_traits.dm index 22c7492fb8eaf..2030c1b61585b 100644 --- a/code/modules/fishing/fish/fish_traits.dm +++ b/code/modules/fishing/fish/fish_traits.dm @@ -39,6 +39,8 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) var/added_difficulty = 0 /// Reagents to add to the fish whenever the COMSIG_GENERATE_REAGENTS_TO_ADD signal is sent. Their values will be multiplied later. var/list/reagents_to_add + /// If set, the fish may return this infusion entry when get_infusion_entry is called instead of /datum/infuser_entry/fish + var/infusion_entry /// Difficulty modifier from this mod, needs to return a list with two values /datum/fish_trait/proc/difficulty_mod(obj/item/fishing_rod/rod, mob/fisherman) @@ -336,7 +338,11 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) name = "Mateless" catalog_description = "This fish cannot reproduce with other fishes." incompatible_traits = list(/datum/fish_trait/crossbreeder) - spontaneous_manifest_types = list(/obj/item/fish/fryish = 100) + spontaneous_manifest_types = list( + /obj/item/fish/fryish = 100, + /obj/item/fish/fryish/fritterish = 0, + /obj/item/fish/fryish/nessie = 0 + ) /datum/fish_trait/no_mating/apply_to_fish(obj/item/fish/fish) . = ..() @@ -423,6 +429,9 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) catalog_description = "This fish contains toxins. Feeding it to predatory fishes or people is not recommended." diff_traits_inheritability = 25 reagents_to_add = list(/datum/reagent/toxin/tetrodotoxin = 1) + infusion_entry = /datum/infuser_entry/ttx_healing + ///The amount of venom injected if the fish has a stinger is multiplied by this value. + var/venom_mult = 1 /datum/fish_trait/toxic/apply_to_fish(obj/item/fish/fish) . = ..() @@ -434,13 +443,13 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) SIGNAL_HANDLER if(!HAS_TRAIT(source, TRAIT_FISH_STINGER)) return - add_venom(source, /datum/reagent/toxin/tetrodotoxin, new_weight, mult = source.status == FISH_DEAD ? 0.1 : 0.25) + add_venom(source, reagents_to_add[1], new_weight, mult = (source.status == FISH_DEAD ? 0.1 : 0.25) * venom_mult) /datum/fish_trait/toxic/proc/on_status_change(obj/item/fish/source) SIGNAL_HANDLER if(!HAS_TRAIT(source, TRAIT_FISH_STINGER)) return - change_venom_on_death(source, /datum/reagent/toxin/tetrodotoxin, 0.25, 0.1) + change_venom_on_death(source, reagents_to_add[1], 0.25 * venom_mult, 0.1 * venom_mult) /datum/fish_trait/toxic/proc/on_eaten(obj/item/fish/source, obj/item/fish/predator) if(HAS_TRAIT(predator, TRAIT_FISH_TOXIN_IMMUNE)) @@ -459,7 +468,15 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) /datum/fish_trait/toxic/apply_to_mob(mob/living/basic/mob) . = ..() - mob.AddElement(/datum/element/venomous, /datum/reagent/toxin/tetrodotoxin, 0.5 * mob.mob_size) + mob.AddElement(/datum/element/venomous, reagents_to_add[1], 0.5 * mob.mob_size * venom_mult) + +/datum/fish_trait/toxic/carpotoxin + name = "Carpotoxic" + catalog_description = "This fish contains carpotoxin. Definitely not safe for consumption." + diff_traits_inheritability = 50 + reagents_to_add = list(/datum/reagent/toxin/carpotoxin = 4) + infusion_entry = null + venom_mult = 6 /datum/fish_trait/toxin_immunity name = "Toxin Immunity" @@ -530,6 +547,7 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) inheritability = 80 diff_traits_inheritability = 40 catalog_description = "This fish has developed a primitive adaptation to life on both land and water." + infusion_entry = /datum/infuser_entry/amphibious /datum/fish_trait/amphibious/apply_to_fish(obj/item/fish/fish) . = ..() @@ -640,7 +658,7 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) /datum/fish_trait/stunted name = "Stunted Growth" catalog_description = "This chrab's development is stunted, and will not properly reach adulthood." - spontaneous_manifest_types = list(/obj/item/fish/chasm_crab = 12, /obj/item/fish/chasm_crab/ice = 12) + spontaneous_manifest_types = list(/obj/item/fish/chasm_crab = 12) fish_whitelist = list(/obj/item/fish/chasm_crab, /obj/item/fish/chasm_crab/ice) diff_traits_inheritability = 40 @@ -708,6 +726,7 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) catalog_description = "This fish possess a sac that produces ink." diff_traits_inheritability = 70 spontaneous_manifest_types = list(/obj/item/fish/squid = 35) + infusion_entry = /datum/infuser_entry/squid /datum/fish_trait/ink/apply_to_fish(obj/item/fish/fish) . = ..() diff --git a/code/modules/fishing/fish/types/air_space.dm b/code/modules/fishing/fish/types/air_space.dm index dda3794ff4e1c..177ae9c6e0e7d 100644 --- a/code/modules/fishing/fish/types/air_space.dm +++ b/code/modules/fishing/fish/types/air_space.dm @@ -99,3 +99,85 @@ ///It spins, and dimly glows in the dark. /obj/item/fish/starfish/flop_animation() DO_FLOATING_ANIM(src) + +/obj/item/fish/baby_carp + name = "baby space carp" + desc = "A juvenile spawn of the dreaded space carp. Don't let the innocent looks fool you, they're aggressive little bastards." + icon_state = "baby_carp" + sprite_height = 3 + sprite_width = 5 + average_size = 35 + average_weight = 550 + stable_population = 7 + required_fluid_type = AQUARIUM_FLUID_ANY_WATER + random_case_rarity = FISH_RARITY_VERY_RARE + required_temperature_min = 0 + required_temperature_max = MIN_AQUARIUM_TEMP+200 + safe_air_limits = null + fillet_type = /obj/item/food/fishmeat/carp/no_tox + fish_traits = list( + /datum/fish_trait/carnivore, + /datum/fish_trait/aggressive, + /datum/fish_trait/predator, + /datum/fish_trait/necrophage, + /datum/fish_trait/no_mating, + /datum/fish_trait/toxic/carpotoxin, + ) + favorite_bait = list( + list( + FISH_BAIT_TYPE = FISH_BAIT_FOODTYPE, + FISH_BAIT_VALUE = MEAT, + ), + ) + disliked_bait = list( + list( + FISH_BAIT_TYPE = FISH_BAIT_FOODTYPE, + FISH_BAIT_VALUE = GRAIN|DAIRY, + ), + ) + beauty = FISH_BEAUTY_GREAT + +/obj/item/fish/baby_carp/Initialize(mapload, apply_qualities = TRUE) + color = pick_weight(GLOB.carp_colors) + . = ..() + RegisterSignal(src, COMSIG_FISH_BEFORE_GROWING, PROC_REF(growth_checks)) + RegisterSignal(src, COMSIG_FISH_FINISH_GROWING, PROC_REF(on_growth)) + update_appearance(UPDATE_OVERLAYS) + +/obj/item/fish/baby_carp/update_overlays() + . = ..() + var/mutable_appearance/eyes = mutable_appearance(icon, "baby_carp_eyes") + if(status == FISH_DEAD) + eyes.icon_state += "_dead" + else + eyes.appearance_flags = RESET_COLOR + . += eyes + +///Determines the speed at which the carp grows based on how big it's +/obj/item/fish/baby_carp/update_size_and_weight(new_size = average_size, new_weight = average_weight) + . = ..() + var/growth_rate = 4.5 MINUTES + growth_rate *= clamp(size/average_size, 0.5, 2) + growth_rate *= clamp(weight/average_weight, 0.5, 2) + + AddComponent(/datum/component/fish_growth, /mob/living/basic/carp/advanced, growth_rate) + +/obj/item/fish/baby_carp/proc/growth_checks(datum/source, seconds_per_tick) + SIGNAL_HANDLER + var/hunger = CLAMP01((world.time - last_feeding) / feeding_frequency) + if(health <= initial(health) * 0.6 || hunger >= 0.6) //if too hurt or hungry, don't grow. + return COMPONENT_DONT_GROW + + if(!isaquarium(loc)) + return + + var/obj/structure/aquarium/aquarium = loc + if(!aquarium.reproduction_and_growth) //the aquarium has breeding disabled + return COMPONENT_DONT_GROW + if(length(aquarium.get_fishes()) > AQUARIUM_MAX_BREEDING_POPULATION * 0.5) //check if there's enough room to maturate. + return COMPONENT_DONT_GROW + +/obj/item/fish/baby_carp/proc/on_growth(datum/source, mob/living/basic/carp/result) + SIGNAL_HANDLER + //yes, this means that if we use a spraycan on the fish, the resulting space carp will be of spraycan color + result.set_greyscale(colors = list(color)) diff --git a/code/modules/fishing/fish/types/freshwater.dm b/code/modules/fishing/fish/types/freshwater.dm index fe0ff437c7d8c..75d4891b4f0ad 100644 --- a/code/modules/fishing/fish/types/freshwater.dm +++ b/code/modules/fishing/fish/types/freshwater.dm @@ -175,7 +175,7 @@ /obj/item/fish/tadpole/Initialize(mapload, apply_qualities = TRUE) . = ..() - AddComponent(/datum/component/fish_growth, /mob/living/basic/frog, rand(2.5, 3 MINUTES)) + AddComponent(/datum/component/fish_growth, /mob/living/basic/frog, rand(2 MINUTES, 3 MINUTES)) RegisterSignal(src, COMSIG_FISH_BEFORE_GROWING, PROC_REF(growth_checks)) RegisterSignal(src, COMSIG_FISH_FINISH_GROWING, PROC_REF(on_growth)) diff --git a/code/modules/fishing/fish/types/station.dm b/code/modules/fishing/fish/types/station.dm index 70e641fa3e900..e811996d5af04 100644 --- a/code/modules/fishing/fish/types/station.dm +++ b/code/modules/fishing/fish/types/station.dm @@ -138,7 +138,7 @@ ///The evolution datum of the next thing we grow into, given time (and food) var/next_type = /datum/fish_evolution/fritterish ///How long does it take for us to grow up? - var/growth_time = 5 MINUTES + var/growth_time = 3.5 MINUTES /obj/item/fish/fryish/Initialize(mapload) . = ..() @@ -184,7 +184,7 @@ fish_movement_type = /datum/fish_movement is_bait = FALSE next_type = /datum/fish_evolution/nessie - growth_time = 10 MINUTES + growth_time = 8 MINUTES /obj/item/fish/fryish/fritterish/Initialize(mapload, apply_qualities = TRUE) . = ..() diff --git a/code/modules/fishing/fishing_equipment.dm b/code/modules/fishing/fishing_equipment.dm index 7e46618accf72..ccad3b4708017 100644 --- a/code/modules/fishing/fishing_equipment.dm +++ b/code/modules/fishing/fishing_equipment.dm @@ -387,7 +387,7 @@ name = "fishing tip" desc = "A slip of paper containing a pearl of wisdom about fishing within it, though you wish it were an actual pearl." -/obj/item/paper/paperslip/fortune/Initialize(mapload) +/obj/item/paper/paperslip/fishing_tip/Initialize(mapload) default_raw_text = pick(GLOB.fishing_tips) return ..() diff --git a/code/modules/fishing/fishing_minigame.dm b/code/modules/fishing/fishing_minigame.dm index bf4cd463ef1ab..30ce2b33ad0cc 100644 --- a/code/modules/fishing/fishing_minigame.dm +++ b/code/modules/fishing/fishing_minigame.dm @@ -271,7 +271,7 @@ GLOBAL_LIST_EMPTY(fishing_challenges_by_user) return if(phase == WAIT_PHASE) if(world.time < last_baiting_click + 0.25 SECONDS) - return //Don't punish players if they accidentally double clicked. + return COMSIG_MOB_CANCEL_CLICKON //Don't punish players if they accidentally double clicked. if(float.spin_frequency) if(!float.spin_ready) send_alert("too early!") @@ -360,6 +360,7 @@ GLOBAL_LIST_EMPTY(fishing_challenges_by_user) playsound(location, 'sound/effects/fish_splash.ogg', 100) if(HAS_MIND_TRAIT(user, TRAIT_REVEAL_FISH)) + fish_icon = GLOB.specific_fish_icons[reward_path] || FISH_ICON_DEF switch(fish_icon) if(FISH_ICON_DEF) send_alert("fish!!!") @@ -466,9 +467,6 @@ GLOBAL_LIST_EMPTY(fishing_challenges_by_user) if(difficulty > FISHING_DEFAULT_DIFFICULTY) completion -= MAX_FISH_COMPLETION_MALUS * (difficulty * 0.01) - if(HAS_MIND_TRAIT(user, TRAIT_REVEAL_FISH)) - fish_icon = GLOB.specific_fish_icons[reward_path] || FISH_ICON_DEF - /// Fish minigame properties if(ispath(reward_path,/obj/item/fish)) var/obj/item/fish/fish = reward_path diff --git a/code/modules/fishing/fishing_rod.dm b/code/modules/fishing/fishing_rod.dm index 23aabcc3ece7c..bfa701d36eb0a 100644 --- a/code/modules/fishing/fishing_rod.dm +++ b/code/modules/fishing/fishing_rod.dm @@ -69,6 +69,11 @@ update_appearance() + //Bane effect that make it extra-effective against mobs with water adaptation (read: fish infusion) + AddElement(/datum/element/bane, target_type = /mob/living, damage_multiplier = 1.25) + RegisterSignal(src, COMSIG_OBJECT_PRE_BANING, PROC_REF(attempt_bane)) + RegisterSignal(src, COMSIG_OBJECT_ON_BANING, PROC_REF(bane_effects)) + /obj/item/fishing_rod/add_context(atom/source, list/context, obj/item/held_item, mob/user) if(src == held_item) if(currently_hooked) @@ -135,6 +140,19 @@ QDEL_NULL(bait) update_icon() +///Fishing rodss should only bane fish DNA-infused spessman +/obj/item/fishing_rod/proc/attempt_bane(datum/source, mob/living/fish) + SIGNAL_HANDLER + if(!force || !HAS_TRAIT(fish, TRAIT_WATER_ADAPTATION)) + return COMPONENT_CANCEL_BANING + +///Fishing rods should hard-counter fish DNA-infused spessman +/obj/item/fishing_rod/proc/bane_effects(datum/source, mob/living/fish) + SIGNAL_HANDLER + fish.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH, 4 SECONDS) + fish.adjust_confusion_up_to(1.5 SECONDS, 3 SECONDS) + fish.adjust_wet_stacks(-4) + /obj/item/fishing_rod/interact(mob/user) if(currently_hooked) reel(user) @@ -503,6 +521,11 @@ line = null show_in_wiki = FALSE +///From the mining order console, meant to help miners rescue their fallen brethren +/obj/item/fishing_rod/rescue + hook = /obj/item/fishing_hook/rescue + show_in_wiki = FALSE + /obj/item/fishing_rod/bone name = "bone fishing rod" desc = "A humble rod, made with whatever happened to be on hand." diff --git a/code/modules/fishing/sources/_fish_source.dm b/code/modules/fishing/sources/_fish_source.dm index 38455068ce22e..c2db0a43fc9b5 100644 --- a/code/modules/fishing/sources/_fish_source.dm +++ b/code/modules/fishing/sources/_fish_source.dm @@ -41,6 +41,7 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons()) /obj/item/fish/stingray = FISH_ICON_WEAPON, /obj/item/fish/swordfish = FISH_ICON_WEAPON, /obj/item/fish/zipzap = FISH_ICON_ELECTRIC, + /obj/item/knife/carp = FISH_ICON_WEAPON, /obj/item/seeds/grass = FISH_ICON_SEED, /obj/item/seeds/random = FISH_ICON_SEED, /obj/item/storage/wallet = FISH_ICON_COIN, diff --git a/code/modules/fishing/sources/source_types.dm b/code/modules/fishing/sources/source_types.dm index 2f56ffaad3cd1..f6cbd969a8d6d 100644 --- a/code/modules/fishing/sources/source_types.dm +++ b/code/modules/fishing/sources/source_types.dm @@ -193,6 +193,7 @@ fish_table = list( FISHING_DUD = 5, /obj/item/fish/starfish = 6, + /obj/item/fish/baby_carp = 6, /obj/item/stack/ore/bluespace_crystal = 2, /mob/living/basic/carp = 2, ) @@ -353,9 +354,6 @@ /datum/fish_source/lavaland/reason_we_cant_fish(obj/item/fishing_rod/rod, mob/fisherman, atom/parent) . = ..() - var/turf/approx = get_turf(fisherman) //todo pass the parent - if(!SSmapping.level_trait(approx.z, ZTRAIT_MINING)) - return "There doesn't seem to be anything to catch here." if(!rod.line || !(rod.line.fishing_line_traits & FISHING_LINE_REINFORCED)) return "You'll need reinforced fishing line to fish in there" @@ -580,6 +578,25 @@ var/picked_path = pick(seeds_to_draw_from) return new picked_path(get_turf(fishing_spot)) +/datum/fish_source/carp_rift + catalog_description = "Space Dragon Rifts" + radial_state = "carp" + fish_table = list( + FISHING_DUD = 3, + /obj/item/fish/baby_carp = 5, + /mob/living/basic/carp = 1, + /mob/living/basic/carp/passive = 1, + /mob/living/basic/carp/mega = 1, + /obj/item/clothing/head/fedora/carpskin = 1, + /obj/item/toy/plush/carpplushie = 1, + /obj/item/toy/plush/carpplushie/dehy_carp/peaceful = 1, + /obj/item/knife/carp = 1, + ) + fish_counts = list( + /mob/living/basic/carp/mega = 2, + ) + fishing_difficulty = FISHING_DEFAULT_DIFFICULTY + 18 + /datum/fish_source/deepfryer catalog_description = "Deep Fryers" radial_state = "fryer" diff --git a/code/modules/food_and_drinks/machinery/griddle.dm b/code/modules/food_and_drinks/machinery/griddle.dm index e0c45e6c9af10..ed1884c89af27 100644 --- a/code/modules/food_and_drinks/machinery/griddle.dm +++ b/code/modules/food_and_drinks/machinery/griddle.dm @@ -73,8 +73,8 @@ return if(user.transferItemToLoc(I, src, silent = FALSE)) //Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf) - I.pixel_x = clamp(text2num(LAZYACCESS(modifiers, ICON_X)) - 16, -(world.icon_size/2), world.icon_size/2) - I.pixel_y = clamp(text2num(LAZYACCESS(modifiers, ICON_Y)) - 16, -(world.icon_size/2), world.icon_size/2) + I.pixel_x = clamp(text2num(LAZYACCESS(modifiers, ICON_X)) - 16, -(ICON_SIZE_X/2), ICON_SIZE_X/2) + I.pixel_y = clamp(text2num(LAZYACCESS(modifiers, ICON_Y)) - 16, -(ICON_SIZE_Y/2), ICON_SIZE_Y/2) to_chat(user, span_notice("You place [I] on [src].")) AddToGrill(I, user) else diff --git a/code/modules/food_and_drinks/machinery/stove_component.dm b/code/modules/food_and_drinks/machinery/stove_component.dm index c5e32b541995e..76f52345c8c35 100644 --- a/code/modules/food_and_drinks/machinery/stove_component.dm +++ b/code/modules/food_and_drinks/machinery/stove_component.dm @@ -267,7 +267,7 @@ return // this gets badly murdered by sidemap soup_smoke = new(parent, particle_type) - soup_smoke.set_particle_position(container_x, round(world.icon_size * 0.66), 0) + soup_smoke.set_particle_position(container_x, round(ICON_SIZE_Y * 0.66), 0) return QDEL_NULL(soup_smoke) diff --git a/code/modules/hallucination/mother.dm b/code/modules/hallucination/mother.dm index d9cd7f1983119..7d407e43d8eb1 100644 --- a/code/modules/hallucination/mother.dm +++ b/code/modules/hallucination/mother.dm @@ -37,7 +37,7 @@ var/obj/visual = image('icons/hud/screen_gen.dmi', mother.loc, "arrow", FLY_LAYER) INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(flick_overlay_global), visual, list(hallucinator.client), 2.5 SECONDS) - animate(visual, pixel_x = (tile.x - mother.x) * world.icon_size, pixel_y = (tile.y - mother.y) * world.icon_size, time = 1.7, easing = EASE_OUT) + animate(visual, pixel_x = (tile.x - mother.x) * ICON_SIZE_X, pixel_y = (tile.y - mother.y) * ICON_SIZE_Y, time = 1.7, easing = EASE_OUT) /datum/hallucination/your_mother/proc/talk(text) var/plus_runechat = hallucinator.client?.prefs.read_preference(/datum/preference/toggle/enable_runechat) diff --git a/code/modules/hallucination/on_fire.dm b/code/modules/hallucination/on_fire.dm index cb4a95dd4420c..7266de17f4669 100644 --- a/code/modules/hallucination/on_fire.dm +++ b/code/modules/hallucination/on_fire.dm @@ -37,7 +37,6 @@ return ..() /datum/hallucination/fire/start() - hallucinator.set_fire_stacks(max(hallucinator.fire_stacks, 0.1)) //Placebo flammability fire_overlay = image(fire_icon, hallucinator, fire_icon_state, ABOVE_MOB_LAYER) hallucinator.client?.images |= fire_overlay to_chat(hallucinator, span_userdanger("You're set on fire!")) @@ -47,7 +46,6 @@ return TRUE /datum/hallucination/fire/Destroy() - hallucinator.adjust_fire_stacks(-0.1) hallucinator.clear_alert(ALERT_FIRE, clear_override = TRUE) hallucinator.clear_alert(ALERT_TEMPERATURE, clear_override = TRUE) if(fire_overlay) diff --git a/code/modules/hallucination/screwy_health_doll.dm b/code/modules/hallucination/screwy_health_doll.dm index 7bab267563c74..2a8eeba16e2b3 100644 --- a/code/modules/hallucination/screwy_health_doll.dm +++ b/code/modules/hallucination/screwy_health_doll.dm @@ -66,12 +66,11 @@ bodyparts -= source /// Whenever a bodypart we're tracking has their health hud updated, override it with our fake overlay -/datum/hallucination/fake_health_doll/proc/on_bodypart_hud_update(obj/item/bodypart/source, mob/living/carbon/human/owner) +/datum/hallucination/fake_health_doll/proc/on_bodypart_hud_update(obj/item/bodypart/source, mob/living/carbon/human/owner, list/overridable_key) SIGNAL_HANDLER - var/mutable_appearance/fake_overlay = mutable_appearance('icons/hud/screen_gen.dmi', "[source.body_zone][bodyparts[source]]") - owner.hud_used.healthdoll.add_overlay(fake_overlay) - return COMPONENT_OVERRIDE_BODYPART_HEALTH_HUD + overridable_key[1] = bodyparts[source] + return OVERRIDE_BODYPART_HEALTH_HUD /// Signal proc for [COMSIG_BODYPART_CHECKED_FOR_INJURY]. Our bodyparts look a lot more wounded than they actually are. /datum/hallucination/fake_health_doll/proc/on_bodypart_checked(obj/item/bodypart/source, mob/living/carbon/examiner, list/check_list, list/limb_damage) diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm index f0ebd470dd88f..f000efcfcd59a 100644 --- a/code/modules/jobs/job_types/_job.dm +++ b/code/modules/jobs/job_types/_job.dm @@ -120,8 +120,7 @@ /// Alternate titles to register as pointing to this job. var/list/alternate_titles - /// Does this job ignore human authority? - var/ignore_human_authority = FALSE + var/human_authority = JOB_AUTHORITY_NON_HUMANS_ALLOWED /// String key to track any variables we want to tie to this job in config, so we can avoid using the job title. We CAPITALIZE it in order to ensure it's unique and resistant to trivial formatting changes. /// You'll probably break someone's config if you change this, so it's best to not to. @@ -535,11 +534,28 @@ if(!player_client) return // Disconnected while checking for the appearance ban. - var/require_human = CONFIG_GET(flag/enforce_human_authority) && (job.job_flags & JOB_HEAD_OF_STAFF) - if(require_human) - var/all_authority_require_human = CONFIG_GET(flag/enforce_human_authority_on_everyone) - if(!all_authority_require_human && job.ignore_human_authority) - require_human = FALSE + var/human_authority_setting = CONFIG_GET(string/human_authority) + var/require_human = FALSE + + // If the job in question is a head of staff, + // check the config to see if we should force the player onto a human character or not + if(job.job_flags & JOB_HEAD_OF_STAFF) + switch(human_authority_setting) + + // If non-humans are the norm and jobs must be forced to be only for humans + // then we only force the player to be a human if the job exclusively allows humans + if(HUMAN_AUTHORITY_HUMAN_WHITELIST) + require_human = job.human_authority == JOB_AUTHORITY_HUMANS_ONLY + + // If humans are the norm and jobs must be allowed to be played by non-humans + // then we only force the player to be a human if the job doesn't allow for non-humans to play it + if(HUMAN_AUTHORITY_NON_HUMAN_WHITELIST) + require_human = job.human_authority != JOB_AUTHORITY_NON_HUMANS_ALLOWED + + // If humans are the norm and there is no chance that a non-human can be a head of staff + // always return true, since there is no chance that a non-human can be a head of staff. + if(HUMAN_AUTHORITY_ENFORCED) + require_human = TRUE src.job = job.title diff --git a/code/modules/jobs/job_types/captain.dm b/code/modules/jobs/job_types/captain.dm index 5b82c9adb7116..99bc35bb60320 100644 --- a/code/modules/jobs/job_types/captain.dm +++ b/code/modules/jobs/job_types/captain.dm @@ -46,6 +46,8 @@ job_flags = STATION_JOB_FLAGS | HEAD_OF_STAFF_JOB_FLAGS rpg_title = "Star Duke" + human_authority = JOB_AUTHORITY_HUMANS_ONLY + voice_of_god_power = 1.4 //Command staff has authority diff --git a/code/modules/jobs/job_types/chaplain/chaplain_costumes.dm b/code/modules/jobs/job_types/chaplain/chaplain_costumes.dm index 0968569ae33af..9bd6436994df1 100644 --- a/code/modules/jobs/job_types/chaplain/chaplain_costumes.dm +++ b/code/modules/jobs/job_types/chaplain/chaplain_costumes.dm @@ -40,7 +40,7 @@ icon_state = "holidaypriest" inhand_icon_state = "w_suit" body_parts_covered = CHEST|GROIN|LEGS|ARMS - flags_inv = HIDEJUMPSUIT + flags_inv = HIDEJUMPSUIT|HIDEBELT /obj/item/clothing/suit/chaplainsuit/nun name = "nun robe" @@ -48,7 +48,7 @@ icon_state = "nun" inhand_icon_state = "nun" body_parts_covered = CHEST|GROIN|LEGS|ARMS|HANDS - flags_inv = HIDEJUMPSUIT + flags_inv = HIDEJUMPSUIT|HIDEBELT /obj/item/clothing/suit/chaplainsuit/habit name = "religious tunic" @@ -56,7 +56,7 @@ icon_state = "habit" alternate_worn_layer = GLOVES_LAYER // since the sleeves cover a part of the hands, this way it looks better while retaining glove overlay correctly. body_parts_covered = CHEST|GROIN|LEGS|ARMS|HANDS - flags_inv = HIDEJUMPSUIT + flags_inv = HIDEJUMPSUIT|HIDEBELT /obj/item/clothing/suit/chaplainsuit/bishoprobe name = "bishop's robes" @@ -64,7 +64,7 @@ icon_state = "bishoprobe" inhand_icon_state = "bishoprobe" body_parts_covered = CHEST|GROIN|LEGS|ARMS - flags_inv = HIDEJUMPSUIT + flags_inv = HIDEJUMPSUIT|HIDEBELT /obj/item/clothing/suit/chaplainsuit/armor/studentuni name = "student robe" @@ -106,7 +106,7 @@ icon_state = "monkrobeeast" inhand_icon_state = null body_parts_covered = GROIN|LEGS - flags_inv = HIDEJUMPSUIT + flags_inv = HIDEJUMPSUIT|HIDEBELT /obj/item/clothing/suit/chaplainsuit/whiterobe name = "white robe" @@ -114,7 +114,7 @@ icon_state = "whiterobe" inhand_icon_state = null body_parts_covered = CHEST|GROIN|LEGS|ARMS - flags_inv = HIDEJUMPSUIT + flags_inv = HIDEJUMPSUIT|HIDEBELT /obj/item/clothing/suit/chaplainsuit/clownpriest name = "Robes of the Honkmother" @@ -122,7 +122,7 @@ icon_state = "clownpriest" inhand_icon_state = "clownpriest" body_parts_covered = CHEST|GROIN|LEGS|ARMS - flags_inv = HIDEJUMPSUIT + flags_inv = HIDEJUMPSUIT|HIDEBELT allowed = list(/obj/item/megaphone/clown, /obj/item/soap, /obj/item/food/pie/cream, /obj/item/bikehorn, /obj/item/bikehorn/golden, /obj/item/bikehorn/airhorn, /obj/item/instrument/bikehorn, /obj/item/reagent_containers/cup/soda_cans/canned_laughter, /obj/item/toy/crayon, /obj/item/toy/crayon/spraycan, /obj/item/toy/crayon/spraycan/lubecan, /obj/item/grown/bananapeel, /obj/item/food/grown/banana) /obj/item/clothing/head/helmet/chaplain/clock @@ -151,6 +151,10 @@ inhand_icon_state = null slowdown = 0 +/obj/item/clothing/suit/chaplainsuit/armor/clock/Initialize(mapload) + . = ..() + AddComponent(/datum/component/item_equipped_movement_rustle, SFX_PLATE_ARMOR_RUSTLE, 8) + /obj/item/clothing/head/helmet/chaplain name = "crusader helmet" desc = "Deus Vult." @@ -179,6 +183,10 @@ inhand_icon_state = null slowdown = 0 +/obj/item/clothing/suit/chaplainsuit/armor/templar/Initialize(mapload) + . = ..() + AddComponent(/datum/component/item_equipped_movement_rustle, SFX_PLATE_ARMOR_RUSTLE, 8) + /obj/item/clothing/head/helmet/chaplain/cage name = "cage" desc = "A cage that restrains the will of the self, allowing one to see the profane world for what it is." @@ -199,6 +207,10 @@ icon_state = "knight_ancient" inhand_icon_state = null +/obj/item/clothing/suit/chaplainsuit/armor/ancient/Initialize(mapload) + . = ..() + AddComponent(/datum/component/item_equipped_movement_rustle, SFX_PLATE_ARMOR_RUSTLE, 8) + /obj/item/clothing/head/helmet/chaplain/witchunter_hat name = "witchunter hat" desc = "This hat saw much use back in the day." @@ -230,6 +242,11 @@ body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS armor_type = /datum/armor/armor_crusader +/obj/item/clothing/suit/chaplainsuit/armor/crusader/Initialize(mapload) + . = ..() + AddComponent(/datum/component/item_equipped_movement_rustle, SFX_PLATE_ARMOR_RUSTLE, 8) + + /datum/armor/armor_crusader melee = 50 bullet = 50 @@ -287,4 +304,4 @@ icon_state = "shrinehand" inhand_icon_state = "shrinehand" body_parts_covered = CHEST|GROIN|LEGS|ARMS - flags_inv = HIDEJUMPSUIT + flags_inv = HIDEJUMPSUIT|HIDEBELT diff --git a/code/modules/jobs/job_types/chaplain/chaplain_nullrod.dm b/code/modules/jobs/job_types/chaplain/chaplain_nullrod.dm index 7d41ba36cdc3b..f8e94746d6030 100644 --- a/code/modules/jobs/job_types/chaplain/chaplain_nullrod.dm +++ b/code/modules/jobs/job_types/chaplain/chaplain_nullrod.dm @@ -22,6 +22,8 @@ var/menu_description = "A standard chaplain's weapon. Fits in pockets. Can be worn on the belt." /// Lazylist, tracks refs()s to all cultists which have been crit or killed by this nullrod. var/list/cultists_slain + /// Affects GLOB.holy_weapon_type. Disable to allow null rods to change at will and without affecting the station's type. + var/station_holy_item = TRUE /obj/item/nullrod/Initialize(mapload) . = ..() @@ -35,7 +37,7 @@ ) AddElement(/datum/element/bane, target_type = /mob/living/basic/revenant, damage_multiplier = 0, added_damage = 25, requires_combat_mode = FALSE) - if(!GLOB.holy_weapon_type && type == /obj/item/nullrod) + if((!GLOB.holy_weapon_type || !station_holy_item) && type == /obj/item/nullrod) var/list/rods = list() for(var/obj/item/nullrod/nullrod_type as anything in typesof(/obj/item/nullrod)) if(!initial(nullrod_type.chaplain_spawnable)) @@ -52,6 +54,8 @@ AddComponent(/datum/component/subtype_picker, rods, CALLBACK(src, PROC_REF(on_holy_weapon_picked))) /obj/item/nullrod/proc/on_holy_weapon_picked(obj/item/nullrod/holy_weapon_type) + if(!station_holy_item) + return GLOB.holy_weapon_type = holy_weapon_type SEND_GLOBAL_SIGNAL(COMSIG_GLOB_NULLROD_PICKED) SSblackbox.record_feedback("tally", "chaplain_weapon", 1, "[initial(holy_weapon_type.name)]") @@ -90,6 +94,10 @@ . += span_cult_italic("It has the blood of [num_slain] fallen cultist[num_slain == 1 ? "" : "s"] on it. \ Offering it to Nar'sie will transform it into a [num_slain >= 3 ? "powerful" : "standard"] cult weapon.") +/obj/item/nullrod/non_station + station_holy_item = FALSE + chaplain_spawnable = FALSE + /// Claymore Variant /// This subtype possesses a block chance and is sharp. diff --git a/code/modules/jobs/job_types/chief_engineer.dm b/code/modules/jobs/job_types/chief_engineer.dm index 7ac1b6e29af9b..f85c2c54973b9 100644 --- a/code/modules/jobs/job_types/chief_engineer.dm +++ b/code/modules/jobs/job_types/chief_engineer.dm @@ -46,6 +46,8 @@ rpg_title = "Head Crystallomancer" job_flags = STATION_JOB_FLAGS | HEAD_OF_STAFF_JOB_FLAGS + human_authority = JOB_AUTHORITY_HUMANS_ONLY + voice_of_god_power = 1.4 //Command staff has authority diff --git a/code/modules/jobs/job_types/chief_medical_officer.dm b/code/modules/jobs/job_types/chief_medical_officer.dm index 3f580b8e932a5..c9f126bb750bc 100644 --- a/code/modules/jobs/job_types/chief_medical_officer.dm +++ b/code/modules/jobs/job_types/chief_medical_officer.dm @@ -43,6 +43,8 @@ rpg_title = "High Cleric" job_flags = STATION_JOB_FLAGS | HEAD_OF_STAFF_JOB_FLAGS + human_authority = JOB_AUTHORITY_HUMANS_ONLY + voice_of_god_power = 1.4 //Command staff has authority diff --git a/code/modules/jobs/job_types/head_of_personnel.dm b/code/modules/jobs/job_types/head_of_personnel.dm index e863a782d9b0c..1b8480f0d0b57 100644 --- a/code/modules/jobs/job_types/head_of_personnel.dm +++ b/code/modules/jobs/job_types/head_of_personnel.dm @@ -41,6 +41,9 @@ family_heirlooms = list(/obj/item/reagent_containers/cup/glass/trophy/silver_cup) rpg_title = "Guild Questgiver" job_flags = STATION_JOB_FLAGS | HEAD_OF_STAFF_JOB_FLAGS + + human_authority = JOB_AUTHORITY_HUMANS_ONLY + voice_of_god_power = 1.4 //Command staff has authority diff --git a/code/modules/jobs/job_types/head_of_security.dm b/code/modules/jobs/job_types/head_of_security.dm index f3627c3c2a257..b9560708114be 100644 --- a/code/modules/jobs/job_types/head_of_security.dm +++ b/code/modules/jobs/job_types/head_of_security.dm @@ -37,6 +37,8 @@ rpg_title = "Guard Leader" job_flags = STATION_JOB_FLAGS | HEAD_OF_STAFF_JOB_FLAGS + human_authority = JOB_AUTHORITY_HUMANS_ONLY + voice_of_god_power = 1.4 //Command staff has authority diff --git a/code/modules/jobs/job_types/paramedic.dm b/code/modules/jobs/job_types/paramedic.dm index 2fd4f3a93a6da..80936dce2938a 100644 --- a/code/modules/jobs/job_types/paramedic.dm +++ b/code/modules/jobs/job_types/paramedic.dm @@ -24,7 +24,7 @@ /datum/job_department/medical, ) - family_heirlooms = list(/obj/item/storage/medkit/ancient/heirloom) + family_heirlooms = list(/obj/item/storage/medkit/ancient/heirloom, /obj/item/fishing_hook/rescue) mail_goodies = list( /obj/item/reagent_containers/hypospray/medipen = 20, diff --git a/code/modules/jobs/job_types/quartermaster.dm b/code/modules/jobs/job_types/quartermaster.dm index 858ce8b645536..32053daa5d8c8 100644 --- a/code/modules/jobs/job_types/quartermaster.dm +++ b/code/modules/jobs/job_types/quartermaster.dm @@ -36,7 +36,7 @@ rpg_title = "Steward" job_flags = STATION_JOB_FLAGS | HEAD_OF_STAFF_JOB_FLAGS voice_of_god_power = 1.4 //Command staff has authority - ignore_human_authority = TRUE + human_authority = JOB_AUTHORITY_NON_HUMANS_ALLOWED /datum/outfit/job/quartermaster name = "Quartermaster" diff --git a/code/modules/jobs/job_types/research_director.dm b/code/modules/jobs/job_types/research_director.dm index 5d3c620322759..420138a6b9fba 100644 --- a/code/modules/jobs/job_types/research_director.dm +++ b/code/modules/jobs/job_types/research_director.dm @@ -44,6 +44,8 @@ rpg_title = "Archmagister" job_flags = STATION_JOB_FLAGS | HEAD_OF_STAFF_JOB_FLAGS + human_authority = JOB_AUTHORITY_HUMANS_ONLY + voice_of_god_power = 1.4 //Command staff has authority diff --git a/code/modules/jobs/job_types/station_trait/bridge_assistant.dm b/code/modules/jobs/job_types/station_trait/bridge_assistant.dm index b1ae57de1ffe6..d776ae6251f7f 100644 --- a/code/modules/jobs/job_types/station_trait/bridge_assistant.dm +++ b/code/modules/jobs/job_types/station_trait/bridge_assistant.dm @@ -33,7 +33,7 @@ rpg_title = "Royal Guard" allow_bureaucratic_error = FALSE job_flags = STATION_JOB_FLAGS | STATION_TRAIT_JOB_FLAGS - ignore_human_authority = TRUE + human_authority = JOB_AUTHORITY_NON_HUMANS_ALLOWED /datum/job/bridge_assistant/after_spawn(mob/living/spawned, client/player_client) . = ..() diff --git a/code/modules/jobs/job_types/station_trait/human_ai.dm b/code/modules/jobs/job_types/station_trait/human_ai.dm index a6e77d77a510c..d6f89357b4489 100644 --- a/code/modules/jobs/job_types/station_trait/human_ai.dm +++ b/code/modules/jobs/job_types/station_trait/human_ai.dm @@ -40,7 +40,7 @@ random_spawns_possible = FALSE allow_bureaucratic_error = FALSE job_flags = STATION_JOB_FLAGS | STATION_TRAIT_JOB_FLAGS - ignore_human_authority = TRUE //we can safely assume NT doesn't care what species AIs are made of, much less if they can't even afford an AI. + human_authority = JOB_AUTHORITY_NON_HUMANS_ALLOWED //we can safely assume NT doesn't care what species AIs are made of, much less if they can't even afford an AI. /datum/job/human_ai/get_roundstart_spawn_point() return get_latejoin_spawn_point() @@ -111,6 +111,18 @@ l_hand = /obj/item/paper/default_lawset_list +/datum/outfit/job/human_ai/pre_equip(mob/living/carbon/human/equipped, visualsOnly) + . = ..() + if(visualsOnly) + return + if(is_safe_turf(equipped.loc, dense_atoms = TRUE)) //skip this if it's safe. We allow dense atoms because we spawn out of the inactive core. + return + if(isnull(equipped.dna.species.outfit_important_for_life)) //custom species stuff will handle this for us. + internals_slot = ITEM_SLOT_SUITSTORE + suit_store = /obj/item/tank/internals/oxygen + suit = /obj/item/clothing/suit/space/nasavoid + head = /obj/item/clothing/head/helmet/space/nasavoid + /datum/outfit/job/human_ai/post_equip(mob/living/carbon/human/equipped, visualsOnly) . = ..() if(visualsOnly) @@ -122,9 +134,6 @@ ADD_TRAIT(equipped, TRAIT_COMMISSIONED, INNATE_TRAIT) equipped.faction |= list(FACTION_SILICON, FACTION_TURRET) - var/static/list/allowed_areas = typecacheof(list(/area/station/ai_monitored)) - equipped.AddComponent(/datum/component/hazard_area, area_whitelist = allowed_areas) - /obj/item/paper/default_lawset_list name = "Lawset Note" desc = "A note explaining the lawset, quickly written yet everso important." diff --git a/code/modules/jobs/job_types/station_trait/pun_pun.dm b/code/modules/jobs/job_types/station_trait/pun_pun.dm index eca4861e77ef0..b6ac7b813bffc 100644 --- a/code/modules/jobs/job_types/station_trait/pun_pun.dm +++ b/code/modules/jobs/job_types/station_trait/pun_pun.dm @@ -37,7 +37,7 @@ /datum/job/pun_pun/after_spawn(mob/living/carbon/human/monkey, client/player_client) . = ..() - monkey.make_clever_and_no_dna_scramble() + monkey.crewlike_monkify() /datum/outfit/job/pun_pun name = "Pun Pun" diff --git a/code/modules/library/skill_learning/generic_skillchips/misc.dm b/code/modules/library/skill_learning/generic_skillchips/misc.dm new file mode 100644 index 0000000000000..aea850b8f49f2 --- /dev/null +++ b/code/modules/library/skill_learning/generic_skillchips/misc.dm @@ -0,0 +1,157 @@ +//Contains generic skillchips that are fairly short and simple + +/obj/item/skillchip/basketweaving + name = "Basketsoft 3000 skillchip" + desc = "Underwater edition." + auto_traits = list(TRAIT_UNDERWATER_BASKETWEAVING_KNOWLEDGE) + skill_name = "Underwater Basketweaving" + skill_description = "Master intricate art of using twine to create perfect baskets while submerged." + skill_icon = "shopping-basket" + activate_message = span_notice("You're one with the twine and the sea.") + deactivate_message = span_notice("Higher mysteries of underwater basketweaving leave your mind.") + +/obj/item/skillchip/wine_taster + name = "WINE skillchip" + desc = "Wine.Is.Not.Equal version 5." + auto_traits = list(TRAIT_WINE_TASTER) + skill_name = "Wine Tasting" + skill_description = "Recognize wine vintage from taste alone. Never again lack an opinion when presented with an unknown drink." + skill_icon = "wine-bottle" + activate_message = span_notice("You recall wine taste.") + deactivate_message = span_notice("Your memories of wine evaporate.") + +/obj/item/skillchip/bonsai + name = "Hedge 3 skillchip" + auto_traits = list(TRAIT_BONSAI) + skill_name = "Hedgetrimming" + skill_description = "Trim hedges and potted plants into marvelous new shapes with any old knife. Not applicable to plastic plants." + skill_icon = "spa" + activate_message = span_notice("Your mind is filled with plant arrangments.") + deactivate_message = span_notice("You can't remember what a hedge looks like anymore.") + +/obj/item/skillchip/useless_adapter + name = "Skillchip adapter" + skill_name = "Useless adapter" + skill_description = "Allows you to insert another skillchip into this adapter after it has been inserted into your brain..." + skill_icon = "plug" + activate_message = span_notice("You can now activate another chip through this adapter, but you're not sure why you did this...") + deactivate_message = span_notice("You no longer have the useless skillchip adapter.") + skillchip_flags = SKILLCHIP_ALLOWS_MULTIPLE + // Literally does nothing. + complexity = 0 + slot_use = 0 + +/obj/item/skillchip/light_remover + name = "N16H7M4R3 skillchip" + auto_traits = list(TRAIT_LIGHTBULB_REMOVER) + skill_name = "Lightbulb Removing" + skill_description = "Stop failing taking out lightbulbs today, no gloves needed!" + skill_icon = "lightbulb" + activate_message = span_notice("Your feel like your pain receptors are less sensitive to hot objects.") + deactivate_message = span_notice("You feel like hot objects could stop you again...") + +/obj/item/skillchip/disk_verifier + name = "K33P-TH4T-D15K skillchip" + auto_traits = list(TRAIT_DISK_VERIFIER) + skill_name = "Nuclear Disk Verification" + skill_description = "Nuclear authentication disks have an extremely long serial number for verification. This skillchip stores that number, which allows the user to automatically spot forgeries." + skill_icon = "save" + activate_message = span_notice("You feel your mind automatically verifying long serial numbers on disk shaped objects.") + deactivate_message = span_notice("The innate recognition of absurdly long disk-related serial numbers fades from your mind.") + +/obj/item/skillchip/entrails_reader + name = "3NTR41LS skillchip" + auto_traits = list(TRAIT_ENTRAILS_READER) + skill_name = "Entrails Reader" + skill_description = "Be able to learn about a person's life, by looking at their internal organs. Not to be confused with looking into the future." + skill_icon = "lungs" + activate_message = span_notice("You feel that you know a lot about interpreting organs.") + deactivate_message = span_notice("Knowledge of liver damage, heart strain and lung scars fades from your mind.") + +/obj/item/skillchip/appraiser + name = "GENUINE ID Appraisal Now! skillchip" + auto_traits = list(TRAIT_ID_APPRAISER) + skill_name = "ID Appraisal" + skill_description = "Appraise an ID and see if it's issued from centcom, or just a cruddy station-printed one." + skill_icon = "magnifying-glass" + activate_message = span_notice("You feel that you can recognize special, minute details on ID cards.") + deactivate_message = span_notice("Was there something special about certain IDs?") + +/obj/item/skillchip/sabrage + name = "Le S48R4G3 skillchip" + auto_traits = list(TRAIT_SABRAGE_PRO) + skill_name = "Sabrage Proficiency" + skill_description = "Grants the user knowledge of the intricate structure of a champagne bottle's structural weakness at the neck, \ + improving their proficiency at being a show-off at officer parties." + skill_icon = "bottle-droplet" + activate_message = span_notice("You feel a new understanding of champagne bottles and methods on how to remove their corks.") + deactivate_message = span_notice("The knowledge of the subtle physics residing inside champagne bottles fades from your mind.") + +/obj/item/skillchip/brainwashing + name = "suspicious skillchip" + auto_traits = list(TRAIT_BRAINWASHING) + skill_name = "Brainwashing" + skill_description = "WARNING: The integrity of this chip is compromised. Please discard this skillchip." + skill_icon = "soap" + activate_message = span_notice("...But all at once it comes to you... something involving putting a brain in a washing machine?") + deactivate_message = span_warning("All knowledge of the secret brainwashing technique is GONE.") + +/obj/item/skillchip/brainwashing/examine(mob/user) + . = ..() + . += span_warning("It seems to have been corroded over time, putting this in your head may not be the best idea...") + +/obj/item/skillchip/brainwashing/on_activate(mob/living/carbon/user, silent = FALSE) + to_chat(user, span_danger("You get a pounding headache as the chip sends corrupt memories into your head!")) + user.adjustOrganLoss(ORGAN_SLOT_BRAIN, 20) + . = ..() + +/obj/item/skillchip/chefs_kiss + name = "K1SS skillchip" + auto_traits = list(TRAIT_CHEF_KISS) + skill_name = "Chef's Kiss" + skill_description = "Allows you to kiss food you've created to make them with love." + skill_icon = "cookie" + activate_message = span_notice("You recall learning from your grandmother how they baked their cookies with love.") + deactivate_message = span_notice("You forget all memories imparted upon you by your grandmother. Were they even your real grandma?") + +/obj/item/skillchip/intj + name = "Integrated Intuitive Thinking and Judging skillchip" + auto_traits = list(TRAIT_REMOTE_TASTING) + skill_name = "Mental Flavour Calculus" + skill_description = "When examining food, you can experience the flavours just as well as if you were eating it." + skill_icon = FA_ICON_DRUMSTICK_BITE + activate_message = span_notice("You think of your favourite food and realise that you can rotate its flavour in your mind.") + deactivate_message = span_notice("You feel your food-based mind palace crumbling...") + +/obj/item/skillchip/drunken_brawler + name = "F0RC3 4DD1CT10N skillchip" + auto_traits = list(TRAIT_DRUNKEN_BRAWLER) + skill_name = "Drunken Unarmed Proficiency" + skill_description = "When intoxicated, you gain increased unarmed effectiveness." + skill_icon = "wine-bottle" + activate_message = span_notice("You honestly could do with a drink. Never know when someone might try and jump you around here.") + deactivate_message = span_notice("You suddenly feel a lot safer going around the station sober... ") + +/obj/item/skillchip/master_angler + name = "Mast-Angl-Er skillchip" + auto_traits = list(TRAIT_REVEAL_FISH, TRAIT_EXAMINE_FISHING_SPOT, TRAIT_EXAMINE_FISH, TRAIT_EXAMINE_DEEPER_FISH) + skill_name = "Fisherman's Discernment" + skill_description = "Lists fishes when examining a fishing spot, gives a hint of whatever thing's biting the hook and more." + skill_icon = "fish" + activate_message = span_notice("You feel the knowledge and passion of several sunbaked, seasoned fishermen burn within you.") + deactivate_message = span_notice("You no longer feel like casting a fishing rod by the sunny riverside.") + + actions_types = list(/datum/action/cooldown/fishing_tip) + +/datum/action/cooldown/fishing_tip + name = "Dispense Fishing Tip" + desc = "Recall a pearl of wisdom about fishing." + button_icon = 'icons/hud/radial_fishing.dmi' + button_icon_state = "river" + background_icon_state = "bg_default" + overlay_icon_state = "bg_default_border" + cooldown_time = 2.5 SECONDS //enough time to skim through tips. + +/datum/action/cooldown/fishing_tip/Activate(atom/target_atom) + . = ..() + send_tip_of_the_round(owner, pick(GLOB.fishing_tips), source = "Ancient fishing wisdom") diff --git a/code/modules/library/skill_learning/generic_skillchips/musical.dm b/code/modules/library/skill_learning/generic_skillchips/musical.dm new file mode 100644 index 0000000000000..0eea811ffab77 --- /dev/null +++ b/code/modules/library/skill_learning/generic_skillchips/musical.dm @@ -0,0 +1,91 @@ +/obj/item/skillchip/musical + name = "\improper Old Copy of \"Space Station 13: The Musical\"" + desc = "An old copy of \"Space Station 13: The Musical\", \ + ran on the station's 100th anniversary...Or maybe it was the 200th?" + skill_name = "Memory of a Musical" + skill_description = "Allows you to hit that high note, like those that came a century before us." + skill_icon = FA_ICON_MUSIC + activate_message = span_notice("You feel like you could \u2669 sing a soooong! \u266B") + deactivate_message = span_notice("The musical fades from your mind, leaving you with a sense of nostalgia.") + custom_premium_price = PAYCHECK_CREW * 4 + +/obj/item/skillchip/musical/Initialize(mapload, is_removable) + . = ..() + name = replacetext(name, "Old", round(CURRENT_STATION_YEAR - pick(50, 100, 150, 200, 250), 5)) + +/obj/item/skillchip/musical/on_activate(mob/living/carbon/user, silent = FALSE) + . = ..() + RegisterSignal(user, COMSIG_MOB_SAY, PROC_REF(make_music)) + +/obj/item/skillchip/musical/on_deactivate(mob/living/carbon/user, silent) + . = ..() + UnregisterSignal(user, COMSIG_MOB_SAY) + +/obj/item/skillchip/musical/proc/make_music(mob/living/carbon/source, list/say_args) + SIGNAL_HANDLER + + var/raw_message = say_args[SPEECH_MESSAGE] + var/list/words = splittext(raw_message, " ") + if(length(words) <= 1) + say_args[SPEECH_MODS][MODE_SING] = TRUE + return + var/last_word = words[length(words)] + var/num_chars = length_char(last_word) + var/last_vowel = "" + // find the last vowel present in the word + for(var/i in 1 to num_chars) + var/char = copytext_char(last_word, i, i + 1) + if(char in VOWELS) + last_vowel = char + + // now we'll reshape the final word to make it sound like they're singing it + var/final_word = "" + var/has_ellipsis = copytext(last_word, -3) == "..." + for(var/i in 1 to num_chars) + var/char = copytext_char(last_word, i, i + 1) + // replacing any final periods with exclamation marks (so long as it's not an ellipsis) + if(char == "." && i == num_chars && !has_ellipsis) + final_word += "!" + // or if it's the vowel we found, we're gonna repeat it a few times (holding the note) + else if(char == last_vowel) + for(var/j in 1 to 4) + final_word += char + // if we dragged out the last character of the word, just period it + if(i == num_chars) + final_word += "." + // no special handing otherwise + else + final_word += char + + if(!has_ellipsis) + // adding an extra exclamation mark at the end if there's no period + var/last_char = copytext_char(final_word, -1) + if(last_char != ".") + final_word += "!" + + words[length(words)] = final_word + // now we siiiiiiing + say_args[SPEECH_MESSAGE] = jointext(words, " ") + say_args[SPEECH_MODS][MODE_SING] = TRUE + +/obj/item/skillchip/musical/examine(mob/user) + . = ..() + . += span_tinynoticeital("Huh, looks like it'd fit in a skillchip adapter.") + +/obj/item/skillchip/musical/examine_more(mob/user) + . = ..() + var/list/songs = list() + songs += "• \"The Ballad of Space Station 13\"" + songs += "• \"The Captain's Call\"" + songs += "• \"A Mime's Lament\"" + songs += "• \"Banned from Cargo\"" + songs += "• \"Botany Blues\"" + songs += "• \"Clown Song\"" + songs += "• \"Elegy to an Engineer\"" + songs += "• \"Medical Malpractitioner\"" + songs += "• \"Security Strike\"" + songs += "• \"Send for the Shuttle\"" + songs += "• And one song scratched out..." + + . += span_notice("On the back of the chip, you see a list of songs:") + . += span_smallnotice("[jointext(songs, "
")]
") diff --git a/code/modules/library/skill_learning/generic_skillchips/point.dm b/code/modules/library/skill_learning/generic_skillchips/point.dm index 761a482268952..ba6a2e3e236ec 100644 --- a/code/modules/library/skill_learning/generic_skillchips/point.dm +++ b/code/modules/library/skill_learning/generic_skillchips/point.dm @@ -11,25 +11,17 @@ activate_message = span_notice("From \"The Definitive Compendium of Body Language for the Aspiring Leader\", page 164, paragraph 3...") deactivate_message = span_notice("So, uh, yeah, how do I point at things again?") - ///The action for changing the pointer color - var/datum/action/change_pointer_color/action - -/obj/item/skillchip/big_pointer/Destroy() - action = null - return ..() + actions_types = list(/datum/action/change_pointer_color) /obj/item/skillchip/big_pointer/on_activate(mob/living/carbon/user, silent=FALSE) . = ..() RegisterSignal(user, COMSIG_MOVABLE_POINTED, PROC_REF(fancier_pointer)) - if(!action) - action = new(src) - action.Grant(user) /obj/item/skillchip/big_pointer/on_deactivate(mob/living/carbon/user, silent=FALSE) UnregisterSignal(user, COMSIG_MOVABLE_POINTED) + var/datum/action/change_pointer_color/action = locate() in actions action?.arrow_color = null action?.arrow_overlay = null - action?.Remove(user) return ..() /obj/item/skillchip/big_pointer/proc/fancier_pointer(mob/living/user, atom/pointed, obj/effect/temp_visual/point/point) @@ -37,6 +29,7 @@ if(HAS_TRAIT(user, TRAIT_UNKNOWN)) return point.cut_overlays() + var/datum/action/change_pointer_color/action = locate() in actions if(!action.arrow_color) point.icon_state = "arrow_large" return diff --git a/code/modules/library/skill_learning/generic_skillchips/rod_suplex.dm b/code/modules/library/skill_learning/job_skillchips/research_director.dm similarity index 100% rename from code/modules/library/skill_learning/generic_skillchips/rod_suplex.dm rename to code/modules/library/skill_learning/job_skillchips/research_director.dm diff --git a/code/modules/library/skill_learning/skillchip.dm b/code/modules/library/skill_learning/skillchip.dm index 10139585dd9a7..eddaf300e08a9 100644 --- a/code/modules/library/skill_learning/skillchip.dm +++ b/code/modules/library/skill_learning/skillchip.dm @@ -48,6 +48,10 @@ . = ..() removable = is_removable +///We don't grant actions outside of being activated when implanted +/obj/item/skillchip/item_action_slot_check(slot, mob/user, datum/action/action) + return FALSE + /** * Activates the skillchip, if possible. * @@ -150,6 +154,9 @@ active = TRUE + for(var/datum/action/action as anything in actions) + action.Grant(user) + COOLDOWN_START(src, chip_cooldown, cooldown) /** @@ -185,6 +192,9 @@ active = FALSE + for(var/datum/action/action as anything in actions) + action.Remove(user) + COOLDOWN_START(src, chip_cooldown, cooldown) /** @@ -369,236 +379,3 @@ removable = metadata["removable"] return active_msg - -/obj/item/skillchip/basketweaving - name = "Basketsoft 3000 skillchip" - desc = "Underwater edition." - auto_traits = list(TRAIT_UNDERWATER_BASKETWEAVING_KNOWLEDGE) - skill_name = "Underwater Basketweaving" - skill_description = "Master intricate art of using twine to create perfect baskets while submerged." - skill_icon = "shopping-basket" - activate_message = span_notice("You're one with the twine and the sea.") - deactivate_message = span_notice("Higher mysteries of underwater basketweaving leave your mind.") - -/obj/item/skillchip/wine_taster - name = "WINE skillchip" - desc = "Wine.Is.Not.Equal version 5." - auto_traits = list(TRAIT_WINE_TASTER) - skill_name = "Wine Tasting" - skill_description = "Recognize wine vintage from taste alone. Never again lack an opinion when presented with an unknown drink." - skill_icon = "wine-bottle" - activate_message = span_notice("You recall wine taste.") - deactivate_message = span_notice("Your memories of wine evaporate.") - -/obj/item/skillchip/bonsai - name = "Hedge 3 skillchip" - auto_traits = list(TRAIT_BONSAI) - skill_name = "Hedgetrimming" - skill_description = "Trim hedges and potted plants into marvelous new shapes with any old knife. Not applicable to plastic plants." - skill_icon = "spa" - activate_message = span_notice("Your mind is filled with plant arrangments.") - deactivate_message = span_notice("You can't remember what a hedge looks like anymore.") - -/obj/item/skillchip/useless_adapter - name = "Skillchip adapter" - skill_name = "Useless adapter" - skill_description = "Allows you to insert another skillchip into this adapter after it has been inserted into your brain..." - skill_icon = "plug" - activate_message = span_notice("You can now activate another chip through this adapter, but you're not sure why you did this...") - deactivate_message = span_notice("You no longer have the useless skillchip adapter.") - skillchip_flags = SKILLCHIP_ALLOWS_MULTIPLE - // Literally does nothing. - complexity = 0 - slot_use = 0 - -/obj/item/skillchip/light_remover - name = "N16H7M4R3 skillchip" - auto_traits = list(TRAIT_LIGHTBULB_REMOVER) - skill_name = "Lightbulb Removing" - skill_description = "Stop failing taking out lightbulbs today, no gloves needed!" - skill_icon = "lightbulb" - activate_message = span_notice("Your feel like your pain receptors are less sensitive to hot objects.") - deactivate_message = span_notice("You feel like hot objects could stop you again...") - -/obj/item/skillchip/disk_verifier - name = "K33P-TH4T-D15K skillchip" - auto_traits = list(TRAIT_DISK_VERIFIER) - skill_name = "Nuclear Disk Verification" - skill_description = "Nuclear authentication disks have an extremely long serial number for verification. This skillchip stores that number, which allows the user to automatically spot forgeries." - skill_icon = "save" - activate_message = span_notice("You feel your mind automatically verifying long serial numbers on disk shaped objects.") - deactivate_message = span_notice("The innate recognition of absurdly long disk-related serial numbers fades from your mind.") - -/obj/item/skillchip/entrails_reader - name = "3NTR41LS skillchip" - auto_traits = list(TRAIT_ENTRAILS_READER) - skill_name = "Entrails Reader" - skill_description = "Be able to learn about a person's life, by looking at their internal organs. Not to be confused with looking into the future." - skill_icon = "lungs" - activate_message = span_notice("You feel that you know a lot about interpreting organs.") - deactivate_message = span_notice("Knowledge of liver damage, heart strain and lung scars fades from your mind.") - -/obj/item/skillchip/appraiser - name = "GENUINE ID Appraisal Now! skillchip" - auto_traits = list(TRAIT_ID_APPRAISER) - skill_name = "ID Appraisal" - skill_description = "Appraise an ID and see if it's issued from centcom, or just a cruddy station-printed one." - skill_icon = "magnifying-glass" - activate_message = span_notice("You feel that you can recognize special, minute details on ID cards.") - deactivate_message = span_notice("Was there something special about certain IDs?") - -/obj/item/skillchip/sabrage - name = "Le S48R4G3 skillchip" - auto_traits = list(TRAIT_SABRAGE_PRO) - skill_name = "Sabrage Proficiency" - skill_description = "Grants the user knowledge of the intricate structure of a champagne bottle's structural weakness at the neck, \ - improving their proficiency at being a show-off at officer parties." - skill_icon = "bottle-droplet" - activate_message = span_notice("You feel a new understanding of champagne bottles and methods on how to remove their corks.") - deactivate_message = span_notice("The knowledge of the subtle physics residing inside champagne bottles fades from your mind.") - -/obj/item/skillchip/brainwashing - name = "suspicious skillchip" - auto_traits = list(TRAIT_BRAINWASHING) - skill_name = "Brainwashing" - skill_description = "WARNING: The integrity of this chip is compromised. Please discard this skillchip." - skill_icon = "soap" - activate_message = span_notice("...But all at once it comes to you... something involving putting a brain in a washing machine?") - deactivate_message = span_warning("All knowledge of the secret brainwashing technique is GONE.") - -/obj/item/skillchip/brainwashing/examine(mob/user) - . = ..() - . += span_warning("It seems to have been corroded over time, putting this in your head may not be the best idea...") - -/obj/item/skillchip/brainwashing/on_activate(mob/living/carbon/user, silent = FALSE) - to_chat(user, span_danger("You get a pounding headache as the chip sends corrupt memories into your head!")) - user.adjustOrganLoss(ORGAN_SLOT_BRAIN, 20) - . = ..() - -/obj/item/skillchip/chefs_kiss - name = "K1SS skillchip" - auto_traits = list(TRAIT_CHEF_KISS) - skill_name = "Chef's Kiss" - skill_description = "Allows you to kiss food you've created to make them with love." - skill_icon = "cookie" - activate_message = span_notice("You recall learning from your grandmother how they baked their cookies with love.") - deactivate_message = span_notice("You forget all memories imparted upon you by your grandmother. Were they even your real grandma?") - -/obj/item/skillchip/master_angler - name = "Mast-Angl-Er skillchip" - auto_traits = list(TRAIT_REVEAL_FISH, TRAIT_EXAMINE_FISHING_SPOT, TRAIT_EXAMINE_FISH, TRAIT_EXAMINE_DEEPER_FISH) - skill_name = "Fisherman's Discernment" - skill_description = "Lists fishes when examining a fishing spot, gives a hint of whatever thing's biting the hook and more." - skill_icon = "fish" - activate_message = span_notice("You feel the knowledge and passion of several sunbaked, seasoned fishermen burn within you.") - deactivate_message = span_notice("You no longer feel like casting a fishing rod by the sunny riverside.") - -/obj/item/skillchip/intj - name = "Integrated Intuitive Thinking and Judging skillchip" - auto_traits = list(TRAIT_REMOTE_TASTING) - skill_name = "Mental Flavour Calculus" - skill_description = "When examining food, you can experience the flavours just as well as if you were eating it." - skill_icon = FA_ICON_DRUMSTICK_BITE - activate_message = span_notice("You think of your favourite food and realise that you can rotate its flavour in your mind.") - deactivate_message = span_notice("You feel your food-based mind palace crumbling...") - -/obj/item/skillchip/drunken_brawler - name = "F0RC3 4DD1CT10N skillchip" - auto_traits = list(TRAIT_DRUNKEN_BRAWLER) - skill_name = "Drunken Unarmed Proficiency" - skill_description = "When intoxicated, you gain increased unarmed effectiveness." - skill_icon = "wine-bottle" - activate_message = span_notice("You honestly could do with a drink. Never know when someone might try and jump you around here.") - deactivate_message = span_notice("You suddenly feel a lot safer going around the station sober... ") - -/obj/item/skillchip/musical - name = "\improper Old Copy of \"Space Station 13: The Musical\"" - desc = "An old copy of \"Space Station 13: The Musical\", \ - ran on the station's 100th anniversary...Or maybe it was the 200th?" - skill_name = "Memory of a Musical" - skill_description = "Allows you to hit that high note, like those that came a century before us." - skill_icon = FA_ICON_MUSIC - activate_message = span_notice("You feel like you could \u2669 sing a soooong! \u266B") - deactivate_message = span_notice("The musical fades from your mind, leaving you with a sense of nostalgia.") - custom_premium_price = PAYCHECK_CREW * 4 - -/obj/item/skillchip/musical/Initialize(mapload, is_removable) - . = ..() - name = replacetext(name, "Old", round(CURRENT_STATION_YEAR - pick(50, 100, 150, 200, 250), 5)) - -/obj/item/skillchip/musical/on_activate(mob/living/carbon/user, silent = FALSE) - . = ..() - RegisterSignal(user, COMSIG_MOB_SAY, PROC_REF(make_music)) - -/obj/item/skillchip/musical/on_deactivate(mob/living/carbon/user, silent) - . = ..() - UnregisterSignal(user, COMSIG_MOB_SAY) - -/obj/item/skillchip/musical/proc/make_music(mob/living/carbon/source, list/say_args) - SIGNAL_HANDLER - - var/raw_message = say_args[SPEECH_MESSAGE] - var/list/words = splittext(raw_message, " ") - if(length(words) <= 1) - say_args[SPEECH_MODS][MODE_SING] = TRUE - return - var/last_word = words[length(words)] - var/num_chars = length_char(last_word) - var/last_vowel = "" - // find the last vowel present in the word - for(var/i in 1 to num_chars) - var/char = copytext_char(last_word, i, i + 1) - if(char in VOWELS) - last_vowel = char - - // now we'll reshape the final word to make it sound like they're singing it - var/final_word = "" - var/has_ellipsis = copytext(last_word, -3) == "..." - for(var/i in 1 to num_chars) - var/char = copytext_char(last_word, i, i + 1) - // replacing any final periods with exclamation marks (so long as it's not an ellipsis) - if(char == "." && i == num_chars && !has_ellipsis) - final_word += "!" - // or if it's the vowel we found, we're gonna repeat it a few times (holding the note) - else if(char == last_vowel) - for(var/j in 1 to 4) - final_word += char - // if we dragged out the last character of the word, just period it - if(i == num_chars) - final_word += "." - // no special handing otherwise - else - final_word += char - - if(!has_ellipsis) - // adding an extra exclamation mark at the end if there's no period - var/last_char = copytext_char(final_word, -1) - if(last_char != ".") - final_word += "!" - - words[length(words)] = final_word - // now we siiiiiiing - say_args[SPEECH_MESSAGE] = jointext(words, " ") - say_args[SPEECH_MODS][MODE_SING] = TRUE - -/obj/item/skillchip/musical/examine(mob/user) - . = ..() - . += span_tinynoticeital("Huh, looks like it'd fit in a skillchip adapter.") - -/obj/item/skillchip/musical/examine_more(mob/user) - . = ..() - var/list/songs = list() - songs += "• \"The Ballad of Space Station 13\"" - songs += "• \"The Captain's Call\"" - songs += "• \"A Mime's Lament\"" - songs += "• \"Banned from Cargo\"" - songs += "• \"Botany Blues\"" - songs += "• \"Clown Song\"" - songs += "• \"Elegy to an Engineer\"" - songs += "• \"Medical Malpractitioner\"" - songs += "• \"Security Strike\"" - songs += "• \"Send for the Shuttle\"" - songs += "• And one song scratched out..." - - . += span_notice("On the back of the chip, you see a list of songs:") - . += span_smallnotice("[jointext(songs, "
")]
") diff --git a/code/modules/lighting/lighting_atom.dm b/code/modules/lighting/lighting_atom.dm index e3f72da5bbffd..21676d1741e74 100644 --- a/code/modules/lighting/lighting_atom.dm +++ b/code/modules/lighting/lighting_atom.dm @@ -201,8 +201,8 @@ var/list/hand_back if(!(get_offset.light_flags & LIGHT_IGNORE_OFFSET)) hand_back = get_visual_offset(get_offset) - hand_back[1] = -hand_back[1] / world.icon_size - hand_back[2] = -hand_back[2] / world.icon_size + hand_back[1] = -hand_back[1] / ICON_SIZE_X + hand_back[2] = -hand_back[2] / ICON_SIZE_Y else hand_back = list(0, 0) diff --git a/code/modules/loadout/categories/heads.dm b/code/modules/loadout/categories/heads.dm index 6b939495684ba..ad23f0b2dfb7b 100644 --- a/code/modules/loadout/categories/heads.dm +++ b/code/modules/loadout/categories/heads.dm @@ -132,6 +132,26 @@ name = "Rose" item_path = /obj/item/food/grown/rose +/datum/loadout_item/head/sunflower + name = "Sunflower" + item_path = /obj/item/food/grown/sunflower + +/datum/loadout_item/head/poppy + name = "Poppy" + item_path = /obj/item/food/grown/poppy + +/datum/loadout_item/head/lily + name = "Lily" + item_path = /obj/item/food/grown/poppy/lily + +/datum/loadout_item/head/geranium + name = "Geranium" + item_path = /obj/item/food/grown/poppy/geranium + +/datum/loadout_item/head/harebell + name = "Harebell" + item_path = /obj/item/food/grown/harebell + /datum/loadout_item/head/wig name = "Wig" item_path = /obj/item/clothing/head/wig/natural diff --git a/code/modules/manufactorio/_manufacturing.dm b/code/modules/manufactorio/_manufacturing.dm new file mode 100644 index 0000000000000..db177ac5ae4d1 --- /dev/null +++ b/code/modules/manufactorio/_manufacturing.dm @@ -0,0 +1,130 @@ +#define MANUFACTURING_FAIL_FULL -1 +#define MANUFACTURING_FAIL 0 +#define MANUFACTURING_SUCCESS 1 + +#define POCKET_INPUT "Input" +#define POCKET_OUTPUT "Output" + +#define MANUFACTURING_TURF_LAG_LIMIT 10 // max items on a turf before we consider it full + +/obj/machinery/power/manufacturing + icon = 'icons/obj/machines/manufactorio.dmi' + name = "base manufacture receiving type" + desc = "this shouldnt exist" + density = TRUE + /// Do we add the simple_rotation component and a text that we are powered by cable? Also allows unwrenching + var/may_be_moved = TRUE + /// Allow taking in mobs from conveyors? + var/allow_mob_bump_intake = FALSE + +/obj/machinery/power/manufacturing/Initialize(mapload) + . = ..() + if(may_be_moved) + AddComponent(/datum/component/simple_rotation) + if(anchored) + connect_to_network() + +/obj/machinery/power/manufacturing/examine(mob/user) + . = ..() + if(may_be_moved) + . += "It receives power via cable, but certain buildings do not need power." + . += length(contents - circuit) ? "It contains:" : "Its empty." + for(var/atom/movable/thing as anything in contents - circuit) + var/text = thing.name + var/obj/item/stack/possible_stack = thing + if(istype(possible_stack)) + text = "[possible_stack.amount] [text]" + . += text + + +/obj/machinery/power/manufacturing/Bumped(atom/movable/bumped_atom) //attempt to put in whatever is pushed into us via conveyor + . = ..() + if((!allow_mob_bump_intake && ismob(bumped_atom)) || !anchored) //only uncomment if youre brave + return + var/conveyor = locate(/obj/machinery/conveyor) in bumped_atom.loc + if(isnull(conveyor)) + return + receive_resource(bumped_atom, bumped_atom.loc, get_dir(src, bumped_atom)) + +/obj/machinery/power/manufacturing/wrench_act(mob/living/user, obj/item/tool) + . = ..() + if(!may_be_moved) + return + default_unfasten_wrench(user, tool) + if(anchored) + connect_to_network() + else + disconnect_from_network() + return ITEM_INTERACT_SUCCESS + +/obj/machinery/power/manufacturing/screwdriver_act(mob/living/user, obj/item/tool) + if(default_deconstruction_screwdriver(user, icon_state, icon_state, tool)) + return ITEM_INTERACT_SUCCESS + return ITEM_INTERACT_BLOCKING + +/obj/machinery/power/manufacturing/crowbar_act(mob/living/user, obj/item/tool) + . = ITEM_INTERACT_BLOCKING + if(default_deconstruction_crowbar(tool)) + return ITEM_INTERACT_SUCCESS + +/obj/machinery/power/manufacturing/proc/generate_io_overlays(direction, color, offsets_override) + var/list/dir_offset + if(islist(offsets_override)) + dir_offset = offsets_override + else + dir_offset = dir2offset(direction) + dir_offset[1] *= 32 + dir_offset[2] *= 32 + var/image/nonemissive = image(icon='icons/obj/doors/airlocks/station/overlays.dmi', icon_state="unres_[direction]") + nonemissive.pixel_x = dir_offset[1] + nonemissive.pixel_y = dir_offset[2] + nonemissive.color = color + var/mutable_appearance/emissive = emissive_appearance(nonemissive.icon, nonemissive.icon_state, offset_spokesman = src, alpha = nonemissive.alpha) + emissive.pixel_y = nonemissive.pixel_y + emissive.pixel_x = nonemissive.pixel_x + return list(nonemissive, emissive) + +/// Returns whatever object it may output, or null if it cant do that +/obj/machinery/power/manufacturing/proc/request_resource() + + +/obj/machinery/power/manufacturing/proc/receive_resource(atom/movable/receiving, atom/from, receive_dir) + CRASH("Unimplemented!") //check can_receive_resource here + +//use dir please +/obj/machinery/power/manufacturing/proc/send_resource(atom/movable/sending, atom/what_or_dir) + if(isobj(what_or_dir)) + var/obj/machinery/power/manufacturing/target = what_or_dir + return target.receive_resource(sending, src, get_step(src, what_or_dir)) + var/turf/next_turf = isturf(what_or_dir) ? what_or_dir : get_step(src, what_or_dir) + var/obj/machinery/power/manufacturing/manufactury = locate(/obj/machinery/power/manufacturing) in next_turf + if(!isnull(manufactury)) + if(!manufactury.anchored) + return MANUFACTURING_FAIL + return manufactury.receive_resource(sending, src, isturf(what_or_dir) ? get_dir(src, what_or_dir) : what_or_dir) + if(next_turf.is_blocked_turf(exclude_mobs = TRUE, source_atom = sending)) + return MANUFACTURING_FAIL + if(length(next_turf.contents) >= MANUFACTURING_TURF_LAG_LIMIT) + return MANUFACTURING_FAIL_FULL + if(isnull(sending)) + return MANUFACTURING_SUCCESS // for the sake of being used as a check + if(isnull(sending.loc) || !sending.Move(next_turf, get_dir(src, next_turf))) + sending.forceMove(next_turf) + return MANUFACTURING_SUCCESS + +/// Checks if this stack (if not a stack does not do anything) can merge WITHOUT creating two stacks in contents +/obj/machinery/power/manufacturing/proc/may_merge_in_contents(obj/item/stack/stack) + if(!istype(stack)) + return + for(var/obj/item/stack/other in contents - circuit) + if(!stack.can_merge(other)) + continue + if(other.amount + stack.amount <= other.max_amount) + return other + +/obj/machinery/power/manufacturing/proc/may_merge_in_contents_and_do_so(obj/item/stack/stack) + var/merging_into = may_merge_in_contents(stack) + if(isnull(merging_into)) + return + return stack.merge(merging_into) + diff --git a/code/modules/manufactorio/machines/crafter.dm b/code/modules/manufactorio/machines/crafter.dm new file mode 100644 index 0000000000000..302202838e53c --- /dev/null +++ b/code/modules/manufactorio/machines/crafter.dm @@ -0,0 +1,145 @@ +/obj/machinery/power/manufacturing/crafter + name = "manufacturing assembling machine" + desc = "Assembles (crafts) the set recipe until it runs out of resources. Inputs irrelevant to the recipe are ignored, and it may only hold exactly what the recipe needs." + icon_state = "crafter" + circuit = /obj/item/circuitboard/machine/manucrafter + /// power used per process() spent crafting + var/power_cost = 5 KILO WATTS + /// our output, if the way out was blocked is held here + var/atom/movable/withheld + /// current recipe + var/datum/crafting_recipe/recipe + /// crafting component + var/datum/component/personal_crafting/machine/craftsman + /// current timer for our crafting + var/craft_timer + /// do we use cooking recipes instead + var/cooking = FALSE + +/obj/machinery/power/manufacturing/crafter/Initialize(mapload) + . = ..() + craftsman = AddComponent(/datum/component/personal_crafting/machine) + if(ispath(recipe)) + recipe = locate(recipe) in (cooking ? GLOB.cooking_recipes : GLOB.crafting_recipes) + +/obj/machinery/power/manufacturing/crafter/examine(mob/user) + . = ..() + . += span_notice("It is currently manufacturing [isnull(recipe) ? "nothing. Use a multitool to set it" : recipe.name].") + if(isnull(recipe)) + return + . += span_notice("It needs:") + for(var/valid_type in recipe.reqs) + // Check if they're datums, specifically reagents. + var/datum/reagent/reagent_ingredient = valid_type + if(istype(reagent_ingredient)) + var/amount = recipe.reqs[reagent_ingredient] + . += "[amount] unit[amount > 1 ? "s" : ""] of [initial(reagent_ingredient.name)]" + + var/atom/ingredient = valid_type + var/amount = recipe.reqs[ingredient] + + . += "[amount > 1 ? ("[amount]" + " of") : "a"] [initial(ingredient.name)]" + +/obj/machinery/power/manufacturing/crafter/update_overlays() + . = ..() + . += generate_io_overlays(dir, COLOR_ORANGE) + for(var/target_dir in GLOB.cardinals - dir) + . += generate_io_overlays(target_dir, COLOR_MODERATE_BLUE) + +/obj/machinery/power/manufacturing/crafter/proc/valid_for_recipe(obj/item/checking) + . = FALSE + for(var/requirement_path in recipe.reqs) + if(!ispath(checking.type, requirement_path) || recipe.blacklist.Find(checking.type)) + continue + var/amount = recipe.reqs[requirement_path] + if(count_path(requirement_path) >= amount) + continue + return TRUE + +/obj/machinery/power/manufacturing/crafter/proc/count_path(path) + . = 0 + for(var/atom/content as anything in contents - circuit) + if(!ispath(path, content.type)) + continue + .++ + +/obj/machinery/power/manufacturing/crafter/receive_resource(obj/receiving, atom/from, receive_dir) + if(isnull(recipe) || !isitem(receiving) || surplus() < power_cost) + return MANUFACTURING_FAIL + if(receive_dir == dir || !valid_for_recipe(receiving)) + return MANUFACTURING_FAIL + if(isstack(receiving) && count_path(receiving.type) && !may_merge_in_contents_and_do_so(receiving)) + return MANUFACTURING_FAIL_FULL + receiving.Move(src, get_dir(receiving, src)) + START_PROCESSING(SSmanufacturing, src) + return MANUFACTURING_SUCCESS + +/obj/machinery/power/manufacturing/crafter/multitool_act(mob/living/user, obj/item/tool) + . = NONE + var/list/unavailable = list() + for(var/datum/crafting_recipe/potential_recipe as anything in cooking ? GLOB.cooking_recipes : GLOB.crafting_recipes) + if(craftsman.is_recipe_available(potential_recipe, user)) + continue + var/obj/result = initial(potential_recipe.result) + if(istype(result) && initial(result.anchored)) + continue + unavailable += potential_recipe + var/result = tgui_input_list(usr, "Recipe", "Select Recipe", (cooking ? GLOB.cooking_recipes : GLOB.crafting_recipes) - unavailable) + if(isnull(result) || result == recipe || !user.can_perform_action(src)) + return ITEM_INTERACT_FAILURE + var/dump_target = get_step(src, get_dir(src, user)) + for(var/atom/movable/thing as anything in contents - circuit) + thing.Move(dump_target) + recipe = result + balloon_alert(user, "set") + return ITEM_INTERACT_SUCCESS + +/obj/machinery/power/manufacturing/crafter/Exited(atom/movable/gone, direction) + . = ..() + if(gone == withheld) + withheld = null + +/obj/machinery/power/manufacturing/crafter/atom_destruction(damage_flag) + . = ..() + withheld?.Move(drop_location(src)) + +/obj/machinery/power/manufacturing/crafter/Destroy() + . = ..() + recipe = null + craftsman = null + QDEL_NULL(withheld) + +/obj/machinery/power/manufacturing/crafter/process(seconds_per_tick) + if(!isnull(withheld) && !send_resource(withheld, dir)) + return + if(!isnull(craft_timer)) + if(surplus() >= power_cost) + add_load() + else + deltimer(craft_timer) + craft_timer = null + say("Power failure!") + return + if(isnull(recipe) || !craftsman.check_contents(src, recipe, craftsman.get_surroundings(src))) + return + flick_overlay_view(mutable_appearance(icon, "crafter_printing"), recipe.time) + craft_timer = addtimer(CALLBACK(src, PROC_REF(craft), recipe), recipe.time, TIMER_STOPPABLE) + +/obj/machinery/power/manufacturing/crafter/proc/craft(datum/crafting_recipe/recipe) + if(QDELETED(src)) + return + craft_timer = null + var/atom/movable/result = craftsman.construct_item(src, recipe) + if(istype(result)) + if(isitem(result)) + result.pixel_x += rand(-4, 4) + result.pixel_y += rand(-4, 4) + result.Move(src) + send_resource(result, dir) + else + say(result) + +/obj/machinery/power/manufacturing/crafter/cooker + name = "manufacturing cooking machine" // maybe this shouldnt be available dont wanna make chef useless, though otherwise it would need a sprite + desc = "Cooks the set recipe until it runs out of resources. Inputs irrelevant to the recipe are ignored." + cooking = TRUE diff --git a/code/modules/manufactorio/machines/crusher.dm b/code/modules/manufactorio/machines/crusher.dm new file mode 100644 index 0000000000000..272cfeee02ee3 --- /dev/null +++ b/code/modules/manufactorio/machines/crusher.dm @@ -0,0 +1,83 @@ +/obj/machinery/power/manufacturing/crusher //todo make it work for other stuff + name = "manufacturing crusher" + desc = "Crushes any item put into it, boulders and such. Materials below a sheet are stored in the machine." + icon_state = "crusher" + circuit = /obj/item/circuitboard/machine/manucrusher + /// power used to crush + var/crush_cost = 3 KILO WATTS + /// how much can we hold + var/capacity = 5 + /// withheld output because output is either blocked or full + var/atom/movable/withholding + /// list of held mats + var/list/obj/item/stack/held_mats = list() + +/obj/machinery/power/manufacturing/crusher/update_overlays() + . = ..() + . += generate_io_overlays(dir, COLOR_ORANGE) // OUT - stuff in it + . += generate_io_overlays(REVERSE_DIR(dir), COLOR_MODERATE_BLUE) // IN - to crush + +/obj/machinery/power/manufacturing/crusher/Destroy() + . = ..() + QDEL_NULL(withholding) + +/obj/machinery/power/manufacturing/crusher/atom_destruction(damage_flag) + withholding?.Move(drop_location()) + return ..() + +/obj/machinery/power/manufacturing/crusher/receive_resource(obj/receiving, atom/from, receive_dir) + if(istype(receiving, /obj/item/stack/ore) || receiving.resistance_flags & INDESTRUCTIBLE || !isitem(receiving) || surplus() < crush_cost || receive_dir != REVERSE_DIR(dir)) + return MANUFACTURING_FAIL + if(length(contents - circuit) >= capacity && may_merge_in_contents_and_do_so(receiving)) + return MANUFACTURING_FAIL_FULL + receiving.Move(src, get_dir(receiving, src)) + START_PROCESSING(SSmanufacturing, src) + return MANUFACTURING_SUCCESS + +/obj/machinery/power/manufacturing/crusher/Exited(atom/movable/gone, direction) + . = ..() + if(gone == withholding) + withholding = null + +/obj/machinery/power/manufacturing/crusher/process(seconds_per_tick) //noot functional + if(!isnull(withholding) && !send_resource(withholding, dir)) + return + for(var/material in held_mats) + if(held_mats[material] >= 1) + var/new_amount = floor(held_mats[material]) + held_mats[material] -= new_amount + if(held_mats[material] <= 0) + held_mats -= material + withholding = new material(null, new_amount) + return + var/list/poor_saps = contents - circuit + if(!length(poor_saps)) + return PROCESS_KILL + if(surplus() < crush_cost) + return + var/obj/victim = poor_saps[length(poor_saps)] + if(istype(victim)) //todo handling for other things + if(!length(victim.custom_materials)) + add_load(crush_cost) + victim.atom_destruction() + for(var/obj/object in victim.contents+victim) + for(var/datum/material/possible_mat as anything in object.custom_materials) + var/quantity = object.custom_materials[possible_mat] + object.set_custom_materials(object.custom_materials.Copy() - possible_mat, 1) + var/type_to_use = istype(victim, /obj/item/boulder) ? possible_mat.ore_type : possible_mat.sheet_type + if(quantity < SHEET_MATERIAL_AMOUNT) + if(!(type_to_use in held_mats)) + held_mats[type_to_use] = quantity / SHEET_MATERIAL_AMOUNT + continue + held_mats[type_to_use] += quantity / SHEET_MATERIAL_AMOUNT + continue + var/obj/item/stack/sheet/new_item = new type_to_use(src, quantity / SHEET_MATERIAL_AMOUNT) + if(!send_resource(new_item, dir)) + withholding = new_item + return + else if(isliving(victim)) + var/mob/living/poor_sap = victim + poor_sap.adjustBruteLoss(95, TRUE) + if(!send_resource(poor_sap, dir)) + withholding = poor_sap + return diff --git a/code/modules/manufactorio/machines/debug.dm b/code/modules/manufactorio/machines/debug.dm new file mode 100644 index 0000000000000..7c21cf4e989a7 --- /dev/null +++ b/code/modules/manufactorio/machines/debug.dm @@ -0,0 +1,18 @@ +/obj/loop_spawner + name = "testing loop spawner" + icon = 'icons/obj/machines/mining_machines.dmi' + icon_state = "unloader" + anchored = TRUE + color = COLOR_PURPLE + /// directions we can output to right now + var/to_spawn = /obj/item/screwdriver + /// the subsystem to process us + var/subsystem_to_process_us = /datum/controller/subsystem/processing/obj + +/obj/loop_spawner/Initialize(mapload) + . = ..() + var/datum/controller/subsystem/processing/subsystem = locate(subsystem_to_process_us) in Master.subsystems + START_PROCESSING(subsystem, src) + +/obj/loop_spawner/process(seconds_per_tick) + new to_spawn(get_step(src, dir)) diff --git a/code/modules/manufactorio/machines/lathe.dm b/code/modules/manufactorio/machines/lathe.dm new file mode 100644 index 0000000000000..2669e851b931f --- /dev/null +++ b/code/modules/manufactorio/machines/lathe.dm @@ -0,0 +1,145 @@ +/obj/machinery/power/manufacturing/lathe // this is a heavily gutted autolathe + name = "manufacturing lathe" + desc = "Lathes the set recipe until it runs out of resources. Only accepts sheets or other kinds of material stacks." + icon_state = "lathe" + circuit = /obj/item/circuitboard/machine/manulathe + /// power cost for lathing + var/power_cost = 5 KILO WATTS + /// design id we print + var/design_id + ///The container to hold materials + var/datum/component/material_container/materials + //looping sound for printing items + var/datum/looping_sound/lathe_print/print_sound + ///Designs related to the autolathe + var/datum/techweb/autounlocking/stored_research + /// timer id of printing + var/busy = FALSE + /// our output, if the way out was blocked is held here + var/atom/movable/withheld + +/obj/machinery/power/manufacturing/lathe/Initialize(mapload) + . = ..() + print_sound = new(src, FALSE) + materials = AddComponent( \ + /datum/component/material_container, \ + SSmaterials.materials_by_category[MAT_CATEGORY_ITEM_MATERIAL], \ + SHEET_MATERIAL_AMOUNT * MAX_STACK_SIZE * 2, \ + MATCONTAINER_EXAMINE|MATCONTAINER_NO_INSERT, \ + ) + if(!GLOB.autounlock_techwebs[/datum/techweb/autounlocking/autolathe]) + GLOB.autounlock_techwebs[/datum/techweb/autounlocking/autolathe] = new /datum/techweb/autounlocking/autolathe + stored_research = GLOB.autounlock_techwebs[/datum/techweb/autounlocking/autolathe] + +/obj/machinery/power/manufacturing/lathe/examine(mob/user) + . = ..() + var/datum/design/design + if(!isnull(design_id)) + design = SSresearch.techweb_design_by_id(design_id) + . += span_notice("It is set to print [!isnull(design) ? design.name : "nothing, set with a multitool"].") + if(isnull(design)) + return + . += span_notice("It needs:") + for(var/valid_type in design.materials) + var/atom/ingredient = valid_type + var/amount = design.materials[ingredient] / SHEET_MATERIAL_AMOUNT + + . += "[amount] sheets of [initial(ingredient.name)]" + +/obj/machinery/power/manufacturing/lathe/update_overlays() + . = ..() + . += generate_io_overlays(dir, COLOR_ORANGE) // OUT - stuff in it + . += generate_io_overlays(REVERSE_DIR(dir), COLOR_MODERATE_BLUE) // IN - to crush + +/obj/machinery/power/manufacturing/lathe/Destroy() + . = ..() + stored_research = null + QDEL_NULL(print_sound) + materials = null + QDEL_NULL(withheld) + +/obj/machinery/power/manufacturing/lathe/atom_destruction(damage_flag) + withheld?.Move(drop_location()) + return ..() + +/obj/machinery/power/manufacturing/lathe/receive_resource(atom/movable/receiving, atom/from, receive_dir) + if(!isstack(receiving) || receiving.resistance_flags & INDESTRUCTIBLE || receive_dir != REVERSE_DIR(dir)) + return MANUFACTURING_FAIL + materials.insert_item(receiving) + return MANUFACTURING_SUCCESS + +/obj/machinery/power/manufacturing/lathe/multitool_act(mob/living/user, obj/item/tool) + . = ..() + var/list/name_to_id = list() + for(var/id in stored_research.researched_designs) + var/datum/design/design = SSresearch.techweb_design_by_id(id) + name_to_id[design.name] = id + var/result = tgui_input_list(user, "Select Design", "Select Design", sort_list(name_to_id)) + if(isnull(result)) + return ITEM_INTERACT_FAILURE + design_id = name_to_id[result] + return ITEM_INTERACT_SUCCESS + +/obj/machinery/power/manufacturing/lathe/process() + if(!isnull(withheld) && !send_resource(withheld, dir)) + return + + var/datum/design/design = SSresearch.techweb_design_by_id(design_id) + if(isnull(design) || !(design.build_type & AUTOLATHE)) + return + if(surplus() < power_cost) + finalize_build() + return + //check for materials required. For custom material items decode their required materials + var/list/materials_needed = list() + for(var/material in design.materials) + var/amount_needed = design.materials[material] + if(istext(material)) // category + for(var/datum/material/valid_candidate as anything in SSmaterials.materials_by_category[material]) + if(materials.get_material_amount(valid_candidate) < amount_needed) + continue + material = valid_candidate + break + if(isnull(material)) + return + materials_needed[material] = amount_needed + + if(!materials.has_materials(materials_needed)) + return + + var/craft_time = (design.construction_time * design.lathe_time_factor) ** 0.8 + flick_overlay_view(mutable_appearance(icon, "crafter_printing"), craft_time) + print_sound.start() + add_load(power_cost) + busy = addtimer(CALLBACK(src, PROC_REF(do_make_item), design, materials_needed), craft_time, TIMER_UNIQUE | TIMER_STOPPABLE | TIMER_DELETE_ME) + +/obj/machinery/power/manufacturing/lathe/proc/do_make_item(datum/design/design, list/materials_needed) + finalize_build() + if(surplus() < power_cost) + return + + var/is_stack = ispath(design.build_path, /obj/item/stack) + if(!materials.has_materials(materials_needed)) + return + materials.use_materials(materials_needed) + + var/atom/movable/created + if(is_stack) + var/obj/item/stack/stack_item = initial(design.build_path) + created = new stack_item(null, 1) + else + created = new design.build_path(null) + split_materials_uniformly(materials_needed, target_object = created) + if(isitem(created)) + created.pixel_x = created.base_pixel_x + rand(-6, 6) + created.pixel_y = created.base_pixel_y + rand(-6, 6) + SSblackbox.record_feedback("nested tally", "lathe_printed_items", 1, list("[type]", "[created.type]")) + + if(!send_resource(created, dir)) + withheld = created + + +/obj/machinery/power/manufacturing/lathe/proc/finalize_build() + print_sound.stop() + deltimer(busy) + busy = null diff --git a/code/modules/manufactorio/machines/router.dm b/code/modules/manufactorio/machines/router.dm new file mode 100644 index 0000000000000..8e1c20214339e --- /dev/null +++ b/code/modules/manufactorio/machines/router.dm @@ -0,0 +1,60 @@ +/obj/machinery/power/manufacturing/router // Basically a splitter + name = "manufacturing router" + desc = "Distributes input to 3 output directions equally. Stacks are split, and you may toggle outputs with a multitool. May not receive from other routers." + allow_mob_bump_intake = TRUE + icon_state = "splitter" + circuit = /obj/item/circuitboard/machine/manurouter + /// outputs disabled with a multitool + var/list/disabled_dirs = list() + /// directions we can output to right now + var/list/directions + +/obj/machinery/power/manufacturing/router/Initialize(mapload) + . = ..() + directions = GLOB.cardinals.Copy() + +/obj/machinery/power/manufacturing/router/multitool_act(mob/living/user, obj/item/tool) + . = ..() + var/to_toggle = get_dir(src, user) + if(!(to_toggle in GLOB.cardinals)) + balloon_alert(user, "stand inline!") + return ITEM_INTERACT_FAILURE + if(to_toggle in disabled_dirs) + disabled_dirs -= to_toggle + else + disabled_dirs += to_toggle + update_appearance(UPDATE_OVERLAYS) + balloon_alert(user, "toggled output") + return ITEM_INTERACT_SUCCESS + +/obj/machinery/power/manufacturing/router/update_overlays() + . = ..() + for(var/direction in GLOB.cardinals) + var/variant + if(disabled_dirs.Find(direction)) + variant = "bl" + else + variant = (direction == dir) ? "in" : "out" + var/image/new_overlay = image(icon, "splitter_[variant]", layer = layer+0.001, dir = direction) + . += new_overlay + +/obj/machinery/power/manufacturing/router/receive_resource(obj/receiving, atom/from, receive_dir) + if(istype(from, /obj/machinery/power/manufacturing/router)) + return MANUFACTURING_FAIL + var/list/filtered = directions - receive_dir - disabled_dirs + if(!length(filtered)) + directions = GLOB.cardinals.Copy() + for(var/target in filtered) + directions -= target + if(isstack(receiving)) + receiving = handle_stack(receiving, receive_dir) + if(send_resource(receiving, target)) + dir = receive_dir + update_appearance(UPDATE_OVERLAYS) // im sorry + return MANUFACTURING_SUCCESS + return MANUFACTURING_FAIL_FULL + +/obj/machinery/power/manufacturing/router/proc/handle_stack(obj/item/stack/stack, direction) + if(stack.amount <= 1) // last implementation was just not good so lets cheap out + return stack + return stack.split_stack(amount = 1) diff --git a/code/modules/manufactorio/machines/smelter.dm b/code/modules/manufactorio/machines/smelter.dm new file mode 100644 index 0000000000000..597c9a7b43a50 --- /dev/null +++ b/code/modules/manufactorio/machines/smelter.dm @@ -0,0 +1,59 @@ +/obj/machinery/power/manufacturing/smelter + name = "manufacturing smelter" + desc = "Pretty much incinerates whatever is put into it. Refines ore (not boulders)." + icon_state = "smelter" + circuit = /obj/item/circuitboard/machine/manusmelter + /// power used to smelt + var/power_cost = 4 KILO WATTS + /// our output, if the way out was blocked is held here + var/atom/movable/withheld + +/obj/machinery/power/manufacturing/smelter/update_overlays() + . = ..() + . += generate_io_overlays(dir, COLOR_ORANGE) // OUT - stuff in it + . += generate_io_overlays(REVERSE_DIR(dir), COLOR_MODERATE_BLUE) // IN - to crush + +/obj/machinery/power/manufacturing/smelter/receive_resource(obj/receiving, atom/from, receive_dir) + if(!isitem(receiving) || surplus() < power_cost || receive_dir != REVERSE_DIR(dir)) + return MANUFACTURING_FAIL + var/list/stacks = contents - circuit + if(length(stacks) >= 5 && !may_merge_in_contents_and_do_so(receiving)) + return MANUFACTURING_FAIL_FULL + receiving.Move(src, get_dir(receiving, src)) + START_PROCESSING(SSmanufacturing, src) + return MANUFACTURING_SUCCESS + +/obj/machinery/power/manufacturing/smelter/Destroy() + . = ..() + QDEL_NULL(withheld) + +/obj/machinery/power/manufacturing/smelter/atom_destruction(damage_flag) + withheld?.Move(drop_location()) + return ..() + +/obj/machinery/power/manufacturing/smelter/process(seconds_per_tick) + var/list/stacks = contents - circuit + if(!length(stacks)) + return + + var/list/stacks_preprocess = contents - circuit + var/obj/item/stack/ore/ore = stacks_preprocess[length(stacks_preprocess)] + if(isnull(ore)) + return + if(isnull(withheld) && surplus() >= power_cost) + icon_state="smelter_on" + add_load(power_cost) + if(istype(ore)) + var/obj/item/stack/new_stack = new ore.refined_type(null, min(5, ore.amount), FALSE) + new_stack.moveToNullspace() + ore.use(min(5, ore.amount)) + ore = new_stack + else + ore.fire_act(1400) + withheld = ore + else if(surplus() < power_cost) + icon_state = "smelter" + if(send_resource(withheld, dir)) + withheld = null // nullspace thumbs down + if(!length(contents - circuit)) + return PROCESS_KILL //we finished diff --git a/code/modules/manufactorio/machines/sorter.dm b/code/modules/manufactorio/machines/sorter.dm new file mode 100644 index 0000000000000..b749b14c6d893 --- /dev/null +++ b/code/modules/manufactorio/machines/sorter.dm @@ -0,0 +1,149 @@ +/obj/machinery/power/manufacturing/sorter + icon_state = "router" + name = "conveyor sort-router" + desc = "Pushes things on it to its sides following set criteria, set via multitool." + layer = BELOW_OPEN_DOOR_LAYER + density = FALSE + interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND + circuit = /obj/item/circuitboard/machine/manusorter + /// for mappers; filter path = list(direction, value), otherwise a list of initialized filters + var/list/sort_filters = list() + /// dir to push to if there is no criteria + var/dir_if_not_met + /// timer id of the thing that makes stuff move + var/delay_timerid + /// max filters + var/max_filters = 10 + +/obj/machinery/power/manufacturing/sorter/Initialize(mapload) + . = ..() + if(isnull(dir_if_not_met)) + dir_if_not_met = dir + var/static/list/loc_connections = list( + COMSIG_ATOM_ENTERED = PROC_REF(on_entered), + ) + AddElement(/datum/element/connect_loc, loc_connections) + for(var/i in 1 to length(sort_filters)) + var/creating_type = sort_filters[i] + var/list/values = sort_filters[creating_type] + var/datum/sortrouter_filter/new_type = new creating_type(src) + new_type.dir_target = values[1] + new_type.value = values[2] + sort_filters[i] = new_type + START_PROCESSING(SSobj, src) + +/obj/machinery/power/manufacturing/sorter/Destroy() + . = ..() + QDEL_LIST(sort_filters) + +/obj/machinery/power/manufacturing/sorter/multitool_act(mob/living/user, obj/item/tool) + . = ..() + ui_interact(user) + +/obj/machinery/power/manufacturing/sorter/receive_resource(atom/movable/receiving, atom/from, receive_dir) + if(length(loc.contents) >= MANUFACTURING_TURF_LAG_LIMIT) + return MANUFACTURING_FAIL_FULL + receiving.Move(loc) + return MANUFACTURING_SUCCESS + + +/obj/machinery/power/manufacturing/sorter/ui_data(mob/user) + . = list() + .["unmet_dir"] = dir_if_not_met + .["filters"] = list() + for(var/datum/sortrouter_filter/sorting as anything in sort_filters) + .["filters"] += list(list( + "name" = sorting.return_name(), + "ref" = REF(sorting), + "inverted" = sorting.inverted, + "dir" = sorting.dir_target, + )) + +/obj/machinery/power/manufacturing/sorter/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return + switch(action) + if("del_filter") + var/datum/sortrouter_filter/filter = locate(params["ref"]) + if(isnull(filter)) + return + sort_filters -= filter + qdel(filter) + return TRUE + if("new_filter") + if(length(sort_filters) >= max_filters) + return + var/static/list/filter_by_name + if(!length(filter_by_name)) + filter_by_name = list() + for(var/datum/sortrouter_filter/to_do as anything in subtypesof(/datum/sortrouter_filter)) + filter_by_name[initial(to_do.name)] = to_do + filter_by_name = sort_list(filter_by_name) + var/target_type = tgui_input_list(usr, "Select a filter", "New Filter", filter_by_name) + if(isnull(target_type)|| !usr.can_perform_action(src, ALLOW_SILICON_REACH)) + return + target_type = filter_by_name[target_type] + sort_filters += new target_type(src) + return TRUE + if("rotate") + var/datum/sortrouter_filter/filter = locate(params["ref"]) + if(isnull(filter)) + return + var/next_ind = GLOB.cardinals.Find(filter.dir_target) + 1 + filter.dir_target = GLOB.cardinals[WRAP(next_ind, 1, 5)] + return TRUE + if("rotate_unmet") + var/next_ind = GLOB.cardinals.Find(dir_if_not_met) + 1 + dir_if_not_met = GLOB.cardinals[WRAP(next_ind, 1, 5)] + return TRUE + if("edit") + var/datum/sortrouter_filter/filter = locate(params["ref"]) + if(isnull(filter)) + return + filter.edit(usr) + return TRUE + if("shift") + var/datum/sortrouter_filter/filter = locate(params["ref"]) + if(isnull(filter)) + return + var/next_ind = WRAP(sort_filters.Find(filter) + text2num(params["amount"]), 1, length(sort_filters)+1) + sort_filters -= filter + sort_filters.Insert(next_ind, filter) + return TRUE + +/obj/machinery/power/manufacturing/sorter/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ManufacturingSorter") + ui.open() + +/obj/machinery/power/manufacturing/sorter/proc/send_nomobs(atom/movable/moving, dir) + var/mutable_appearance/operate = mutable_appearance(icon, "router_operate") + operate.dir = dir + flick_overlay_view(operate, 1 SECONDS) + return ismob(moving) ? moving.Move(get_step(src,dir), dir) : send_resource(moving, dir) + +/obj/machinery/power/manufacturing/sorter/process() + if(delay_timerid || !length(loc?.contents - 1)) + return + launch_everything() + +/obj/machinery/power/manufacturing/sorter/proc/on_entered(datum/source, atom/movable/mover) + SIGNAL_HANDLER + if(mover == src || !istype(mover) || mover.anchored || delay_timerid) + return + delay_timerid = addtimer(CALLBACK(src, PROC_REF(launch_everything)), 0.2 SECONDS) + +/obj/machinery/power/manufacturing/sorter/proc/launch_everything() + delay_timerid = null + var/turf/where_we_at = get_turf(src) + for(var/atom/movable/mover as anything in where_we_at.contents) + if(mover.anchored) + continue + for(var/datum/sortrouter_filter/sorting as anything in sort_filters) + if(sorting.meets_conditions(mover) == sorting.inverted) + continue + send_nomobs(mover, sorting.dir_target) + return + send_nomobs(mover, dir_if_not_met) diff --git a/code/modules/manufactorio/machines/sorter_filters.dm b/code/modules/manufactorio/machines/sorter_filters.dm new file mode 100644 index 0000000000000..cb7e31cc41ed4 --- /dev/null +++ b/code/modules/manufactorio/machines/sorter_filters.dm @@ -0,0 +1,120 @@ +/datum/sortrouter_filter + /// name of the filter shown in UI + var/name + /// if it meets criteria, item is pushed to this direction + var/dir_target = NORTH + /// value of our filter, checked by us + var/value = "" + /// is our output inverted? checked by sorter + var/inverted = FALSE + /// the sorter we belong to + var/obj/machinery/power/manufacturing/sorter/sorter + +/datum/sortrouter_filter/New(sorter) + . = ..() + if(isnull(sorter)) + return + src.sorter = sorter + +/datum/sortrouter_filter/Destroy() + . = ..() + if(isnull(sorter)) + return + sorter = null + +/datum/sortrouter_filter + +/datum/sortrouter_filter/proc/return_name() + return name + +/datum/sortrouter_filter/proc/edit(mob/user) + to_chat(user, "This filter is not editable.") + +/datum/sortrouter_filter/proc/meets_conditions(atom/checking) + +/datum/sortrouter_filter/is_stack + name = "input is stack" + +/datum/sortrouter_filter/is_stack/meets_conditions(atom/checking) + return isstack(checking) + +/datum/sortrouter_filter/is_ore + name = "input is ore" + +/datum/sortrouter_filter/is_ore/meets_conditions(atom/checking) + return istype(checking, /obj/item/stack/ore) + +/datum/sortrouter_filter/is_mail + name = "input is mail" + +/datum/sortrouter_filter/is_mail/meets_conditions(atom/checking) + return istype(checking, /obj/item/mail) + +/datum/sortrouter_filter/is_tagged + name = "input is tagged X" + +/datum/sortrouter_filter/is_tagged/edit(mob/user) + var/target = tgui_input_list(user, "Select a tag", "Tag", sort_list(GLOB.TAGGERLOCATIONS)) + if(isnull(target) || !user.can_perform_action(sorter, ALLOW_SILICON_REACH)) + return + value = GLOB.TAGGERLOCATIONS.Find(target) + +/datum/sortrouter_filter/is_tagged/return_name() + return "input is tagged [value ? GLOB.TAGGERLOCATIONS[value] : ""]" + +/datum/sortrouter_filter/is_tagged/meets_conditions(checking) + var/obj/item/delivery/mail_or_delivery = checking + var/sort_tag + if(istype(checking, /obj/item/delivery) || istype(checking, /obj/item/mail)) + sort_tag = mail_or_delivery.sort_tag + + return value == sort_tag + +/datum/sortrouter_filter/name_contains + name = "input's name contains" + +/datum/sortrouter_filter/name_contains/edit(mob/user) + var/target = tgui_input_text(user, "What should it contain?", "Name", value, 12) + if(isnull(target)|| !user.can_perform_action(sorter, ALLOW_SILICON_REACH)) + return + value = target + +/datum/sortrouter_filter/name_contains/return_name() + return "input's name contains [value]" + +/datum/sortrouter_filter/name_contains/meets_conditions(atom/checking) + return findtext(LOWER_TEXT(checking.name), value) + +/datum/sortrouter_filter/is_path_specific + name = "input is specific item" + /// are we currently listening for an item to set as our filter? + var/currently_listening = FALSE + +/datum/sortrouter_filter/is_path_specific/edit(mob/user) + name = initial(name) + if(!currently_listening) + name = "awaiting item" + to_chat(user, "Hit the sorter with the item of choice to set the filter.") + sorter.balloon_alert(user, "awaiting item!") + currently_listening = TRUE + RegisterSignal(sorter, COMSIG_ATOM_ATTACKBY, PROC_REF(sorter_hit)) + else + currently_listening = FALSE + UnregisterSignal(sorter, COMSIG_ATOM_ATTACKBY) + +/datum/sortrouter_filter/is_path_specific/proc/sorter_hit(datum/source, obj/item/attacking_item, user, params) + currently_listening = FALSE + value = attacking_item.type + name = attacking_item.name + sorter.balloon_alert(user, "filter set") + UnregisterSignal(sorter, COMSIG_ATOM_ATTACKBY) + return COMPONENT_NO_AFTERATTACK + +/datum/sortrouter_filter/is_path_specific/meets_conditions(atom/checking) + return checking.type == value + +/datum/sortrouter_filter/is_path_specific/subtypes + name = "input is specific kind of item" + +/datum/sortrouter_filter/is_path_specific/subtypes/meets_conditions(atom/checking) + return istype(checking.type, value) diff --git a/code/modules/manufactorio/machines/storagebox.dm b/code/modules/manufactorio/machines/storagebox.dm new file mode 100644 index 0000000000000..b8a6f5cccac39 --- /dev/null +++ b/code/modules/manufactorio/machines/storagebox.dm @@ -0,0 +1,46 @@ +/obj/machinery/power/manufacturing/storagebox + name = "manufacturing storage unit" + desc = "Its basically a box. Receives resources (if anchored). Needs a machine to take stuff out of without dumping everything out." + icon_state = "box" + /// how much can we hold + var/max_stuff = 16 + +/obj/machinery/power/manufacturing/request_resource() //returns last inserted item + var/list/real_contents = contents - circuit + if(!length(real_contents)) + return + return (real_contents)[length(real_contents)] + +/obj/machinery/power/manufacturing/storagebox/receive_resource(atom/movable/receiving, atom/from, receive_dir) + if(iscloset(receiving) && length(receiving.contents)) + return MANUFACTURING_FAIL + if(length(contents - circuit) >= max_stuff && !may_merge_in_contents_and_do_so(receiving)) + return MANUFACTURING_FAIL_FULL + receiving.Move(src,receive_dir) + return MANUFACTURING_SUCCESS + +/obj/machinery/power/manufacturing/storagebox/container_resist_act(mob/living/user) + . = ..() + user.Move(drop_location()) + +/obj/machinery/power/manufacturing/storagebox/screwdriver_act(mob/living/user, obj/item/tool) + . = NONE + balloon_alert(user, "disassembling...") + if(!do_after(user, 5 SECONDS, src)) + return ITEM_INTERACT_FAILURE + atom_destruction() + return ITEM_INTERACT_SUCCESS + +/obj/machinery/power/manufacturing/storagebox/atom_destruction(damage_flag) + new /obj/item/stack/sheet/iron(drop_location(), 10) + dump_inventory_contents() + return ..() + +/obj/machinery/power/manufacturing/storagebox/attack_hand(mob/living/user, list/modifiers) + . = ..() + if(user.combat_mode) + return + balloon_alert(user, "dumping..") + if(!do_after(user, 1.25 SECONDS, src)) + return + dump_inventory_contents() diff --git a/code/modules/manufactorio/machines/unloader.dm b/code/modules/manufactorio/machines/unloader.dm new file mode 100644 index 0000000000000..982c33582684e --- /dev/null +++ b/code/modules/manufactorio/machines/unloader.dm @@ -0,0 +1,78 @@ +/obj/machinery/power/manufacturing/unloader + name = "manufacturing crate unloader" + desc = "Unloads crates (and ore boxes) passed into it, ejecting the empty crate to the side and its contents forwards. Use a multitool to flip the crate output." + icon = 'icons/obj/machines/mining_machines.dmi' + icon_state = "unloader-corner" + circuit = /obj/item/circuitboard/machine/manuunloader + /// power used per attempt to unload a crate + var/power_to_unload_crate = 2 KILO WATTS + /// whether the side we output unloaded crates is flipped + var/flip_side = FALSE + +/obj/machinery/power/manufacturing/unloader/update_overlays() + . = ..() + . += generate_io_overlays(dir, COLOR_ORANGE) // OUT - stuff in it + . += generate_io_overlays(REVERSE_DIR(dir), COLOR_MODERATE_BLUE) // IN - crate + . += generate_io_overlays(turn(dir, flip_side ? 90 : -90), COLOR_ORANGE) // OUT -- empty crate + +/obj/machinery/power/manufacturing/unloader/request_resource() //returns held crate if someone wants to do that for some reason + var/list/real_contents = contents - circuit + if(!length(real_contents)) + return + return (real_contents)[1] + +/obj/machinery/power/manufacturing/unloader/multitool_act(mob/living/user, obj/item/tool) + . = ..() + balloon_alert(user, "flipped") + flip_side = !flip_side + update_appearance() + +/obj/machinery/power/manufacturing/unloader/receive_resource(obj/receiving, atom/from, receive_dir) + if(surplus() < power_to_unload_crate || receive_dir != REVERSE_DIR(dir)) + return MANUFACTURING_FAIL + var/list/real_contents = contents - circuit + if(length(real_contents)) + return MANUFACTURING_FAIL_FULL + + var/obj/structure/closet/as_closet = receiving + var/obj/structure/ore_box/as_orebox = receiving + if(istype(as_closet)) + if(!as_closet.can_open()) + return MANUFACTURING_FAIL + else if(!istype(as_orebox)) + return MANUFACTURING_FAIL + receiving.Move(src, get_dir(receiving, src)) + START_PROCESSING(SSfastprocess, src) + return MANUFACTURING_SUCCESS + +/obj/machinery/power/manufacturing/unloader/process(seconds_per_tick) + var/list/real_contents = contents - circuit + if(!length(real_contents)) + return PROCESS_KILL + if(surplus() < power_to_unload_crate) + return + add_load(power_to_unload_crate) + var/obj/structure/closet/closet = real_contents[1] + if(istype(closet)) + return unload_crate(closet) + else + return unload_orebox(closet) + +/obj/machinery/power/manufacturing/unloader/proc/unload_crate(obj/structure/closet/closet) + if (!closet.contents_initialized) + closet.contents_initialized = TRUE + closet.PopulateContents() + SEND_SIGNAL(closet, COMSIG_CLOSET_CONTENTS_INITIALIZED) + for(var/atom/thing as anything in closet.contents) + if(ismob(thing)) + continue + send_resource(thing, dir) + if(!length(closet.contents) && send_resource(closet, turn(dir, flip_side ? 90 : -90))) + closet.open(force = TRUE) + return PROCESS_KILL + +/obj/machinery/power/manufacturing/unloader/proc/unload_orebox(obj/structure/ore_box/box) + for(var/atom/thing as anything in box.contents) + send_resource(thing, dir) + if(!length(box.contents) && send_resource(box, turn(dir, flip_side ? 90 : -90))) + return PROCESS_KILL diff --git a/code/modules/mapfluff/ruins/lavalandruin_code/puzzle.dm b/code/modules/mapfluff/ruins/lavalandruin_code/puzzle.dm index ef6dc902c9f08..8501c21cbccf7 100644 --- a/code/modules/mapfluff/ruins/lavalandruin_code/puzzle.dm +++ b/code/modules/mapfluff/ruins/lavalandruin_code/puzzle.dm @@ -160,10 +160,10 @@ var/y = width - round((id - 1) / width) var/x = ((id - 1) % width) + 1 - var/x_start = 1 + (x - 1) * world.icon_size - var/x_end = x_start + world.icon_size - 1 - var/y_start = 1 + ((y - 1) * world.icon_size) - var/y_end = y_start + world.icon_size - 1 + var/x_start = 1 + (x - 1) * ICON_SIZE_X + var/x_end = x_start + ICON_SIZE_X - 1 + var/y_start = 1 + ((y - 1) * ICON_SIZE_Y) + var/y_end = y_start + ICON_SIZE_Y - 1 var/icon/T = new(base_icon) T.Crop(x_start,y_start,x_end,y_end) diff --git a/code/modules/mapfluff/ruins/spaceruin_code/commsbuoy.dm b/code/modules/mapfluff/ruins/spaceruin_code/commsbuoy.dm new file mode 100644 index 0000000000000..895200d487a1b --- /dev/null +++ b/code/modules/mapfluff/ruins/spaceruin_code/commsbuoy.dm @@ -0,0 +1,267 @@ +/obj/structure/fluff/commsbuoy_receiver + name = "interstellar receiver" + desc = "A dish-shaped component of the Comms Buoy used to detect and record interstellar signals." + icon = 'icons/obj/machines/telecomms.dmi' + icon_state = "broadcast receiver" + +/obj/structure/fluff/commsbuoy_processor + name = "comms buoy processor unit" + desc = "This machine is used to process and unscramble interstellar transmissions, to then be relayed and broadcast." + icon = 'icons/obj/machines/telecomms.dmi' + icon_state = "processor" + +/obj/structure/fluff/commsbuoy_broadcaster + name = "interstellar broadcaster" + desc = "A dish-shaped component of the Comms Buoy used to broadcast processed interstellar signals." + icon = 'icons/obj/machines/telecomms.dmi' + icon_state = "broadcaster" + +/obj/structure/fluff/sat_dish + name = "satellite dish" + desc = "I wonder if they get any sports channels out here." + density = FALSE + deconstructible = TRUE + icon = 'icons/obj/fluff/general.dmi' + icon_state = "sat_dish" + +/obj/item/keycard/nt_commsbuoy + name = "Nanotrasen comms buoy keycard" + desc = "A keycard with the NT logo prominently displayed. The last user broke off the end; the card can still swipe, but this won't insert \ + into any chip readers now. On the back, mostly obscured by dried blood, the text \"SPINWARD\" is printed, followed by an illegible ID string." + color = "#4c80b1" + puzzle_id = "nt_commsbuoy" + +/obj/machinery/door/puzzle/keycard/nt_commsbuoy + name = "secure airlock" + puzzle_id = "nt_commsbuoy" + +/area/ruin/space/nt_commsbuoy + name = "\improper Nanotrasen Comms Buoy" + sound_environment = SOUND_AREA_SMALL_ENCLOSED + has_gravity = FALSE + ambientsounds = list( + 'sound/ambience/engineering/ambisin2.ogg', + 'sound/ambience/misc/signal.ogg', + 'sound/ambience/misc/signal.ogg', + 'sound/ambience/general/ambigen9.ogg', + 'sound/ambience/engineering/ambitech.ogg', + 'sound/ambience/engineering/ambitech2.ogg', + 'sound/ambience/engineering/ambitech3.ogg', + 'sound/ambience/misc/ambimystery.ogg', + ) //same ambience as tcommsat + +/obj/item/paper/fluff/ruins/nt_commsbuoy + color = COLOR_BLUE_GRAY + +/obj/item/paper/fluff/ruins/nt_commsbuoy/table_of_contents + name = "Table of Contents: NT-EBCB Model 7" + desc = "The Table of Contents page, text mostly faded. Rest of handbook not included." + default_raw_text = {" +

Nanotrasen Extraorbital Bluespace Communications Buoy Operations Manual

+
PROPERTY OF NANOTRASEN. DO NOT DISTRIBUTE.
+
+

Table of Contents

+ Legal Disclaimers: p1-p6
+ How to Sign: Nondisclosure Agreement: p7
+ Main and Secondary Dish: p8-p10
+ Standard Operation Codes: p11
+ Local-Network Array: p12-p13
+ Interstellar Relay: p14-p27
+ Maintinence: p28-p46
+ Common Error Codes: p47
+ Contacting NT Tech Support: p48-54
+
+ (The page is torn straight along the end of the Table of Contents... wish they'd left the actual Contents.) + "} + +/obj/item/paper/fluff/ruins/nt_commsbuoy/torn_page + name = "Page 33: NT-EBCB Model 7" + desc = "Page 33, torn out and annotated with lots of underlining." + default_raw_text = {" +
PROPERTY OF NANOTRASEN. DO NOT DISTRIBUTE.
+
+ ... is listing any of the mentioned Operation or Error codes. If the shown error is \ + not listed in the manual, please refer to pages 48/54 to contact a Nanotrasen Techician for direct assistance.
+

Realigning the Satellite Dish

+ Now that you have identified the Error code as an alignment issue, repairs will follow a simple step-by-step list. Be sure to follow the \ + list precisely, as additional damage may occur while the dish is misaligned.
+ 1. Assess the outside of the Comms Buoy for any damage or indication of impact to the dish. If any is found, refer to the Replacement Parts subsection\ + on page 43.
+ 2. Before entering the Comms Buoy, collect the Nanotrasen Comms Buoy keycard provided in the front of this manual. This keycard is vital to \ + the repair process, operational efficiency of the Buoy, and in disabling the automated defensive system.
+ 3. Display this card prominently on your persons. This can be done with an official Nanotrasen neck lanyard or Nanotrasen clip-on retractible laynard, \ + worn on your collar, attached to a breast pocket, or on your waist.
+ 4. Enter the Comms Buoy from the designated airlock. There is no system aboard to recycle air, so keep internals and a suit handy in case \ + the Comms Buoy has depressurized.
+ 5. Immediately upon entering the room, be sure to disable the Automated Defense System (refer to page 29). \ + Failiure to follow this step may risk injury or even death.
+ 6. Proceed to the terminal corresponding to the misaligned disk - the Primary Dish controller (pages 8/9) can be located in the room past the Local-Network Array (pages 12/13), \ + while the one closest to the airlock will control the Secondary Dish (page 10).
+ 7. Insert the Nanotrasen Comms Buoy keycard into the slot along the bottom right of the terminal (refer to diagram RD-2). +
+ (The back of the page is covered in blood. A shame, now you can't see the diagram...) + "} + +/obj/item/paper/fluff/ruins/nt_commsbuoy/inspection + name = "Spinward-NT-EBCB Inspection Report" + desc = "A few notes from the pre-activation inspection. Probably shouldn't still be here post-activation." + default_raw_text = {" +

"SS13-Relay" Spinward NT-EBCB Pre-Activation Inspection

+
+ Alright, just a few notes for consideration before we launch this new model. Would really appreciate review and action on the listed items.
+ - Open space on the exterior chassis. Nanotrasen insignia and paint? Could sell advertising space?
+ - The Primary Dish has proven to be sufficient for even severe network loads. Offloading half of its processing to the Secondary just creates \ + a fault risk; isn't this meant to be a backup? Why are we using it at all times?
+ - Interstellar Relay has some outdated encryption. This sat shouldn't have even left CC until this was updated.
+ - Please reconsider deployment location. SS13's local space is not secure enough for untested comms equipment. Combine with above \ + note about encryption, this is a serious security risk.
+ - Turrets are functioning as expected, read the ID correctly as long as the full barcode is unobscured. However, please review: location of \ + turrets. Critical consoles are in the firing line and NOT laser-resistant. No, a backup recorder in the Main Dish is not sufficient.
+ - A note of praise: including a manual with each satellite is very good. Better recommendation might be a console, or something similar \ + which people can't just tear off the corkboard.
+ - I fixed the breaker while I was aboard; it was routing 2kW into lighting and blew them all out. Simple wiring fault. Fix before launching \ + other Model-7s to prevent power issues.
+ - While it's not a habitable satellite, a fax machine might have been handy. Now I have to make sure not to lose these notes during the return \ + trip. +
+
PROPERTY OF NANOTRASEN. DO NOT DISTRIBUTE.
+ "} + +/obj/machinery/computer/terminal/nt_commsbuoy + name = "satellite dish operations terminal" + icon_screen = "comm" + tguitheme = "ntos" + upperinfo = "SATELLITE DISH OPERATIONS READOUT" + content = list( + "10/07/2563 - Inbound Packet Stability - FAIL
\ + Please realign dish!
", + "17/07/2563 - Inbound Packet Stability - FAIL
\ + Please realign dish!
", + "19/07/2563 - Outbound Packet Stability - SUCCESS
", + "24/07/2563 - Inbound Packet Stability - FAIL
\ + Please realign dish!
", + "02/08/2563 - Inbound Packet Stability - FAIL
\ + Please realign dish!
", + "09/08/2563 - Inbound Packet Stability - FAIL
\ + Please realign dish!
", + "13/08/2563 - Secondary Dish reports manual alignment changes.
\ + If this was not intentional, please check the exterior for signs of impact damage!
", + "13/08/2563 - Outbound Packet Stability - SUCCESS
", + "14/08/2563 - Inbound Packet Stability - SUCCESS
\ + Forwarding to Processor for signal restoration.
\ + ... Signal restored, Inbound relayed to Outbound
\ + ... Outbound Packet Stability - SUCCESS
", + "15/08/2563 - Outbound Packet Stability - SUCCESS
", + ) + +/obj/machinery/computer/terminal/nt_commsbuoy/blackbox + name = "blackbox transcription terminal" + upperinfo = "BLACKBOX TRANSCRIPT - 13/08/2563" + content = list( + "Notice: this transcript was generated by Nanotrasen speech-to-text. By reading this transcript you are hereby agreeing to the speech-to-text terms \ + of service, and agree that any fault or inaccuracies in transcriptions legally falls entirely on the speaker.
", + "11:07 - NTSS WAKAHIRU
\ + Yeah, we're close enough. Passing within about a thousand meters of that Buoy that's been having trouble. We can re-route to check on it, I've got \ + an extraorbital engineer aboard. Hell, guy's already looking for the right handbook.
", + "11:08 - NANOTRASEN TRAFFIC CONTROL
\ + Approved, Wakahiru. Redirect per the updated charts coming in on your CDTI, keep your speed below sub-light until further notice. ETA will be 27 minutes. \ + Be sure to follow all Company regulations during repairs, these systems are extremely sensitive and you will be held liable for any new damages.", + "11:10 - NTSS WAKAHIRU
\ + Adjusting course now, and already printing out the waivers. Clearing Broadband.", + "11:11 - NTSS WAKAHIRU - Local
\ + Operations to the Bridge, repeat, Operations to the Bridge.
", + "11:34 - (TRANSPONDER INACTIVE)
\ + Control, I've got a, uh- fish or something chewing through my NAV array, can you guys dispatch a team or something? Bring a, like, big net?", + "11:37 - NANOTRASEN TRAFFIC CONTROL
\ + Negative. Your Transponder is inactive - stop all operations, a Security patrol is being dispatched to your location.", + "11:37 - (TRANSPONDER INACTIVE)
\ + Y'know what, that's close enough. Make sure that they bring some repair tools with them. And a harpoon.
", + "11:40 - NTSS WAKAHIRU - Local
\ + Allllllright, guys, we're at the reported Buoy. NT's Traffic-Con said they've been getting messy data through the relay, too messy to forward. \ + Probably just a misaligned dish. Operations will be dispatching the Away team soon, but otherwise just keep doing whatever it is you're doing.", + "11:47 - Unidentified - Local
\ + This is Away to Wakahiru, how read.", + "11:47 - NTSS WAKAHIRU - Local
\ + Loud and clear Away. What's the hold-up?", + "11:48 - Unidentified - Local
\ + Yeah, uh, this access card doesn't seem to be working on the dish controller. Kept the turrets tame and opened the front door, but \ + the console's not responding to it. Lost that manual page I brought with me too... Huh? One second- Oh, insert it entirely? I don't think- Dude- dude, I know how to put a card into a reader, just let me-", + "11:50 - NT-EBCB-7 ARRAY
\ + ALERT. LIFE FORMS DETECTED WITHOUT VALID IDENTIFICATION. INITIATING DEFENSIVE PROTOCOL.", + "11:50 - Unidentified - Local
\ + SHIIIIIT!! GET THE CARD BACK OUT OF THE CONSOLE! GET IT OUT! G-", + "11:51 - NT-EBCB-7 ARRAY
\ + ALL LIFE FORMS ELIMINATED. HAVE A SECURE DAY!
", + "12:07 - NTSS WAKAHIRU
\ + NT-TC, this is the NTSS Wakahiru. You're, uh... going to need to dispatch a cleanup crew to that satellite. Sending you our Operations report now.", + ) + +/obj/machinery/computer/terminal/nt_commsbuoy/relay + name = "long-range interstellar relay operations terminal" + upperinfo = "LONG-RANGE INTERSTELLAR RELAY OPERATIONS READOUT" + content = list( + "19/07/2563 - Outbound Direct -
\ + From: totally_not_a_burner@kosmokomm.net
\ + To: john_doe_a_deer_a_female_deer@kosmokomm.net
\ +
\ + im telling you! they dont monitor this relay. ive had a bug on the interstellar relay since it was launched. outdated encryption, \ + its an easy tap. just be patient.
\ +
PACKET FLAGGED AS SUSPICIOUS. LOGGING FOR REVIEW.

", + + "13/08/2563 - Outbound Direct -
\ + From: NT_S13TC_OFFICIAL@NTFIDspinward.nt
\ + To: wilson_peters@NTFIDspinward.nt
\ +
\ + Hello,
\ + Your ticket has been marked as Resolved with the following comment:
\ + \"This is Spinward Sector 13 NT Traffic Control, reaching out to inform you that your ticket has been resolved. The relay should now \ + be operating as expected. Please re-attempt sending that message again. If any other issue arises, open a new ticket.\"
\ + Thank you for your patience and continued support.
\ +
The Spinward Project - brought to you by Nanotrasen Futures and Innovation Division, in partnership with Nanotrasen \ + Heavy Industry.

", + + "14/08/2563 - Inbound to Foward -
\ + From: wilson_peters@NTFIDspinward.nt
\ + Relay Target: PORT_ELLIS
\ +
\ + Hey. I miss you. Hope we can holo-call again soon.
\ + Work's been busy. Wish you could be here for it, but I know you were adamant on getting your citizenship. I hope Gateway's been nice to you.
\ + I was working on that project folder you left me, the plasma stuff. Really see why you asked to change divisions...
\ +
\ + Regardless of the heavy topic of the research, I've made some astounding breakthroughs. A majority of this is still your notes just progressing, \ + long-term ingestion of plasma - specifically Pudicitite - in humanoid species. I really had hoped these projections weren't so accurate. \ + Guess it just shows your dazzling intellect... as dark as this is.
\ +
\ + That doomed assistant you had on observation finally expired. The constant medium-level exposure, even treated with a myriad of medications, \ + left the Amygdala extremely malformed like we were seeing prior. Additionally, it entirely and irrepairably destroyed every neural pathway in \ + the Hypothalamus, leaving the subject on a direct path to literally burning out.
\ + The damage to their bodily temperature regulation wasn't the focus, nor did I get much opportunity to make it one. Security had to kill them \ + pre-emptively; their Amygdala is engorged and stained with purple and white streaks (almost as vibrant as your scales). Whatever this damage \ + truly is seems to have contributed to overstimulation and amplified emotional responses to the testing.
\ +
\ + It's... a perfect storm. The loss of control of emotional responses in tandem with the exaggurated environmental stimuli. I've already pushed \ + a few of the results up as high as I can and advised we push towards improving our plasma filtration, especially in masks. Specifically \ + the Mining gas masks, as your papers mentioned - the elevated gas exposure makes them a high risk group.
\ + My peers over here are already adjusting their testing to boost this to Central's attention so that other stations might \ + contribute to improving our protections from this.
\ +
\ + I know you told me to stop messaging you, especially about this - but I thought you deserved to know, of all people. You were right. You were \ + always right. Please... respond. Even just to tell me if *I* did something right.
\ +
The Spinward Project - brought to you by Nanotrasen Futures and Innovation Division, in partnership with Nanotrasen Heavy Industry.

", + + "15/08/2563 - Outbound Direct -
\ + From: totally_not_a_burner@kosmokomm.net
\ + To: john_doe_a_deer_a_female_deer@kosmokomm.net
\ +
\ + IM THE BEST HACKER IN THE GALAXY. youre paying me TRIPLE for that, holy CRAP the syndicate are going to pay us so much. actually you owe me \ + at least half the profits. no no over half i did all the work.
\ + (Attached data file: WEGOTIT.syndzip)
\ +
PACKET FLAGGED AS SUSPICIOUS. BEGINNING TRACE.
\ +
ORIGIN TRACED. NT-DAP DISPATCHED.
\ + DESTINATION TRACED. NT-DAP DISPATCHED.
\ + DATA FILE SCANNED AND FORWARDED TO NT-DAP.
\ +
\ + FILE ORIGIN TRACED TO NT STATION. LOCKDOWN INITIATED.
\ + SECURITY ADVISORY RAISED TO: RED STAR.
\ + NT-DAP DISPATCHED. TARGET: wilson_peters.

", + ) diff --git a/code/modules/mapping/mapping_helpers.dm b/code/modules/mapping/mapping_helpers.dm index 587a62ec0e1b7..55b802cc26c1d 100644 --- a/code/modules/mapping/mapping_helpers.dm +++ b/code/modules/mapping/mapping_helpers.dm @@ -326,9 +326,6 @@ if(target.syndicate_access + target.away_general_access + target.engine_access + target.mixingchamber_access + target.all_access > 1) CRASH("Tried to combine incompatible air alarm access helpers!") - if(target.air_sensor_chamber_id) - target.setup_chamber_link() - target.update_appearance() qdel(src) @@ -418,6 +415,7 @@ /obj/effect/mapping_helpers/airalarm/link name = "airalarm link helper" icon_state = "airalarm_link_helper" + late = TRUE var/chamber_id = "" var/allow_link_change = FALSE @@ -427,13 +425,15 @@ log_mapping("[src] spawned outside of mapload!") return INITIALIZE_HINT_QDEL +/obj/effect/mapping_helpers/airalarm/link/LateInitialize(mapload) var/obj/machinery/airalarm/alarm = locate(/obj/machinery/airalarm) in loc if(!isnull(alarm)) alarm.air_sensor_chamber_id = chamber_id alarm.allow_link_change = allow_link_change + alarm.setup_chamber_link() else log_mapping("[src] failed to find air alarm at [AREACOORD(src)].") - return INITIALIZE_HINT_QDEL + qdel(src) //apc helpers /obj/effect/mapping_helpers/apc diff --git a/code/modules/meteors/meteor_spawning.dm b/code/modules/meteors/meteor_spawning.dm index 83b1c9533c577..17e4746753522 100644 --- a/code/modules/meteors/meteor_spawning.dm +++ b/code/modules/meteors/meteor_spawning.dm @@ -4,7 +4,7 @@ for(var/i in 1 to number) spawn_meteor(meteor_types, direction) -/proc/spawn_meteor(list/meteor_types, direction, atom/target) +/proc/spawn_meteor(list/meteor_types, direction, atom/target, distance_from_edge = 0) if (SSmapping.is_planetary()) stack_trace("Tried to spawn meteors in a map which isn't in space.") return // We're not going to find any space turfs here @@ -18,7 +18,7 @@ else start_side = pick(GLOB.cardinals) var/start_Z = pick(SSmapping.levels_by_trait(ZTRAIT_STATION)) - picked_start = spaceDebrisStartLoc(start_side, start_Z) + picked_start = spaceDebrisStartLoc(start_side, start_Z, distance_from_edge) if(target) if(!isturf(target)) target = get_turf(target) @@ -31,22 +31,22 @@ var/new_meteor = pick_weight(meteor_types) new new_meteor(picked_start, picked_goal) -/proc/spaceDebrisStartLoc(start_side, Z) +/proc/spaceDebrisStartLoc(start_side, Z, distance_from_edge = 0) var/starty var/startx switch(start_side) if(NORTH) - starty = world.maxy-(TRANSITIONEDGE + MAP_EDGE_PAD) - startx = rand((TRANSITIONEDGE + MAP_EDGE_PAD), world.maxx-(TRANSITIONEDGE + MAP_EDGE_PAD)) + starty = world.maxy - (TRANSITIONEDGE + MAP_EDGE_PAD) - distance_from_edge + startx = rand((TRANSITIONEDGE + MAP_EDGE_PAD + distance_from_edge), world.maxx-(TRANSITIONEDGE + MAP_EDGE_PAD + distance_from_edge)) if(EAST) - starty = rand((TRANSITIONEDGE + MAP_EDGE_PAD),world.maxy-(TRANSITIONEDGE + MAP_EDGE_PAD)) - startx = world.maxx-(TRANSITIONEDGE + MAP_EDGE_PAD) + starty = rand((TRANSITIONEDGE + MAP_EDGE_PAD + distance_from_edge),world.maxy-(TRANSITIONEDGE + MAP_EDGE_PAD + distance_from_edge)) + startx = world.maxx-(TRANSITIONEDGE + MAP_EDGE_PAD) - distance_from_edge if(SOUTH) - starty = (TRANSITIONEDGE + MAP_EDGE_PAD) - startx = rand((TRANSITIONEDGE + MAP_EDGE_PAD), world.maxx-(TRANSITIONEDGE + MAP_EDGE_PAD)) + starty = (TRANSITIONEDGE + MAP_EDGE_PAD) + distance_from_edge + startx = rand((TRANSITIONEDGE + MAP_EDGE_PAD + distance_from_edge), world.maxx-(TRANSITIONEDGE + MAP_EDGE_PAD + distance_from_edge)) if(WEST) - starty = rand((TRANSITIONEDGE + MAP_EDGE_PAD), world.maxy-(TRANSITIONEDGE + MAP_EDGE_PAD)) - startx = (TRANSITIONEDGE + MAP_EDGE_PAD) + starty = rand((TRANSITIONEDGE + MAP_EDGE_PAD + distance_from_edge), world.maxy-(TRANSITIONEDGE + MAP_EDGE_PAD + distance_from_edge)) + startx = (TRANSITIONEDGE + MAP_EDGE_PAD) + distance_from_edge . = locate(startx, starty, Z) /proc/spaceDebrisFinishLoc(startSide, Z) diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm index 40cb967d3a0ab..10b2fbe71d062 100644 --- a/code/modules/mining/abandoned_crates.dm +++ b/code/modules/mining/abandoned_crates.dm @@ -246,7 +246,7 @@ new /obj/item/clothing/mask/balaclava(src) new /obj/item/gun/ballistic/shotgun/toy(src) new /obj/item/gun/ballistic/automatic/pistol/toy(src) - new /obj/item/gun/ballistic/automatic/toy/unrestricted(src) + new /obj/item/gun/ballistic/automatic/toy(src) new /obj/item/gun/ballistic/automatic/l6_saw/toy/unrestricted(src) new /obj/item/ammo_box/foambox(src) if(98) diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm index af31d32719f14..c2dffd37ee533 100644 --- a/code/modules/mining/equipment/explorer_gear.dm +++ b/code/modules/mining/equipment/explorer_gear.dm @@ -61,7 +61,6 @@ actions_types = list(/datum/action/item_action/adjust) armor_type = /datum/armor/gas_explorer resistance_flags = FIRE_PROOF - has_fov = FALSE /datum/armor/gas_explorer melee = 10 @@ -293,6 +292,7 @@ /obj/item/clothing/suit/hooded/cloak/godslayer/Initialize(mapload) . = ..() allowed = GLOB.mining_suit_allowed + AddComponent(/datum/component/item_equipped_movement_rustle, SFX_PLATE_ARMOR_RUSTLE, 8) /obj/item/clothing/head/hooded/cloakhood/godslayer name = "godslayer helm" diff --git a/code/modules/mining/lavaland/tendril_loot.dm b/code/modules/mining/lavaland/tendril_loot.dm index af1b990a6fb6a..7acc0299f1018 100644 --- a/code/modules/mining/lavaland/tendril_loot.dm +++ b/code/modules/mining/lavaland/tendril_loot.dm @@ -735,6 +735,7 @@ . = ..() ADD_TRAIT(src, TRAIT_NODROP, LOCKED_HELMET_TRAIT) AddComponent(/datum/component/armor_plate, maxamount = 1, upgrade_item = /obj/item/drake_remains, armor_mod = /datum/armor/drake_empowerment, upgrade_prefix = "empowered") + AddComponent(/datum/component/item_equipped_movement_rustle, SFX_PLATE_ARMOR_RUSTLE, 8) /obj/item/clothing/head/hooded/berserker/examine() . = ..() diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index 7ad08083df3a8..0b051248a3966 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -442,14 +442,13 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ pixel_x = base_pixel_x + rand(0, 16) - 8 pixel_y = base_pixel_y + rand(0, 8) - 8 -/obj/item/coin/set_custom_materials(list/materials, multiplier = 1) +/obj/item/coin/finalize_material_effects(list/materials) . = ..() if(override_material_worth) return value = 0 - for(var/i in custom_materials) - var/datum/material/M = i - value += M.value_per_unit * custom_materials[M] + for(var/datum/material/material as anything in materials) + value += material.value_per_unit * materials[material][MATERIAL_LIST_OPTIMAL_AMOUNT] /obj/item/coin/get_item_credit_value() return value diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm index 4d74e029860a6..17591d93d5221 100644 --- a/code/modules/mob/dead/dead.dm +++ b/code/modules/mob/dead/dead.dm @@ -76,7 +76,8 @@ INITIALIZE_IMMEDIATE(/mob/dead) var/client/C = client to_chat(C, span_notice("Sending you to [pick].")) - new /atom/movable/screen/splash(null, null, C) + var/atom/movable/screen/splash/S = new(null, null, C) + S.Fade(FALSE) ADD_TRAIT(src, TRAIT_NO_TRANSFORM, SERVER_HOPPER_TRAIT) sleep(2.9 SECONDS) //let the animation play diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 80f7be5e3180e..5567162d8bd78 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -483,7 +483,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp var/list/icon_dimensions = get_icon_dimensions(target.icon) var/orbitsize = (icon_dimensions["width"] + icon_dimensions["height"]) * 0.5 - orbitsize -= (orbitsize/world.icon_size)*(world.icon_size*0.25) + orbitsize -= (orbitsize/ICON_SIZE_ALL)*(ICON_SIZE_ALL*0.25) var/rot_seg @@ -1061,31 +1061,14 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/dead/observer/proc/tray_view() set category = "Ghost" - set name = "T-ray view" - set desc = "Toggles a view of sub-floor objects" + set name = "T-ray scan" + set desc = "Perfom a scan to view sub-floor objects" - var/static/t_ray_view = FALSE - if(SSlag_switch.measures[DISABLE_GHOST_ZOOM_TRAY] && !client?.holder && !t_ray_view) + if(SSlag_switch.measures[DISABLE_GHOST_ZOOM_TRAY] && !client?.holder) to_chat(usr, span_notice("That verb is currently globally disabled.")) return - t_ray_view = !t_ray_view - - var/list/t_ray_images = list() - var/static/list/stored_t_ray_images = list() - for(var/obj/O in orange(client.view, src) ) - if(HAS_TRAIT(O, TRAIT_T_RAY_VISIBLE)) - var/image/I = new(loc = get_turf(O)) - var/mutable_appearance/MA = new(O) - MA.alpha = 128 - MA.dir = O.dir - I.appearance = MA - t_ray_images += I - stored_t_ray_images += t_ray_images - if(length(t_ray_images)) - if(t_ray_view) - client.images += t_ray_images - else - client.images -= stored_t_ray_images + + t_ray_scan(src) /mob/dead/observer/default_lighting_cutoff() var/datum/preferences/prefs = client?.prefs diff --git a/code/modules/mob/living/basic/bots/bot_hud.dm b/code/modules/mob/living/basic/bots/bot_hud.dm index 345fcd2bbe7bf..6cb3f6bcd01b0 100644 --- a/code/modules/mob/living/basic/bots/bot_hud.dm +++ b/code/modules/mob/living/basic/bots/bot_hud.dm @@ -1,13 +1,13 @@ /mob/living/basic/bot/proc/diag_hud_set_bothealth() var/image/holder = hud_list[DIAG_HUD] var/icon/icon_image = icon(icon, icon_state, dir) - holder.pixel_y = icon_image.Height() - world.icon_size + holder.pixel_y = icon_image.Height() - ICON_SIZE_Y holder.icon_state = "huddiag[RoundDiagBar(health/maxHealth)]" /mob/living/basic/bot/proc/diag_hud_set_botstat() //On (With wireless on or off), Off, EMP'ed var/image/holder = hud_list[DIAG_STAT_HUD] var/icon/our_icon = icon(icon, icon_state, dir) - holder.pixel_y = our_icon.Height() - world.icon_size + holder.pixel_y = our_icon.Height() - ICON_SIZE_Y if(bot_mode_flags & BOT_MODE_ON) holder.icon_state = "hudstat" return @@ -19,7 +19,7 @@ /mob/living/basic/bot/proc/diag_hud_set_botmode() //Shows a bot's current operation var/image/holder = hud_list[DIAG_BOT_HUD] var/icon/icon_image = icon(icon, icon_state, dir) - holder.pixel_y = icon_image.Height() - world.icon_size + holder.pixel_y = icon_image.Height() - ICON_SIZE_Y if(client) //If the bot is player controlled, it will not be following mode logic! holder.icon_state = "hudsentient" return diff --git a/code/modules/mob/living/basic/bots/hygienebot/hygienebot_ai.dm b/code/modules/mob/living/basic/bots/hygienebot/hygienebot_ai.dm index 2c614e003c8ab..f678843c7ccb9 100644 --- a/code/modules/mob/living/basic/bots/hygienebot/hygienebot_ai.dm +++ b/code/modules/mob/living/basic/bots/hygienebot/hygienebot_ai.dm @@ -12,6 +12,7 @@ planning_subtrees = list( /datum/ai_planning_subtree/manage_unreachable_list, /datum/ai_planning_subtree/respond_to_summon, + /datum/ai_planning_subtree/handle_trash_talk, /datum/ai_planning_subtree/wash_people, /datum/ai_planning_subtree/salute_authority, /datum/ai_planning_subtree/find_patrol_beacon, @@ -23,16 +24,27 @@ BB_BOT_SUMMON_TARGET, ) -/datum/ai_controller/basic_controller/bot/hygienebot/TryPossessPawn(atom/new_pawn) - . = ..() - if(. & AI_CONTROLLER_INCOMPATIBLE) +/datum/ai_planning_subtree/handle_trash_talk + +/datum/ai_planning_subtree/handle_trash_talk/SelectBehaviors(datum/ai_controller/basic_controller/bot/controller, seconds_per_tick) + if(!controller.blackboard_key_exists(BB_WASH_TARGET)) return - RegisterSignal(new_pawn, COMSIG_AI_BLACKBOARD_KEY_CLEARED(BB_WASH_TARGET), PROC_REF(reset_anger)) + controller.queue_behavior(/datum/ai_behavior/commence_trashtalk, BB_WASH_TARGET) -/datum/ai_controller/basic_controller/bot/hygienebot/proc/reset_anger() - SIGNAL_HANDLER +/datum/ai_behavior/commence_trashtalk + action_cooldown = 4 SECONDS - set_blackboard_key(BB_WASH_FRUSTRATION, 0) +/datum/ai_behavior/commence_trashtalk/perform(seconds_per_tick, datum/ai_controller/controller, target_key) + if(!controller.blackboard_key_exists(target_key)) + return AI_BEHAVIOR_FAILED | AI_BEHAVIOR_DELAY + + var/frustration_count = controller.blackboard[BB_WASH_FRUSTRATION] + controller.set_blackboard_key(BB_WASH_FRUSTRATION, min(frustration_count + 1, BOT_FRUSTRATION_LIMIT)) + if(controller.blackboard[BB_WASH_FRUSTRATION] < BOT_ANGER_THRESHOLD) + return AI_BEHAVIOR_FAILED | AI_BEHAVIOR_DELAY + var/datum/action/cooldown/bot_announcement/announcement = controller.blackboard[BB_ANNOUNCE_ABILITY] + announcement?.announce(pick(controller.blackboard[BB_WASH_THREATS])) + return AI_BEHAVIOR_SUCCEEDED | AI_BEHAVIOR_DELAY /datum/ai_planning_subtree/wash_people @@ -85,8 +97,6 @@ controller.set_blackboard_key(target_key, found_target) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED - - /datum/ai_behavior/find_valid_wash_targets/finish_action(datum/ai_controller/controller, succeeded, target_key) . = ..() if(!succeeded) @@ -95,9 +105,8 @@ announcement.announce(pick(controller.blackboard[BB_WASH_FOUND])) /datum/ai_behavior/wash_target - behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION | AI_BEHAVIOR_MOVE_AND_PERFORM + behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION required_distance = 0 - action_cooldown = 1 SECONDS /datum/ai_behavior/wash_target/setup(datum/ai_controller/controller, target_key) . = ..() @@ -117,25 +126,17 @@ living_pawn.melee_attack(unclean_target) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED - var/frustration_count = controller.blackboard[BB_WASH_FRUSTRATION] - controller.set_blackboard_key(BB_WASH_FRUSTRATION, frustration_count + 1) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED /datum/ai_behavior/wash_target/finish_action(datum/ai_controller/controller, succeeded, target_key) . = ..() - var/datum/action/cooldown/bot_announcement/announcement = controller.blackboard[BB_ANNOUNCE_ABILITY] - - if(succeeded) - if(controller.blackboard[BB_WASH_FRUSTRATION] > BOT_ANGER_THRESHOLD) - announcement.announce(pick(controller.blackboard[BB_WASH_DONE])) - controller.clear_blackboard_key(target_key) + controller.clear_blackboard_key(target_key) + var/wash_frustration = controller.blackboard[BB_WASH_FRUSTRATION] + controller.clear_blackboard_key(BB_WASH_FRUSTRATION) + if(!succeeded || wash_frustration <= BOT_ANGER_THRESHOLD) return - - if(controller.blackboard[BB_WASH_FRUSTRATION] < BOT_FRUSTRATION_LIMIT) - return - - announcement.announce(pick(controller.blackboard[BB_WASH_THREATS])) - controller.set_blackboard_key(BB_WASH_FRUSTRATION, 0) + var/datum/action/cooldown/bot_announcement/announcement = controller.blackboard[BB_ANNOUNCE_ABILITY] + announcement.announce(pick(controller.blackboard[BB_WASH_DONE])) #undef BOT_ANGER_THRESHOLD #undef BOT_FRUSTRATION_LIMIT diff --git a/code/modules/mob/living/basic/drone/_drone.dm b/code/modules/mob/living/basic/drone/_drone.dm index 12e3125581f14..fe5dbb4d2d5a3 100644 --- a/code/modules/mob/living/basic/drone/_drone.dm +++ b/code/modules/mob/living/basic/drone/_drone.dm @@ -131,9 +131,9 @@ /obj/item/weldingtool/drone, /obj/item/wirecutters/drone, /obj/item/multitool/drone, - /obj/item/pipe_dispenser, - /obj/item/t_scanner, - /obj/item/analyzer, + /obj/item/pipe_dispenser/drone, + /obj/item/t_scanner/drone, + /obj/item/analyzer/drone, /obj/item/rack_parts, ) /// whitelisted drone items, recursive/includes descendants @@ -221,13 +221,13 @@ /mob/living/basic/drone/med_hud_set_health() var/image/holder = hud_list[DIAG_HUD] var/icon/hud_icon = icon(icon, icon_state, dir) - holder.pixel_y = hud_icon.Height() - world.icon_size + holder.pixel_y = hud_icon.Height() - ICON_SIZE_Y holder.icon_state = "huddiag[RoundDiagBar(health/maxHealth)]" /mob/living/basic/drone/med_hud_set_status() var/image/holder = hud_list[DIAG_STAT_HUD] var/icon/hud_icon = icon(icon, icon_state, dir) - holder.pixel_y = hud_icon.Height() - world.icon_size + holder.pixel_y = hud_icon.Height() - ICON_SIZE_Y if(stat == DEAD) holder.icon_state = "huddead2" else if(incapacitated) diff --git a/code/modules/mob/living/basic/drone/drone_tools.dm b/code/modules/mob/living/basic/drone/drone_tools.dm index 7effefcd7f906..b55b438362a9d 100644 --- a/code/modules/mob/living/basic/drone/drone_tools.dm +++ b/code/modules/mob/living/basic/drone/drone_tools.dm @@ -3,31 +3,14 @@ desc = "Access your built-in tools." icon = 'icons/hud/screen_drone.dmi' icon_state = "tool_storage" + storage_type = /datum/storage/drone item_flags = ABSTRACT resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF /obj/item/storage/drone_tools/Initialize(mapload) . = ..() - ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) - - var/static/list/drone_builtins = list( - /obj/item/crowbar/drone, - /obj/item/screwdriver/drone, - /obj/item/wrench/drone, - /obj/item/weldingtool/drone, - /obj/item/wirecutters/drone, - /obj/item/multitool/drone, - /obj/item/pipe_dispenser, - /obj/item/t_scanner, - /obj/item/analyzer, - /obj/item/soap/drone, - ) - atom_storage.max_total_storage = 40 - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.max_slots = 10 - atom_storage.do_rustle = FALSE - atom_storage.set_holdable(drone_builtins) + ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) /obj/item/storage/drone_tools/PopulateContents() var/list/builtintools = list() @@ -37,14 +20,14 @@ builtintools += new /obj/item/weldingtool/drone(src) builtintools += new /obj/item/wirecutters/drone(src) builtintools += new /obj/item/multitool/drone(src) - builtintools += new /obj/item/pipe_dispenser(src) - builtintools += new /obj/item/t_scanner(src) - builtintools += new /obj/item/analyzer(src) + builtintools += new /obj/item/pipe_dispenser/drone(src) + builtintools += new /obj/item/t_scanner/drone(src) + builtintools += new /obj/item/analyzer/drone(src) builtintools += new /obj/item/soap/drone(src) + for(var/obj/item/tool as anything in builtintools) tool.AddComponent(/datum/component/holderloving, src, TRUE) - /obj/item/crowbar/drone name = "built-in crowbar" desc = "A crowbar built into your chassis." @@ -103,3 +86,18 @@ icon_state = "toolkit_engiborg_multitool" item_flags = NO_MAT_REDEMPTION toolspeed = 0.5 + +/obj/item/analyzer/drone + name = "digital gas analyzer" + desc = "A gas analyzer built into your chassis." + item_flags = NO_MAT_REDEMPTION + +/obj/item/t_scanner/drone + name = "digital T-ray scanner" + desc = "A T-ray scanner built into your chassis." + item_flags = NO_MAT_REDEMPTION + +/obj/item/pipe_dispenser/drone + name = "built-in rapid pipe dispenser" + desc = "A rapid pipe dispenser built into your chassis." + item_flags = NO_MAT_REDEMPTION diff --git a/code/modules/mob/living/basic/farm_animals/bee/_bee.dm b/code/modules/mob/living/basic/farm_animals/bee/_bee.dm index 3c2aae36bc1d0..53f9c618c637b 100644 --- a/code/modules/mob/living/basic/farm_animals/bee/_bee.dm +++ b/code/modules/mob/living/basic/farm_animals/bee/_bee.dm @@ -100,13 +100,8 @@ return ..() /mob/living/basic/bee/death(gibbed) - if(beehome) - beehome.bees -= src - beehome = null - beegent = null - if(flags_1 & HOLOGRAM_1 || gibbed) - return ..() - spawn_corpse() + if(!(flags_1 & HOLOGRAM_1) && !gibbed) + spawn_corpse() return ..() /// Leave something to remember us by diff --git a/code/modules/mob/living/basic/farm_animals/bee/bee_ai_behavior.dm b/code/modules/mob/living/basic/farm_animals/bee/bee_ai_behavior.dm index b4d73ad59273a..77fa9ce8ca088 100644 --- a/code/modules/mob/living/basic/farm_animals/bee/bee_ai_behavior.dm +++ b/code/modules/mob/living/basic/farm_animals/bee/bee_ai_behavior.dm @@ -26,14 +26,12 @@ /datum/ai_behavior/enter_exit_hive/perform(seconds_per_tick, datum/ai_controller/controller, target_key, attack_key) var/obj/structure/beebox/current_home = controller.blackboard[target_key] - var/mob/living/bee_pawn = controller.pawn var/atom/attack_target = controller.blackboard[attack_key] if(attack_target) // forget about who we attacking when we go home controller.clear_blackboard_key(attack_key) - var/datum/callback/callback = CALLBACK(bee_pawn, TYPE_PROC_REF(/mob/living/basic/bee, handle_habitation), current_home) - callback.Invoke() + controller.ai_interact(target = current_home, combat_mode = FALSE) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED /datum/ai_behavior/inhabit_hive @@ -53,8 +51,7 @@ if(!potential_home.habitable(bee_pawn)) //the house become full before we get to it return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED - var/datum/callback/callback = CALLBACK(bee_pawn, TYPE_PROC_REF(/mob/living/basic/bee, handle_habitation), potential_home) - callback.Invoke() + controller.ai_interact(target = potential_home, combat_mode = FALSE) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED /datum/ai_behavior/inhabit_hive/finish_action(datum/ai_controller/controller, succeeded, target_key) diff --git a/code/modules/mob/living/basic/farm_animals/chicken/chick.dm b/code/modules/mob/living/basic/farm_animals/chicken/chick.dm index 9e4af384aeeff..7ddf86b0cfb7f 100644 --- a/code/modules/mob/living/basic/farm_animals/chicken/chick.dm +++ b/code/modules/mob/living/basic/farm_animals/chicken/chick.dm @@ -33,6 +33,18 @@ /// What we grow into. var/grow_as = /mob/living/basic/chicken +/datum/emote/chick + mob_type_allowed_typecache = /mob/living/basic/chick + mob_type_blacklist_typecache = list() + +/datum/emote/chick/chirp + key = "chirp" + key_third_person = "chirps" + message = "chirps!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + vary = TRUE + sound = 'sound/mobs/non-humanoids/chicken/chick_peep.ogg' + /mob/living/basic/chick/Initialize(mapload) . = ..() pixel_x = base_pixel_x + rand(-6, 6) @@ -40,7 +52,7 @@ ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) - AddElement(/datum/element/pet_bonus, "chirps!") + AddElement(/datum/element/pet_bonus, "chirp") AddElement(/datum/element/swabable, CELL_LINE_TABLE_CHICKEN, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5) AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW) diff --git a/code/modules/mob/living/basic/farm_animals/chicken/chicken.dm b/code/modules/mob/living/basic/farm_animals/chicken/chicken.dm index 9508f8fae3be6..4f83608b9d64c 100644 --- a/code/modules/mob/living/basic/farm_animals/chicken/chicken.dm +++ b/code/modules/mob/living/basic/farm_animals/chicken/chicken.dm @@ -38,12 +38,24 @@ GLOBAL_VAR_INIT(chicken_count, 0) ///boolean deciding whether eggs laid by this chicken can hatch into chicks var/fertile = TRUE +/datum/emote/chicken + mob_type_allowed_typecache = /mob/living/basic/chicken + mob_type_blacklist_typecache = list() + +/datum/emote/chicken/cluck + key = "cluck" + key_third_person = "clucks" + message = "clucks happily!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + vary = TRUE + sound = 'sound/mobs/non-humanoids/chicken/bagawk.ogg' + /mob/living/basic/chicken/Initialize(mapload) . = ..() GLOB.chicken_count++ ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) AddElement(/datum/element/ai_retaliate) - AddElement(/datum/element/pet_bonus, "clucks happily!") + AddElement(/datum/element/pet_bonus, "cluck") AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW) AddElement(/datum/element/swabable, CELL_LINE_TABLE_CHICKEN, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5) AddElement(/datum/element/animal_variety, "chicken", pick("brown", "black", "white"), modify_pixels = TRUE) diff --git a/code/modules/mob/living/basic/farm_animals/cow/_cow.dm b/code/modules/mob/living/basic/farm_animals/cow/_cow.dm index fadac576ea599..5c771e72bad15 100644 --- a/code/modules/mob/living/basic/farm_animals/cow/_cow.dm +++ b/code/modules/mob/living/basic/farm_animals/cow/_cow.dm @@ -36,13 +36,25 @@ /// What kind of juice do we produce? var/milked_reagent = /datum/reagent/consumable/milk +/datum/emote/cow + mob_type_allowed_typecache = /mob/living/basic/cow + mob_type_blacklist_typecache = list() + +/datum/emote/cow/moo + key = "moo" + key_third_person = "moos" + message = "moos happily!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + vary = TRUE + sound = 'sound/mobs/non-humanoids/cow/cow.ogg' + /mob/living/basic/cow/Initialize(mapload) AddComponent(/datum/component/tippable, \ tip_time = 0.5 SECONDS, \ untip_time = 0.5 SECONDS, \ self_right_time = rand(25 SECONDS, 50 SECONDS), \ post_tipped_callback = CALLBACK(src, PROC_REF(after_cow_tipped))) - AddElement(/datum/element/pet_bonus, "moos happily!") + AddElement(/datum/element/pet_bonus, "moo") AddElement(/datum/element/swabable, CELL_LINE_TABLE_COW, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5) setup_udder() setup_eating() diff --git a/code/modules/mob/living/basic/farm_animals/pig.dm b/code/modules/mob/living/basic/farm_animals/pig.dm index d0fbb5a82473a..c3cfc57ac0522 100644 --- a/code/modules/mob/living/basic/farm_animals/pig.dm +++ b/code/modules/mob/living/basic/farm_animals/pig.dm @@ -28,9 +28,20 @@ blood_volume = BLOOD_VOLUME_NORMAL ai_controller = /datum/ai_controller/basic_controller/pig +/datum/emote/pig + mob_type_allowed_typecache = /mob/living/basic/pig + mob_type_blacklist_typecache = list() + +/datum/emote/pig/oink + key = "oink" + key_third_person = "oinks" + message = "oinks!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + vary = TRUE + sound = SFX_PIG_OINK /mob/living/basic/pig/Initialize(mapload) . = ..() - AddElement(/datum/element/pet_bonus, "oinks!") + AddElement(/datum/element/pet_bonus, "oink") AddElement(/datum/element/ai_retaliate) AddElement(/datum/element/ai_flee_while_injured) make_tameable() diff --git a/code/modules/mob/living/basic/farm_animals/pony.dm b/code/modules/mob/living/basic/farm_animals/pony.dm index 29672e032c84b..a39fd328f1116 100644 --- a/code/modules/mob/living/basic/farm_animals/pony.dm +++ b/code/modules/mob/living/basic/farm_animals/pony.dm @@ -33,11 +33,23 @@ /// Greyscale color config; 1st color is body, 2nd is mane var/list/ponycolors = list("#cc8c5d", "#cc8c5d") +/datum/emote/pony + mob_type_allowed_typecache = /mob/living/basic/pony + mob_type_blacklist_typecache = list() + +/datum/emote/pony/whicker + key = "whicker" + key_third_person = "whickers" + message = "whickers." + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + vary = TRUE + sound = 'sound/mobs/non-humanoids/pony/snort.ogg' + /mob/living/basic/pony/Initialize(mapload) . = ..() apply_colour() - AddElement(/datum/element/pet_bonus, "whickers.") + AddElement(/datum/element/pet_bonus, "whicker") AddElement(/datum/element/ai_retaliate) AddElement(/datum/element/ai_flee_while_injured) AddElementTrait(TRAIT_WADDLING, INNATE_TRAIT, /datum/element/waddling) diff --git a/code/modules/mob/living/basic/farm_animals/rabbit.dm b/code/modules/mob/living/basic/farm_animals/rabbit.dm index dec48ea8be4af..c667ac311cdf9 100644 --- a/code/modules/mob/living/basic/farm_animals/rabbit.dm +++ b/code/modules/mob/living/basic/farm_animals/rabbit.dm @@ -39,10 +39,20 @@ /// passed to animal_varity as the prefix icon. var/icon_prefix = "rabbit" +/datum/emote/rabbit + mob_type_allowed_typecache = /mob/living/basic/rabbit + mob_type_blacklist_typecache = list() + +/datum/emote/rabbit + key = "hop" + key_third_person = "hops" + message = "hops around happily!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + /mob/living/basic/rabbit/Initialize(mapload) . = ..() AddElement(/datum/element/ai_retaliate) - AddElement(/datum/element/pet_bonus, "hops around happily!") + AddElement(/datum/element/pet_bonus, "hop") AddElement(/datum/element/animal_variety, icon_prefix, pick("brown", "black", "white"), TRUE) if(prob(20)) // bunny name = "bunny" diff --git a/code/modules/mob/living/basic/heretic/fire_shark.dm b/code/modules/mob/living/basic/heretic/fire_shark.dm index e65fefc235e59..1ac4ccb7b237a 100644 --- a/code/modules/mob/living/basic/heretic/fire_shark.dm +++ b/code/modules/mob/living/basic/heretic/fire_shark.dm @@ -30,4 +30,5 @@ AddComponent(/datum/component/swarming) AddComponent(/datum/component/regenerator, outline_colour = COLOR_DARK_RED) ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT) + ADD_TRAIT(src, TRAIT_FREE_HYPERSPACE_MOVEMENT, INNATE_TRAIT) ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) diff --git a/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm index 53d7e7191ef05..33d091db4e4b1 100644 --- a/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm +++ b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm @@ -21,7 +21,7 @@ /datum/ai_planning_subtree/find_and_hunt_target/corpses/ice_whelp target_key = BB_TARGET_CANNIBAL finding_behavior = /datum/ai_behavior/find_hunt_target/corpses/dragon_corpse - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/dragon_cannibalise + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/dragon_cannibalise hunt_targets = list(/mob/living/basic/mining/ice_whelp) hunt_range = 10 @@ -32,10 +32,10 @@ return FALSE return ..() -/datum/ai_behavior/hunt_target/unarmed_attack_target/dragon_cannibalise +/datum/ai_behavior/hunt_target/interact_with_target/dragon_cannibalise behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION -/datum/ai_behavior/hunt_target/unarmed_attack_target/dragon_cannibalise/perform(seconds_per_tick, datum/ai_controller/controller, target_key, attack_key) +/datum/ai_behavior/hunt_target/interact_with_target/dragon_cannibalise/perform(seconds_per_tick, datum/ai_controller/controller, target_key, attack_key) var/mob/living/target = controller.blackboard[target_key] if(QDELETED(target) || target.stat != DEAD || target.pulledby) //we were too slow return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED @@ -66,20 +66,14 @@ set_movement_target(controller, target) /datum/ai_behavior/sculpt_statue/perform(seconds_per_tick, datum/ai_controller/controller, target_key) - var/atom/target = controller.blackboard[target_key] - var/mob/living/basic/living_pawn = controller.pawn - - if(QDELETED(target)) + if(!controller.ai_interact(target = target_key, combat_mode = FALSE)) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED - - living_pawn.melee_attack(target) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED /datum/ai_behavior/sculpt_statue/finish_action(datum/ai_controller/controller, succeeded, target_key) . = ..() controller.clear_blackboard_key(target_key) - //subtree to use our attacks on the victim /datum/ai_planning_subtree/targeted_mob_ability/ice_whelp ability_key = BB_WHELP_STRAIGHTLINE_FIRE diff --git a/code/modules/mob/living/basic/jungle/mega_arachnid/mega_arachnid_ai.dm b/code/modules/mob/living/basic/jungle/mega_arachnid/mega_arachnid_ai.dm index fa2a86787d861..7d1b40fc5ec23 100644 --- a/code/modules/mob/living/basic/jungle/mega_arachnid/mega_arachnid_ai.dm +++ b/code/modules/mob/living/basic/jungle/mega_arachnid/mega_arachnid_ai.dm @@ -19,7 +19,7 @@ /datum/ai_planning_subtree/find_and_hunt_target/destroy_surveillance target_key = BB_SURVEILLANCE_TARGET finding_behavior = /datum/ai_behavior/find_hunt_target/find_active_surveillance - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target hunt_targets = list(/obj/machinery/camera, /obj/machinery/light) hunt_range = 7 diff --git a/code/modules/mob/living/basic/jungle/seedling/seedling_ai.dm b/code/modules/mob/living/basic/jungle/seedling/seedling_ai.dm index 2ed4811e46f25..440cfc2861b69 100644 --- a/code/modules/mob/living/basic/jungle/seedling/seedling_ai.dm +++ b/code/modules/mob/living/basic/jungle/seedling/seedling_ai.dm @@ -19,7 +19,7 @@ /datum/ai_planning_subtree/find_and_hunt_target/watering_can target_key = BB_WATERCAN_TARGET finding_behavior = /datum/ai_behavior/find_hunt_target - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target hunt_targets = list(/obj/item/reagent_containers/cup/watering_can) hunt_range = 7 @@ -32,7 +32,7 @@ /datum/ai_planning_subtree/find_and_hunt_target/treat_hydroplants target_key = BB_HYDROPLANT_TARGET finding_behavior = /datum/ai_behavior/find_and_set/treatable_hydro - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/treat_hydroplant + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/treat_hydroplant hunt_targets = list(/obj/machinery/hydroponics) hunt_range = 7 @@ -58,11 +58,11 @@ if(possible_trays.len) return pick(possible_trays) -/datum/ai_behavior/hunt_target/unarmed_attack_target/treat_hydroplant +/datum/ai_behavior/hunt_target/interact_with_target/treat_hydroplant hunt_cooldown = 2 SECONDS always_reset_target = TRUE -/datum/ai_behavior/hunt_target/unarmed_attack_target/treat_hydroplant/target_caught(mob/living/living_pawn, obj/machinery/hydroponics/hydro_target) +/datum/ai_behavior/hunt_target/interact_with_target/treat_hydroplant/target_caught(mob/living/living_pawn, obj/machinery/hydroponics/hydro_target) if(QDELETED(hydro_target) || QDELETED(hydro_target.myseed)) return @@ -112,7 +112,7 @@ /datum/ai_planning_subtree/find_and_hunt_target/fill_watercan target_key = BB_LOW_PRIORITY_HUNTING_TARGET finding_behavior = /datum/ai_behavior/find_hunt_target/suitable_dispenser - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/water_source + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/water_source hunt_targets = list(/obj/structure/sink, /obj/structure/reagent_dispensers) hunt_range = 7 @@ -135,7 +135,7 @@ return can_see(source, water_source, radius) -/datum/ai_behavior/hunt_target/unarmed_attack_target/water_source +/datum/ai_behavior/hunt_target/interact_with_target/water_source behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION hunt_cooldown = 5 SECONDS diff --git a/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_loot.dm b/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_loot.dm index 78960b5340d30..014cfb626be0a 100644 --- a/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_loot.dm +++ b/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_loot.dm @@ -20,7 +20,8 @@ desc = "Dust from a brimdemon. It is considered valuable for its' botanical abilities." icon_state = "brimdust" icon = 'icons/obj/mining.dmi' - layer = FLOOR_CLEAN_LAYER + plane = GAME_PLANE + layer = GAME_CLEAN_LAYER mergeable_decal = FALSE /obj/effect/decal/cleanable/brimdust/Initialize(mapload) diff --git a/code/modules/mob/living/basic/lavaland/goldgrub/goldgrub_ai.dm b/code/modules/mob/living/basic/lavaland/goldgrub/goldgrub_ai.dm index a31bf1f3e1d2e..8ea2467a2a813 100644 --- a/code/modules/mob/living/basic/lavaland/goldgrub/goldgrub_ai.dm +++ b/code/modules/mob/living/basic/lavaland/goldgrub/goldgrub_ai.dm @@ -1,3 +1,4 @@ +#define BURROW_RANGE 5 /datum/ai_controller/basic_controller/goldgrub blackboard = list( BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic, @@ -11,6 +12,7 @@ planning_subtrees = list( /datum/ai_planning_subtree/simple_find_target, /datum/ai_planning_subtree/pet_planning, + /datum/ai_planning_subtree/burrow_through_ground, /datum/ai_planning_subtree/dig_away_from_danger, /datum/ai_planning_subtree/flee_target, /datum/ai_planning_subtree/find_and_hunt_target/hunt_ores, @@ -39,10 +41,50 @@ /datum/ai_planning_subtree/look_for_adult, ) +/datum/ai_planning_subtree/burrow_through_ground + +/datum/ai_planning_subtree/burrow_through_ground/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + if(is_jaunting(controller.pawn) && controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET)) + controller.queue_behavior(/datum/ai_behavior/burrow_through_ground, BB_BASIC_MOB_CURRENT_TARGET) + return SUBTREE_RETURN_FINISH_PLANNING + +/datum/ai_behavior/burrow_through_ground + action_cooldown = 10 SECONDS + +/datum/ai_behavior/burrow_through_ground/perform(seconds_per_tick, datum/ai_controller/controller, target_key) + var/atom/target = controller.blackboard[target_key] + if(!is_jaunting(controller.pawn) || QDELETED(target)) + return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED + + var/mob/living/living_pawn = controller.pawn + var/atom/movable/phased = living_pawn.loc + + var/list/turfs_list = RANGE_TURFS(BURROW_RANGE, phased) + var/current_max_distance = 0 + var/turf/selected_turf + + for(var/turf/possible_turf as anything in turfs_list) + if(!ismineralturf(possible_turf) && !isasteroidturf(possible_turf)) + continue + + var/distance_to_target = get_dist(possible_turf, target) + if(distance_to_target > current_max_distance) + current_max_distance = distance_to_target + selected_turf = possible_turf + + if(distance_to_target == BURROW_RANGE) + break + + if(isnull(selected_turf)) + return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED + + phased.forceMove(selected_turf) + return AI_BEHAVIOR_SUCCEEDED | AI_BEHAVIOR_DELAY + ///consume food! /datum/ai_planning_subtree/find_and_hunt_target/hunt_ores target_key = BB_ORE_TARGET - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/hunt_ores + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/hunt_ores finding_behavior = /datum/ai_behavior/find_hunt_target/hunt_ores hunt_targets = list(/obj/item/stack/ore) hunt_chance = 90 @@ -65,13 +107,13 @@ return can_see(source, target, radius) -/datum/ai_behavior/hunt_target/unarmed_attack_target/hunt_ores +/datum/ai_behavior/hunt_target/interact_with_target/hunt_ores always_reset_target = TRUE ///break boulders so that we can find more food! /datum/ai_planning_subtree/find_and_hunt_target/harvest_vents target_key = BB_VENT_TARGET - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target //We call the ore vent's produce_boulder() proc here to produce a single boulder. + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target //We call the ore vent's produce_boulder() proc here to produce a single boulder. finding_behavior = /datum/ai_behavior/find_hunt_target/harvest_vents hunt_targets = list(/obj/structure/ore_vent) hunt_chance = 25 @@ -95,7 +137,7 @@ ///break boulders so that we can find more food! /datum/ai_planning_subtree/find_and_hunt_target/break_boulders target_key = BB_BOULDER_TARGET - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target //We process boulders once every tap, so we dont need to do anything special here + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target //We process boulders once every tap, so we dont need to do anything special here finding_behavior = /datum/ai_behavior/find_hunt_target/break_boulders hunt_targets = list(/obj/item/boulder) hunt_chance = 100 //If we can, we should always break boulders. @@ -179,3 +221,5 @@ controller.queue_behavior(/datum/ai_behavior/use_mob_ability, BB_SPIT_ABILITY) controller.clear_blackboard_key(BB_ACTIVE_PET_COMMAND) return SUBTREE_RETURN_FINISH_PLANNING + +#undef BURROW_RANGE diff --git a/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers_ai.dm b/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers_ai.dm index c7f7e86c86680..261f6d22a021b 100644 --- a/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers_ai.dm +++ b/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers_ai.dm @@ -73,7 +73,7 @@ ///consume food! /datum/ai_planning_subtree/find_and_hunt_target/food_trough target_key = BB_TROUGH_TARGET - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/food_trough + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/food_trough finding_behavior = /datum/ai_behavior/find_hunt_target/food_trough hunt_targets = list(/obj/structure/ore_container/food_trough/gutlunch_trough) hunt_chance = 75 @@ -96,9 +96,9 @@ return can_see(source, target, radius) -/datum/ai_behavior/hunt_target/unarmed_attack_target/food_trough +/datum/ai_behavior/hunt_target/interact_with_target/food_trough always_reset_target = TRUE - switch_combat_mode = TRUE + behavior_combat_mode = FALSE /datum/pet_command/mine_walls command_name = "Mine" diff --git a/code/modules/mob/living/basic/lavaland/hivelord/spawn_hivelord_brood.dm b/code/modules/mob/living/basic/lavaland/hivelord/spawn_hivelord_brood.dm index 7d50806e63a0c..6dbbe72a2459b 100644 --- a/code/modules/mob/living/basic/lavaland/hivelord/spawn_hivelord_brood.dm +++ b/code/modules/mob/living/basic/lavaland/hivelord/spawn_hivelord_brood.dm @@ -98,8 +98,8 @@ var/turf/my_turf = get_turf(src) dir = get_dir(spawn_from, my_turf) - var/move_x = (my_turf.x - spawn_from.x) * world.icon_size - var/move_y = (my_turf.y - spawn_from.y) * world.icon_size + var/move_x = (my_turf.x - spawn_from.x) * ICON_SIZE_X + var/move_y = (my_turf.y - spawn_from.y) * ICON_SIZE_Y pixel_x = -move_x pixel_y = -move_y diff --git a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm index b4de3d2321fe6..625dc4af90726 100644 --- a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm +++ b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm @@ -157,6 +157,17 @@ /// Were we tamed? If yes, tame the mob we become when we grow up too. var/was_tamed = FALSE +/datum/emote/lobstrosity_juvenile + mob_type_allowed_typecache = /mob/living/basic/mining/lobstrosity/juvenile + mob_type_blacklist_typecache = list() + +/datum/emote/lobstrosity_juvenile/chitter + key = "chitter" + key_third_person = "chitters" + message = "chitters pleasantly!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + sound = 'sound/mobs/non-humanoids/insect/chitter.ogg' + /mob/living/basic/mining/lobstrosity/juvenile/Initialize(mapload) . = ..() var/growth_step = 1000/(7 MINUTES) //It should take 7-ish minutes if you keep the happiness above 40% and at most 12 @@ -203,7 +214,7 @@ . = ..() was_tamed = TRUE // They are more pettable I guess - AddElement(/datum/element/pet_bonus, "chitters pleasantly!") + AddElement(/datum/element/pet_bonus, "chitter") REMOVE_TRAIT(src, TRAIT_MOB_HIDE_HAPPINESS, INNATE_TRAIT) /mob/living/basic/mining/lobstrosity/juvenile/proc/ready_to_grow() diff --git a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm index 32ec66a62cc37..de62b43e4a054 100644 --- a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm +++ b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm @@ -104,7 +104,7 @@ /datum/ai_planning_subtree/find_and_hunt_target/lobster_fishing target_key = BB_FISHING_TARGET hunt_targets = list(/turf/open/lava) - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/reset_target_combat_mode + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/reset_target_combat_mode_off /datum/ai_planning_subtree/basic_melee_attack_subtree/lobster melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/lobster @@ -323,7 +323,7 @@ var/atom/fingers = controller.blackboard[target_key] if (QDELETED(fingers) || living_pawn.pulling != fingers) return AI_BEHAVIOR_FAILED - living_pawn.melee_attack(fingers) + controller.ai_interact(target = fingers) return AI_BEHAVIOR_SUCCEEDED /datum/ai_behavior/hoard_fingers/finish_action(datum/ai_controller/controller, succeeded, target_key) diff --git a/code/modules/mob/living/basic/lavaland/mook/mook_ai.dm b/code/modules/mob/living/basic/lavaland/mook/mook_ai.dm index eeefc7a8b5c72..15da812a0b237 100644 --- a/code/modules/mob/living/basic/lavaland/mook/mook_ai.dm +++ b/code/modules/mob/living/basic/lavaland/mook/mook_ai.dm @@ -70,7 +70,7 @@ GLOBAL_LIST_INIT(mook_commands, list( ///deposit ores into the stand! /datum/ai_planning_subtree/find_and_hunt_target/material_stand target_key = BB_MATERIAL_STAND_TARGET - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/material_stand + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/material_stand finding_behavior = /datum/ai_behavior/find_hunt_target hunt_targets = list(/obj/structure/ore_container/material_stand) hunt_range = 9 @@ -81,14 +81,14 @@ GLOBAL_LIST_INIT(mook_commands, list( return return ..() -/datum/ai_behavior/hunt_target/unarmed_attack_target/material_stand +/datum/ai_behavior/hunt_target/interact_with_target/material_stand required_distance = 0 always_reset_target = TRUE - switch_combat_mode = TRUE + behavior_combat_mode = FALSE behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT ///try to face the counter when depositing ores -/datum/ai_behavior/hunt_target/unarmed_attack_target/material_stand/setup(datum/ai_controller/controller, hunting_target_key, hunting_cooldown_key) +/datum/ai_behavior/hunt_target/interact_with_target/material_stand/setup(datum/ai_controller/controller, hunting_target_key, hunting_cooldown_key) . = ..() var/atom/hunt_target = controller.blackboard[hunting_target_key] if (QDELETED(hunt_target)) @@ -297,7 +297,7 @@ GLOBAL_LIST_INIT(mook_commands, list( ///find injured miner mooks after they come home from a long day of work /datum/ai_planning_subtree/find_and_hunt_target/injured_mooks target_key = BB_INJURED_MOOK - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/injured_mooks + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/injured_mooks finding_behavior = /datum/ai_behavior/find_hunt_target/injured_mooks hunt_targets = list(/mob/living/basic/mining/mook/worker) hunt_range = 9 @@ -313,9 +313,7 @@ GLOBAL_LIST_INIT(mook_commands, list( /datum/ai_behavior/find_hunt_target/injured_mooks/valid_dinner(mob/living/source, mob/living/injured_mook) return (injured_mook.health < injured_mook.maxHealth) -/datum/ai_behavior/hunt_target/unarmed_attack_target/injured_mooks - -/datum/ai_behavior/hunt_target/unarmed_attack_target/injured_mooks +/datum/ai_behavior/hunt_target/interact_with_target/injured_mooks always_reset_target = TRUE hunt_cooldown = 10 SECONDS @@ -405,7 +403,7 @@ GLOBAL_LIST_INIT(mook_commands, list( /datum/ai_planning_subtree/find_and_hunt_target/bonfire target_key = BB_MOOK_BONFIRE_TARGET finding_behavior = /datum/ai_behavior/find_hunt_target/bonfire - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/bonfire + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/bonfire hunt_targets = list(/obj/structure/bonfire) hunt_range = 9 @@ -418,5 +416,5 @@ GLOBAL_LIST_INIT(mook_commands, list( return can_see(source, fire, radius) -/datum/ai_behavior/hunt_target/unarmed_attack_target/bonfire +/datum/ai_behavior/hunt_target/interact_with_target/bonfire always_reset_target = TRUE diff --git a/code/modules/mob/living/basic/lavaland/raptor/_raptor.dm b/code/modules/mob/living/basic/lavaland/raptor/_raptor.dm index 17e3cdc370753..29c98e0bc77cb 100644 --- a/code/modules/mob/living/basic/lavaland/raptor/_raptor.dm +++ b/code/modules/mob/living/basic/lavaland/raptor/_raptor.dm @@ -66,7 +66,7 @@ GLOBAL_LIST_EMPTY(raptor_population) /mob/living/basic/raptor/Initialize(mapload) . = ..() - if(SSmapping.config.minetype == "iceland" || SSmapping.is_planetary()) // DOPPLER STATION EDIT, old code: if(SSmapping.is_planetary()) + if(SSmapping.current_map.minetype == "iceland" || SSmapping.is_planetary()) // DOPPLER STATION EDIT, old code: if(SSmapping.is_planetary()) change_offsets = FALSE icon = 'icons/mob/simple/lavaland/raptor_icebox.dmi' diff --git a/code/modules/mob/living/basic/lavaland/raptor/raptor_ai_behavior.dm b/code/modules/mob/living/basic/lavaland/raptor/raptor_ai_behavior.dm index 33a655869072a..7e3022f95716d 100644 --- a/code/modules/mob/living/basic/lavaland/raptor/raptor_ai_behavior.dm +++ b/code/modules/mob/living/basic/lavaland/raptor/raptor_ai_behavior.dm @@ -1,4 +1,4 @@ -/datum/ai_behavior/hunt_target/unarmed_attack_target/heal_raptor +/datum/ai_behavior/hunt_target/interact_with_target/heal_raptor always_reset_target = TRUE /datum/ai_behavior/find_hunt_target/injured_raptor @@ -11,12 +11,11 @@ /datum/ai_behavior/find_hunt_target/raptor_victim/valid_dinner(mob/living/source, mob/living/target, radius) if(target.ai_controller?.blackboard[BB_RAPTOR_TROUBLE_MAKER]) return FALSE - return target.stat != DEAD && can_see(source, target, radius) + return target.stat != DEAD && can_see(source, target, radius) -/datum/ai_behavior/hunt_target/unarmed_attack_target/bully_raptors - always_reset_target = TRUE +/datum/ai_behavior/hunt_target/interact_with_target/reset_target/bully_raptors -/datum/ai_behavior/hunt_target/unarmed_attack_target/bully_raptors/finish_action(datum/ai_controller/controller, succeeded, hunting_target_key, hunting_cooldown_key) +/datum/ai_behavior/hunt_target/interact_with_target/bully_raptors/finish_action(datum/ai_controller/controller, succeeded, hunting_target_key, hunting_cooldown_key) if(succeeded) controller.set_blackboard_key(BB_RAPTOR_TROUBLE_COOLDOWN, world.time + 2 MINUTES) return ..() @@ -24,31 +23,13 @@ /datum/ai_behavior/find_hunt_target/raptor_baby/valid_dinner(mob/living/source, mob/living/target, radius) return can_see(source, target, radius) && target.stat != DEAD -/datum/ai_behavior/hunt_target/care_for_young - always_reset_target = TRUE +/datum/ai_behavior/hunt_target/interact_with_target/reset_target_combat_mode_off/care_for_young -/datum/ai_behavior/hunt_target/care_for_young/target_caught(mob/living/hunter, atom/hunted) +/datum/ai_behavior/hunt_target/interact_with_target/reset_target_combat_mode_off/care_for_young/target_caught(mob/living/hunter, atom/hunted) hunter.manual_emote("grooms [hunted]!") - hunter.set_combat_mode(FALSE) - hunter.ClickOn(hunted) - -/datum/ai_behavior/hunt_target/care_for_young/finish_action(datum/ai_controller/controller, succeeded, hunting_target_key, hunting_cooldown_key) - var/mob/living/living_pawn = controller.pawn - living_pawn.set_combat_mode(initial(living_pawn.combat_mode)) return ..() /datum/ai_behavior/find_hunt_target/raptor_trough /datum/ai_behavior/find_hunt_target/raptor_trough/valid_dinner(mob/living/source, atom/movable/trough, radius) return !!(locate(/obj/item/stack/ore) in trough.contents) - -/datum/ai_behavior/hunt_target/unarmed_attack_target/raptor_trough - always_reset_target = TRUE - -/datum/ai_behavior/hunt_target/unarmed_attack_target/raptor_trough/target_caught(mob/living/hunter, atom/hunted) - hunter.set_combat_mode(FALSE) - -/datum/ai_behavior/hunt_target/unarmed_attack_target/raptor_trough/finish_action(datum/ai_controller/controller, succeeded, hunting_target_key, hunting_cooldown_key) - var/mob/living/living_pawn = controller.pawn - living_pawn.set_combat_mode(initial(living_pawn.combat_mode)) - return ..() diff --git a/code/modules/mob/living/basic/lavaland/raptor/raptor_ai_subtrees.dm b/code/modules/mob/living/basic/lavaland/raptor/raptor_ai_subtrees.dm index 7ba0dad5561f6..a8d91963ebfb7 100644 --- a/code/modules/mob/living/basic/lavaland/raptor/raptor_ai_subtrees.dm +++ b/code/modules/mob/living/basic/lavaland/raptor/raptor_ai_subtrees.dm @@ -1,6 +1,6 @@ /datum/ai_planning_subtree/find_and_hunt_target/heal_raptors target_key = BB_INJURED_RAPTOR - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/heal_raptor + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/heal_raptor finding_behavior = /datum/ai_behavior/find_hunt_target/injured_raptor hunt_targets = list(/mob/living/basic/raptor) hunt_chance = 70 @@ -13,7 +13,7 @@ /datum/ai_planning_subtree/find_and_hunt_target/raptor_start_trouble target_key = BB_RAPTOR_VICTIM - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/bully_raptors + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/reset_target/bully_raptors finding_behavior = /datum/ai_behavior/find_hunt_target/raptor_victim hunt_targets = list(/mob/living/basic/raptor) hunt_chance = 30 @@ -36,7 +36,7 @@ /datum/ai_planning_subtree/find_and_hunt_target/care_for_young target_key = BB_RAPTOR_BABY - hunting_behavior = /datum/ai_behavior/hunt_target/care_for_young + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/reset_target_combat_mode_off/care_for_young finding_behavior = /datum/ai_behavior/find_hunt_target/raptor_baby hunt_targets = list(/mob/living/basic/raptor/baby_raptor) hunt_chance = 75 @@ -49,7 +49,7 @@ /datum/ai_planning_subtree/find_and_hunt_target/raptor_trough target_key = BB_RAPTOR_TROUGH_TARGET - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/reset_target_combat_mode_off finding_behavior = /datum/ai_behavior/find_hunt_target/raptor_trough hunt_targets = list(/obj/structure/ore_container/food_trough/raptor_trough) hunt_chance = 80 diff --git a/code/modules/mob/living/basic/lavaland/raptor/raptor_dex.dm b/code/modules/mob/living/basic/lavaland/raptor/raptor_dex.dm index f6e555adfe31b..cd1439b3c5ffc 100644 --- a/code/modules/mob/living/basic/lavaland/raptor/raptor_dex.dm +++ b/code/modules/mob/living/basic/lavaland/raptor/raptor_dex.dm @@ -32,7 +32,7 @@ var/happiness_percentage = my_raptor.ai_controller?.blackboard[BB_BASIC_HAPPINESS] var/obj/effect/overlay/happiness_overlay/display = new display.set_hearts(happiness_percentage) - display.pixel_y = world.icon_size * 0.5 + display.pixel_y = ICON_SIZE_Y * 0.5 data["raptor_happiness"] = icon2base64(getFlatIcon(display)) qdel(display) diff --git a/code/modules/mob/living/basic/lavaland/raptor/raptor_egg.dm b/code/modules/mob/living/basic/lavaland/raptor/raptor_egg.dm index 0a7805ef9e0ed..2935426b3f6e0 100644 --- a/code/modules/mob/living/basic/lavaland/raptor/raptor_egg.dm +++ b/code/modules/mob/living/basic/lavaland/raptor/raptor_egg.dm @@ -6,7 +6,7 @@ /obj/item/food/egg/raptor_egg/Initialize(mapload) . = ..() - if(SSmapping.config.minetype == "iceland" || SSmapping.is_planetary()) // DOPPLER STATION EDIT, old code: if(SSmapping.is_planetary()) + if(SSmapping.current_map.minetype == "iceland" || SSmapping.is_planetary()) // DOPPLER STATION EDIT, old code: if(SSmapping.is_planetary()) icon = 'icons/mob/simple/lavaland/raptor_icebox.dmi' /obj/item/food/egg/raptor_egg/proc/determine_growth_path(mob/living/basic/raptor/dad, mob/living/basic/raptor/mom) diff --git a/code/modules/mob/living/basic/minebots/minebot_ai.dm b/code/modules/mob/living/basic/minebots/minebot_ai.dm index 31fed0ec1f32c..8043fda65d0a6 100644 --- a/code/modules/mob/living/basic/minebots/minebot_ai.dm +++ b/code/modules/mob/living/basic/minebots/minebot_ai.dm @@ -98,7 +98,7 @@ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED var/mob/living/living_pawn = controller.pawn living_pawn.say("REPAIRING [target]!") - living_pawn.UnarmedAttack(target) + controller.ai_interact(target = target) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED /datum/ai_behavior/repair_drone/finish_action(datum/ai_controller/controller, success, target_key) @@ -251,7 +251,7 @@ ///store ores in our body /datum/ai_planning_subtree/find_and_hunt_target/hunt_ores/minebot - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/consume_ores/minebot + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/consume_ores/minebot hunt_chance = 100 /datum/ai_planning_subtree/find_and_hunt_target/hunt_ores/minebot/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) @@ -263,10 +263,10 @@ return ..() -/datum/ai_behavior/hunt_target/unarmed_attack_target/consume_ores/minebot +/datum/ai_behavior/hunt_target/interact_with_target/consume_ores/minebot hunt_cooldown = 2 SECONDS -/datum/ai_behavior/hunt_target/unarmed_attack_target/consume_ores/minebot/target_caught(mob/living/hunter, obj/item/stack/ore/hunted) +/datum/ai_behavior/hunt_target/interact_with_target/consume_ores/minebot/target_caught(mob/living/hunter, obj/item/stack/ore/hunted) if(hunter.combat_mode) hunter.set_combat_mode(FALSE) return ..() diff --git a/code/modules/mob/living/basic/pets/cat/bread_cat_ai.dm b/code/modules/mob/living/basic/pets/cat/bread_cat_ai.dm index 35a5d9e12afcf..655a6431fc2a7 100644 --- a/code/modules/mob/living/basic/pets/cat/bread_cat_ai.dm +++ b/code/modules/mob/living/basic/pets/cat/bread_cat_ai.dm @@ -9,7 +9,7 @@ /datum/ai_planning_subtree/find_and_hunt_target/turn_off_stove target_key = BB_STOVE_TARGET - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/stove_target + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/stove_target finding_behavior = /datum/ai_behavior/find_hunt_target/stove hunt_targets = list(/obj/machinery/oven/range) hunt_range = 9 @@ -25,10 +25,10 @@ return FALSE return TRUE -/datum/ai_behavior/hunt_target/unarmed_attack_target/stove_target +/datum/ai_behavior/hunt_target/interact_with_target/stove_target always_reset_target = TRUE -/datum/ai_behavior/hunt_target/unarmed_attack_target/stove_target/target_caught(mob/living/hunter, obj/machinery/oven/range/stove) +/datum/ai_behavior/hunt_target/interact_with_target/stove_target/target_caught(mob/living/hunter, obj/machinery/oven/range/stove) if(stove.open) return return ..() diff --git a/code/modules/mob/living/basic/pets/cat/cat.dm b/code/modules/mob/living/basic/pets/cat/cat.dm index 596308fdee169..68821731ee4de 100644 --- a/code/modules/mob/living/basic/pets/cat/cat.dm +++ b/code/modules/mob/living/basic/pets/cat/cat.dm @@ -45,6 +45,14 @@ /obj/item/food/deadmouse, /obj/item/food/fishmeat, ) + ///list of pet commands we follow + var/static/list/pet_commands = list( + /datum/pet_command/idle, + /datum/pet_command/free, + /datum/pet_command/follow, + /datum/pet_command/perform_trick_sequence, + ) + ///item we are currently holding var/obj/item/held_food ///mutable appearance for held item @@ -52,12 +60,33 @@ ///icon state of our cult icon var/cult_icon_state = "cat_cult" +/datum/emote/cat + mob_type_allowed_typecache = /mob/living/basic/pet/cat + mob_type_blacklist_typecache = list() + +/datum/emote/cat/meow + key = "meow" + key_third_person = "meows" + message = "meows!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + vary = TRUE + sound = SFX_CAT_MEOW + +/datum/emote/cat/purr + key = "purr" + key_third_person = "purrs" + message = "purrs." + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + vary = TRUE + sound = SFX_CAT_PURR + /mob/living/basic/pet/cat/Initialize(mapload) . = ..() + AddComponent(/datum/component/obeys_commands, pet_commands) AddElement(/datum/element/cultist_pet, pet_cult_icon_state = cult_icon_state) AddElement(/datum/element/wears_collar, collar_icon_state = collar_icon_state, collar_resting_icon_state = TRUE) AddElement(/datum/element/ai_retaliate) - AddElement(/datum/element/pet_bonus, "purrs!") + AddElement(/datum/element/pet_bonus, "purr", /datum/mood_event/pet_animal) AddElement(/datum/element/footstep, footstep_type = FOOTSTEP_MOB_CLAW) add_cell_sample() add_verb(src, /mob/living/proc/toggle_resting) @@ -204,3 +233,9 @@ name = "Jerry" desc = "Tom is VERY amused." gender = MALE + +/mob/living/basic/pet/cat/tabby + icon_state = "cat" + icon_living = "cat" + icon_dead = "cat_dead" + held_state = "cat" diff --git a/code/modules/mob/living/basic/pets/cat/cat_ai.dm b/code/modules/mob/living/basic/pets/cat/cat_ai.dm index d6589d29b407e..2a2d3204bad5f 100644 --- a/code/modules/mob/living/basic/pets/cat/cat_ai.dm +++ b/code/modules/mob/living/basic/pets/cat/cat_ai.dm @@ -1,6 +1,7 @@ /datum/ai_controller/basic_controller/cat blackboard = list( BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic, + BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends, BB_HOSTILE_MEOWS = list("Mawwww", "Mrewwww", "mhhhhng..."), BB_BABIES_PARTNER_TYPES = list(/mob/living/basic/pet/cat), BB_BABIES_CHILD_TYPES = list(/mob/living/basic/pet/cat/kitten), @@ -9,6 +10,7 @@ ai_movement = /datum/ai_movement/basic_avoidance idle_behavior = /datum/idle_behavior/idle_random_walk planning_subtrees = list( + /datum/ai_planning_subtree/pet_planning, /datum/ai_planning_subtree/reside_in_home, /datum/ai_planning_subtree/flee_target/from_flee_key/cat_struggle, /datum/ai_planning_subtree/find_and_hunt_target/hunt_mice, @@ -63,7 +65,7 @@ var/obj/structure/cat_house/home = controller.blackboard[target_key] var/mob/living/basic/living_pawn = controller.pawn if(living_pawn == home.resident_cat || isnull(home.resident_cat)) - living_pawn.melee_attack(home) + controller.ai_interact(target = home) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED @@ -213,13 +215,13 @@ /datum/ai_planning_subtree/find_and_hunt_target/find_cat_food target_key = BB_CAT_FOOD_TARGET - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/find_cat_food + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/find_cat_food finding_behavior = /datum/ai_behavior/find_hunt_target/find_cat_food hunt_targets = list(/obj/item/fish, /obj/item/food/deadmouse, /obj/item/food/fishmeat) hunt_chance = 75 hunt_range = 9 -/datum/ai_behavior/hunt_target/unarmed_attack_target/find_cat_food +/datum/ai_behavior/hunt_target/interact_with_target/find_cat_food always_reset_target = TRUE /datum/ai_behavior/find_hunt_target/find_cat_food/valid_dinner(mob/living/source, atom/dinner, radius) @@ -253,7 +255,6 @@ return kitten return null -/datum/ai_behavior/deliver_food_to_kitten /datum/ai_behavior/deliver_food_to_kitten behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION | AI_BEHAVIOR_REQUIRE_REACH action_cooldown = 5 SECONDS diff --git a/code/modules/mob/living/basic/pets/cat/kitten_ai.dm b/code/modules/mob/living/basic/pets/cat/kitten_ai.dm index b694235a39ebc..4136aa0aa0151 100644 --- a/code/modules/mob/living/basic/pets/cat/kitten_ai.dm +++ b/code/modules/mob/living/basic/pets/cat/kitten_ai.dm @@ -3,10 +3,12 @@ blackboard = list( BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic, BB_HUNGRY_MEOW = list("mrrp...", "mraw..."), + BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends, BB_MAX_DISTANCE_TO_FOOD = 2, ) planning_subtrees = list( + /datum/ai_planning_subtree/pet_planning, /datum/ai_planning_subtree/target_retaliate, /datum/ai_planning_subtree/flee_target, /datum/ai_planning_subtree/beg_human, diff --git a/code/modules/mob/living/basic/pets/dog/_dog.dm b/code/modules/mob/living/basic/pets/dog/_dog.dm index 1ff991941d327..b5259d275b530 100644 --- a/code/modules/mob/living/basic/pets/dog/_dog.dm +++ b/code/modules/mob/living/basic/pets/dog/_dog.dm @@ -40,6 +40,7 @@ /datum/pet_command/free, /datum/pet_command/good_boy/dog, /datum/pet_command/follow/dog, + /datum/pet_command/perform_trick_sequence, /datum/pet_command/point_targeting/attack/dog, /datum/pet_command/point_targeting/fetch, /datum/pet_command/play_dead, @@ -49,12 +50,22 @@ ///icon state of our cult icon var/cult_icon_state +/datum/emote/dog + mob_type_allowed_typecache = /mob/living/basic/pet/dog + mob_type_blacklist_typecache = list() + +/datum/emote/dog/woof + key = "woof" + key_third_person = "woof" + message = "woofs happily!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + /mob/living/basic/pet/dog/Initialize(mapload) . = ..() AddElement(/datum/element/cultist_pet, pet_cult_icon_state = cult_icon_state) AddElement(/datum/element/wears_collar, collar_icon_state = collar_icon_state) ADD_TRAIT(src, TRAIT_WOUND_LICKER, INNATE_TRAIT) - AddElement(/datum/element/pet_bonus, "woofs happily!") + AddElement(/datum/element/pet_bonus, "woof") AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW) AddElement(/datum/element/unfriend_attacker, untamed_reaction = "%SOURCE% fixes %TARGET% with a look of betrayal.") AddComponent(/datum/component/tameable, food_types = list(/obj/item/food/meat/slab/human/mutant/skeleton, /obj/item/stack/sheet/bone), tame_chance = 30, bonus_tame_chance = 15, unique = FALSE) diff --git a/code/modules/mob/living/basic/pets/fox.dm b/code/modules/mob/living/basic/pets/fox.dm index 45ea29024ad66..737f7b21391fd 100644 --- a/code/modules/mob/living/basic/pets/fox.dm +++ b/code/modules/mob/living/basic/pets/fox.dm @@ -28,12 +28,31 @@ attack_sound = 'sound/items/weapons/bite.ogg' attack_vis_effect = ATTACK_EFFECT_BITE ai_controller = /datum/ai_controller/basic_controller/fox + ///list of our pet commands we follow + var/static/list/pet_commands = list( + /datum/pet_command/idle, + /datum/pet_command/free, + /datum/pet_command/follow, + /datum/pet_command/point_targeting/attack, + /datum/pet_command/perform_trick_sequence, + ) + +/datum/emote/fox + mob_type_allowed_typecache = /mob/living/basic/pet/fox + mob_type_blacklist_typecache = list() + +/datum/emote/fox/yap + key = "yap" + key_third_person = "yaps" + message = "yaps happily!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE /mob/living/basic/pet/fox/Initialize(mapload) . = ..() + AddComponent(/datum/component/obeys_commands, pet_commands) AddElement(/datum/element/cultist_pet) AddElement(/datum/element/wears_collar) - AddElement(/datum/element/pet_bonus, "pants and yaps happily!") + AddElement(/datum/element/pet_bonus, "yap") AddElement(/datum/element/footstep, footstep_type = FOOTSTEP_MOB_CLAW) AddElement(/datum/element/tiny_mob_hunter, MOB_SIZE_SMALL) AddElement(/datum/element/ai_retaliate) @@ -42,12 +61,14 @@ blackboard = list( BB_ALWAYS_IGNORE_FACTION = TRUE, BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic/of_size/ours_or_smaller, + BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends, BB_FLEE_TARGETING_STRATEGY = /datum/targeting_strategy/basic, ) ai_movement = /datum/ai_movement/basic_avoidance idle_behavior = /datum/idle_behavior/idle_random_walk planning_subtrees = list( + /datum/ai_planning_subtree/pet_planning, /datum/ai_planning_subtree/target_retaliate/to_flee, /datum/ai_planning_subtree/flee_target/from_flee_key, /datum/ai_planning_subtree/simple_find_target/not_while_observed, diff --git a/code/modules/mob/living/basic/pets/gondolas/gondola.dm b/code/modules/mob/living/basic/pets/gondolas/gondola.dm index 9e17d1e08a5e2..e607a13bf1e59 100644 --- a/code/modules/mob/living/basic/pets/gondolas/gondola.dm +++ b/code/modules/mob/living/basic/pets/gondolas/gondola.dm @@ -39,7 +39,7 @@ /mob/living/basic/pet/gondola/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_MUTE, INNATE_TRAIT) - AddElement(/datum/element/pet_bonus, "smiles!") + AddElement(/datum/element/pet_bonus, "smile") if(LAZYLEN(loot)) loot = string_list(loot) AddElement(/datum/element/death_drops, loot) diff --git a/code/modules/mob/living/basic/pets/parrot/_parrot.dm b/code/modules/mob/living/basic/pets/parrot/_parrot.dm index e61b052217909..e22948848eb1c 100644 --- a/code/modules/mob/living/basic/pets/parrot/_parrot.dm +++ b/code/modules/mob/living/basic/pets/parrot/_parrot.dm @@ -76,6 +76,13 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( var/static/list/edibles = list( /obj/item/food/cracker, ) + ///list of commands we follow + var/static/list/pet_commands = list( + /datum/pet_command/idle, + /datum/pet_command/free, + /datum/pet_command/follow, + /datum/pet_command/perform_trick_sequence, + ) /// Tracks the times when we send a phrase through either being pet or attack to ensure it's not abused to flood COOLDOWN_DECLARE(forced_speech_cooldown) @@ -92,7 +99,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( AddElement(/datum/element/simple_flying) AddComponent(/datum/component/listen_and_repeat, desired_phrases = get_static_list_of_phrases(), blackboard_key = BB_PARROT_REPEAT_STRING) AddComponent(/datum/component/tameable, food_types = edibles, tame_chance = 100, bonus_tame_chance = 0) - + AddComponent(/datum/component/obeys_commands, pet_commands) RegisterSignal(src, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(pre_attacking)) RegisterSignal(src, COMSIG_MOB_CLICKON, PROC_REF(on_click)) RegisterSignal(src, COMSIG_ATOM_ATTACKBY_SECONDARY, PROC_REF(on_attacked)) // this means we could have a peaceful interaction, like getting a cracker diff --git a/code/modules/mob/living/basic/pets/parrot/parrot_ai/_parrot_controller.dm b/code/modules/mob/living/basic/pets/parrot/parrot_ai/_parrot_controller.dm index 987e50774c3f1..139cb81992288 100644 --- a/code/modules/mob/living/basic/pets/parrot/parrot_ai/_parrot_controller.dm +++ b/code/modules/mob/living/basic/pets/parrot/parrot_ai/_parrot_controller.dm @@ -1,6 +1,7 @@ /datum/ai_controller/basic_controller/parrot blackboard = list( BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic/allow_items, + BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends, BB_HOARD_LOCATION_RANGE = 9, ) @@ -9,11 +10,12 @@ idle_behavior = /datum/idle_behavior/idle_random_walk/parrot planning_subtrees = list( + /datum/ai_planning_subtree/parrot_as_in_repeat, // always get a witty oneliner in when you can + /datum/ai_planning_subtree/pet_planning, /datum/ai_planning_subtree/target_retaliate, /datum/ai_planning_subtree/perch_on_target, /datum/ai_planning_subtree/basic_melee_attack_subtree, /datum/ai_planning_subtree/hoard_items, - /datum/ai_planning_subtree/parrot_as_in_repeat, // always get a witty oneliner in when you can ) /datum/idle_behavior/idle_random_walk/parrot diff --git a/code/modules/mob/living/basic/pets/penguin.dm b/code/modules/mob/living/basic/pets/penguin.dm index a597bd70cbba4..c1afe10187c75 100644 --- a/code/modules/mob/living/basic/pets/penguin.dm +++ b/code/modules/mob/living/basic/pets/penguin.dm @@ -17,6 +17,15 @@ ///the egg it carries var/obj/carried_egg +/datum/emote/penguin + mob_type_allowed_typecache = /mob/living/basic/pet/penguin + mob_type_blacklist_typecache = list() + +/datum/emote/penguin/honk + key = "honk" + key_third_person = "honks" + message = "honks happily!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE /mob/living/basic/pet/penguin/Initialize(mapload) . = ..() @@ -24,7 +33,7 @@ AddElement(/datum/element/wears_collar) AddElement(/datum/element/ai_retaliate) AddElement(/datum/element/ai_flee_while_injured) - AddElement(/datum/element/pet_bonus, "honks happily!") + AddElement(/datum/element/pet_bonus, "honk") AddElementTrait(TRAIT_WADDLING, INNATE_TRAIT, /datum/element/waddling) if(!can_lay_eggs) return diff --git a/code/modules/mob/living/basic/pets/pet_cult/pet_cult_ai.dm b/code/modules/mob/living/basic/pets/pet_cult/pet_cult_ai.dm index fb10680991895..77263b1748963 100644 --- a/code/modules/mob/living/basic/pets/pet_cult/pet_cult_ai.dm +++ b/code/modules/mob/living/basic/pets/pet_cult/pet_cult_ai.dm @@ -111,9 +111,7 @@ if(isnull(revive_mob) || revive_mob.stat != DEAD || !(revive_mob.mind in cult_team.members)) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED - var/mob/living/basic/living_pawn = controller.pawn - living_pawn.melee_attack(target) - + controller.ai_interact(target = target) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED /datum/ai_behavior/activate_rune/finish_action(datum/ai_controller/controller, success, target_key) diff --git a/code/modules/mob/living/basic/pets/pet_designer.dm b/code/modules/mob/living/basic/pets/pet_designer.dm new file mode 100644 index 0000000000000..a0cc7ca4018d9 --- /dev/null +++ b/code/modules/mob/living/basic/pets/pet_designer.dm @@ -0,0 +1,205 @@ +#define PET_OPTION_DOG "Dog" +#define PET_OPTION_CAT "Cat" +#define PET_OPTION_FOX "Fox" +#define PET_OPTION_VERMIN "Vermin" +#define PET_OPTION_BIRD "Bird" + +GLOBAL_LIST_INIT(pet_options, list( + PET_OPTION_DOG = list( + /mob/living/basic/pet/dog/corgi, + /mob/living/basic/pet/dog/pug, + /mob/living/basic/pet/dog/bullterrier, + /mob/living/basic/pet/dog/corgi/puppy, + /mob/living/basic/pet/dog/corgi/exoticcorgi, + ), + PET_OPTION_CAT = list( + /mob/living/basic/pet/cat/tabby, + /mob/living/basic/pet/cat, + /mob/living/basic/pet/cat/kitten, + ), + PET_OPTION_FOX = list( + /mob/living/basic/pet/fox, + ), + PET_OPTION_VERMIN = list( + /mob/living/basic/mothroach, + /mob/living/basic/spider/maintenance, + /mob/living/basic/mouse, + ), + PET_OPTION_BIRD = list( + /mob/living/basic/parrot, + ), +)) + +/datum/pet_customization + ///our selected path type + var/mob/living/basic/selected_path = /mob/living/basic/pet/dog/corgi + ///current selected specie + var/pet_specie = PET_OPTION_DOG + ///custom name to apply to our pet + var/custom_name + ///type of pet carrier to give our pet + var/pet_carrier_path + ///pet collar color to give our pet + var/pet_collar_type + ///our pet's gender + var/pet_gender = MALE + ///trick name of our pet! + var/pet_trick_name = "Trick" + ///our pet's trick moves + var/list/pet_trick_moves + ///our selected carrier + var/pet_carrier + ///our cached pet carrier icons + var/static/list/custom_pet_carriers + ///possible emotes our pet can run + var/static/list/pet_possible_emotes = list( + /datum/emote/flip, + /datum/emote/jump, + /datum/emote/spin, + ) + ///list of carrier colors we can pick from + var/static/list/possible_colors = list( + "Blue" = COLOR_BLUE, + "Red" = COLOR_RED, + "Yellow" = COLOR_YELLOW, + "Green" = COLOR_GREEN, + ) + +/datum/pet_customization/New(client/player_client) + . = ..() + if(isnull(custom_pet_carriers)) + custom_pet_carriers = setup_pet_carriers() + pet_carrier = possible_colors[1] + GLOB.customized_pets[REF(player_client)] = src + +/datum/pet_customization/proc/setup_pet_carriers() + var/list/list_to_return = list() + + var/obj/item/pet_carrier/demo_carrier = new() + demo_carrier.open = FALSE + demo_carrier.update_appearance() + + for(var/color in possible_colors) + demo_carrier.set_greyscale(possible_colors[color]) + list_to_return[color] = icon2base64(getFlatIcon(demo_carrier)) + qdel(demo_carrier) + return list_to_return + +/datum/pet_customization/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "PetBuilder") + ui.open() + +/datum/pet_customization/ui_data(mob/user) + var/list/data = list() + data["pet_name"] = custom_name + data["pet_path"] = selected_path + data["pet_gender"] = pet_gender + data["pet_trick_name"] = pet_trick_name + data["pet_specie"] = pet_specie + data["pet_types"] = list() + data["pet_options"] = list() + for(var/pet_option in GLOB.pet_options) + data["pet_types"] += pet_option + data["pet_options"] += retrieve_pet_options(pet_option, GLOB.pet_options[pet_option]) + data["pet_carrier"] = pet_carrier + + data["carrier_options"] = list() + for(var/carrier_option in custom_pet_carriers) + data["carrier_options"] += list(list( + "carrier_color" = carrier_option, + "carrier_icon" = custom_pet_carriers[carrier_option], + )) + + data["pet_possible_emotes"] = list() + for(var/datum/emote/emote as anything in pet_possible_emotes) + data["pet_possible_emotes"] += emote.key + + return data + +/datum/pet_customization/ui_state(mob/user) + return GLOB.always_state + +/datum/pet_customization/proc/retrieve_pet_options(pet_specie, list/input_list) + var/list/pet_options = list() + for(var/mob/living/pet_type as anything in input_list) + pet_options += list(list( + "pet_specie" = pet_specie, + "pet_name" = pet_type::name, + "pet_icon" = pet_type:icon, + "pet_path" = pet_type, + "pet_icon_state" = pet_type::icon_state, + )) + return pet_options + +/datum/pet_customization/ui_act(action, params, datum/tgui/ui) + . = ..() + switch(action) + if("finalize_pet") + + var/pet_type = text2path(params["selected_path"]) + for(var/pet_category in GLOB.pet_options) + var/list/pet_list = GLOB.pet_options[pet_category] + if(pet_list.Find(pet_type)) + selected_path = pet_type + break + + var/trick_name = params["selected_trick_name"] + if(trick_name && sanitize_name(trick_name)) + pet_trick_name = trick_name + + var/pet_name = params["selected_pet_name"] + if(pet_name && sanitize_name(pet_name)) + custom_name = pet_name + + switch(params["selected_gender"]) + if("male") + pet_gender = MALE + if("female") + pet_gender = FEMALE + if("neuter") + pet_gender = NEUTER + + var/list/trick_moves = params["selected_trick_moves"] + if(length(trick_moves)) + pet_trick_moves = trick_moves + + var/selected_color = params["selected_carrier"] + if(!isnull(selected_color)) + pet_carrier = selected_color + + var/selected_specie = params["selected_specie"] + if(!isnull(selected_specie)) + pet_specie = selected_specie + ui.close() + + return TRUE + +/datum/pet_customization/proc/create_pet(mob/living/spawned, client/player_client) + var/obj/item/pet_carrier/carrier = new(get_turf(spawned)) + carrier.open = FALSE + carrier.update_appearance() + var/final_color = possible_colors[pet_carrier] || COLOR_BLUE + carrier.set_greyscale(final_color) + var/mob/living/our_pet = new selected_path(get_turf(spawned)) //spawning these in nullspace leads to runtimes + our_pet.gender = pet_gender + + if(custom_name) + our_pet.fully_replace_character_name(our_pet.name, custom_name) + + if(pet_trick_name) + our_pet.ai_controller.set_blackboard_key(BB_TRICK_NAME, pet_trick_name) + if(pet_trick_moves) + our_pet.ai_controller.override_blackboard_key(BB_TRICK_SEQUENCE, pet_trick_moves) + our_pet.befriend(spawned) + carrier.add_occupant(our_pet) + spawned.put_in_hands(carrier, forced = TRUE) + GLOB.customized_pets -= REF(player_client) + qdel(src) + +#undef PET_OPTION_DOG +#undef PET_OPTION_CAT +#undef PET_OPTION_FOX +#undef PET_OPTION_VERMIN +#undef PET_OPTION_BIRD diff --git a/code/modules/mob/living/basic/pets/sloth.dm b/code/modules/mob/living/basic/pets/sloth.dm index 9cd7711aa0672..b1f5c61001adc 100644 --- a/code/modules/mob/living/basic/pets/sloth.dm +++ b/code/modules/mob/living/basic/pets/sloth.dm @@ -37,9 +37,19 @@ GLOBAL_DATUM(cargo_sloth, /mob/living/basic/sloth) ai_controller = /datum/ai_controller/basic_controller/sloth +/datum/emote/sloth + mob_type_allowed_typecache = /mob/living/basic/sloth + mob_type_blacklist_typecache = list() + +/datum/emote/sloth/smile_slow + key = "ssmile" + key_third_person = "slowlysmiles" + message = "slowly smiles!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + /mob/living/basic/sloth/Initialize(mapload) . = ..() - AddElement(/datum/element/pet_bonus, "slowly smiles!") + AddElement(/datum/element/pet_bonus, "ssmile") AddElement(/datum/element/footstep, footstep_type = FOOTSTEP_MOB_CLAW) AddElement(/datum/element/ai_retaliate) AddComponent(/datum/component/tree_climber) diff --git a/code/modules/mob/living/basic/slime/ai/behaviours.dm b/code/modules/mob/living/basic/slime/ai/behaviours.dm index 35fe1a60c91a1..fe8102eee112f 100644 --- a/code/modules/mob/living/basic/slime/ai/behaviours.dm +++ b/code/modules/mob/living/basic/slime/ai/behaviours.dm @@ -54,9 +54,9 @@ //We are not THAT hungry return FALSE -/datum/ai_behavior/hunt_target/unarmed_attack_target/slime +/datum/ai_behavior/hunt_target/interact_with_target/slime -/datum/ai_behavior/hunt_target/unarmed_attack_target/slime/target_caught(mob/living/basic/slime/hunter, mob/living/hunted) +/datum/ai_behavior/hunt_target/interact_with_target/slime/target_caught(mob/living/basic/slime/hunter, mob/living/hunted) if (!hunter.can_feed_on(hunted)) // Target is no longer edible hunter.UnarmedAttack(hunted, TRUE) return @@ -71,7 +71,7 @@ hunter.start_feeding(hunted) -/datum/ai_behavior/hunt_target/unarmed_attack_target/slime/finish_action(datum/ai_controller/controller, succeeded, hunting_target_key, hunting_cooldown_key) +/datum/ai_behavior/hunt_target/interact_with_target/slime/finish_action(datum/ai_controller/controller, succeeded, hunting_target_key, hunting_cooldown_key) . = ..() var/mob/living/basic/slime/slime_pawn = controller.pawn var/atom/target = controller.blackboard[hunting_target_key] diff --git a/code/modules/mob/living/basic/slime/ai/pet_command.dm b/code/modules/mob/living/basic/slime/ai/pet_command.dm index 42d6b28993728..33484e360fbed 100644 --- a/code/modules/mob/living/basic/slime/ai/pet_command.dm +++ b/code/modules/mob/living/basic/slime/ai/pet_command.dm @@ -4,7 +4,7 @@ pointed_reaction = "and blorbles" refuse_reaction = "jiggles sadly" - var/hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/slime + var/hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/slime /datum/pet_command/point_targeting/attack/slime/execute_action(datum/ai_controller/controller) diff --git a/code/modules/mob/living/basic/slime/ai/subtrees.dm b/code/modules/mob/living/basic/slime/ai/subtrees.dm index 056befece5d4b..08886f98365a6 100644 --- a/code/modules/mob/living/basic/slime/ai/subtrees.dm +++ b/code/modules/mob/living/basic/slime/ai/subtrees.dm @@ -24,7 +24,7 @@ // Slime subtree for hunting down people to drain /datum/ai_planning_subtree/find_and_hunt_target/find_slime_food finding_behavior = /datum/ai_behavior/find_hunt_target/find_slime_food - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/slime + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/slime hunt_targets = list(/mob/living) hunt_range = 7 diff --git a/code/modules/mob/living/basic/space_fauna/ant.dm b/code/modules/mob/living/basic/space_fauna/ant.dm index 7fbbe03e631cd..3ae46b7f53947 100644 --- a/code/modules/mob/living/basic/space_fauna/ant.dm +++ b/code/modules/mob/living/basic/space_fauna/ant.dm @@ -36,10 +36,20 @@ ai_controller = /datum/ai_controller/basic_controller/ant +/datum/emote/ant + mob_type_allowed_typecache = /mob/living/basic/ant + mob_type_blacklist_typecache = list() + +/datum/emote/ant/clack + key = "clack" + key_third_person = "clacks" + message = "clacks happily!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + /mob/living/basic/ant/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) - AddElement(/datum/element/pet_bonus, "clacks happily!") + AddElement(/datum/element/pet_bonus, "clack") AddElement(/datum/element/ai_retaliate) AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW) diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp.dm b/code/modules/mob/living/basic/space_fauna/carp/carp.dm index 3461f5b104e98..a315e253ecebc 100644 --- a/code/modules/mob/living/basic/space_fauna/carp/carp.dm +++ b/code/modules/mob/living/basic/space_fauna/carp/carp.dm @@ -81,6 +81,16 @@ /obj/structure/window, )) +/datum/emote/carp + mob_type_allowed_typecache = /mob/living/basic/carp + mob_type_blacklist_typecache = list() + +/datum/emote/carp/bloop + key = "bloop" + key_third_person = "bloops" + message = "bloops!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + /mob/living/basic/carp/Initialize(mapload, mob/tamer) ADD_TRAIT(src, TRAIT_FREE_HYPERSPACE_MOVEMENT, INNATE_TRAIT) //Need to set before init cause if we init in hyperspace we get dragged before the trait can be added . = ..() @@ -96,6 +106,7 @@ AddComponent(/datum/component/aggro_emote, emote_list = string_list(list("gnashes"))) AddComponent(/datum/component/regenerator, outline_colour = regenerate_colour) + AddComponent(/datum/component/profound_fisher) if (tamer) tamed(tamer, feedback = FALSE) befriend(tamer) @@ -185,7 +196,7 @@ /mob/living/basic/carp/pet/Initialize(mapload) . = ..() AddElement(/datum/element/ai_retaliate) - AddElement(/datum/element/pet_bonus, "bloops happily!") + AddElement(/datum/element/pet_bonus, "bloop") /** * Lia - Sometimes the pet of the Head of Security. @@ -290,7 +301,7 @@ /mob/living/basic/carp/passive/Initialize(mapload) . = ..() AddComponent(/datum/component/ai_retaliate_advanced, CALLBACK(src, PROC_REF(on_attacked))) - AddElement(/datum/element/pet_bonus, "bloops happily!") + AddElement(/datum/element/pet_bonus, "bloop") ADD_TRAIT(src, TRAIT_PACIFISM, INNATE_TRAIT) /// If someone slaps one of the school, scatter diff --git a/code/modules/mob/living/basic/space_fauna/eyeball/eyeball_ai_behavior.dm b/code/modules/mob/living/basic/space_fauna/eyeball/eyeball_ai_behavior.dm index f50fca8c559da..5051f8153714d 100644 --- a/code/modules/mob/living/basic/space_fauna/eyeball/eyeball_ai_behavior.dm +++ b/code/modules/mob/living/basic/space_fauna/eyeball/eyeball_ai_behavior.dm @@ -83,6 +83,6 @@ else return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED -/datum/ai_behavior/hunt_target/unarmed_attack_target/carrot +/datum/ai_behavior/hunt_target/interact_with_target/carrot hunt_cooldown = 2 SECONDS always_reset_target = TRUE diff --git a/code/modules/mob/living/basic/space_fauna/eyeball/eyeball_ai_subtree.dm b/code/modules/mob/living/basic/space_fauna/eyeball/eyeball_ai_subtree.dm index 29ea1dfc352ea..17b260d03ed72 100644 --- a/code/modules/mob/living/basic/space_fauna/eyeball/eyeball_ai_subtree.dm +++ b/code/modules/mob/living/basic/space_fauna/eyeball/eyeball_ai_subtree.dm @@ -47,6 +47,6 @@ /datum/ai_planning_subtree/find_and_hunt_target/carrot target_key = BB_LOW_PRIORITY_HUNTING_TARGET - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/carrot + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/carrot hunt_targets = list(/obj/item/food/grown/carrot) hunt_range = 6 diff --git a/code/modules/mob/living/basic/space_fauna/mushroom.dm b/code/modules/mob/living/basic/space_fauna/mushroom.dm index ae26754259455..de501eaea2ee1 100644 --- a/code/modules/mob/living/basic/space_fauna/mushroom.dm +++ b/code/modules/mob/living/basic/space_fauna/mushroom.dm @@ -78,15 +78,10 @@ /datum/ai_planning_subtree/find_and_hunt_target/mushroom_food target_key = BB_LOW_PRIORITY_HUNTING_TARGET - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/mushroom_food + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/reset_target hunt_targets = list(/obj/item/food/grown/mushroom) hunt_range = 6 - -/datum/ai_behavior/hunt_target/unarmed_attack_target/mushroom_food - hunt_cooldown = 15 SECONDS - always_reset_target = TRUE - /mob/living/basic/mushroom/UnarmedAttack(atom/attack_target, proximity_flag, list/modifiers) . = ..() if(!.) diff --git a/code/modules/mob/living/basic/space_fauna/netherworld/creature.dm b/code/modules/mob/living/basic/space_fauna/netherworld/creature.dm index 0fe732554b286..e7f5ad852cc31 100644 --- a/code/modules/mob/living/basic/space_fauna/netherworld/creature.dm +++ b/code/modules/mob/living/basic/space_fauna/netherworld/creature.dm @@ -28,16 +28,18 @@ lighting_cutoff_blue = 15 ai_controller = /datum/ai_controller/basic_controller/simple_hostile_obstacles + var/health_scaling = TRUE /mob/living/basic/creature/Initialize(mapload) . = ..() AddElement(/datum/element/swabable, CELL_LINE_TABLE_NETHER, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 0) - AddComponent( - /datum/component/health_scaling_effects,\ - min_health_attack_modifier_lower = 15,\ - min_health_attack_modifier_upper = 30,\ - min_health_slowdown = -1.5,\ - ) + if(health_scaling) + AddComponent( + /datum/component/health_scaling_effects,\ + min_health_attack_modifier_lower = 15,\ + min_health_attack_modifier_upper = 30,\ + min_health_slowdown = -1.5,\ + ) GRANT_ACTION(/datum/action/cooldown/spell/jaunt/creature_teleport) @@ -100,3 +102,13 @@ exit_jaunt(cast_on) return enter_jaunt(cast_on) + +/mob/living/basic/creature/tiggles + name = "Miss Tiggles" + +/mob/living/basic/creature/hatchling + name = "hatchling" + health = 25 + maxHealth = 25 + health_scaling = FALSE + current_size = 0.85 diff --git a/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm b/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm index 62b6a8da7e6aa..615f314bf2e4b 100644 --- a/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm +++ b/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm @@ -235,7 +235,7 @@ var/list/icon_dimensions = get_icon_dimensions(target.icon) var/orbitsize = (icon_dimensions["width"] + icon_dimensions["height"]) * 0.5 - orbitsize -= (orbitsize / world.icon_size) * (world.icon_size * 0.25) + orbitsize -= (orbitsize / ICON_SIZE_ALL) * (ICON_SIZE_ALL * 0.25) orbit(target, orbitsize) /mob/living/basic/revenant/adjust_health(amount, updating_health = TRUE, forced = FALSE) diff --git a/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm b/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm index f672e60ee2940..b1acd8f9631b2 100644 --- a/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm +++ b/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm @@ -62,6 +62,11 @@ /// Our wing flap action var/datum/action/cooldown/mob_cooldown/wing_buffet/buffet + ///Are currently sharkified or a plain space dragon? + var/shark_form = FALSE + ///The amount of fish (weight) the space dragon has to eat to be sharkified and receive a cheevo for it. + var/fish_left = 15000 // 30 fish with a weight of 500. + /mob/living/basic/space_dragon/Initialize(mapload) . = ..() add_traits(list(TRAIT_SPACEWALK, TRAIT_FREE_HYPERSPACE_MOVEMENT, TRAIT_NO_FLOATING_ANIM, TRAIT_HEALS_FROM_CARP_RIFTS), INNATE_TRAIT) @@ -70,6 +75,7 @@ AddElement(/datum/element/wall_tearer, tear_time = 4 SECONDS, reinforced_multiplier = 3, do_after_key = DOAFTER_SOURCE_SPACE_DRAGON_INTERACTION) AddElement(/datum/element/door_pryer, pry_time = 4 SECONDS, interaction_key = DOAFTER_SOURCE_SPACE_DRAGON_INTERACTION) AddComponent(/datum/component/seethrough_mob) + AddComponent(/datum/component/profound_fisher, new /obj/item/fishing_rod/mob_fisher/dragon(src)) RegisterSignal(src, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(pre_attack)) RegisterSignal(src, COMSIG_MOB_STATCHANGE, PROC_REF(on_stat_changed)) RegisterSignal(src, COMSIG_ATOM_PRE_EX_ACT, PROC_REF(on_exploded)) @@ -89,9 +95,33 @@ . = ..() if(!isnull(chosen_colour)) return + if(client.get_award_status(/datum/award/achievement/misc/sharkdragon)) + if(tgui_alert(src, "Shall you take the dragon form or the shark form?","Shark Form Unlocked", list("Dragon","Shark")) == "Shark") + sharkify() rename_dragon() select_colour() +/mob/living/basic/space_dragon/mind_initialize() + . = ..() + if(shark_form && mind.get_skill_level(/datum/skill/fishing) < SKILL_LEVEL_APPRENTICE) + mind.set_level(/datum/skill/fishing, SKILL_LEVEL_APPRENTICE, TRUE) + +/mob/living/basic/space_dragon/proc/sharkify() + if(shark_form) + return + pixel_z -= 3 + base_pixel_z -= 3 + do_jitter_animation(150) + shark_form = TRUE + desc = "A piscine mutation of the fearsome leviathan whose flight defies modern physics. Said to be the other ultimate stage in the life cycle of the Space Carp." + icon_state = icon_state == icon_living ? "sharkdragon" : "sharkdragon_dead" + icon_living = "sharkdragon" + icon_dead = "sharkdragon_dead" + if(mind && mind.get_skill_level(/datum/skill/fishing) < SKILL_LEVEL_APPRENTICE) + mind.set_level(/datum/skill/fishing, SKILL_LEVEL_APPRENTICE, TRUE) + client?.give_award(/datum/award/achievement/misc/sharkdragon, src) + update_appearance() + /// Allows the space dragon to pick a funny name /mob/living/basic/space_dragon/proc/rename_dragon() var/chosen_name = sanitize_name(reject_bad_text(tgui_input_text(src, "What would you like your name to be?", "Choose Your Name", real_name, MAX_NAME_LEN))) @@ -125,9 +155,9 @@ icon_state = icon_living return if (HAS_TRAIT(src, TRAIT_WING_BUFFET_TIRED)) - icon_state = "spacedragon_gust_2" + icon_state = "[icon_living]_gust_2" return - icon_state = "spacedragon_gust" + icon_state = "[icon_living]_gust" /mob/living/basic/space_dragon/update_overlays() . = ..() @@ -139,7 +169,7 @@ else if (HAS_TRAIT(src, TRAIT_WING_BUFFET)) overlay_state = "overlay_gust" - var/mutable_appearance/overlay = mutable_appearance(icon, overlay_state) + var/mutable_appearance/overlay = mutable_appearance(icon, "[icon_living]_[overlay_state]") overlay.appearance_flags = RESET_COLOR . += overlay @@ -157,6 +187,8 @@ if (DOING_INTERACTION(source, DOAFTER_SOURCE_SPACE_DRAGON_INTERACTION)) balloon_alert(source, "busy!") return COMPONENT_HOSTILE_NO_ATTACK + if(isfish(target)) + INVOKE_ASYNC(src, PROC_REF(try_eat), target) if (!isliving(target)) return var/mob/living/living_target = target @@ -166,14 +198,23 @@ return COMPONENT_HOSTILE_NO_ATTACK /// Try putting something inside us -/mob/living/basic/space_dragon/proc/try_eat(mob/living/food) +/mob/living/basic/space_dragon/proc/try_eat(atom/movable/food) balloon_alert(src, "swallowing...") if (do_after(src, 3 SECONDS, target = food)) - eat(food) + if(isliving(food)) + eat(food) + else if(isfish(food)) + eat_fish(food) /// Succeed in putting something inside us /mob/living/basic/space_dragon/proc/eat(mob/living/food) - adjust_health(-food.maxHealth * 0.25) + var/health_recovered = food.maxHealth * 0.25 + if(shark_form) + if(istype(food, /mob/living/basic/carp)) + health_recovered *= 1.75 // plus 7.5 points when eating advanced space carps (from the rift) + else + health_recovered *= 0.75 // minus 7.5 points when eating a human for example. + adjust_health(round(-health_recovered, 1)) if (QDELETED(food) || food.loc == src) return FALSE playsound(src, 'sound/effects/magic/demon_attack1.ogg', 60, TRUE) @@ -182,6 +223,43 @@ food.forceMove(src) return TRUE +/mob/living/basic/space_dragon/proc/eat_fish(obj/item/fish/fish) + //a standard fish weights about 500 units on average, rarely exceeds 2000 units, the amount healed is less than a one fiftyth of our total on average. + var/health_recovered = fish.weight * 0.014 + if(shark_form) + health_recovered *= 2 + else + fish_left -= fish.weight + if(fish_left <= 0) + addtimer(CALLBACK(src, PROC_REF(begin_sharkify)), 2 SECONDS) + fish_left = initial(fish_left) //prevent begin_sharkify from being called again by eating another fish. + adjust_health(round(-health_recovered, 1)) + playsound(src, 'sound/effects/magic/demon_attack1.ogg', 40, TRUE) + visible_message(span_boldwarning("[src] swallows [fish] whole!")) + if(HAS_TRAIT(fish, TRAIT_YUCKY_FISH)) + balloon_alert(src, "disgusting!") + to_chat(src, span_warning("that [fish.name] tasted awful, you feel like you're about to throw up...")) + addtimer(CALLBACK(src, PROC_REF(barf_contents)), 3 SECONDS) + qdel(fish) + +/mob/living/basic/space_dragon/proc/begin_sharkify() + do_jitter_animation(300) + addtimer(CALLBACK(src, PROC_REF(sharkify)), 1.2 SECONDS) + visible_message(span_warning("[src] begins mutating!")) + +/mob/living/basic/space_dragon/proc/barf_contents() + if(stat == DEAD) + return + new /obj/effect/decal/cleanable/vomit(loc) + playsound(src, 'sound/effects/splat.ogg', vol = 50, vary = TRUE) + visible_message(span_danger("[src] vomits up everything it ate so far!")) + for(var/atom/movable/eaten in src) + if(HAS_TRAIT(eaten, TRAIT_NOT_BARFABLE)) + continue + eaten.forceMove(eaten.loc) + if(prob(90)) + step(eaten, pick(GLOB.alldirs)) + /mob/living/basic/space_dragon/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs) . = ..() if (isliving(arrived)) @@ -230,5 +308,10 @@ . = ..() mind.add_antag_datum(/datum/antagonist/space_dragon) +/// The internal fishing rod of our space dragon +/obj/item/fishing_rod/mob_fisher/dragon + difficulty_modifier = -14 + hook = /obj/item/fishing_hook/jaws + #undef REJECT_DARK_COLOUR_THRESHOLD #undef DOAFTER_SOURCE_SPACE_DRAGON_INTERACTION diff --git a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_ai.dm b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_ai.dm index ae971fd2558e5..18ae6fc3e7523 100644 --- a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_ai.dm +++ b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_ai.dm @@ -44,11 +44,13 @@ /datum/ai_controller/basic_controller/giant_spider/pest blackboard = list( BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic/of_size/ours_or_smaller, // Hunt mobs our size + BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends, BB_FLEE_TARGETING_STRATEGY = /datum/targeting_strategy/basic/of_size/larger, // Run away from mobs bigger than we are ) idle_behavior = /datum/idle_behavior/idle_random_walk planning_subtrees = list( + /datum/ai_planning_subtree/pet_planning, /datum/ai_planning_subtree/target_retaliate/to_flee, /datum/ai_planning_subtree/flee_target/from_flee_key, /datum/ai_planning_subtree/simple_find_target, diff --git a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spiders.dm b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spiders.dm index f293f1dcbaacd..1e78bd924a833 100644 --- a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spiders.dm +++ b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spiders.dm @@ -608,6 +608,6 @@ /mob/living/basic/spider/giant/sgt_araneus/Initialize(mapload) . = ..() - AddElement(/datum/element/pet_bonus, "chitters proudly!") + AddElement(/datum/element/pet_bonus, "chitter") AddElement(/datum/element/ai_retaliate) ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) diff --git a/code/modules/mob/living/basic/space_fauna/spider/spider.dm b/code/modules/mob/living/basic/space_fauna/spider/spider.dm index 118487f038392..195b814983301 100644 --- a/code/modules/mob/living/basic/space_fauna/spider/spider.dm +++ b/code/modules/mob/living/basic/space_fauna/spider/spider.dm @@ -49,6 +49,18 @@ /// If true then you shouldn't be told that you're a spider antagonist as soon as you are placed into this mob var/apply_spider_antag = TRUE +/datum/emote/spider + mob_type_allowed_typecache = /mob/living/basic/spider + mob_type_blacklist_typecache = list() + +/datum/emote/spider/chitter + key = "chitter" + key_third_person = "chitters" + message = "chitters." + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + vary = TRUE + sound = 'sound/mobs/non-humanoids/insect/chitter.ogg' + /mob/living/basic/spider/Initialize(mapload) . = ..() add_traits(list(TRAIT_WEB_SURFER, TRAIT_FENCE_CLIMBER), INNATE_TRAIT) @@ -171,10 +183,18 @@ response_harm_simple = "splat" ai_controller = /datum/ai_controller/basic_controller/giant_spider/pest apply_spider_antag = FALSE + ///list of pet commands we follow + var/static/list/pet_commands = list( + /datum/pet_command/idle, + /datum/pet_command/free, + /datum/pet_command/follow, + /datum/pet_command/perform_trick_sequence, + ) /mob/living/basic/spider/maintenance/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) AddElement(/datum/element/web_walker, /datum/movespeed_modifier/average_web) AddElement(/datum/element/ai_retaliate) + AddComponent(/datum/component/obeys_commands, pet_commands) AddElement(/datum/element/tiny_mob_hunter) diff --git a/code/modules/mob/living/basic/vermin/lizard.dm b/code/modules/mob/living/basic/vermin/lizard.dm index da68087d70ffa..c1c21850ee62a 100644 --- a/code/modules/mob/living/basic/vermin/lizard.dm +++ b/code/modules/mob/living/basic/vermin/lizard.dm @@ -46,10 +46,19 @@ /mob/living/basic/cockroach, )) +/datum/emote/lizard + mob_type_allowed_typecache = /mob/living/basic/lizard + mob_type_blacklist_typecache = list() + +/datum/emote/lizard/whicker + key = "tongue" + message = "sticks its tongue out contentedly!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + /mob/living/basic/lizard/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) - AddElement(/datum/element/pet_bonus, "sticks its tongue out contentedly!") + AddElement(/datum/element/pet_bonus, "tongue") AddElement(/datum/element/basic_eating, heal_amt = 5, food_types = edibles) ai_controller.set_blackboard_key(BB_BASIC_FOODS, typecacheof(edibles)) diff --git a/code/modules/mob/living/basic/vermin/mothroach/mothroach.dm b/code/modules/mob/living/basic/vermin/mothroach/mothroach.dm index 9659408b8b1aa..e4798ba2d1c6b 100644 --- a/code/modules/mob/living/basic/vermin/mothroach/mothroach.dm +++ b/code/modules/mob/living/basic/vermin/mothroach/mothroach.dm @@ -33,14 +33,32 @@ faction = list(FACTION_NEUTRAL) ai_controller = /datum/ai_controller/basic_controller/mothroach + ///list of pet commands we follow + var/static/list/pet_commands = list( + /datum/pet_command/idle, + /datum/pet_command/free, + /datum/pet_command/follow, + /datum/pet_command/perform_trick_sequence, + ) + +/datum/emote/mothroach + mob_type_allowed_typecache = /mob/living/basic/mothroach + mob_type_blacklist_typecache = list() + +/datum/emote/mothroach/squeaks + key = "squeaks" + key_third_person = "squeaks" + message = "squeaks!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE /mob/living/basic/mothroach/Initialize(mapload) . = ..() var/static/list/food_types = list(/obj/item/clothing) AddElement(/datum/element/basic_eating, food_types = food_types) + AddComponent(/datum/component/obeys_commands, pet_commands) ai_controller.set_blackboard_key(BB_BASIC_FOODS, typecacheof(food_types)) AddElement(/datum/element/ai_retaliate) - AddElement(/datum/element/pet_bonus, "squeaks happily!") + AddElement(/datum/element/pet_bonus, "squeak") add_verb(src, /mob/living/proc/toggle_resting) ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) diff --git a/code/modules/mob/living/basic/vermin/mothroach/mothroach_ai.dm b/code/modules/mob/living/basic/vermin/mothroach/mothroach_ai.dm index 5801d18321594..bed72a982399a 100644 --- a/code/modules/mob/living/basic/vermin/mothroach/mothroach_ai.dm +++ b/code/modules/mob/living/basic/vermin/mothroach/mothroach_ai.dm @@ -3,6 +3,7 @@ /datum/ai_controller/basic_controller/mothroach blackboard = list( BB_FLEE_TARGETING_STRATEGY = /datum/targeting_strategy/basic, + BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends, BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic/allow_items, ) @@ -10,6 +11,7 @@ ai_movement = /datum/ai_movement/basic_avoidance idle_behavior = /datum/idle_behavior/idle_random_walk planning_subtrees = list( + /datum/ai_planning_subtree/pet_planning, /datum/ai_planning_subtree/find_food/mothroach, /datum/ai_planning_subtree/target_retaliate/to_flee, /datum/ai_planning_subtree/flee_target/from_flee_key, diff --git a/code/modules/mob/living/basic/vermin/mouse.dm b/code/modules/mob/living/basic/vermin/mouse.dm index cb62ad956f95c..a0c1faf971d06 100644 --- a/code/modules/mob/living/basic/vermin/mouse.dm +++ b/code/modules/mob/living/basic/vermin/mouse.dm @@ -36,6 +36,25 @@ var/contributes_to_ratcap = TRUE /// Probability that, if we successfully bite a shocked cable, that we will die to it. var/cable_zap_prob = 85 + ///list of pet commands we follow + var/static/list/pet_commands = list( + /datum/pet_command/idle, + /datum/pet_command/free, + /datum/pet_command/follow, + /datum/pet_command/perform_trick_sequence, + ) + +/datum/emote/mouse + mob_type_allowed_typecache = /mob/living/basic/mouse + mob_type_blacklist_typecache = list() + +/datum/emote/mouse/squeak + key = "squeak" + key_third_person = "squeaks" + message = "squeak!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + vary = TRUE + sound = 'sound/mobs/non-humanoids/mouse/mousesqueek.ogg' /mob/living/basic/mouse/Initialize(mapload, tame = FALSE, new_body_color) . = ..() @@ -55,6 +74,7 @@ var/static/list/loc_connections = list( COMSIG_ATOM_ENTERED = PROC_REF(on_entered), ) + AddComponent(/datum/component/obeys_commands, pet_commands) AddElement(/datum/element/connect_loc, loc_connections) make_tameable() AddComponent(/datum/component/swarming, 16, 16) //max_x, max_y @@ -270,7 +290,7 @@ . = ..() // Tom fears no cable. ADD_TRAIT(src, TRAIT_SHOCKIMMUNE, INNATE_TRAIT) - AddElement(/datum/element/pet_bonus, "squeaks happily!") + AddElement(/datum/element/pet_bonus, "squeak") /mob/living/basic/mouse/brown/tom/create_a_new_rat() new /mob/living/basic/mouse/brown(loc, /* tame = */ tame) // dominant gene @@ -383,9 +403,8 @@ /// The mouse AI controller /datum/ai_controller/basic_controller/mouse blackboard = list( // Always cowardly - BB_CURRENT_HUNTING_TARGET = null, // cheese - BB_LOW_PRIORITY_HUNTING_TARGET = null, // cable BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic, // Use this to find people to run away from + BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends, BB_BASIC_MOB_FLEE_DISTANCE = 3, ) @@ -393,6 +412,7 @@ ai_movement = /datum/ai_movement/basic_avoidance idle_behavior = /datum/idle_behavior/idle_random_walk planning_subtrees = list( + /datum/ai_planning_subtree/pet_planning, // Top priority is to look for and execute hunts for cheese even if someone is looking at us /datum/ai_planning_subtree/find_and_hunt_target/look_for_cheese, // Next priority is see if anyone is looking at us diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index 9744bcbada7e5..dcf00435fba91 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -29,6 +29,8 @@ /obj/item/toy/toy_xeno, /obj/item/sticker, //funny ~Jimmyl /obj/item/toy/plush/rouny, + /obj/item/hand_item, + /obj/item/queen_promotion, )) /mob/living/carbon/alien/Initialize(mapload) diff --git a/code/modules/mob/living/carbon/carbon_update_icons.dm b/code/modules/mob/living/carbon/carbon_update_icons.dm index 1049a0bbf9aa4..07dd6f2f737f1 100644 --- a/code/modules/mob/living/carbon/carbon_update_icons.dm +++ b/code/modules/mob/living/carbon/carbon_update_icons.dm @@ -1,7 +1,6 @@ /mob/living/carbon/update_obscured_slots(obscured_flags) ..() - if(obscured_flags & (HIDEEARS|HIDEEYES|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT|HIDEMUTWINGS|HIDETAIL|HIDEHORNS)) // DOPPLER EDIT, old code: if(obscured_flags & (HIDEEARS|HIDEEYES|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT|HIDEMUTWINGS)) - update_body() + update_body() /// Updates features and clothing attached to a specific limb with limb-specific offsets /mob/living/carbon/proc/update_features(feature_key) diff --git a/code/modules/mob/living/carbon/death.dm b/code/modules/mob/living/carbon/death.dm index 8d4e66bccda6e..abf7cdaabdd99 100644 --- a/code/modules/mob/living/carbon/death.dm +++ b/code/modules/mob/living/carbon/death.dm @@ -17,12 +17,6 @@ var/datum/brain_trauma/BT = T BT.on_death() -/mob/living/carbon/proc/inflate_gib() // Plays an animation that makes mobs appear to inflate before finally gibbing - addtimer(CALLBACK(src, PROC_REF(gib), DROP_BRAIN|DROP_ORGANS|DROP_ITEMS), 2.5 SECONDS) - var/matrix/M = matrix() - M.Scale(1.8, 1.2) - animate(src, time = 40, transform = M, easing = SINE_EASING) - /mob/living/carbon/gib(drop_bitflags=NONE) add_memory_in_range(src, 7, /datum/memory/witness_gib, protagonist = src) if(drop_bitflags & DROP_ITEMS) diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index 3d7ed9626ac50..c06e8d268d86d 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -228,6 +228,10 @@ . += "[t_He] [t_is] flushed and wheezing." if (bodytemperature < dna.species.bodytemp_cold_damage_limit) . += "[t_He] [t_is] shivering." + if(HAS_TRAIT(src, TRAIT_EVIL)) + . += "[t_His] eyes radiate with a unfeeling, cold detachment. There is nothing but darkness within [t_his] soul." + living_user.add_mood_event("encountered_evil", /datum/mood_event/encountered_evil) + living_user.set_jitter_if_lower(15 SECONDS) if(HAS_TRAIT(user, TRAIT_SPIRITUAL) && mind?.holy_role) . += "[t_He] [t_has] a holy aura about [t_him]." @@ -470,7 +474,7 @@ var/cables_or_cuffs = istype(handcuffed, /obj/item/restraints/handcuffs/cable) ? "restrained with cable" : "handcuffed" . += span_warning("[t_He] [t_is] [icon2html(handcuffed, user)] [cables_or_cuffs]!") //belt - if(belt && !(belt.item_flags & EXAMINE_SKIP)) + if(belt && !(obscured & ITEM_SLOT_BELT) && !(belt.item_flags & EXAMINE_SKIP)) . += "[t_He] [t_has] [belt.examine_title(user)] about [t_his] waist." //shoes if(shoes && !(obscured & ITEM_SLOT_FEET) && !(shoes.item_flags & EXAMINE_SKIP)) diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index afa488148de16..7bd77bf5736f0 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -112,8 +112,6 @@ GLOBAL_LIST_EMPTY(features_by_species) var/inert_mutation = /datum/mutation/human/dwarfism ///Used to set the mob's death_sound upon species change var/death_sound - ///Sounds to override barefeet walking - var/list/special_step_sounds ///Special sound for grabbing var/grab_sound /// A path to an outfit that is important for species life e.g. plasmaman outfit @@ -374,9 +372,6 @@ GLOBAL_LIST_EMPTY(features_by_species) human_who_gained_species.living_flags |= STOP_OVERLAY_UPDATE_BODY_PARTS //Don't call update_body_parts() for every single bodypart overlay added. // Drop the items the new species can't wear - if(human_who_gained_species.hud_used) - human_who_gained_species.hud_used.update_locked_slots() - human_who_gained_species.mob_biotypes = inherent_biotypes human_who_gained_species.mob_respiration_type = inherent_respiration_type human_who_gained_species.butcher_results = knife_butcher_results?.Copy() @@ -385,7 +380,8 @@ GLOBAL_LIST_EMPTY(features_by_species) replace_body(human_who_gained_species, src) regenerate_organs(human_who_gained_species, old_species, replace_current = FALSE, visual_only = human_who_gained_species.visual_only_organs) - + // Update locked slots AFTER all organ and body stuff is handled + human_who_gained_species.hud_used?.update_locked_slots() // Drop the items the new species can't wear INVOKE_ASYNC(src, PROC_REF(worn_items_fit_body_check), human_who_gained_species, TRUE) @@ -659,7 +655,7 @@ GLOBAL_LIST_EMPTY(features_by_species) if(ITEM_SLOT_OCLOTHING) return equip_delay_self_check(I, H, bypass_equip_delay_self) if(ITEM_SLOT_GLOVES) - if(H.num_hands < 2) + if(H.num_hands == 0) return FALSE return equip_delay_self_check(I, H, bypass_equip_delay_self) if(ITEM_SLOT_FEET) @@ -1146,7 +1142,7 @@ GLOBAL_LIST_EMPTY(features_by_species) humi.adjust_coretemperature(skin_core_change) // get the enviroment details of where the mob is standing - var/datum/gas_mixture/environment = humi.loc.return_air() + var/datum/gas_mixture/environment = humi.loc?.return_air() if(!environment) // if there is no environment (nullspace) drop out here. return @@ -1392,20 +1388,12 @@ GLOBAL_LIST_EMPTY(features_by_species) H.adjustBruteLoss(pressure_damage, required_bodytype = BODYTYPE_ORGANIC) H.throw_alert(ALERT_PRESSURE, /atom/movable/screen/alert/lowpressure, 2) - -////////// -// FIRE // -////////// - -/datum/species/proc/handle_fire(mob/living/carbon/human/H, seconds_per_tick, no_protection = FALSE) - return no_protection - //////////// // Stun // //////////// /datum/species/proc/spec_stun(mob/living/carbon/human/H,amount) - if(H.movement_type & FLYING) + if((H.movement_type & FLYING) && !H.buckled) var/obj/item/organ/external/wings/functional/wings = H.get_organ_slot(ORGAN_SLOT_EXTERNAL_WINGS) if(wings) wings.toggle_flight(H) @@ -1492,6 +1480,10 @@ GLOBAL_LIST_EMPTY(features_by_species) /datum/species/proc/get_sneeze_sound(mob/living/carbon/human/human) return +/// Returns the species' snore sound. +/datum/species/proc/get_snore_sound(mob/living/carbon/human/human) + return + /datum/species/proc/get_mut_organs(include_brain = TRUE) var/list/mut_organs = list() mut_organs += mutant_organs @@ -2038,7 +2030,7 @@ GLOBAL_LIST_EMPTY(features_by_species) * * Returns a color string or null. */ -/datum/species/proc/get_fixed_hair_color(mob/living/carbon/human/for_mob) +/datum/species/proc/get_fixed_hair_color(mob/living/carbon/for_mob) ASSERT(!isnull(for_mob)) switch(hair_color_mode) if(USE_MUTANT_COLOR) diff --git a/code/modules/mob/living/carbon/human/dummy.dm b/code/modules/mob/living/carbon/human/dummy.dm index 23b1ad5126694..9970d973a7dba 100644 --- a/code/modules/mob/living/carbon/human/dummy.dm +++ b/code/modules/mob/living/carbon/human/dummy.dm @@ -115,7 +115,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) target.dna.features["moth_wings"] = get_consistent_feature_entry(SSaccessories.moth_wings_list) target.dna.features["snout"] = get_consistent_feature_entry(SSaccessories.snouts_list) target.dna.features["spines"] = get_consistent_feature_entry(SSaccessories.spines_list) - target.dna.features["tail_cat"] = get_consistent_feature_entry(SSaccessories.tails_list_human) // it's a lie + target.dna.features["tail_cat"] = get_consistent_feature_entry(SSaccessories.tails_list_felinid) // it's a lie target.dna.features["tail_lizard"] = get_consistent_feature_entry(SSaccessories.tails_list_lizard) target.dna.features["tail_monkey"] = get_consistent_feature_entry(SSaccessories.tails_list_monkey) target.dna.features["pod_hair"] = get_consistent_feature_entry(SSaccessories.pod_hair_list) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 29134e5097697..9fcb4083f30f6 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -107,7 +107,7 @@ if(HAS_TRAIT(src, TRAIT_UNKNOWN)) to_chat(viewer, span_notice("You can't make out that ID anymore.")) return - if(get_dist(viewer, src) > ID_EXAMINE_DISTANCE + 1) // leeway + if(!isobserver(viewer) && get_dist(viewer, src) > ID_EXAMINE_DISTANCE + 1) // leeway, ignored if the viewer is a ghost to_chat(viewer, span_notice("You can't make out that ID from here.")) return @@ -707,46 +707,10 @@ /mob/living/carbon/human/update_health_hud() if(!client || !hud_used) return - // Updates the health bar, also sends signal . = ..() - - // Updates the health doll - if(!hud_used.healthdoll) - return - - hud_used.healthdoll.cut_overlays() - if(stat == DEAD) - hud_used.healthdoll.icon_state = "healthdoll_DEAD" - return - - hud_used.healthdoll.icon_state = "healthdoll_OVERLAY" - for(var/obj/item/bodypart/body_part as anything in bodyparts) - var/icon_num = 0 - - if(SEND_SIGNAL(body_part, COMSIG_BODYPART_UPDATING_HEALTH_HUD, src) & COMPONENT_OVERRIDE_BODYPART_HEALTH_HUD) - continue - - var/damage = body_part.burn_dam + body_part.brute_dam - var/comparison = (body_part.max_damage/5) - if(damage) - icon_num = 1 - if(damage > (comparison)) - icon_num = 2 - if(damage > (comparison*2)) - icon_num = 3 - if(damage > (comparison*3)) - icon_num = 4 - if(damage > (comparison*4)) - icon_num = 5 - if(has_status_effect(/datum/status_effect/grouped/screwy_hud/fake_healthy)) - icon_num = 0 - if(icon_num) - hud_used.healthdoll.add_overlay(mutable_appearance('icons/hud/screen_gen.dmi', "[body_part.body_zone][icon_num]")) - for(var/t in get_missing_limbs()) //Missing limbs - hud_used.healthdoll.add_overlay(mutable_appearance('icons/hud/screen_gen.dmi', "[t]6")) - for(var/t in get_disabled_limbs()) //Disabled limbs - hud_used.healthdoll.add_overlay(mutable_appearance('icons/hud/screen_gen.dmi', "[t]7")) + // Handles changing limb colors and stuff + hud_used.healthdoll?.update_appearance() /mob/living/carbon/human/fully_heal(heal_flags = HEAL_ALL) if(heal_flags & HEAL_NEGATIVE_MUTATIONS) @@ -1076,16 +1040,38 @@ if(use_random_name) fully_replace_character_name(real_name, generate_random_mob_name()) -///Proc used to prevent syndicate monkeys and player-selectable Pun Pun able to use objects while stuck in monkey mode. -/mob/living/carbon/human/proc/make_clever_and_no_dna_scramble() +///Proc used to make monkey roles able to function like crew, but not be able to shift into humans easily. +/mob/living/carbon/human/proc/crewlike_monkify() + if(!ismonkey(src)) + set_species(/datum/species/monkey) dna.add_mutation(/datum/mutation/human/clever) // Can't make them human or nonclever. At least not with the easy and boring way out. for(var/datum/mutation/human/mutation as anything in dna.mutations) mutation.mutadone_proof = TRUE mutation.instability = 0 - - // Extra backup! - ADD_TRAIT(src, TRAIT_NO_DNA_SCRAMBLE, SPECIES_TRAIT) + mutation.class = MUT_OTHER + + add_traits(list(TRAIT_NO_DNA_SCRAMBLE, TRAIT_BADDNA, TRAIT_BORN_MONKEY), SPECIES_TRAIT) + +/mob/living/carbon/human/proc/is_atmos_sealed(additional_flags = null, check_hands = FALSE, ignore_chest_pressureprot = FALSE) + var/chest_covered = FALSE + var/head_covered = FALSE + var/hands_covered = FALSE + for (var/obj/item/clothing/equipped in get_equipped_items()) + // We don't really have space-proof gloves, so even if we're checking them we ignore the flags + if ((equipped.body_parts_covered & HANDS) && num_hands >= default_num_hands) + hands_covered = TRUE + if (!isnull(additional_flags) && !(equipped.clothing_flags & additional_flags)) + continue + if ((ignore_chest_pressureprot || (equipped.clothing_flags & STOPSPRESSUREDAMAGE)) && (equipped.body_parts_covered & CHEST)) + chest_covered = TRUE + if ((equipped.clothing_flags & STOPSPRESSUREDAMAGE) && (equipped.body_parts_covered & HEAD)) + head_covered = TRUE + if (!chest_covered) + return FALSE + if (!hands_covered && check_hands) + return FALSE + return head_covered || HAS_TRAIT(src, TRAIT_HEAD_ATMOS_SEALED) /mob/living/carbon/human/species/abductor race = /datum/species/abductor diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 627e8daac0db5..68e6640bdeb10 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -808,6 +808,6 @@ SEND_SIGNAL(src, COMSIG_HUMAN_BURNING) burn_clothing(seconds_per_tick, fire_handler.stacks) var/no_protection = FALSE - if(dna && dna.species) - no_protection = dna.species.handle_fire(src, seconds_per_tick, no_protection) + if (HAS_TRAIT(src, TRAIT_IGNORE_FIRE_PROTECTION)) + no_protection = TRUE fire_handler.harm_human(seconds_per_tick, no_protection) 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 7d996bfc1bc5e..30bcebd5b811f 100644 --- a/code/modules/mob/living/carbon/human/human_update_icons.dm +++ b/code/modules/mob/living/carbon/human/human_update_icons.dm @@ -72,8 +72,7 @@ There are several things that need to be remembered: /mob/living/carbon/human/update_obscured_slots(obscured_flags) ..() - if(obscured_flags & HIDEFACE) - sec_hud_set_security_status() + sec_hud_set_security_status() /* --------------------------------------- */ //vvvvvv UPDATE_INV PROCS vvvvvv @@ -229,6 +228,20 @@ There are several things that need to be remembered: feature_y_offset = glove_offset["y"] gloves_overlay.pixel_y += feature_y_offset + + // We dont have any >2 hands human species (and likely wont ever), so theres no point in splitting this because: + // It will only run if the left hand OR the right hand is missing, and it wont run if both are missing because you cant wear gloves with no arms + // (unless admins mess with this then its their fault) + if(num_hands < default_num_hands) + var/static/atom/movable/alpha_filter_target + if(isnull(alpha_filter_target)) + alpha_filter_target = new(null) + alpha_filter_target.icon = 'icons/effects/effects.dmi' + alpha_filter_target.icon_state = "missing[!has_left_hand(check_disabled = FALSE) ? "l" : "r"]" + alpha_filter_target.render_target = "*MissGlove [REF(src)] [!has_left_hand(check_disabled = FALSE) ? "L" : "R"]" + gloves_overlay.add_overlay(alpha_filter_target) + gloves_overlay.filters += filter(type="alpha", render_source=alpha_filter_target.render_target, y=feature_y_offset, flags=MASK_INVERSE) + overlays_standing[GLOVES_LAYER] = gloves_overlay apply_overlay(GLOVES_LAYER) diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index d2ad1ad89ae2d..eef20329ef890 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -209,6 +209,7 @@ //Item is handled and in slot, valid to call callback, for this proc should always be true if(!not_handled) has_equipped(equipping, slot, initial) + hud_used?.update_locked_slots() // Send a signal for when we equip an item that used to cover our feet/shoes. Used for bloody feet if(equipping.body_parts_covered & FEET || (equipping.flags_inv | equipping.transparent_protection) & HIDESHOES) @@ -300,6 +301,7 @@ update_equipment_speed_mods() update_obscured_slots(I.flags_inv) + hud_used?.update_locked_slots() /mob/living/carbon/human/toggle_internals(obj/item/tank, is_external = FALSE) // Just close the tank if it's the one the mob already has open. diff --git a/code/modules/mob/living/carbon/human/species_types/felinid.dm b/code/modules/mob/living/carbon/human/species_types/felinid.dm index 4c89f9d4b66c1..11fecb60bfcc4 100644 --- a/code/modules/mob/living/carbon/human/species_types/felinid.dm +++ b/code/modules/mob/living/carbon/human/species_types/felinid.dm @@ -13,6 +13,7 @@ TRAIT_CATLIKE_GRACE, TRAIT_HATED_BY_DOGS, TRAIT_USES_SKINTONES, + TRAIT_WATER_HATER, ) changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT species_language_holder = /datum/language_holder/felinid @@ -108,6 +109,10 @@ return 'sound/mobs/humanoids/human/sniff/female_sniff.ogg' return 'sound/mobs/humanoids/human/sniff/male_sniff.ogg' +/datum/species/human/felinid/get_snore_sound(mob/living/carbon/human/felinid) + if(felinid.physique == FEMALE) + return SFX_SNORE_FEMALE + return SFX_SNORE_MALE /proc/mass_purrbation() diff --git a/code/modules/mob/living/carbon/human/species_types/humans.dm b/code/modules/mob/living/carbon/human/species_types/humans.dm index cbb16fea3dccc..92f9110d03f1a 100644 --- a/code/modules/mob/living/carbon/human/species_types/humans.dm +++ b/code/modules/mob/living/carbon/human/species_types/humans.dm @@ -88,6 +88,11 @@ return 'sound/mobs/humanoids/human/sniff/female_sniff.ogg' return 'sound/mobs/humanoids/human/sniff/male_sniff.ogg' +/datum/species/human/get_snore_sound(mob/living/carbon/human/human) + if(human.physique == FEMALE) + return SFX_SNORE_FEMALE + return SFX_SNORE_MALE + /datum/species/human/get_species_description() return "Humans are the dominant species in the known galaxy. \ Their kind extend from old Earth to the edges of known space." @@ -124,7 +129,9 @@ to humans. As a human, silicons are required to both protect and obey you.", )) - if(CONFIG_GET(flag/enforce_human_authority)) + var/human_authority_setting = CONFIG_GET(string/human_authority) + + if(human_authority_setting == HUMAN_AUTHORITY_NON_HUMAN_WHITELIST || human_authority_setting == HUMAN_AUTHORITY_ENFORCED) to_add += list(list( SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, SPECIES_PERK_ICON = "bullhorn", diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm index b7c97b6451bd1..3b1f8fe4037fe 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -528,7 +528,7 @@ var/datum/action/innate/use_extract/major/extract_major = new(src) extract_major.Grant(new_jellyperson) - luminescent_actions += integrate_extract + luminescent_actions += extract_major /datum/species/jelly/luminescent/on_species_loss(mob/living/carbon/C) . = ..() diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm index 45faab6713931..de24a90071c5e 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -109,6 +109,11 @@ return 'sound/mobs/humanoids/human/sniff/female_sniff.ogg' return 'sound/mobs/humanoids/human/sniff/male_sniff.ogg' +/datum/species/lizard/get_snore_sound(mob/living/carbon/human/lizard) + if(lizard.physique == FEMALE) + return SFX_SNORE_FEMALE + return SFX_SNORE_MALE + /datum/species/lizard/get_physical_attributes() return "Lizardpeople can withstand slightly higher temperatures than most species, but they are very vulnerable to the cold \ and can't regulate their body-temperature internally, making the vacuum of space extremely deadly to them." diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index bcbdf0276df6f..c8a8faaa4827c 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -68,62 +68,6 @@ /// If the bones themselves are burning clothes won't help you much var/internal_fire = FALSE -/datum/species/plasmaman/spec_life(mob/living/carbon/human/H, seconds_per_tick, times_fired) - . = ..() - var/atmos_sealed = TRUE - if(HAS_TRAIT(H, TRAIT_NOFIRE)) - atmos_sealed = FALSE - else if(!isclothing(H.wear_suit) || !(H.wear_suit.clothing_flags & STOPSPRESSUREDAMAGE)) - atmos_sealed = FALSE - else if(!HAS_TRAIT(H, TRAIT_NOSELFIGNITION_HEAD_ONLY) && (!isclothing(H.head) || !(H.head.clothing_flags & STOPSPRESSUREDAMAGE))) - atmos_sealed = FALSE - - var/flammable_limb = FALSE - for(var/obj/item/bodypart/found_bodypart as anything in H.bodyparts)//If any plasma based limb is found the plasmaman will attempt to autoignite - if(IS_ORGANIC_LIMB(found_bodypart) && found_bodypart.limb_id == SPECIES_PLASMAMAN) //Allows for "donated" limbs and augmented limbs to prevent autoignition - flammable_limb = TRUE - break - - if(!flammable_limb && !H.on_fire) //Allows their suit to attempt to autoextinguish if augged and on fire - return - - var/can_burn = FALSE - if(!isclothing(H.w_uniform) || !(H.w_uniform.clothing_flags & PLASMAMAN_PREVENT_IGNITION)) - can_burn = TRUE - else if(!isclothing(H.gloves)) - can_burn = TRUE - else if(!HAS_TRAIT(H, TRAIT_NOSELFIGNITION_HEAD_ONLY) && (!isclothing(H.head) || !(H.head.clothing_flags & PLASMAMAN_PREVENT_IGNITION))) - can_burn = TRUE - - if(!atmos_sealed && can_burn) - var/datum/gas_mixture/environment = H.loc.return_air() - if(environment?.total_moles()) - if(environment.gases[/datum/gas/hypernoblium] && (environment.gases[/datum/gas/hypernoblium][MOLES]) >= 5) - if(H.on_fire && H.fire_stacks > 0) - H.adjust_fire_stacks(-10 * seconds_per_tick) - else if(!HAS_TRAIT(H, TRAIT_NOFIRE)) - if(environment.gases[/datum/gas/oxygen] && (environment.gases[/datum/gas/oxygen][MOLES]) >= 1) //Same threshhold that extinguishes fire - H.adjust_fire_stacks(0.25 * seconds_per_tick) - if(!H.on_fire && H.fire_stacks > 0) - H.visible_message(span_danger("[H]'s body reacts with the atmosphere and bursts into flames!"),span_userdanger("Your body reacts with the atmosphere and bursts into flame!")) - H.ignite_mob() - internal_fire = TRUE - - else if(H.fire_stacks) - var/obj/item/clothing/under/plasmaman/P = H.w_uniform - if(istype(P)) - P.Extinguish(H) - internal_fire = FALSE - else - internal_fire = FALSE - - H.update_appearance(UPDATE_OVERLAYS) - -/datum/species/plasmaman/handle_fire(mob/living/carbon/human/H, seconds_per_tick, no_protection = FALSE) - if(internal_fire) - no_protection = TRUE - . = ..() - /datum/species/plasmaman/pre_equip_species_outfit(datum/job/job, mob/living/carbon/human/equipping, visuals_only = FALSE) if(job?.plasmaman_outfit) equipping.equipOutfit(job.plasmaman_outfit, visuals_only) diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm index 5b43bf980c4a1..10af8d53c80f8 100644 --- a/code/modules/mob/living/carbon/inventory.dm +++ b/code/modules/mob/living/carbon/inventory.dm @@ -180,6 +180,7 @@ //in a slot (handled further down inheritance chain, probably living/carbon/human/equip_to_slot if(!not_handled) has_equipped(equipping, slot, initial) + hud_used?.update_locked_slots() return not_handled @@ -237,6 +238,7 @@ update_equipment_speed_mods() update_obscured_slots(I.flags_inv) + hud_used?.update_locked_slots() /// Returns TRUE if an air tank compatible helmet is equipped. /mob/living/carbon/proc/can_breathe_helmet() diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index 03a29762f6dc3..d4005cf51ebed 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -27,6 +27,13 @@ SEND_SIGNAL(src, COMSIG_LIVING_GIBBED, drop_bitflags) qdel(src) +// Plays an animation that makes mobs appear to inflate before finally gibbing +/mob/living/proc/inflate_gib(drop_bitflags=DROP_BRAIN|DROP_ORGANS|DROP_ITEMS, gib_time = 2.5 SECONDS, anim_time = 4 SECONDS) + addtimer(CALLBACK(src, PROC_REF(gib), drop_bitflags), gib_time) + var/matrix/M = matrix() + M.Scale(1.8, 1.2) + animate(src, time = anim_time, transform = M, easing = SINE_EASING) + /mob/living/proc/gib_animation() return diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index c71359c58f12b..7420a5d7bad76 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -436,7 +436,6 @@ return return user.dna.species.get_sniff_sound(user) - /datum/emote/living/snore key = "snore" key_third_person = "snores" @@ -445,6 +444,12 @@ emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE stat_allowed = UNCONSCIOUS +// eventually we want to give species their own "snoring" sounds +/datum/emote/living/snore/get_sound(mob/living/carbon/human/user) + if(!istype(user)) + return + return user.dna.species.get_snore_sound(user) + /datum/emote/living/stare key = "stare" key_third_person = "stares" diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index e3f6b7d1ae981..77d1b3cb05c93 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -832,7 +832,7 @@ if(!livingdoll.filtered) livingdoll.filtered = TRUE var/icon/mob_mask = icon(icon, icon_state) - if(mob_mask.Height() > world.icon_size || mob_mask.Width() > world.icon_size) + if(mob_mask.Height() > ICON_SIZE_Y || mob_mask.Width() > ICON_SIZE_X) var/health_doll_icon_state = health_doll_icon ? health_doll_icon : "megasprite" mob_mask = icon('icons/hud/screen_gen.dmi', health_doll_icon_state) //swap to something generic if they have no special doll livingdoll.add_filter("mob_shape_mask", 1, alpha_mask_filter(icon = mob_mask)) @@ -1204,8 +1204,11 @@ var/altered_grab_state = pulledby.grab_state if((body_position == LYING_DOWN || HAS_TRAIT(src, TRAIT_GRABWEAKNESS) || get_timed_status_effect_duration(/datum/status_effect/staggered)) && pulledby.grab_state < GRAB_KILL) //If prone, resisting out of a grab is equivalent to 1 grab state higher. won't make the grab state exceed the normal max, however altered_grab_state++ - var/resist_chance = BASE_GRAB_RESIST_CHANCE /// see defines/combat.dm, this should be baseline 60% - resist_chance = (resist_chance/altered_grab_state) ///Resist chance divided by the value imparted by your grab state. It isn't until you reach neckgrab that you gain a penalty to escaping a grab. + if(HAS_TRAIT(src, TRAIT_GRABRESISTANCE)) + altered_grab_state-- + // see defines/combat.dm, this should be baseline 60% + // Resist chance divided by the value imparted by your grab state. It isn't until you reach neckgrab that you gain a penalty to escaping a grab. + var/resist_chance = altered_grab_state ? (BASE_GRAB_RESIST_CHANCE / altered_grab_state) : 100 if(prob(resist_chance)) visible_message(span_danger("[src] breaks free of [pulledby]'s grip!"), \ span_danger("You break free of [pulledby]'s grip!"), null, null, pulledby) @@ -2163,6 +2166,19 @@ GLOBAL_LIST_EMPTY(fire_appearances) /mob/living/proc/start_look_up() SIGNAL_HANDLER + + looking_vertically = TRUE + + var/turf/current_turf = get_turf(src) + var/turf/above_turf = GET_TURF_ABOVE(current_turf) + + //Check if turf above exists + if(!above_turf) + to_chat(src, span_warning("There's nothing interesting above.")) + to_chat(src, "You set your head straight again.") + end_look_up() + return + var/turf/ceiling = get_step_multiz(src, UP) if(!ceiling) //We are at the highest z-level. if (prob(0.1)) @@ -2183,7 +2199,6 @@ GLOBAL_LIST_EMPTY(fire_appearances) to_chat(src, span_warning("You can't see through the floor above you.")) return - looking_vertically = TRUE reset_perspective(ceiling) /mob/living/proc/stop_look_up() @@ -2214,6 +2229,19 @@ GLOBAL_LIST_EMPTY(fire_appearances) /mob/living/proc/start_look_down() SIGNAL_HANDLER + + looking_vertically = TRUE + + var/turf/current_turf = get_turf(src) + var/turf/below_turf = GET_TURF_BELOW(current_turf) + + //Check if turf below exists + if(!below_turf) + to_chat(src, span_warning("There's nothing interesting below.")) + to_chat(src, "You set your head straight again.") + end_look_up() + return + var/turf/floor = get_turf(src) var/turf/lower_level = get_step_multiz(floor, DOWN) if(!lower_level) //We are at the lowest z-level. @@ -2235,7 +2263,6 @@ GLOBAL_LIST_EMPTY(fire_appearances) to_chat(src, span_warning("You can't see through the floor below you.")) return - looking_vertically = TRUE reset_perspective(lower_level) /mob/living/proc/stop_look_down() @@ -2765,18 +2792,40 @@ GLOBAL_LIST_EMPTY(fire_appearances) set category = "IC" if(looking_vertically) + to_chat(src, "You set your head straight again.") end_look_up() - else - look_up() + return + + var/turf/current_turf = get_turf(src) + var/turf/above_turf = GET_TURF_ABOVE(current_turf) + + //Check if turf above exists + if(!above_turf) + to_chat(src, span_warning("There's nothing interesting above. Better keep your eyes ahead.")) + return + + to_chat(src, "You tilt your head upwards.") + look_up() /mob/living/verb/lookdown() set name = "Look Down" set category = "IC" if(looking_vertically) + to_chat(src, "You set your head straight again.") end_look_down() - else - look_down() + return + + var/turf/current_turf = get_turf(src) + var/turf/below_turf = GET_TURF_BELOW(current_turf) + + //Check if turf below exists + if(!below_turf) + to_chat(src, span_warning("There's nothing interesting below. Better keep your eyes ahead.")) + return + + to_chat(src, "You tilt your head downwards.") + look_down() /** * Totals the physical cash on the mob and returns the total. diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index 32382b663398b..2f29fdd7bc6d1 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -179,7 +179,7 @@ // I'd like to make this scale with the steps we take, but it like, just can't // So we're doin this instead - eyeobj.glide_size = world.icon_size + eyeobj.glide_size = ICON_SIZE_ALL last_moved = world.timeofday if(acceleration) diff --git a/code/modules/mob/living/silicon/ai/multicam.dm b/code/modules/mob/living/silicon/ai/multicam.dm index 97ea9ebedc9e4..4ef437a53036a 100644 --- a/code/modules/mob/living/silicon/ai/multicam.dm +++ b/code/modules/mob/living/silicon/ai/multicam.dm @@ -32,7 +32,7 @@ if((width > 0) && (height > 0)) var/matrix/M = matrix() M.Scale(width + 0.5, height + 0.5) - M.Translate((width-1)/2 * world.icon_size, (height-1)/2 * world.icon_size) + M.Translate((width-1)/2 * ICON_SIZE_X, (height-1)/2 * ICON_SIZE_Y) highlighted_background.transform = M standard_background.transform = M add_overlay(highlighted ? highlighted_background : standard_background) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 1d3562d9dfb08..e53fa80dfdd8c 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -342,9 +342,12 @@ /mob/living/silicon/robot/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents) if(same_z_layer || QDELING(src)) return ..() - cut_overlay(eye_lights) - SET_PLANE_EXPLICIT(eye_lights, PLANE_TO_TRUE(eye_lights.plane), src) - add_overlay(eye_lights) + + if(eye_lights) + cut_overlay(eye_lights) + SET_PLANE_EXPLICIT(eye_lights, PLANE_TO_TRUE(eye_lights.plane), src) + add_overlay(eye_lights) + return ..() /mob/living/silicon/robot/proc/self_destruct(mob/usr) diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 2142d1bb0a3d7..d19526e584c79 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -484,3 +484,11 @@ if(builtInCamera && builtInCamera.can_use()) return TRUE return ..() + +///Places laws on the status panel for silicons +/mob/living/silicon/get_status_tab_items() + . = ..() + var/list/law_list = list("Obey these laws:") + law_list += laws.get_law_list(include_zeroth = TRUE, render_html = FALSE) + for(var/borg_laws in law_list) + . += borg_laws diff --git a/code/modules/mob/living/sneeze.dm b/code/modules/mob/living/sneeze.dm index 4c38027fda0d8..ebf6162083482 100644 --- a/code/modules/mob/living/sneeze.dm +++ b/code/modules/mob/living/sneeze.dm @@ -30,8 +30,8 @@ if(catcher && catcher.given_turf) catcher.calculate_params() /// Take the target and subtract self for relative grid position. Then take the pixel x on the tile and divide by the tiles pixel size, and add 0.5 so it's fired from the center - var/sneeze_x = catcher.given_turf.x - x + catcher.given_x / world.icon_size - 0.5 - var/sneeze_y = catcher.given_turf.y - y + catcher.given_y / world.icon_size - 0.5 + var/sneeze_x = catcher.given_turf.x - x + catcher.given_x / ICON_SIZE_X - 0.5 + var/sneeze_y = catcher.given_turf.y - y + catcher.given_y / ICON_SIZE_Y - 0.5 angle = ATAN2(sneeze_y, sneeze_x) // Check if we're within the sneeze cone, otherwise just sneeze straight diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 24e95cad60800..28062fd06699a 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -63,6 +63,9 @@ ///Cursor icon used when holding shift over things var/examine_cursor_icon = 'icons/effects/mouse_pointers/examine_pointer.dmi' + /// Mob bitflags + var/mob_flags = NONE + /// Whether a mob is alive or dead. TODO: Move this to living - Nodrak (2019, still here) var/stat = CONSCIOUS diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 6cb7ad84902f3..bb3397cfec9c5 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -167,19 +167,21 @@ var/client/C = M.client var/oldx = C.pixel_x var/oldy = C.pixel_y - var/max = strength*world.icon_size - var/min = -(strength*world.icon_size) + var/max_x = strength*ICON_SIZE_X + var/max_y = strength*ICON_SIZE_Y + var/min_x = -(strength*ICON_SIZE_X) + var/min_y = -(strength*ICON_SIZE_Y) //How much time to allot for each pixel moved - var/time_scalar = (1 / world.icon_size) * TILES_PER_SECOND + var/time_scalar = (1 / ICON_SIZE_ALL) * TILES_PER_SECOND var/last_x = oldx var/last_y = oldy var/time_spent = 0 while(time_spent < duration) //Get a random pos in our box - var/x_pos = rand(min, max) + oldx - var/y_pos = rand(min, max) + oldy + var/x_pos = rand(min_x, max_x) + oldx + var/y_pos = rand(min_y, max_y) + oldy //We take the smaller of our two distances so things still have the propencity to feel somewhat jerky var/time = round(max(min(abs(last_x - x_pos), abs(last_y - y_pos)) * time_scalar, 1)) diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 13bd8ee2318e8..1c8d6ad09fc75 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -543,28 +543,22 @@ return remote_control.relaymove(src, UP) var/turf/current_turf = get_turf(src) - var/turf/above_turf = GET_TURF_ABOVE(current_turf) - - if(!above_turf) - to_chat(src, span_warning("There's nowhere to go in that direction!")) - return if(ismovable(loc)) //Inside an object, tell it we moved var/atom/loc_atom = loc return loc_atom.relaymove(src, UP) - var/ventcrawling_flag = HAS_TRAIT(src, TRAIT_MOVE_VENTCRAWLING) ? ZMOVE_VENTCRAWLING : 0 + var/obj/structure/ladder/current_ladder = locate() in current_turf + if(current_ladder) + current_ladder.use(src, TRUE) + return - if(can_z_move(DOWN, above_turf, current_turf, ZMOVE_FALL_FLAGS|ventcrawling_flag)) //Will we fall down if we go up? - if(buckled) - to_chat(src, span_warning("[buckled] is is not capable of flight.")) - else - to_chat(src, span_warning("You are not Superman.")) + if(!can_z_move(UP, current_turf, null, ZMOVE_CAN_FLY_CHECKS|ZMOVE_FEEDBACK)) return balloon_alert(src, "moving up...") if(!do_after(src, 1 SECONDS, hidden = TRUE)) return - if(zMove(UP, z_move_flags = ZMOVE_FLIGHT_FLAGS|ZMOVE_FEEDBACK|ventcrawling_flag)) + if(zMove(UP, z_move_flags = ZMOVE_FLIGHT_FLAGS|ZMOVE_FEEDBACK)) to_chat(src, span_notice("You move upwards.")) ///Moves a mob down a z level @@ -576,21 +570,22 @@ return remote_control.relaymove(src, DOWN) var/turf/current_turf = get_turf(src) - var/turf/below_turf = GET_TURF_BELOW(current_turf) - - if(!below_turf) - to_chat(src, span_warning("There's nowhere to go in that direction!")) - return if(ismovable(loc)) //Inside an object, tell it we moved var/atom/loc_atom = loc return loc_atom.relaymove(src, DOWN) - var/ventcrawling_flag = HAS_TRAIT(src, TRAIT_MOVE_VENTCRAWLING) ? ZMOVE_VENTCRAWLING : 0 + var/obj/structure/ladder/current_ladder = locate() in current_turf + if(current_ladder) + current_ladder.use(src, FALSE) + return + + if(!can_z_move(DOWN, current_turf, null, ZMOVE_CAN_FLY_CHECKS|ZMOVE_FEEDBACK)) + return balloon_alert(src, "moving down...") if(!do_after(src, 1 SECONDS, hidden = TRUE)) return - if(zMove(DOWN, z_move_flags = ZMOVE_FLIGHT_FLAGS|ZMOVE_FEEDBACK|ventcrawling_flag)) + if(zMove(DOWN, z_move_flags = ZMOVE_FLIGHT_FLAGS|ZMOVE_FEEDBACK)) to_chat(src, span_notice("You move down.")) return FALSE diff --git a/code/modules/mod/modules/module_kinesis.dm b/code/modules/mod/modules/module_kinesis.dm index c17f03747b13f..3c9ae3310b755 100644 --- a/code/modules/mod/modules/module_kinesis.dm +++ b/code/modules/mod/modules/module_kinesis.dm @@ -81,12 +81,12 @@ return mod.wearer.setDir(get_dir(mod.wearer, grabbed_atom)) if(grabbed_atom.loc == kinesis_catcher.given_turf) - if(grabbed_atom.pixel_x == kinesis_catcher.given_x - world.icon_size/2 && grabbed_atom.pixel_y == kinesis_catcher.given_y - world.icon_size/2) + if(grabbed_atom.pixel_x == kinesis_catcher.given_x - ICON_SIZE_X/2 && grabbed_atom.pixel_y == kinesis_catcher.given_y - ICON_SIZE_Y/2) return //spare us redrawing if we are standing still - animate(grabbed_atom, 0.2 SECONDS, pixel_x = grabbed_atom.base_pixel_x + kinesis_catcher.given_x - world.icon_size/2, pixel_y = grabbed_atom.base_pixel_y + kinesis_catcher.given_y - world.icon_size/2) + animate(grabbed_atom, 0.2 SECONDS, pixel_x = grabbed_atom.base_pixel_x + kinesis_catcher.given_x - ICON_SIZE_X/2, pixel_y = grabbed_atom.base_pixel_y + kinesis_catcher.given_y - ICON_SIZE_Y/2) kinesis_beam.redrawing() return - animate(grabbed_atom, 0.2 SECONDS, pixel_x = grabbed_atom.base_pixel_x + kinesis_catcher.given_x - world.icon_size/2, pixel_y = grabbed_atom.base_pixel_y + kinesis_catcher.given_y - world.icon_size/2) + animate(grabbed_atom, 0.2 SECONDS, pixel_x = grabbed_atom.base_pixel_x + kinesis_catcher.given_x - ICON_SIZE_X/2, pixel_y = grabbed_atom.base_pixel_y + kinesis_catcher.given_y - ICON_SIZE_Y/2) kinesis_beam.redrawing() var/turf/next_turf = get_step_towards(grabbed_atom, kinesis_catcher.given_turf) if(grabbed_atom.Move(next_turf, get_dir(grabbed_atom, next_turf), 8)) @@ -100,13 +100,13 @@ var/pixel_y_change = 0 var/direction = get_dir(grabbed_atom, next_turf) if(direction & NORTH) - pixel_y_change = world.icon_size/2 + pixel_y_change = ICON_SIZE_Y/2 else if(direction & SOUTH) - pixel_y_change = -world.icon_size/2 + pixel_y_change = -ICON_SIZE_Y/2 if(direction & EAST) - pixel_x_change = world.icon_size/2 + pixel_x_change = ICON_SIZE_X/2 else if(direction & WEST) - pixel_x_change = -world.icon_size/2 + pixel_x_change = -ICON_SIZE_X/2 animate(grabbed_atom, 0.2 SECONDS, pixel_x = grabbed_atom.base_pixel_x + pixel_x_change, pixel_y = grabbed_atom.base_pixel_y + pixel_y_change) kinesis_beam.redrawing() if(!isitem(grabbed_atom) || !COOLDOWN_FINISHED(src, hit_cooldown)) diff --git a/code/modules/mod/modules/modules_engineering.dm b/code/modules/mod/modules/modules_engineering.dm index dffa66e3931b5..9ddb0f9351c82 100644 --- a/code/modules/mod/modules/modules_engineering.dm +++ b/code/modules/mod/modules/modules_engineering.dm @@ -97,13 +97,22 @@ . = ..() if(!.) return - var/obj/projectile/tether = new /obj/projectile/tether(mod.wearer.loc) + var/obj/projectile/tether = new /obj/projectile/tether(mod.wearer.loc, src) tether.preparePixelProjectile(target, mod.wearer) tether.firer = mod.wearer playsound(src, 'sound/items/weapons/batonextend.ogg', 25, TRUE) INVOKE_ASYNC(tether, TYPE_PROC_REF(/obj/projectile, fire)) drain_power(use_energy_cost) +/obj/item/mod/module/tether/get_configuration() + . = ..() + .["cut_tethers"] = add_ui_configuration("Cut Tethers", "pin", TRUE) + +/obj/item/mod/module/tether/configure_edit(key, value) + if (key != "cut_tethers") + return + SEND_SIGNAL(src, COMSIG_MOD_TETHER_SNAP) + /obj/projectile/tether name = "tether" icon_state = "tether_projectile" @@ -120,15 +129,19 @@ var/line /// Last turf that we passed before impact var/turf/open/last_turf + /// MODsuit tether module that fired us + var/obj/item/mod/module/tether/parent_module -/obj/projectile/tether/Initialize(mapload) +/obj/projectile/tether/Initialize(mapload, module) . = ..() RegisterSignal(src, COMSIG_PROJECTILE_ON_EMBEDDED, PROC_REF(on_embedded)) + if (!isnull(module)) + parent_module = module /obj/projectile/tether/proc/on_embedded(datum/source, obj/item/payload, atom/hit) SIGNAL_HANDLER - firer.AddComponent(/datum/component/tether, hit, 7, "MODtether", payload) + firer.AddComponent(/datum/component/tether, hit, 7, "MODtether", payload, parent_module = parent_module) /obj/projectile/tether/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change) . = ..() @@ -150,7 +163,7 @@ return if (istype(target, /obj/item/tether_anchor) || isstructure(target) || ismachinery(target)) - firer.AddComponent(/datum/component/tether, target, 7, "MODtether") + firer.AddComponent(/datum/component/tether, target, 7, "MODtether", parent_module = parent_module) return var/hitx @@ -177,7 +190,7 @@ anchor.pixel_x = hitx anchor.pixel_y = hity anchor.anchored = TRUE - firer.AddComponent(/datum/component/tether, anchor, 7, "MODtether") + firer.AddComponent(/datum/component/tether, anchor, 7, "MODtether", parent_module = parent_module) /obj/projectile/tether/Destroy() QDEL_NULL(line) @@ -194,6 +207,7 @@ /obj/item/tether_anchor/examine(mob/user) . = ..() . += span_info("It can be secured by using a wrench on it. Use right-click to tether yourself to [src].") + . += span_info("LMB shortens the tether while RMB lengthens it. Ctrl-click to cut the tether.") /obj/item/tether_anchor/wrench_act(mob/living/user, obj/item/tool) . = ..() diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm index 3faf44fe2f088..485b66941d434 100644 --- a/code/modules/mod/modules/modules_general.dm +++ b/code/modules/mod/modules/modules_general.dm @@ -675,10 +675,10 @@ return ..() /obj/item/mod/module/plasma_stabilizer/on_equip() - ADD_TRAIT(mod.wearer, TRAIT_NOSELFIGNITION_HEAD_ONLY, MOD_TRAIT) + ADD_TRAIT(mod.wearer, TRAIT_HEAD_ATMOS_SEALED, MOD_TRAIT) /obj/item/mod/module/plasma_stabilizer/on_unequip() - REMOVE_TRAIT(mod.wearer, TRAIT_NOSELFIGNITION_HEAD_ONLY, MOD_TRAIT) + REMOVE_TRAIT(mod.wearer, TRAIT_HEAD_ATMOS_SEALED, MOD_TRAIT) //Finally, https://pipe.miroware.io/5b52ba1d94357d5d623f74aa/mspfa/Nuke%20Ops/Panels/0648.gif can be real: diff --git a/code/modules/mod/modules/modules_medical.dm b/code/modules/mod/modules/modules_medical.dm index 1d83f91dac81f..a0cf2408860d0 100644 --- a/code/modules/mod/modules/modules_medical.dm +++ b/code/modules/mod/modules/modules_medical.dm @@ -54,8 +54,6 @@ . = ..() .["mode"] = add_ui_configuration("Scan Mode", "list", mode, modes) - return . - /obj/item/mod/module/health_analyzer/configure_edit(key, value) switch(key) if("mode") diff --git a/code/modules/movespeed/modifiers/mobs.dm b/code/modules/movespeed/modifiers/mobs.dm index aa8c8153e97f5..aa6b9ac3a34c2 100644 --- a/code/modules/movespeed/modifiers/mobs.dm +++ b/code/modules/movespeed/modifiers/mobs.dm @@ -175,3 +175,17 @@ /datum/movespeed_modifier/magic_ties multiplicative_slowdown = 0.5 + +///movespeed modifier that makes you go faster when wet and lying on the floor once past the fish organ set threshold. +/datum/movespeed_modifier/fish_flopping + blacklisted_movetypes = MOVETYPES_NOT_TOUCHING_GROUND + multiplicative_slowdown = - (CRAWLING_ADD_SLOWDOWN * 0.71) + +///speed bonus given by the fish tail organ when inside water. +/datum/movespeed_modifier/fish_on_water + blacklisted_movetypes = MOVETYPES_NOT_TOUCHING_GROUND + multiplicative_slowdown = - /turf/open/water::slowdown + +///speed malus given by the fish organ set when dry +/datum/movespeed_modifier/fish_waterless + multiplicative_slowdown = 0.36 diff --git a/code/modules/paperwork/handlabeler.dm b/code/modules/paperwork/handlabeler.dm index 203d8234ca79f..938d41da51c28 100644 --- a/code/modules/paperwork/handlabeler.dm +++ b/code/modules/paperwork/handlabeler.dm @@ -211,7 +211,7 @@ return ..() -/obj/item/label/proc/stick_to_atom(atom/applying_to, stick_px = world.icon_size / 2, stick_py = world.icon_size / 2) +/obj/item/label/proc/stick_to_atom(atom/applying_to, stick_px = ICON_SIZE_X / 2, stick_py = ICON_SIZE_Y / 2) applying_to.AddComponent( \ /datum/component/sticker, \ stickering_atom = src, \ diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 14202b1bf3b36..eb7b2991852a2 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -367,7 +367,7 @@ return UI_CLOSE if(!user.can_read(src)) return UI_CLOSE - if(in_contents_of(/obj/machinery/door/airlock) || in_contents_of(/obj/item/clipboard)) + if(in_contents_of(/obj/machinery/door/airlock) || in_contents_of(/obj/item/clipboard) || in_contents_of(/obj/item/folder)) return UI_INTERACTIVE return ..() diff --git a/code/modules/photography/camera/camera.dm b/code/modules/photography/camera/camera.dm index 8666bcbda4dfd..5e9d8443408d8 100644 --- a/code/modules/photography/camera/camera.dm +++ b/code/modules/photography/camera/camera.dm @@ -226,8 +226,8 @@ dead_spotted += mob desc += mob.get_photo_description(src) - var/psize_x = (size_x * 2 + 1) * world.icon_size - var/psize_y = (size_y * 2 + 1) * world.icon_size + var/psize_x = (size_x * 2 + 1) * ICON_SIZE_X + var/psize_y = (size_y * 2 + 1) * ICON_SIZE_Y var/icon/get_icon = camera_get_icon(turfs, target_turf, psize_x, psize_y, clone_area, size_x, size_y, (size_x * 2 + 1), (size_y * 2 + 1)) qdel(clone_area) get_icon.Blend("#000", ICON_UNDERLAY) diff --git a/code/modules/photography/camera/camera_image_capturing.dm b/code/modules/photography/camera/camera_image_capturing.dm index c9f8d8dbe8eca..90afaaff2ad22 100644 --- a/code/modules/photography/camera/camera_image_capturing.dm +++ b/code/modules/photography/camera/camera_image_capturing.dm @@ -10,7 +10,7 @@ step_y = AM.step_y . = ..() -#define PHYSICAL_POSITION(atom) ((atom.y * world.icon_size) + (atom.pixel_y)) +#define PHYSICAL_POSITION(atom) ((atom.y * ICON_SIZE_Y) + (atom.pixel_y)) /obj/item/camera/proc/camera_get_icon(list/turfs, turf/center, psize_x = 96, psize_y = 96, datum/turf_reservation/clone_area, size_x, size_y, total_x, total_y) var/list/atoms = list() @@ -99,8 +99,8 @@ if(!skip_normal) //these are not clones for(var/atom/A in sorted) - var/xo = (A.x - center.x) * world.icon_size + A.pixel_x + xcomp - var/yo = (A.y - center.y) * world.icon_size + A.pixel_y + ycomp + var/xo = (A.x - center.x) * ICON_SIZE_X + A.pixel_x + xcomp + var/yo = (A.y - center.y) * ICON_SIZE_Y + A.pixel_y + ycomp if(ismovable(A)) var/atom/movable/AM = A xo += AM.step_x @@ -116,9 +116,9 @@ CHECK_TICK continue // Center of the image in X - var/xo = (clone.x - center.x) * world.icon_size + clone.pixel_x + xcomp + clone.step_x + var/xo = (clone.x - center.x) * ICON_SIZE_X + clone.pixel_x + xcomp + clone.step_x // Center of the image in Y - var/yo = (clone.y - center.y) * world.icon_size + clone.pixel_y + ycomp + clone.step_y + var/yo = (clone.y - center.y) * ICON_SIZE_Y + clone.pixel_y + ycomp + clone.step_y if(clone.transform) // getFlatIcon doesn't give a snot about transforms. var/datum/decompose_matrix/decompose = clone.transform.decompose() diff --git a/code/modules/photography/photos/frame.dm b/code/modules/photography/photos/frame.dm index 9efde283e0767..989fbb596c6df 100644 --- a/code/modules/photography/photos/frame.dm +++ b/code/modules/photography/photos/frame.dm @@ -278,6 +278,6 @@ ///Generates a persistence id unique to the current map. Every bar should feel a little bit different after all. /obj/structure/sign/picture_frame/portrait/bar/Initialize(mapload) - if(SSmapping.config.map_path != CUSTOM_MAP_PATH) //skip adminloaded custom maps. - persistence_id = "frame_bar_[SSmapping.config.map_name]" + if(SSmapping.current_map.map_path != CUSTOM_MAP_PATH) //skip adminloaded custom maps. + persistence_id = "frame_bar_[SSmapping.current_map.map_name]" return ..() diff --git a/code/modules/plumbing/ducts.dm b/code/modules/plumbing/ducts.dm index a7045567fa80d..66f745129be4d 100644 --- a/code/modules/plumbing/ducts.dm +++ b/code/modules/plumbing/ducts.dm @@ -368,16 +368,18 @@ All the important duct code: stack.merge(src) return ITEM_INTERACT_SUCCESS - check_attach_turf(interacting_with) - return ITEM_INTERACT_SUCCESS - + if(isopenturf(interacting_with)) + return check_attach_turf(interacting_with) ? ITEM_INTERACT_SUCCESS : ITEM_INTERACT_BLOCKING + return NONE /obj/item/stack/ducts/proc/check_attach_turf(atom/target) if(isopenturf(target) && use(1)) var/turf/open/open_turf = target var/is_omni = duct_color == DUCT_COLOR_OMNI new /obj/machinery/duct(open_turf, FALSE, GLOB.pipe_paint_colors[duct_color], GLOB.plumbing_layers[duct_layer], null, is_omni) - playsound(get_turf(src), 'sound/machines/click.ogg', 50, TRUE) + playsound(open_turf, 'sound/machines/click.ogg', 50, TRUE) + return TRUE + return FALSE /obj/item/stack/ducts/fifty amount = 50 diff --git a/code/modules/point/point.dm b/code/modules/point/point.dm index 681fbce2c6bac..ae7d9f78cb91a 100644 --- a/code/modules/point/point.dm +++ b/code/modules/point/point.dm @@ -24,7 +24,7 @@ SEND_SIGNAL(src, COMSIG_MOVABLE_POINTED, pointed_atom, visual, intentional) - animate(visual, pixel_x = (tile.x - our_tile.x) * world.icon_size + pointed_atom.pixel_x, pixel_y = (tile.y - our_tile.y) * world.icon_size + pointed_atom.pixel_y, time = 1.7, easing = EASE_OUT) + animate(visual, pixel_x = (tile.x - our_tile.x) * ICON_SIZE_X + pointed_atom.pixel_x, pixel_y = (tile.y - our_tile.y) * ICON_SIZE_Y + pointed_atom.pixel_y, time = 1.7, easing = EASE_OUT) return TRUE /mob/point_at(atom/pointed_atom, intentional = FALSE) diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 4b6c03c5eae05..fdfab1fed8462 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -1,6 +1,9 @@ //Use this only for things that aren't a subtype of obj/machinery/power //For things that are, override "should_have_node()" on them -GLOBAL_LIST_INIT(wire_node_generating_types, typecacheof(list(/obj/structure/grille))) +GLOBAL_LIST_INIT(wire_node_generating_types, typecacheof(list( + /obj/structure/grille, + /obj/structure/table/reinforced, +))) #define UNDER_SMES -1 #define UNDER_TERMINAL 1 diff --git a/code/modules/power/lighting/light.dm b/code/modules/power/lighting/light.dm index defb73fe2c7d5..487b26dd31459 100644 --- a/code/modules/power/lighting/light.dm +++ b/code/modules/power/lighting/light.dm @@ -680,12 +680,8 @@ /obj/machinery/light/proc/on_light_eater(obj/machinery/light/source, datum/light_eater) SIGNAL_HANDLER - . = COMPONENT_BLOCK_LIGHT_EATER - if(status == LIGHT_EMPTY) - return - var/obj/item/light/tube = drop_light_tube() - tube?.burn() - return + break_light_tube() + return COMPONENT_BLOCK_LIGHT_EATER /obj/machinery/light/on_saboteur(datum/source, disrupt_duration) . = ..() diff --git a/code/modules/power/singularity/dark_matter_singularity.dm b/code/modules/power/singularity/dark_matter_singularity.dm index bd379162b13a6..870e298cf97cf 100644 --- a/code/modules/power/singularity/dark_matter_singularity.dm +++ b/code/modules/power/singularity/dark_matter_singularity.dm @@ -13,13 +13,17 @@ icon_state = "dark_matter_s1" singularity_icon_variant = "dark_matter" maximum_stage = STAGE_FOUR + energy = 250 singularity_component_type = /datum/component/singularity/bloodthirsty ///to avoid cases of the singuloth getting blammed out of existence by the very meteor it rode in on... COOLDOWN_DECLARE(initial_explosion_immunity) -/obj/singularity/dark_matter/Initialize(mapload, starting_energy = 250) +/obj/singularity/dark_matter/Initialize(mapload, starting_energy) . = ..() COOLDOWN_START(src, initial_explosion_immunity, 5 SECONDS) + var/datum/component/singularity/resolved_singularity = singularity_component.resolve() + resolved_singularity.chance_to_move_to_target = 100 + addtimer(CALLBACK(src, PROC_REF(normalize_tracking)), 20 SECONDS) /obj/singularity/dark_matter/examine(mob/user) . = ..() @@ -49,4 +53,9 @@ desc = "You managed to make a singularity from dark matter, which makes no sense at all, and then you threw a supermatter into it? Are you fucking insane? Fuck it, praise Lord Singuloth." consumed_supermatter = TRUE +///For 20 seconds, the singularity has buffed tracking to ensure it actually makes its way to the station, normalizes after 20 seconds +/obj/singularity/dark_matter/proc/normalize_tracking() + var/datum/component/singularity/resolved_singularity = singularity_component.resolve() + resolved_singularity.chance_to_move_to_target = consumed_supermatter ? initial(resolved_singularity.chance_to_move_to_target) + DARK_MATTER_SUPERMATTER_CHANCE_BONUS : initial(resolved_singularity.chance_to_move_to_target) + #undef DARK_MATTER_SUPERMATTER_CHANCE_BONUS diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 0475736f6a502..40385624007b7 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -28,7 +28,7 @@ var/maximum_stage = STAGE_SIX ///How strong are we? - var/energy = 100 + var/energy = 50 ///Do we lose energy over time? var/dissipate = TRUE /// How long should it take for us to dissipate in seconds? @@ -55,10 +55,10 @@ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF | SHUTTLE_CRUSH_PROOF obj_flags = CAN_BE_HIT | DANGEROUS_POSSESSION -/obj/singularity/Initialize(mapload, starting_energy = 50) +/obj/singularity/Initialize(mapload, starting_energy) . = ..() - energy = starting_energy + energy = starting_energy || energy START_PROCESSING(SSsinguloprocess, src) SSpoints_of_interest.make_point_of_interest(src) @@ -70,7 +70,7 @@ singularity_component = WEAKREF(new_component) - expand(current_size) + check_energy() for (var/obj/machinery/power/singularity_beacon/singu_beacon as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/power/singularity_beacon)) if (singu_beacon.active) @@ -293,19 +293,19 @@ qdel(src) return FALSE switch(energy)//Some of these numbers might need to be changed up later -Mport - if(1 to 199) + if(STAGE_ONE_ENERGY_REQUIREMENT to STAGE_TWO_ENERGY_REQUIREMENT) allowed_size = STAGE_ONE - if(200 to 499) + if(STAGE_TWO_ENERGY_REQUIREMENT to STAGE_THREE_ENERGY_REQUIREMENT) allowed_size = STAGE_TWO - if(500 to 999) + if(STAGE_THREE_ENERGY_REQUIREMENT to STAGE_FOUR_ENERGY_REQUIREMENT) allowed_size = STAGE_THREE - if(1000 to 1999) + if(STAGE_FOUR_ENERGY_REQUIREMENT to STAGE_FIVE_ENERGY_REQUIREMENT) allowed_size = STAGE_FOUR - if(2000 to INFINITY) - if(energy >= 3000 && consumed_supermatter) - allowed_size = STAGE_SIX - else - allowed_size = STAGE_FIVE + if(STAGE_FIVE_ENERGY_REQUIREMENT to STAGE_SIX_ENERGY_REQUIREMENT) + allowed_size = STAGE_FIVE + if(STAGE_SIX_ENERGY_REQUIREMENT to INFINITY) + allowed_size = consumed_supermatter ? STAGE_SIX : STAGE_FIVE + if(current_size != allowed_size) expand() return TRUE @@ -496,10 +496,6 @@ . = ..() deadchat_plays(mode = DEMOCRACY_MODE) -/// Special singularity that spawns for shuttle events only -/obj/singularity/shuttle_event - anchored = FALSE - /// Special singularity spawned by being sucked into a black hole during emagged orion trail. /obj/singularity/orion move_self = FALSE @@ -512,3 +508,11 @@ /obj/singularity/orion/process(seconds_per_tick) if(SPT_PROB(0.5, seconds_per_tick)) mezzer() + +/// Special singularity that spawns for shuttle events only +/obj/singularity/shuttle_event + anchored = FALSE // this is required to work with shuttle event otherwise singularity gets stuck and doesn't move + +/obj/singularity/shuttle_event/no_escape + energy = STAGE_SIX_ENERGY + consumed_supermatter = TRUE // so we can get to the final stage diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index f74a93e263da4..9e708855d570e 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -39,12 +39,15 @@ var/output_level_max = 200 KILO WATTS // cap on output_level var/output_used = 0 // amount of power actually outputted. may be less than output_level if the powernet returns excess power + /// does this SMES show its input/output lights? + var/show_display_lights = TRUE + var/obj/machinery/power/terminal/terminal = null /obj/machinery/power/smes/examine(user) . = ..() if(!terminal) - . += span_warning("This SMES has no power terminal!") + . += span_warning("This [src] has no power terminal!") /obj/machinery/power/smes/Initialize(mapload) . = ..() @@ -81,20 +84,32 @@ /obj/machinery/power/smes/should_have_node() return TRUE +// adapted from APC item interacts for cable act handling +/obj/machinery/power/smes/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + . = NONE + if(istype(tool, /obj/item/stack/cable_coil)) + . = cable_act(user, tool, LAZYACCESS(modifiers, RIGHT_CLICK)) + if(.) + return . + return . + /obj/machinery/power/smes/cable_layer_act(mob/living/user, obj/item/tool) if(!QDELETED(terminal)) balloon_alert(user, "cut the terminal first!") return ITEM_INTERACT_BLOCKING return ..() -/obj/machinery/power/smes/attackby(obj/item/item, mob/user, params) - //opening using screwdriver - if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), item)) +//opening using screwdriver +/obj/machinery/power/smes/screwdriver_act(mob/living/user, obj/item/tool) + . = ITEM_INTERACT_BLOCKING + if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), tool)) update_appearance() - return + return ITEM_INTERACT_SUCCESS - //changing direction using wrench - if(default_change_direction_wrench(user, item)) +//changing direction using wrench +/obj/machinery/power/smes/wrench_act(mob/living/user, obj/item/tool) + . = ITEM_INTERACT_BLOCKING + if(default_change_direction_wrench(user, tool)) terminal = null var/turf/turf = get_step(src, dir) for(var/obj/machinery/power/terminal/term in turf) @@ -105,62 +120,59 @@ break if(!terminal) to_chat(user, span_alert("No power terminal found.")) - return + return ITEM_INTERACT_SUCCESS set_machine_stat(machine_stat & ~BROKEN) update_appearance() - return + return ITEM_INTERACT_SUCCESS - //building and linking a terminal - if(istype(item, /obj/item/stack/cable_coil)) - if(!can_place_terminal(user, item, silent = FALSE)) - return - - var/terminal_cable_layer - if(LAZYACCESS(params2list(params), RIGHT_CLICK)) - var/choice = tgui_input_list(user, "Select Power Input Cable Layer", "Select Cable Layer", GLOB.cable_name_to_layer) - if(isnull(choice) \ - || !user.is_holding(item) \ - || !user.Adjacent(src) \ - || user.incapacitated \ - || !can_place_terminal(user, item, silent = TRUE) \ - ) - return - terminal_cable_layer = GLOB.cable_name_to_layer[choice] - - user.visible_message(span_notice("[user.name] starts adding cables to [src].")) - balloon_alert(user, "adding cables...") - playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE) - - if(!do_after(user, 2 SECONDS, target = src)) - return - if(!can_place_terminal(user, item, silent = TRUE)) - return - var/obj/item/stack/cable_coil/cable = item - var/turf/turf = get_turf(user) - var/obj/structure/cable/connected_cable = turf.get_cable_node(terminal_cable_layer) //get the connecting node cable, if there's one - if (prob(50) && electrocute_mob(user, connected_cable, connected_cable, 1, TRUE)) //animate the electrocution if uncautious and unlucky - do_sparks(5, TRUE, src) - return - cable.use(10) - user.visible_message(span_notice("[user.name] adds cables to [src]")) - balloon_alert(user, "cables added") - //build the terminal and link it to the network - make_terminal(turf, terminal_cable_layer) - terminal.connect_to_network() - connect_to_network() +//building and linking a terminal +/obj/machinery/power/smes/proc/cable_act(mob/living/user, obj/item/stack/cable_coil/installing_cable, is_right_clicking) + . = ITEM_INTERACT_BLOCKING + if(!can_place_terminal(user, installing_cable, silent = FALSE)) + return ITEM_INTERACT_BLOCKING + var/terminal_cable_layer + if(is_right_clicking) + var/choice = tgui_input_list(user, "Select Power Input Cable Layer", "Select Cable Layer", GLOB.cable_name_to_layer) + if(isnull(choice) \ + || !user.is_holding(installing_cable) \ + || !user.Adjacent(src) \ + || user.incapacitated \ + || !can_place_terminal(user, installing_cable, silent = TRUE) \ + ) + return ITEM_INTERACT_BLOCKING + terminal_cable_layer = GLOB.cable_name_to_layer[choice] + user.visible_message(span_notice("[user.name] starts adding cables to [src].")) + balloon_alert(user, "adding cables...") + playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE) + + if(!do_after(user, 2 SECONDS, target = src)) + return ITEM_INTERACT_BLOCKING + if(!can_place_terminal(user, installing_cable, silent = TRUE)) + return ITEM_INTERACT_BLOCKING + var/obj/item/stack/cable_coil/cable = installing_cable + var/turf/turf = get_turf(user) + var/obj/structure/cable/connected_cable = turf.get_cable_node(terminal_cable_layer) //get the connecting node cable, if there's one + if (prob(50) && electrocute_mob(user, connected_cable, connected_cable, 1, TRUE)) //animate the electrocution if uncautious and unlucky + do_sparks(5, TRUE, src) + return ITEM_INTERACT_BLOCKING + cable.use(10) + user.visible_message(span_notice("[user.name] adds cables to [src].")) + balloon_alert(user, "cables added") + //build the terminal and link it to the network + make_terminal(turf, terminal_cable_layer) + terminal.connect_to_network() + return ITEM_INTERACT_SUCCESS + +//crowbarring it! +/obj/machinery/power/smes/crowbar_act(mob/living/user, obj/item/tool) + if(!panel_open) return - - //crowbarring it ! var/turf/turf = get_turf(src) - if(default_deconstruction_crowbar(item)) + if(default_deconstruction_crowbar(tool)) message_admins("[src] has been deconstructed by [ADMIN_LOOKUPFLW(user)] in [ADMIN_VERBOSEJMP(turf)].") user.log_message("deconstructed [src]", LOG_GAME) investigate_log("deconstructed by [key_name(user)] at [AREACOORD(src)].", INVESTIGATE_ENGINE) return - else if(panel_open && item.tool_behaviour == TOOL_CROWBAR) - return - - return ..() /// Checks if we're in a valid state to place a terminal /obj/machinery/power/smes/proc/can_place_terminal(mob/living/user, obj/item/stack/cable_coil/installing_cable, silent = TRUE) @@ -197,7 +209,7 @@ /obj/machinery/power/smes/default_deconstruction_crowbar(obj/item/crowbar/crowbar) if(istype(crowbar) && terminal) - to_chat(usr, span_warning("You must first remove the power terminal!")) + balloon_alert(usr, "remove the power terminal!") return FALSE return ..() @@ -231,24 +243,31 @@ terminal = null atom_break() +/// is this SMES in a suitable state to display overlays? +/obj/machinery/power/smes/proc/display_ready() + if(machine_stat & BROKEN) + return FALSE + if(panel_open) + return FALSE + return TRUE /obj/machinery/power/smes/update_overlays() . = ..() - if(machine_stat & BROKEN) - return - - if(panel_open) + if(!display_ready()) return - . += "smes-op[outputting ? 1 : 0]" - . += "smes-oc[inputting ? 1 : 0]" + if(show_display_lights) + . += "smes-op[outputting ? 1 : 0]" + . += "smes-oc[inputting ? 1 : 0]" - var/clevel = chargedisplay() - if(clevel > 0) - . += "smes-og[clevel]" + var/clevel = chargedisplay() + if(clevel > 0) + . += "smes-og[clevel]" /obj/machinery/power/smes/proc/chargedisplay() + if(capacity <= 0) + return 0 return clamp(round(5.5*charge/capacity),0,5) /obj/machinery/power/smes/process(seconds_per_tick) @@ -268,7 +287,7 @@ output_used = min(charge, output_energy) //limit output to that stored if (add_avail(output_used)) // add output to powernet if it exists (smes side) - charge -= output_used // reduce the storage (may be recovered in /restore() if excessive) + adjust_charge(-output_used) // reduce the storage (may be recovered in /restore() if excessive) else outputting = FALSE @@ -291,7 +310,7 @@ var/load = min((capacity-charge), input_energy, input_available) // charge at set rate, limited to spare capacity - charge += load // increase the charge + adjust_charge(load) // increase the charge terminal.add_load(load) // add the load to the terminal side network @@ -308,7 +327,13 @@ if(last_disp != chargedisplay() || last_chrg != inputting || last_onln != outputting) update_appearance() +/// Adjusts the charge in this SMES, used instead of directly adjusting the charge value. Mainly for the benefit of the power connector/portable SMES system. +/obj/machinery/power/smes/proc/adjust_charge(charge_adjust) + charge += charge_adjust +/// Sets the charge in this SMES, used instead of directly adjusting the charge value. Mainly for the benefit of the power connector/portable SMES system. +/obj/machinery/power/smes/proc/set_charge(charge_set) + charge = charge_set // called after all power processes are finished // restores charge level to smes if there was excess this ptick @@ -330,7 +355,7 @@ var/clev = chargedisplay() - charge += excess // restore unused power + adjust_charge(excess) // restore unused power powernet.netexcess -= excess // remove the excess from the powernet, so later SMESes don't try to use it output_used -= excess @@ -431,9 +456,9 @@ outputting = output_attempt output_level = rand(0, output_level_max) input_level = rand(0, input_level_max) - charge -= STANDARD_BATTERY_CHARGE/severity + adjust_charge(-STANDARD_BATTERY_CHARGE/severity) if (charge < 0) - charge = 0 + set_charge(0) update_appearance() log_smes() @@ -466,7 +491,6 @@ charge = INFINITY ..() - #undef SMES_CLEVEL_1 #undef SMES_CLEVEL_2 #undef SMES_CLEVEL_3 diff --git a/code/modules/power/smes_portable.dm b/code/modules/power/smes_portable.dm new file mode 100644 index 0000000000000..3b2d61669594b --- /dev/null +++ b/code/modules/power/smes_portable.dm @@ -0,0 +1,280 @@ +// idea inspired by vgstation, original pr on github vgstation-coders/vgstation13#4555 + +/obj/machinery/power/smes/connector + name = "power connector" + desc = "A user-safe high-current contact port, used for connecting and interfacing with portable power storage units. Practically useless without one." + icon_state = "battery_port" + circuit = /obj/item/circuitboard/machine/smes/connector + density = FALSE + input_attempt = FALSE + output_attempt = FALSE + + show_display_lights = FALSE + + capacity = 1 // solely to avoid div by zero + charge = 0 + var/obj/machinery/power/smesbank/connected_smes + +/obj/machinery/power/smes/connector/RefreshParts() + SHOULD_CALL_PARENT(FALSE) + var/power_coefficient = 0 + for(var/datum/stock_part/capacitor/capacitor in component_parts) + power_coefficient += capacitor.tier + input_level_max = initial(input_level_max) * power_coefficient + output_level_max = initial(output_level_max) * power_coefficient + +/obj/machinery/power/smes/connector/ui_act(action, params) + // prevent UI interactions if there's no SMES + if(!connected_smes) + balloon_alert(usr, "needs a connected SMES!") + return FALSE + return ..() + +/obj/machinery/power/smes/connector/display_ready() + if(!connected_smes) + return FALSE + return ..() + +/obj/machinery/power/smes/connector/update_appearance(updates) + . = ..() + connected_smes?.update_appearance(updates) + +/obj/machinery/power/smes/connector/update_overlays() + . = ..() + if(connected_smes && inputting) + . += "bp-c" + else + if(connected_smes) + if(charge > 0) + . += "bp-o" + else + . += "bp-d" + connected_smes?.update_appearance(UPDATE_OVERLAYS) + +/obj/machinery/power/smes/connector/crowbar_act(mob/living/user, obj/item/tool) + if(!connector_free(user)) + return ITEM_INTERACT_BLOCKING + return ..() + +/obj/machinery/power/smes/connector/wrench_act(mob/living/user, obj/item/tool) + if(!connector_free(user)) + return ITEM_INTERACT_BLOCKING + return ..() + +/obj/machinery/power/smes/connector/screwdriver_act(mob/living/user, obj/item/tool) + if(!connector_free(user)) + return ITEM_INTERACT_BLOCKING + return ..() + +/// checks if the connector is free; if not, alerts a user and returns FALSE +/obj/machinery/power/smes/connector/proc/connector_free(mob/living/user) + if(connected_smes) + balloon_alert(user, "disconnect SMES first!") + return FALSE + return TRUE + +/// connects the actual portable SMES once it's assigned, adjusting charge/maxcharge +/obj/machinery/power/smes/connector/proc/on_connect_smes() + charge = connected_smes.charge + capacity = connected_smes.capacity + update_appearance() + +/// disconnects the portable SMES, resetting internal charge + capacity +/obj/machinery/power/smes/connector/proc/on_disconnect_smes() + input_attempt = FALSE + output_attempt = FALSE + charge = initial(charge) + capacity = initial(capacity) + update_appearance() + +// we really should only be adjusting charge when there's a connected SMES bank. +/obj/machinery/power/smes/connector/adjust_charge(charge_adjust) + . = ..() + connected_smes?.charge += charge_adjust + +// same as above - if we have to set charge, affect the connected SMES bank as well +/obj/machinery/power/smes/connector/set_charge(charge_set) + . = ..() + connected_smes?.charge = charge_set + +/obj/machinery/power/smes/connector/Destroy() + connected_smes?.disconnect_port() // in the unlikely but possible case a SMES is connected and this explodes + return ..() + +/// The actual portable part of the portable SMES system. Pretty useless without an actual connector. +/obj/machinery/power/smesbank + name = "portable power storage unit" + desc = "A portable, high-capacity superconducting magnetic energy storage (SMES) unit. Requires a separate power connector port to actually interface with power networks." + icon_state = "port_smes" + circuit = /obj/item/circuitboard/machine/smesbank + use_power = NO_POWER_USE // well, technically + density = TRUE + anchored = FALSE + can_change_cable_layer = FALSE // cable layering is handled via connector port + /// The charge capacity. + var/capacity = 50 * STANDARD_BATTERY_CHARGE // The board defaults with 5 high capacity batteries. + /// The current charge. + var/charge = 0 + /// The port this is connected to. + var/obj/machinery/power/smes/connector/connected_port + +/obj/machinery/power/smesbank/on_construction(mob/user) + . = ..() + set_anchored(FALSE) + +/obj/machinery/power/smesbank/Initialize(mapload) + . = ..() + if(mapload) + mapped_setup() + +/obj/machinery/power/smesbank/interact(mob/user) + . = ..() + connected_port?.interact(user) + +/obj/machinery/power/smesbank/examine(user) + . = ..() + if(!connected_port) + . += span_warning("This SMES has no connector port!") + +//opening using screwdriver +/obj/machinery/power/smesbank/screwdriver_act(mob/living/user, obj/item/tool) + . = ITEM_INTERACT_BLOCKING + if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), tool)) + update_appearance() + return ITEM_INTERACT_SUCCESS + +/obj/machinery/power/smesbank/RefreshParts() + SHOULD_CALL_PARENT(FALSE) + var/max_charge = 0 + var/new_charge = 0 + for(var/obj/item/stock_parts/power_store/power_cell in component_parts) + max_charge += power_cell.maxcharge + new_charge += power_cell.charge + capacity = max_charge + if(!initial(charge) && !charge) + charge = new_charge + +/obj/machinery/power/smesbank/update_overlays() + . = ..() + if(machine_stat & BROKEN) + return + + if(panel_open) + return + + . += "smes-op[connected_port?.outputting ? 1 : 0]" + . += "smes-oc[connected_port?.inputting ? 1 : 0]" + var/clevel = chargedisplay() + if(clevel > 0) + . += "smes-og[clevel]" + +/obj/machinery/power/smesbank/proc/chargedisplay() + return clamp(round(5.5*charge/capacity),0,5) + +/obj/machinery/power/smesbank/default_deconstruction_crowbar(obj/item/crowbar/crowbar) + if(istype(crowbar) && connected_port) + balloon_alert(usr, "disconnect from [connected_port] first!") + return FALSE + return ..() + +// adapted from portable atmos connection code +/obj/machinery/power/smesbank/wrench_act(mob/living/user, obj/item/wrench) + if(connected_port) + wrench.play_tool_sound(src) + if(!wrench.use_tool(src, user, 8 SECONDS)) + return ITEM_INTERACT_BLOCKING + user.visible_message( \ + "[user] disconnects [src].", \ + span_notice("You unfasten [src] from [connected_port]."), \ + span_hear("You hear a ratchet.")) + investigate_log("was disconnected from [connected_port] by [key_name(user)].", INVESTIGATE_ENGINE) + disconnect_port() + update_appearance() + return ITEM_INTERACT_SUCCESS + + var/obj/machinery/power/smes/connector/possible_connector = locate(/obj/machinery/power/smes/connector) in loc + if(!possible_connector) + to_chat(user, span_notice("There's no power connector to connect to.")) + return ITEM_INTERACT_BLOCKING + wrench.play_tool_sound(src) + if(!wrench.use_tool(src, user, 4 SECONDS)) + return ITEM_INTERACT_BLOCKING + if(!connect_port(possible_connector)) + to_chat(user, span_notice("[src] failed to connect to [possible_connector].")) + return ITEM_INTERACT_BLOCKING + user.visible_message( \ + "[user] connects [src].", \ + span_notice("You fasten [src] to [possible_connector]."), \ + span_hear("You hear a ratchet.")) + update_appearance() + investigate_log("was connected to [possible_connector] by [key_name(user)].", INVESTIGATE_ENGINE) + return ITEM_INTERACT_SUCCESS + +/// Attempt to connect the portable SMES to a given connector. Adapted from portable atmos connection code. +/obj/machinery/power/smesbank/proc/connect_port(obj/machinery/power/smes/connector/possible_connector) + //Make sure not already connected to something else + if(connected_port || !possible_connector || possible_connector.connected_smes || possible_connector.panel_open) + return FALSE + + //Make sure are close enough for a valid connection + if(possible_connector.loc != get_turf(src)) + return FALSE + + //Perform the connection + connected_port = possible_connector + connected_port.connected_smes = src + possible_connector.on_connect_smes() + set_anchored(TRUE) //Prevent movement + connected_port.update_appearance() + update_appearance() + return TRUE + +/// Disconnects the portable SMES from its assigned connector, if it has any. Also adapted from portable atmos connection code. +/obj/machinery/power/smesbank/proc/disconnect_port() + if(!connected_port) + return + connected_port.on_disconnect_smes() + connected_port.connected_smes = null + connected_port = null + set_anchored(FALSE) + update_appearance() + +/obj/machinery/power/smesbank/Destroy() + disconnect_port() + return ..() + +/// Adjusts the charge of the portable SMES. See SMES code. +/obj/machinery/power/smesbank/proc/adjust_charge(charge_adjust) + charge += charge_adjust + +/// Sets the charge of the portable SMES. See SMES code. +/obj/machinery/power/smesbank/proc/set_charge(charge_set) + charge = charge_set + +/obj/machinery/power/smesbank/emp_act(severity) + . = ..() + if(. & EMP_PROTECT_SELF) + return + adjust_charge(-STANDARD_BATTERY_CHARGE/severity) // EMP'd banks double-dip on draining if connected. too bad, i guess + if (charge < 0) + set_charge(0) + update_appearance() + +/// Attempt to locate, connect to, and activate a portable connector, for pre-mapped portable SMESes. +/obj/machinery/power/smesbank/proc/mapped_setup() + var/obj/machinery/power/smes/connector/possible_connector = locate(/obj/machinery/power/smes/connector) in loc + if(!possible_connector) + return + if(!connect_port(possible_connector)) + return + possible_connector.input_attempt = TRUE + possible_connector.output_attempt = TRUE + +/obj/machinery/power/smesbank/super + name = "super capacity power storage unit" + desc = "A portable, super-capacity, superconducting magnetic energy storage (SMES) unit. Relatively rare, and typically installed in long-range outposts where minimal maintenance is expected." + circuit = /obj/item/circuitboard/machine/smesbank/super + capacity = 100 * STANDARD_BATTERY_CHARGE + +/obj/machinery/power/smesbank/super/full + charge = 100 * STANDARD_BATTERY_CHARGE diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 439c0b8d177b4..8c40d2d731aa6 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -153,10 +153,12 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) ///Stores the time of when the last zap occurred var/last_power_zap = 0 - ///Stores the tick of the machines subsystem of when the last zap occurred. Gives a passage of time in the perspective of SSmachines. - var/last_power_zap_perspective_machines = 0 - ///Same as [last_power_zap_perspective_machines], but based around the high energy zaps found in handle_high_power(). - var/last_high_energy_zap_perspective_machines = 0 + ///Stores the tick of the machines subsystem of when the last zap energy accumulation occurred. Gives a passage of time in the perspective of SSmachines. + var/last_energy_accumulation_perspective_machines = 0 + ///Same as [last_energy_accumulation_perspective_machines], but based around the high energy zaps found in handle_high_power(). + var/last_high_energy_accumulation_perspective_machines = 0 + /// Accumulated energy to be transferred from supermatter zaps. + var/list/zap_energy_accumulation = list() ///Do we show this crystal in the CIMS modular program var/include_in_cims = TRUE @@ -297,22 +299,25 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) // PART 3: POWER PROCESSING internal_energy_factors = calculate_internal_energy() zap_factors = calculate_zap_transmission_rate() - var/delta_time = (SSmachines.times_fired - last_power_zap_perspective_machines) * SSmachines.wait / (1 SECONDS) - if(delta_time && internal_energy && (last_power_zap + (4 - internal_energy * 0.001) SECONDS) < world.time) + var/delta_time = (SSmachines.times_fired - last_energy_accumulation_perspective_machines) * SSmachines.wait / (1 SECONDS) + var/accumulated_energy = accumulate_energy(ZAP_ENERGY_ACCUMULATION_NORMAL, energy = internal_energy * zap_transmission_rate * delta_time) + if(accumulated_energy && (last_power_zap + (4 - internal_energy * 0.001) SECONDS) < world.time) + var/discharged_energy = discharge_energy(ZAP_ENERGY_ACCUMULATION_NORMAL) playsound(src, 'sound/items/weapons/emitter2.ogg', 70, TRUE) hue_angle_shift = clamp(903 * log(10, (internal_energy + 8000)) - 3590, -50, 240) var/zap_color = color_matrix_rotate_hue(hue_angle_shift) supermatter_zap( zapstart = src, range = 3, - zap_str = internal_energy * zap_transmission_rate * delta_time, + zap_str = discharged_energy, zap_flags = ZAP_SUPERMATTER_FLAGS, - zap_cutoff = 240 KILO WATTS * delta_time, + zap_cutoff = 240 KILO JOULES, power_level = internal_energy, color = zap_color, ) + last_power_zap = world.time - last_power_zap_perspective_machines = SSmachines.times_fired + last_energy_accumulation_perspective_machines = SSmachines.times_fired // PART 4: DAMAGE PROCESSING temp_limit_factors = calculate_temp_limit() @@ -716,7 +721,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) activation_logged = TRUE // so we dont spam the log. else if(!internal_energy) last_power_zap = world.time - last_power_zap_perspective_machines = SSmachines.times_fired + last_energy_accumulation_perspective_machines = SSmachines.times_fired return additive_power /** Log when the supermatter is activated for the first time. @@ -893,6 +898,28 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) delamination_strategy.on_select(src) return TRUE +/** + * Accumulates energy for the zap_energy_accumulation key. + * Args: + * * key: The zap energy accumulation key to use. + * * energy: The amount of energy to accumulate. + * Returns: The accumulated energy for that key. + */ +/obj/machinery/power/supermatter_crystal/proc/accumulate_energy(key, energy) + . = (zap_energy_accumulation[key] ? zap_energy_accumulation[key] : 0) + energy + zap_energy_accumulation[key] = . + +/** + * Depletes a portion of the accumulated energy for the given key and returns it. Used for discharging energy from the supermatter. + * Args: + * * key: The zap energy accumulation key to use. + * * portion: The portion of the accumulated energy that gets discharged. + * Returns: The discharged energy for that key. + */ +/obj/machinery/power/supermatter_crystal/proc/discharge_energy(key, portion = ZAP_ENERGY_DISCHARGE_PORTION) + . = portion * zap_energy_accumulation[key] + zap_energy_accumulation[key] -= . + /obj/machinery/proc/supermatter_zap(atom/zapstart = src, range = 5, zap_str = 3.2 MEGA JOULES, zap_flags = ZAP_SUPERMATTER_FLAGS, list/targets_hit = list(), zap_cutoff = 1.2 MEGA JOULES, power_level = 0, zap_icon = DEFAULT_ZAP_ICON_STATE, color = null) if(QDELETED(zapstart)) return diff --git a/code/modules/power/supermatter/supermatter_extra_effects.dm b/code/modules/power/supermatter/supermatter_extra_effects.dm index a21a5ee728739..ffbbf566386dd 100644 --- a/code/modules/power/supermatter/supermatter_extra_effects.dm +++ b/code/modules/power/supermatter/supermatter_extra_effects.dm @@ -91,7 +91,7 @@ /obj/machinery/power/supermatter_crystal/proc/handle_high_power() if(internal_energy <= POWER_PENALTY_THRESHOLD && damage <= danger_point) //If the power is above 5000 or if the damage is above 550 - last_high_energy_zap_perspective_machines = SSmachines.times_fired //Prevent oddly high initial zap due to high energy zaps not getting triggered via too low energy. + last_high_energy_accumulation_perspective_machines = SSmachines.times_fired //Prevent oddly high initial zap due to high energy zaps not getting triggered via too low energy. return var/range = 4 zap_cutoff = 1500 @@ -129,11 +129,13 @@ if(zap_count >= 1) playsound(loc, 'sound/items/weapons/emitter2.ogg', 100, TRUE, extrarange = 10) - var/delta_time = (SSmachines.times_fired - last_high_energy_zap_perspective_machines) * SSmachines.wait / (1 SECONDS) - if(delta_time) + var/delta_time = (SSmachines.times_fired - last_high_energy_accumulation_perspective_machines) * SSmachines.wait / (1 SECONDS) + var/accumulated_energy = accumulate_energy(ZAP_ENERGY_ACCUMULATION_HIGH_ENERGY, energy = clamp(internal_energy * 3200, 6.4e6, 3.2e7) * delta_time) + if(accumulated_energy) for(var/i in 1 to zap_count) - supermatter_zap(src, range, clamp(internal_energy * 3200, 6.4e6, 3.2e7) * delta_time, flags, zap_cutoff = src.zap_cutoff * delta_time, power_level = internal_energy, zap_icon = src.zap_icon) - last_high_energy_zap_perspective_machines = SSmachines.times_fired + var/discharged_energy = discharge_energy(ZAP_ENERGY_ACCUMULATION_HIGH_ENERGY, portion = 1 - (1 - ZAP_ENERGY_DISCHARGE_PORTION) ** INVERSE(zap_count)) + supermatter_zap(src, range = range, zap_str = discharged_energy, zap_flags = flags, zap_cutoff = src.zap_cutoff, power_level = internal_energy, zap_icon = src.zap_icon) + last_high_energy_accumulation_perspective_machines = SSmachines.times_fired if(prob(5)) supermatter_anomaly_gen(src, FLUX_ANOMALY, rand(5, 10)) if(prob(5)) @@ -158,7 +160,7 @@ step_towards(movable_atom,center) /proc/supermatter_anomaly_gen(turf/anomalycenter, type = FLUX_ANOMALY, anomalyrange = 5, has_changed_lifespan = TRUE) - var/turf/local_turf = pick(orange(anomalyrange, anomalycenter)) + var/turf/local_turf = pick(RANGE_TURFS(anomalyrange, anomalycenter)) if(!local_turf) return switch(type) diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index b6187760f8360..5437ee0afd93c 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -24,8 +24,8 @@ light_range = 6 move_resist = INFINITY obj_flags = CAN_BE_HIT | DANGEROUS_POSSESSION - pixel_x = -32 - pixel_y = -32 + pixel_x = -ICON_SIZE_X + pixel_y = -ICON_SIZE_Y resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF | SHUTTLE_CRUSH_PROOF flags_1 = SUPERMATTER_IGNORES_1 @@ -78,8 +78,8 @@ var/list/shocking_info = list() tesla_zap(source = src, zap_range = 3, power = TESLA_DEFAULT_ENERGY, shocked_targets = shocking_info) - pixel_x = -32 - pixel_y = -32 + pixel_x = -ICON_SIZE_X + pixel_y = -ICON_SIZE_Y for (var/ball in orbiting_balls) var/range = rand(1, clamp(orbiting_balls.len, 2, 3)) var/list/temp_shock = list() @@ -149,7 +149,7 @@ var/list/icon_dimensions = get_icon_dimensions(icon) var/orbitsize = (icon_dimensions["width"] + icon_dimensions["height"]) * pick(0.4, 0.5, 0.6, 0.7, 0.8) - orbitsize -= (orbitsize / world.icon_size) * (world.icon_size * 0.25) + orbitsize -= (orbitsize / ICON_SIZE_ALL) * (ICON_SIZE_ALL * 0.25) miniball.orbit(src, orbitsize, pick(FALSE, TRUE), rand(10, 25), pick(3, 4, 5, 6, 36)) /obj/energy_ball/Bump(atom/A) diff --git a/code/modules/procedural_mapping/mapGenerators/repair.dm b/code/modules/procedural_mapping/mapGenerators/repair.dm index 505dc36f02c12..da086773591de 100644 --- a/code/modules/procedural_mapping/mapGenerators/repair.dm +++ b/code/modules/procedural_mapping/mapGenerators/repair.dm @@ -27,7 +27,7 @@ // changed to allow Z cropping and that's a mess var/z_offset = SSmapping.station_start var/list/bounds - for (var/path in SSmapping.config.GetFullMapPaths()) + for (var/path in SSmapping.current_map.GetFullMapPaths()) var/datum/parsed_map/parsed = load_map( file(path), 1, diff --git a/code/modules/projectiles/boxes_magazines/_box_magazine.dm b/code/modules/projectiles/boxes_magazines/_box_magazine.dm index c010111113c66..d6fa14771dc7d 100644 --- a/code/modules/projectiles/boxes_magazines/_box_magazine.dm +++ b/code/modules/projectiles/boxes_magazines/_box_magazine.dm @@ -216,6 +216,12 @@ ammo_band_image.appearance_flags = RESET_COLOR|KEEP_APART return ammo_band_image +/obj/item/ammo_box/magazine + name = "A magazine (what?)" + desc = "A magazine of rounds, they look like error signs..." + drop_sound = 'sound/items/handling/gun/ballistics/magazine/magazine_drop1.ogg' + pickup_sound = 'sound/items/handling/gun/ballistics/magazine/magazine_pickup1.ogg' + ///Count of number of bullets in the magazine /obj/item/ammo_box/magazine/proc/ammo_count(countempties = TRUE) var/boolets = 0 diff --git a/code/modules/projectiles/boxes_magazines/internal/toy.dm b/code/modules/projectiles/boxes_magazines/internal/toy.dm index 639323f81d86d..395ad80972bb2 100644 --- a/code/modules/projectiles/boxes_magazines/internal/toy.dm +++ b/code/modules/projectiles/boxes_magazines/internal/toy.dm @@ -3,5 +3,11 @@ caliber = CALIBER_FOAM max_ammo = 4 +/obj/item/ammo_box/magazine/internal/shot/toy/riot + ammo_type = /obj/item/ammo_casing/foam_dart/riot + /obj/item/ammo_box/magazine/internal/shot/toy/crossbow max_ammo = 5 + +/obj/item/ammo_box/magazine/internal/shot/toy/crossbow/riot + ammo_type = /obj/item/ammo_casing/foam_dart/riot diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm index f09f650aca73d..1c158cf4a87da 100644 --- a/code/modules/projectiles/guns/ballistic/automatic.dm +++ b/code/modules/projectiles/guns/ballistic/automatic.dm @@ -10,6 +10,8 @@ rack_sound = 'sound/items/weapons/gun/smg/smgrack.ogg' suppressed_sound = 'sound/items/weapons/gun/smg/shot_suppressed.ogg' burst_fire_selection = TRUE + drop_sound = 'sound/items/handling/gun/ballistics/smg/smg_drop1.ogg' + pickup_sound = 'sound/items/handling/gun/ballistics/smg/smg_pickup1.ogg' /obj/item/gun/ballistic/automatic/proto name = "\improper Nanotrasen Saber SMG" diff --git a/code/modules/projectiles/guns/ballistic/pistol.dm b/code/modules/projectiles/guns/ballistic/pistol.dm index ad925222703dc..afe35b9626550 100644 --- a/code/modules/projectiles/guns/ballistic/pistol.dm +++ b/code/modules/projectiles/guns/ballistic/pistol.dm @@ -19,6 +19,8 @@ rack_sound = 'sound/items/weapons/gun/pistol/rack_small.ogg' lock_back_sound = 'sound/items/weapons/gun/pistol/lock_small.ogg' bolt_drop_sound = 'sound/items/weapons/gun/pistol/drop_small.ogg' + drop_sound = 'sound/items/handling/gun/ballistics/pistol/pistol_drop1.ogg' + pickup_sound = 'sound/items/handling/gun/ballistics/pistol/pistol_pickup1.ogg' fire_sound_volume = 90 bolt_wording = "slide" suppressor_x_offset = 10 diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index c073c6a6aafbc..1817e7374832d 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -135,20 +135,20 @@ "Black Panther" = "c38_panther" ) -/obj/item/gun/ballistic/revolver/syndicate - name = "\improper Syndicate Revolver" - desc = "A modernized 7 round revolver manufactured by Waffle Corp. Uses .357 ammo." +/obj/item/gun/ballistic/revolver/badass + name = "\improper Badass Revolver" + desc = "A 7-chamber revolver manufactured by Waffle Corp to make their operatives feel Badass. Offers no tactical advantage whatsoever. Uses .357 ammo." icon_state = "revolversyndie" -/obj/item/gun/ballistic/revolver/syndicate/nuclear +/obj/item/gun/ballistic/revolver/badass/nuclear pin = /obj/item/firing_pin/implant/pindicate -/obj/item/gun/ballistic/revolver/syndicate/cowboy +/obj/item/gun/ballistic/revolver/cowboy desc = "A classic revolver, refurbished for modern use. Uses .357 ammo." //There's already a cowboy sprite in there! icon_state = "lucky" -/obj/item/gun/ballistic/revolver/syndicate/cowboy/nuclear +/obj/item/gun/ballistic/revolver/cowboy/nuclear pin = /obj/item/firing_pin/implant/pindicate /obj/item/gun/ballistic/revolver/mateba @@ -296,10 +296,7 @@ user.visible_message(span_danger("[user.name]'s soul is captured by \the [src]!"), span_userdanger("You've lost the gamble! Your soul is forfeit!")) /obj/item/gun/ballistic/revolver/reverse //Fires directly at its user... unless the user is a clown, of course. - name = /obj/item/gun/ballistic/revolver/syndicate::name - desc = /obj/item/gun/ballistic/revolver/syndicate::desc clumsy_check = FALSE - icon_state = "revolversyndie" /obj/item/gun/ballistic/revolver/reverse/can_trigger_gun(mob/living/user, akimbo_usage) if(akimbo_usage) diff --git a/code/modules/projectiles/guns/ballistic/rifle.dm b/code/modules/projectiles/guns/ballistic/rifle.dm index 855547dd5f313..c65cc51e9a8ce 100644 --- a/code/modules/projectiles/guns/ballistic/rifle.dm +++ b/code/modules/projectiles/guns/ballistic/rifle.dm @@ -13,6 +13,8 @@ fire_sound_volume = 90 rack_sound = 'sound/items/weapons/gun/rifle/bolt_out.ogg' bolt_drop_sound = 'sound/items/weapons/gun/rifle/bolt_in.ogg' + drop_sound = 'sound/items/handling/gun/ballistics/rifle/rifle_drop1.ogg' + pickup_sound = 'sound/items/handling/gun/ballistics/rifle/rifle_pickup1.ogg' tac_reloads = FALSE /obj/item/gun/ballistic/rifle/rack(mob/user = null) diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index bf4715bdb41fd..fe808bcf79865 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -12,6 +12,8 @@ fire_sound_volume = 90 rack_sound = 'sound/items/weapons/gun/shotgun/rack.ogg' load_sound = 'sound/items/weapons/gun/shotgun/insert_shell.ogg' + drop_sound = 'sound/items/handling/gun/ballistics/shotgun/shotgun_drop1.ogg' + pickup_sound = 'sound/items/handling/gun/ballistics/shotgun/shotgun_pickup1.ogg' w_class = WEIGHT_CLASS_BULKY force = 10 obj_flags = CONDUCTS_ELECTRICITY diff --git a/code/modules/projectiles/guns/ballistic/toy.dm b/code/modules/projectiles/guns/ballistic/toy.dm index cb90438f56b4f..bd84e5f794188 100644 --- a/code/modules/projectiles/guns/ballistic/toy.dm +++ b/code/modules/projectiles/guns/ballistic/toy.dm @@ -15,9 +15,8 @@ gun_flags = TOY_FIREARM_OVERLAY | NOT_A_REAL_GUN casing_ejector = FALSE -/obj/item/gun/ballistic/automatic/toy/unrestricted - pin = /obj/item/firing_pin - +/obj/item/gun/ballistic/automatic/toy/riot + spawn_magazine_type = /obj/item/ammo_box/magazine/toy/smg/riot /obj/item/gun/ballistic/automatic/pistol/toy name = "foam force pistol" desc = "A small, easily concealable toy handgun. Ages 8 and up." @@ -52,8 +51,8 @@ if(chambered && !chambered.loaded_projectile) qdel(chambered) -/obj/item/gun/ballistic/shotgun/toy/unrestricted - pin = /obj/item/firing_pin +/obj/item/gun/ballistic/shotgun/toy/riot + spawn_magazine_type = /obj/item/ammo_box/magazine/internal/shot/toy/riot /obj/item/gun/ballistic/shotgun/toy/crossbow name = "foam force crossbow" @@ -73,6 +72,9 @@ w_class = WEIGHT_CLASS_SMALL gun_flags = NONE +/obj/item/gun/ballistic/shotgun/toy/crossbow/riot + spawn_magazine_type = /obj/item/ammo_box/magazine/internal/shot/toy/crossbow/riot + /obj/item/gun/ballistic/automatic/c20r/toy //This is the syndicate variant with syndicate firing pin and riot darts. name = "donksoft SMG" desc = "A bullpup three-round burst toy SMG, designated 'C-20r'. Ages 8 and up." diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 0648f7992487b..b4cd8fa490472 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -77,7 +77,10 @@ recharge_newshot() //and try to charge a new shot update_appearance() -/obj/item/gun/energy/get_cell() +/obj/item/gun/energy/get_cell(atom/movable/interface, mob/user) + if(istype(interface, /obj/item/inducer)) + to_chat(user, span_alert("Error: unable to interface with [interface].")) + return null return cell /obj/item/gun/energy/Initialize(mapload) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 5bb933cb23cde..80616a88cfa7c 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -153,7 +153,7 @@ var/armor_flag = BULLET ///How much armor this projectile pierces. var/armour_penetration = 0 - ///Whether or not our bullet lacks penetrative power, and is easily stopped by armor. + ///Whether or not our projectile doubles the value of affecting armour var/weak_against_armour = FALSE var/projectile_type = /obj/projectile var/range = 50 //This will de-increment every step. When 0, it will deletze the projectile. @@ -224,6 +224,8 @@ AddElement(/datum/element/embed) AddElement(/datum/element/connect_loc, projectile_connections) + add_traits(list(TRAIT_FREE_HYPERSPACE_MOVEMENT, TRAIT_FREE_HYPERSPACE_SOFTCORDON_MOVEMENT), INNATE_TRAIT) + /obj/projectile/proc/Range() range-- if(wound_bonus != CANT_WOUND) @@ -1024,14 +1026,14 @@ */ /proc/calculate_projectile_angle_and_pixel_offsets(atom/source, atom/target, modifiers) var/angle = 0 - var/p_x = LAZYACCESS(modifiers, ICON_X) ? text2num(LAZYACCESS(modifiers, ICON_X)) : world.icon_size / 2 // ICON_(X|Y) are measured from the bottom left corner of the icon. - var/p_y = LAZYACCESS(modifiers, ICON_Y) ? text2num(LAZYACCESS(modifiers, ICON_Y)) : world.icon_size / 2 // This centers the target if modifiers aren't passed. + var/p_x = LAZYACCESS(modifiers, ICON_X) ? text2num(LAZYACCESS(modifiers, ICON_X)) : ICON_SIZE_X / 2 // ICON_(X|Y) are measured from the bottom left corner of the icon. + var/p_y = LAZYACCESS(modifiers, ICON_Y) ? text2num(LAZYACCESS(modifiers, ICON_Y)) : ICON_SIZE_Y / 2 // This centers the target if modifiers aren't passed. if(target) var/turf/source_loc = get_turf(source) var/turf/target_loc = get_turf(target) - var/dx = ((target_loc.x - source_loc.x) * world.icon_size) + (target.pixel_x - source.pixel_x) + (p_x - (world.icon_size / 2)) - var/dy = ((target_loc.y - source_loc.y) * world.icon_size) + (target.pixel_y - source.pixel_y) + (p_y - (world.icon_size / 2)) + var/dx = ((target_loc.x - source_loc.x) * ICON_SIZE_X) + (target.pixel_x - source.pixel_x) + (p_x - (ICON_SIZE_X / 2)) + var/dy = ((target_loc.y - source_loc.y) * ICON_SIZE_Y) + (target.pixel_y - source.pixel_y) + (p_y - (ICON_SIZE_Y / 2)) angle = ATAN2(dy, dx) return list(angle, p_x, p_y) @@ -1050,8 +1052,8 @@ //Split Y+Pixel_Y up into list(Y, Pixel_Y) var/list/screen_loc_Y = splittext(screen_loc_params[2],":") - var/tx = (text2num(screen_loc_X[1]) - 1) * world.icon_size + text2num(screen_loc_X[2]) - var/ty = (text2num(screen_loc_Y[1]) - 1) * world.icon_size + text2num(screen_loc_Y[2]) + var/tx = (text2num(screen_loc_X[1]) - 1) * ICON_SIZE_X + text2num(screen_loc_X[2]) + var/ty = (text2num(screen_loc_Y[1]) - 1) * ICON_SIZE_Y + text2num(screen_loc_Y[2]) //Calculate the "resolution" of screen based on client's view and world's icon size. This will work if the user can view more tiles than average. var/list/screenview = view_to_pixels(user.client.view) diff --git a/code/modules/projectiles/projectile/energy/_energy.dm b/code/modules/projectiles/projectile/energy/_energy.dm index 86ec80b3b20ff..8527041e86006 100644 --- a/code/modules/projectiles/projectile/energy/_energy.dm +++ b/code/modules/projectiles/projectile/energy/_energy.dm @@ -6,9 +6,3 @@ armor_flag = ENERGY reflectable = REFLECT_NORMAL impact_effect_type = /obj/effect/temp_visual/impact_effect/energy - -/obj/projectile/energy/Initialize(mapload) - . = ..() - - ADD_TRAIT(src, TRAIT_FREE_HYPERSPACE_MOVEMENT, INNATE_TRAIT) - ADD_TRAIT(src, TRAIT_FREE_HYPERSPACE_SOFTCORDON_MOVEMENT, INNATE_TRAIT) diff --git a/code/modules/projectiles/projectile/special/neurotoxin.dm b/code/modules/projectiles/projectile/special/neurotoxin.dm deleted file mode 100644 index 077b3a275e99e..0000000000000 --- a/code/modules/projectiles/projectile/special/neurotoxin.dm +++ /dev/null @@ -1,17 +0,0 @@ -/obj/projectile/neurotoxin - name = "neurotoxin spit" - icon_state = "neurotoxin" - damage = 65 - damage_type = STAMINA - armor_flag = BIO - impact_effect_type = /obj/effect/temp_visual/impact_effect/neurotoxin - armour_penetration = 50 - -/obj/projectile/neurotoxin/on_hit(atom/target, blocked = 0, pierce_hit) - if(isalien(target)) - damage = 0 - return ..() - -/obj/projectile/neurotoxin/damaging //for ai controlled aliums - damage = 30 - paralyze = 0 SECONDS diff --git a/code/modules/projectiles/projectile/special/spit.dm b/code/modules/projectiles/projectile/special/spit.dm new file mode 100644 index 0000000000000..1bc0d547ae1fc --- /dev/null +++ b/code/modules/projectiles/projectile/special/spit.dm @@ -0,0 +1,58 @@ +/obj/projectile/neurotoxin + name = "neurotoxin spit" + icon_state = "neurotoxin" + damage = 65 + damage_type = STAMINA + armor_flag = BIO + impact_effect_type = /obj/effect/temp_visual/impact_effect/neurotoxin + armour_penetration = 50 + +/obj/projectile/neurotoxin/on_hit(atom/target, blocked = 0, pierce_hit) + if(isalien(target)) + damage = 0 + return ..() + +/obj/projectile/neurotoxin/damaging //for ai controlled aliums + damage = 30 + paralyze = 0 SECONDS + +/obj/projectile/ink_spit + name = "ink spit" + icon_state = "ink_spit" + damage = 5 + damage_type = STAMINA + armor_flag = BIO + impact_effect_type = /obj/effect/temp_visual/impact_effect/ink_spit + armour_penetration = 50 + hitsound = SFX_DESECRATION + hitsound_wall = SFX_DESECRATION + +/obj/projectile/ink_spit/Initialize(mapload) + . = ..() + if(isliving(firer)) + var/mob/living/living = firer + var/datum/status_effect/organ_set_bonus/fish/bonus = living?.has_status_effect(/datum/status_effect/organ_set_bonus/fish) + if(bonus?.bonus_active) + damage = 12 + armour_penetration = 65 + + AddComponent(/datum/component/splat, \ + memory_type = /datum/memory/witnessed_inking, \ + smudge_type = /obj/effect/decal/cleanable/food/squid_ink, \ + moodlet_type = /datum/mood_event/inked, \ + splat_color = COLOR_NEARLY_ALL_BLACK, \ + hit_callback = CALLBACK(src, PROC_REF(blind_em)), \ + ) + +/obj/projectile/ink_spit/proc/blind_em(mob/living/victim, can_splat_on) + if(!can_splat_on) + return + var/powered_up = FALSE + if(isliving(firer)) + var/mob/living/living = firer + var/datum/status_effect/organ_set_bonus/fish/bonus = living?.has_status_effect(/datum/status_effect/organ_set_bonus/fish) + powered_up = bonus?.bonus_active + victim.adjust_temp_blindness_up_to((powered_up ? 6.5 : 4.5) SECONDS, 10 SECONDS) + victim.adjust_confusion_up_to((powered_up ? 3 : 1.5) SECONDS, 6 SECONDS) + if(powered_up) + victim.Knockdown(2 SECONDS) //splat! diff --git a/code/modules/reagents/chemistry/equilibrium.dm b/code/modules/reagents/chemistry/equilibrium.dm index 6b43e441d483c..bc7cbd37f4854 100644 --- a/code/modules/reagents/chemistry/equilibrium.dm +++ b/code/modules/reagents/chemistry/equilibrium.dm @@ -381,7 +381,7 @@ holder.adjust_thermal_energy(heat_energy * SPECIFIC_HEAT_DEFAULT, 0, CHEMICAL_MAXIMUM_TEMPERATURE) //Give a chance of sounds - if(prob(5)) + if(prob(5) && !HAS_TRAIT(holder.my_atom, TRAIT_SILENT_REACTIONS)) holder.my_atom.audible_message(span_notice("[icon2html(holder.my_atom, viewers(DEFAULT_MESSAGE_RANGE, src))] [reaction.mix_message]")) if(reaction.mix_sound) playsound(get_turf(holder.my_atom), reaction.mix_sound, 80, TRUE) diff --git a/code/modules/reagents/chemistry/holder/mob_life.dm b/code/modules/reagents/chemistry/holder/mob_life.dm index 5d7da162743b4..785b6261307db 100644 --- a/code/modules/reagents/chemistry/holder/mob_life.dm +++ b/code/modules/reagents/chemistry/holder/mob_life.dm @@ -40,7 +40,7 @@ if(belly) amount += belly.reagents.get_reagent_amount(toxin.type) - if(amount <= liver_tolerance) + if(amount <= liver_tolerance * toxin.liver_tolerance_multiplier) owner.reagents.remove_reagent(toxin.type, toxin.metabolization_rate * owner.metabolism_efficiency * seconds_per_tick) continue diff --git a/code/modules/reagents/chemistry/holder/reactions.dm b/code/modules/reagents/chemistry/holder/reactions.dm index 3fbcb57a43424..10c34864dd90c 100644 --- a/code/modules/reagents/chemistry/holder/reactions.dm +++ b/code/modules/reagents/chemistry/holder/reactions.dm @@ -183,7 +183,7 @@ if(num_reactions) SEND_SIGNAL(src, COMSIG_REAGENTS_REACTION_STEP, num_reactions, seconds_per_tick) - if(length(mix_message)) //This is only at the end + if(length(mix_message) && !HAS_TRAIT(my_atom, TRAIT_SILENT_REACTIONS)) //This is only at the end my_atom.audible_message(span_notice("[icon2html(my_atom, viewers(DEFAULT_MESSAGE_RANGE, src))] [mix_message.Join()]")) if(!LAZYLEN(reaction_list)) @@ -210,9 +210,12 @@ stack_trace("The equilibrium datum currently processing in this reagents datum had a desynced holder to the ending reaction. src holder:[my_atom] | equilibrium holder:[equilibrium.holder.my_atom] || src type:[my_atom.type] | equilibrium holder:[equilibrium.holder.my_atom.type]") LAZYREMOVE(reaction_list, equilibrium) - var/reaction_message = equilibrium.reaction.mix_message - if(equilibrium.reaction.mix_sound) - playsound(get_turf(my_atom), equilibrium.reaction.mix_sound, 80, TRUE) + var/reaction_message = null + + if (!HAS_TRAIT(my_atom, TRAIT_SILENT_REACTIONS)) + reaction_message = equilibrium.reaction.mix_message + if(equilibrium.reaction.mix_sound) + playsound(get_turf(my_atom), equilibrium.reaction.mix_sound, 80, TRUE) qdel(equilibrium) update_total() SEND_SIGNAL(src, COMSIG_REAGENTS_REACTED, .) @@ -256,7 +259,7 @@ if(result == reagent.type) mix_message += end_reaction(equilibrium) any_stopped = TRUE - if(length(mix_message)) + if(length(mix_message) && !HAS_TRAIT(my_atom, TRAIT_SILENT_REACTIONS)) my_atom.audible_message(span_notice("[icon2html(my_atom, viewers(DEFAULT_MESSAGE_RANGE, src))][mix_message.Join()]")) return any_stopped @@ -326,7 +329,7 @@ var/list/seen = viewers(4, get_turf(my_atom)) var/iconhtml = icon2html(cached_my_atom, seen) if(cached_my_atom) - if(!ismob(cached_my_atom)) // No bubbling mobs + if(!ismob(cached_my_atom) && !HAS_TRAIT(my_atom, TRAIT_SILENT_REACTIONS)) // No bubbling mobs if(selected_reaction.mix_sound) playsound(get_turf(cached_my_atom), selected_reaction.mix_sound, 80, TRUE) my_atom.audible_message(span_notice("[iconhtml] [selected_reaction.mix_message]")) diff --git a/code/modules/reagents/chemistry/machinery/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm index c9ad2424b2de7..aaa2763eea2bc 100644 --- a/code/modules/reagents/chemistry/machinery/pandemic.dm +++ b/code/modules/reagents/chemistry/machinery/pandemic.dm @@ -12,10 +12,10 @@ circuit = /obj/item/circuitboard/computer/pandemic /// Whether the pandemic is ready to make another culture/vaccine - var/wait - /// The currently selected symptom + var/wait = FALSE + ///The currently selected symptom var/datum/symptom/selected_symptom - /// The inserted beaker + ///The inserted beaker var/obj/item/reagent_containers/beaker /obj/machinery/computer/pandemic/Initialize(mapload) @@ -78,9 +78,10 @@ if(gone == beaker) beaker = null update_appearance() + SStgui.update_uis(src) /obj/machinery/computer/pandemic/attackby(obj/item/held_item, mob/user, params) - //Advanced science! Percision instruments (eg droppers and syringes) are precise enough to modify the loaded sample! + //Advanced science! Precision instruments (eg droppers and syringes) are precise enough to modify the loaded sample! if(istype(held_item, /obj/item/reagent_containers/dropper) || istype(held_item, /obj/item/reagent_containers/syringe)) if(!beaker) balloon_alert(user, "no beaker!") diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index 8edfb38abc397..87c509bd0a1ed 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -78,6 +78,8 @@ var/list/metabolized_traits /// A list of traits to apply while the reagent is in a mob. var/list/added_traits + /// Multiplier of the amount purged by reagents such as calomel, multiver, syniver etc. + var/purge_multiplier = 1 ///The default reagent container for the reagent, used for icon generation var/obj/item/reagent_containers/default_container = /obj/item/reagent_containers/cup/bottle @@ -121,8 +123,8 @@ SHOULD_CALL_PARENT(TRUE) . = SEND_SIGNAL(src, COMSIG_REAGENT_EXPOSE_MOB, exposed_mob, methods, reac_volume, show_message, touch_protection) - if((methods & penetrates_skin) && exposed_mob.reagents) //smoke, foam, spray - var/amount = round(reac_volume*clamp((1 - touch_protection), 0, 1), 0.1) + if(penetrates_skin & methods) // models things like vapors which penetrate the skin + var/amount = round(reac_volume * clamp((1 - touch_protection), 0, 1), 0.1) if(amount >= 0.5) exposed_mob.reagents.add_reagent(type, amount, added_purity = purity) @@ -282,6 +284,10 @@ Primarily used in reagents/reaction_agents purity = src.purity return min(1-inverse_chem_val + purity + 0.01, 1) //Gives inverse reactions a 1% purity threshold for being 100% pure to appease players with OCD. +///Called when feeding a fish. If TRUE is returned, a portion of reagent will be consumed. +/datum/reagent/proc/used_on_fish(obj/item/fish/fish) + return FALSE + /** * Input a reagent_list, outputs pretty readable text! * Default output will be formatted as diff --git a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm index 7b6fb34efe1a4..36081a7aba79f 100644 --- a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm @@ -389,16 +389,13 @@ var/need_mob_update need_mob_update = affected_mob.adjustToxLoss(-0.5 * min(medibonus, 3 * normalise_creation_purity()) * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) //not great at healing but if you have nothing else it will work need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) //kills at 40u - for(var/r2 in affected_mob.reagents.reagent_list) - var/datum/reagent/the_reagent2 = r2 - if(the_reagent2 == src) - continue - var/amount2purge = 3 - if(holder.has_reagent(/datum/reagent/toxin/anacea)) - amount2purge = 0 - if(medibonus >= 3 && istype(the_reagent2, /datum/reagent/medicine)) //3 unique meds (2+multiver) | (1 + pure multiver) will make it not purge medicines - continue - affected_mob.reagents.remove_reagent(the_reagent2.type, amount2purge * REM * seconds_per_tick) + if(!holder.has_reagent(/datum/reagent/toxin/anacea)) + for(var/datum/reagent/second_reagent as anything in affected_mob.reagents.reagent_list) + if(second_reagent == src) + continue + if(medibonus >= 3 && istype(second_reagent, /datum/reagent/medicine)) //3 unique meds (2+multiver) | (1 + pure multiver) will make it not purge medicines + continue + affected_mob.reagents.remove_reagent(second_reagent.type, 3 * second_reagent.purge_multiplier * REM * seconds_per_tick) if(need_mob_update) return UPDATE_MOB_HEALTH @@ -469,10 +466,10 @@ var/need_mob_update need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.1 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) need_mob_update += affected_mob.adjustToxLoss(-1.5 * REM * seconds_per_tick * normalise_creation_purity(), updating_health = FALSE, required_biotype = affected_biotype) - for(var/datum/reagent/R in affected_mob.reagents.reagent_list) - if(issyrinormusc(R)) + for(var/datum/reagent/reagent as anything in affected_mob.reagents.reagent_list) + if(issyrinormusc(reagent)) continue - affected_mob.reagents.remove_reagent(R.type, 0.2 * REM * seconds_per_tick) + affected_mob.reagents.remove_reagent(reagent.type, 0.2 * reagent.purge_multiplier * REM * seconds_per_tick) if(need_mob_update) return UPDATE_MOB_HEALTH diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 393b91ae02b9f..64626883b3c47 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -432,18 +432,17 @@ /datum/reagent/medicine/calomel/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() - for(var/datum/reagent/target_reagent in affected_mob.reagents.reagent_list) + for(var/datum/reagent/target_reagent as anything in affected_mob.reagents.reagent_list) if(istype(target_reagent, /datum/reagent/medicine/calomel)) continue - affected_mob.reagents.remove_reagent(target_reagent.type, 3 * REM * seconds_per_tick) + affected_mob.reagents.remove_reagent(target_reagent.type, 3 * target_reagent.purge_multiplier * REM * seconds_per_tick) var/toxin_amount = round(affected_mob.health / 40, 0.1) if(affected_mob.adjustToxLoss(toxin_amount * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) return UPDATE_MOB_HEALTH /datum/reagent/medicine/calomel/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) . = ..() - for(var/datum/reagent/medicine/calomel/target_reagent in affected_mob.reagents.reagent_list) - affected_mob.reagents.remove_reagent(target_reagent.type, 2 * REM * seconds_per_tick) + affected_mob.reagents.remove_reagent(type, 2 * REM * seconds_per_tick) if(affected_mob.adjustToxLoss(2.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) return UPDATE_MOB_HEALTH @@ -467,7 +466,7 @@ var/toxin_chem_amount = 0 for(var/datum/reagent/toxin/target_reagent in affected_mob.reagents.reagent_list) toxin_chem_amount += 1 - affected_mob.reagents.remove_reagent(target_reagent.type, 5 * REM * seconds_per_tick) + affected_mob.reagents.remove_reagent(target_reagent.type, 5 * target_reagent.purge_multiplier * REM * seconds_per_tick) var/toxin_amount = round(affected_mob.getBruteLoss() / 15, 0.1) + round(affected_mob.getFireLoss() / 30, 0.1) - 3 if(affected_mob.adjustToxLoss(toxin_amount * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) . = UPDATE_MOB_HEALTH @@ -512,9 +511,9 @@ . = ..() if(affected_mob.adjustToxLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) . = UPDATE_MOB_HEALTH - for(var/datum/reagent/R in affected_mob.reagents.reagent_list) - if(R != src) - affected_mob.reagents.remove_reagent(R.type, 2 * REM * seconds_per_tick) + for(var/datum/reagent/reagent as anything in affected_mob.reagents.reagent_list) + if(reagent != src) + affected_mob.reagents.remove_reagent(reagent.type, 2 * reagent.purge_multiplier * REM * seconds_per_tick) /datum/reagent/medicine/sal_acid name = "Salicylic Acid" @@ -1036,7 +1035,7 @@ else tips = world.file2list("strings/chemistrytips.txt") var/message = pick(tips) - send_tip_of_the_round(affected_mob, message) + send_tip_of_the_round(affected_mob, message, source = "Chemical-induced wisdom") /datum/reagent/medicine/neurine name = "Neurine" @@ -1093,7 +1092,7 @@ var/mob/living/carbon/human/human_mob = affected_mob if (ismonkey(human_mob)) if (!HAS_TRAIT(human_mob, TRAIT_BORN_MONKEY)) - human_mob.dna.remove_mutation(/datum/mutation/human/race) + human_mob.dna.remove_mutation(/datum/mutation/human/race, mutadone = TRUE) else if (HAS_TRAIT(human_mob, TRAIT_BORN_MONKEY)) human_mob.monkeyize() @@ -1339,8 +1338,8 @@ /datum/reagent/medicine/haloperidol/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() - for(var/datum/reagent/drug/R in affected_mob.reagents.reagent_list) - affected_mob.reagents.remove_reagent(R.type, 5 * REM * seconds_per_tick) + for(var/datum/reagent/drug/reagent in affected_mob.reagents.reagent_list) + affected_mob.reagents.remove_reagent(reagent.type, 5 * reagent.purge_multiplier * REM * seconds_per_tick) affected_mob.adjust_drowsiness(4 SECONDS * REM * seconds_per_tick) if(affected_mob.get_timed_status_effect_duration(/datum/status_effect/jitter) >= 6 SECONDS) diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index cb0cf9ae6620c..9f768e48fba9e 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -117,13 +117,13 @@ var/obj/effect/decal/cleanable/blood/bloodsplatter = locate() in exposed_turf //find some blood here if(!bloodsplatter) bloodsplatter = new(exposed_turf, data["viruses"]) - else if(LAZYLEN(data["viruses"])) - var/list/viri_to_add = list() + if(LAZYLEN(data["viruses"])) + var/list/viruses_to_add = list() for(var/datum/disease/virus in data["viruses"]) if(virus.spread_flags & DISEASE_SPREAD_CONTACT_FLUIDS) - viri_to_add += virus - if(LAZYLEN(viri_to_add)) - bloodsplatter.AddComponent(/datum/component/infective, viri_to_add) + viruses_to_add += virus + if(LAZYLEN(viruses_to_add)) + bloodsplatter.AddComponent(/datum/component/infective, viruses_to_add) if(data["blood_DNA"]) bloodsplatter.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"])) @@ -277,7 +277,7 @@ if(methods & VAPOR) exposed_mob.adjust_wet_stacks(reac_volume * WATER_TO_WET_STACKS_FACTOR_VAPOR) // Spraying someone with water with the hope to put them out is just simply too funny to me not to add it. - if(!isfelinid(exposed_mob)) + if(!HAS_TRAIT(exposed_mob, TRAIT_WATER_HATER) || HAS_TRAIT(exposed_mob, TRAIT_WATER_ADAPTATION)) return exposed_mob.incapacitate(1) // startles the felinid, canceling any do_after @@ -290,9 +290,18 @@ /datum/reagent/water/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() + var/water_adaptation = HAS_TRAIT(affected_mob, TRAIT_WATER_ADAPTATION) if(affected_mob.blood_volume) - affected_mob.blood_volume += 0.1 * REM * seconds_per_tick // water is good for you! - affected_mob.adjust_drunk_effect(-0.25 * REM * seconds_per_tick) // and even sobers you up slowly!! + var/blood_restored = water_adaptation ? 0.3 : 0.1 + affected_mob.blood_volume += blood_restored * REM * seconds_per_tick // water is good for you! + var/drunkness_restored = water_adaptation ? -0.5 : -0.25 + affected_mob.adjust_drunk_effect(drunkness_restored * REM * seconds_per_tick) // and even sobers you up slowly!! + if(water_adaptation) + var/need_mob_update = FALSE + need_mob_update = affected_mob.adjustToxLoss(-0.2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustFireLoss(-0.2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustBruteLoss(-0.2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + return need_mob_update ? UPDATE_MOB_HEALTH : . // For weird backwards situations where water manages to get added to trays nutrients, as opposed to being snowflaked away like usual. /datum/reagent/water/on_hydroponics_apply(obj/machinery/hydroponics/mytray, mob/user) @@ -391,6 +400,7 @@ data["deciseconds_metabolized"] += (seconds_per_tick * 1 SECONDS * REM) affected_mob.adjust_jitter_up_to(4 SECONDS * REM * seconds_per_tick, 20 SECONDS) + var/need_mob_update = FALSE if(IS_CULTIST(affected_mob)) for(var/datum/action/innate/cult/blood_magic/BM in affected_mob.actions) @@ -411,14 +421,23 @@ affected_mob.Unconscious(12 SECONDS) to_chat(affected_mob, span_cult_large("[pick("Your blood is your bond - you are nothing without it", "Do not forget your place", \ "All that power, and you still fail?", "If you cannot scour this poison, I shall scour your meager life!")].")) + else if(HAS_TRAIT(affected_mob, TRAIT_EVIL) && SPT_PROB(25, seconds_per_tick)) //Congratulations, your committment to evil has now made holy water a deadly poison to you! + if(!IS_CULTIST(affected_mob) || affected_mob.mind?.holy_role != HOLY_ROLE_PRIEST) + affected_mob.emote("scream") + need_mob_update += affected_mob.adjustFireLoss(3 * REM * seconds_per_tick, updating_health = FALSE) if(data["deciseconds_metabolized"] >= (1 MINUTES)) // 24 units if(IS_CULTIST(affected_mob)) affected_mob.mind.remove_antag_datum(/datum/antagonist/cult) affected_mob.Unconscious(10 SECONDS) + else if(HAS_TRAIT(affected_mob, TRAIT_EVIL)) //At this much holy water, you're probably going to fucking melt. good luck + if(!IS_CULTIST(affected_mob) || affected_mob.mind?.holy_role != HOLY_ROLE_PRIEST) + need_mob_update += affected_mob.adjustFireLoss(10 * REM * seconds_per_tick, updating_health = FALSE) affected_mob.remove_status_effect(/datum/status_effect/jitter) affected_mob.remove_status_effect(/datum/status_effect/speech/stutter) holder?.remove_reagent(type, volume) // maybe this is a little too perfect and a max() cap on the statuses would be better?? + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/water/holywater/expose_turf(turf/exposed_turf, reac_volume) . = ..() @@ -569,6 +588,11 @@ if(reac_volume >= 1) exposed_turf.MakeSlippery(lube_kind, 15 SECONDS, min(reac_volume * 2 SECONDS, 120)) +/datum/reagent/lube/used_on_fish(obj/item/fish/fish) + ADD_TRAIT(fish, TRAIT_FISH_FED_LUBE, type) //required for the lubefish mutation + addtimer(TRAIT_CALLBACK_REMOVE(fish, TRAIT_FISH_FED_LUBE, type), fish.feeding_frequency, TIMER_UNIQUE|TIMER_OVERRIDE) + return TRUE + ///Stronger kind of lube. Applies TURF_WET_SUPERLUBE. /datum/reagent/lube/superlube name = "Super Duper Lube" @@ -2457,6 +2481,11 @@ affected_mob.update_transform(RESIZE_DEFAULT_SIZE/current_size) current_size = RESIZE_DEFAULT_SIZE +/datum/reagent/growthserum/used_on_fish(obj/item/fish/fish) + ADD_TRAIT(fish, TRAIT_FISH_QUICK_GROWTH, type) + addtimer(TRAIT_CALLBACK_REMOVE(fish, TRAIT_FISH_QUICK_GROWTH, type), fish.feeding_frequency * 0.8, TIMER_UNIQUE|TIMER_OVERRIDE) + return TRUE + /datum/reagent/plastic_polymers name = "Plastic Polymers" description = "the petroleum based components of plastic." @@ -2688,7 +2717,7 @@ taste_mult = 0 // oderless and tasteless chemical_flags = REAGENT_NO_RANDOM_RECIPE /// The material flags used to apply the transmuted materials - var/applied_material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR + var/applied_material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS /// The amount of materials to apply to the transmuted objects if they don't contain materials var/default_material_amount = 100 diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm index a804a106f7353..c81eb5e1fb6a5 100644 --- a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm @@ -312,6 +312,14 @@ affected_mob.electrocute_act(rand(5, 20), "Teslium in their body", 1, SHOCK_NOGLOVES) //SHOCK_NOGLOVES because it's caused from INSIDE of you playsound(affected_mob, SFX_SPARKS, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) +/datum/reagent/teslium/used_on_fish(obj/item/fish/fish) + if(HAS_TRAIT_FROM(fish, TRAIT_FISH_ELECTROGENESIS, FISH_TRAIT_DATUM)) + return FALSE + fish.add_traits(list(TRAIT_FISH_ON_TESLIUM, TRAIT_FISH_ELECTROGENESIS), type) + addtimer(TRAIT_CALLBACK_REMOVE(fish, TRAIT_FISH_ON_TESLIUM, type), fish.feeding_frequency * 0.75, TIMER_UNIQUE|TIMER_OVERRIDE) + addtimer(TRAIT_CALLBACK_REMOVE(fish, TRAIT_FISH_ELECTROGENESIS, type), fish.feeding_frequency * 0.75, TIMER_UNIQUE|TIMER_OVERRIDE) + return TRUE + /datum/reagent/teslium/on_mob_metabolize(mob/living/carbon/human/affected_mob) . = ..() if(!istype(affected_mob)) diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 95f73e552be34..39b477a51a572 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -12,6 +12,8 @@ var/toxpwr = 1.5 ///The amount to multiply the liver damage this toxin does by (Handled solely in liver code) var/liver_damage_multiplier = 1 + ///The multiplier of the liver toxin tolerance, below which any amount toxin will be simply metabolized out with no effect. + var/liver_tolerance_multiplier = 1 ///won't produce a pain message when processed by liver/life() if there isn't another non-silent toxin present if true var/silent_toxin = FALSE ///The afflicted must be above this health value in order for the toxin to deal damage @@ -71,6 +73,11 @@ mytray.mutation_roll(user) mytray.adjust_toxic(3) //It is still toxic, mind you, but not to the same degree. +/datum/reagent/mutagen/used_on_fish(obj/item/fish/fish) + ADD_TRAIT(fish, TRAIT_FISH_MUTAGENIC, type) + addtimer(TRAIT_CALLBACK_REMOVE(fish, TRAIT_FISH_MUTAGENIC, type), fish.feeding_frequency * 0.8, TIMER_UNIQUE|TIMER_OVERRIDE) + return TRUE + #define LIQUID_PLASMA_BP (50+T0C) #define LIQUID_PLASMA_IG (325+T0C) @@ -333,7 +340,7 @@ /datum/reagent/toxin/mindbreaker/fish/on_new(data) . = ..() if(holder?.my_atom) - RegisterSignals(holder.my_atom, list(COMSIG_ITEM_FRIED, TRAIT_FOOD_BBQ_GRILLED), PROC_REF(on_atom_cooked)) + RegisterSignals(holder.my_atom, list(COMSIG_ITEM_FRIED, COMSIG_ITEM_BARBEQUE_GRILLED), PROC_REF(on_atom_cooked)) /datum/reagent/toxin/mindbreaker/fish/proc/on_atom_cooked(datum/source, cooking_time) SIGNAL_HANDLER @@ -956,9 +963,9 @@ if(prob(50)) constructed_flags |= MOB_VOMIT_STUN affected_mob.vomit(vomit_flags = constructed_flags, distance = rand(0,4)) - for(var/datum/reagent/toxin/R in affected_mob.reagents.reagent_list) - if(R != src) - affected_mob.reagents.remove_reagent(R.type, 1) + for(var/datum/reagent/toxin/reagent in affected_mob.reagents.reagent_list) + if(reagent != src) + affected_mob.reagents.remove_reagent(reagent.type, 1 * reagent.purge_multiplier * REM * seconds_per_tick) /datum/reagent/toxin/spewium/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() @@ -1051,8 +1058,8 @@ if(holder.has_reagent(/datum/reagent/medicine/calomel) || holder.has_reagent(/datum/reagent/medicine/pen_acid)) remove_amt = 0.5 . = ..() - for(var/datum/reagent/medicine/R in affected_mob.reagents.reagent_list) - affected_mob.reagents.remove_reagent(R.type, remove_amt * REM * normalise_creation_purity() * seconds_per_tick) + for(var/datum/reagent/medicine/reagent in affected_mob.reagents.reagent_list) + affected_mob.reagents.remove_reagent(reagent.type, remove_amt * reagent.purge_multiplier * REM * normalise_creation_purity() * seconds_per_tick) //ACID @@ -1293,6 +1300,9 @@ reagent_state = SOLID color = COLOR_VERY_LIGHT_GRAY metabolization_rate = 0.1 * REAGENTS_METABOLISM + liver_tolerance_multiplier = 0.1 + liver_damage_multiplier = 1.25 + purge_multiplier = 0.15 toxpwr = 0 taste_mult = 0 chemical_flags = REAGENT_NO_RANDOM_RECIPE|REAGENT_CAN_BE_SYNTHESIZED @@ -1305,9 +1315,22 @@ /datum/reagent/toxin/tetrodotoxin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() + var/need_mob_update + if(HAS_TRAIT(affected_mob, TRAIT_TETRODOTOXIN_HEALING)) + toxpwr = 0 + liver_tolerance_multiplier = 0 + silent_toxin = TRUE + remove_paralysis() + need_mob_update += affected_mob.adjustOxyLoss(-0.7 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update = affected_mob.adjustToxLoss(-0.75 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustBruteLoss(-1.2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustFireLoss(-1.35 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + return need_mob_update ? UPDATE_MOB_HEALTH : . + + liver_tolerance_multiplier = initial(liver_tolerance_multiplier) + //be ready for a cocktail of symptoms, including: //numbness, nausea, vomit, breath loss, weakness, paralysis and nerve damage/impairment and eventually a heart attack if enough time passes. - var/need_mob_update switch(current_cycle) if(7 to 13) if(SPT_PROB(20, seconds_per_tick)) @@ -1338,6 +1361,7 @@ if(21 to 29) toxpwr = 1 need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5) + need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.7) if(SPT_PROB(40, seconds_per_tick)) affected_mob.losebreath += 2 * REM * seconds_per_tick need_mob_update = TRUE @@ -1354,13 +1378,14 @@ if(29 to INFINITY) toxpwr = 1.5 need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1, BRAIN_DAMAGE_DEATH) + need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_LUNGS, 1.4) affected_mob.set_silence_if_lower(3 SECONDS * REM * seconds_per_tick) need_mob_update += affected_mob.adjustStaminaLoss(5 * REM * seconds_per_tick, updating_stamina = FALSE) affected_mob.adjust_disgust(2 * REM * seconds_per_tick) if(SPT_PROB(15, seconds_per_tick)) paralyze_limb(affected_mob) need_mob_update = TRUE - if(SPT_PROB(10, seconds_per_tick)) + if(SPT_PROB(20, seconds_per_tick)) affected_mob.adjust_confusion(rand(6 SECONDS, 8 SECONDS)) if(current_cycle > 38 && !length(traits_not_applied) && SPT_PROB(5, seconds_per_tick) && !affected_mob.undergoing_cardiac_arrest()) @@ -1376,6 +1401,11 @@ var/added_trait = pick_n_take(traits_not_applied) ADD_TRAIT(affected_mob, added_trait, REF(src)) +/datum/reagent/toxin/tetrodotoxin/on_mob_add(mob/living/affected_mob) + . = ..() + if(HAS_TRAIT(affected_mob, TRAIT_TETRODOTOXIN_HEALING)) + liver_tolerance_multiplier = 0 + /datum/reagent/toxin/tetrodotoxin/on_mob_metabolize(mob/living/affected_mob) . = ..() RegisterSignal(affected_mob, COMSIG_CARBON_ATTEMPT_BREATHE, PROC_REF(block_breath)) @@ -1383,6 +1413,9 @@ /datum/reagent/toxin/tetrodotoxin/on_mob_end_metabolize(mob/living/affected_mob) . = ..() UnregisterSignal(affected_mob, COMSIG_CARBON_ATTEMPT_BREATHE, PROC_REF(block_breath)) + remove_paralysis(affected_mob) + +/datum/reagent/toxin/tetrodotoxin/proc/remove_paralysis(mob/living/affected_mob) // the initial() proc doesn't work for lists. var/list/initial_list = list( TRAIT_PARALYSIS_L_ARM = BODY_ZONE_L_ARM, @@ -1395,5 +1428,5 @@ /datum/reagent/toxin/tetrodotoxin/proc/block_breath(mob/living/source) SIGNAL_HANDLER - if(current_cycle > 28) + if(current_cycle > 28 && !HAS_TRAIT(source, TRAIT_TETRODOTOXIN_HEALING)) return COMSIG_CARBON_BLOCK_BREATH diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm index 69dda419d7cd3..0814834b25a51 100644 --- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm +++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm @@ -178,12 +178,12 @@ ghostie.apply_status_effect(/datum/status_effect/incapacitating/paralyzed/revenant, 2 SECONDS) ghostie.apply_status_effect(/datum/status_effect/revenant/revealed, 10 SECONDS) ghostie.adjust_health(50) - for(var/mob/living/carbon/C in get_hearers_in_view(effective_size,T)) - if(IS_CULTIST(C)) - to_chat(C, span_userdanger("The divine explosion sears you!")) - C.Paralyze(40) - C.adjust_fire_stacks(5) - C.ignite_mob() + for(var/mob/living/carbon/evil_motherfucker in get_hearers_in_view(effective_size,T)) + if(IS_CULTIST(evil_motherfucker) || HAS_TRAIT(evil_motherfucker, TRAIT_EVIL)) + to_chat(evil_motherfucker, span_userdanger("The divine explosion sears you!")) + evil_motherfucker.Paralyze(40) + evil_motherfucker.adjust_fire_stacks(5) + evil_motherfucker.ignite_mob() ..() /datum/chemical_reaction/gunpowder diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index e95b5eea82089..77e1ef3903992 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -37,6 +37,8 @@ var/fill_icon_state = null /// The icon file to take fill icon appearances from var/fill_icon = 'icons/obj/medical/reagent_fillings.dmi' + ///The sound this container makes when picked up, dropped if there is liquid inside. + var/reagent_container_liquid_sound = null /obj/item/reagent_containers/apply_fantasy_bonuses(bonus) . = ..() @@ -291,3 +293,13 @@ filling.color = mix_color_from_reagents(reagents.reagent_list) . += filling + +/obj/item/reagent_containers/dropped(mob/user, silent) + . = ..() + if(reagent_container_liquid_sound && reagents.total_volume > 0) + playsound(src, reagent_container_liquid_sound, LIQUID_SLOSHING_SOUND_VOLUME, vary = TRUE, ignore_walls = FALSE) + +/obj/item/reagent_containers/equipped(mob/user, slot, initial = FALSE) + . = ..() + if((slot & ITEM_SLOT_HANDS) && reagent_container_liquid_sound && reagents.total_volume > 0) + playsound(src, reagent_container_liquid_sound, LIQUID_SLOSHING_SOUND_VOLUME, vary = TRUE, ignore_walls = FALSE) diff --git a/code/modules/reagents/reagent_containers/cups/_cup.dm b/code/modules/reagents/reagent_containers/cups/_cup.dm index c01ad352f54dd..90ddd0d4b380d 100644 --- a/code/modules/reagents/reagent_containers/cups/_cup.dm +++ b/code/modules/reagents/reagent_containers/cups/_cup.dm @@ -9,6 +9,7 @@ icon_state = "bottle" lefthand_file = 'icons/mob/inhands/items/drinks_lefthand.dmi' righthand_file = 'icons/mob/inhands/items/drinks_righthand.dmi' + reagent_container_liquid_sound = SFX_DEFAULT_LIQUID_SLOSH ///Like Edible's food type, what kind of drink is this? var/drink_type = NONE @@ -350,6 +351,9 @@ /obj/item/reagent_containers/cup/beaker/synthflesh list_reagents = list(/datum/reagent/medicine/c2/synthflesh = 50) +/obj/item/reagent_containers/cup/beaker/synthflesh/named + name = "synthflesh beaker" + /obj/item/reagent_containers/cup/bucket name = "bucket" desc = "It's a bucket." diff --git a/code/modules/reagents/reagent_containers/cups/drinks.dm b/code/modules/reagents/reagent_containers/cups/drinks.dm index b473c6b38a2ef..a5b64b61d06eb 100644 --- a/code/modules/reagents/reagent_containers/cups/drinks.dm +++ b/code/modules/reagents/reagent_containers/cups/drinks.dm @@ -228,6 +228,7 @@ /// DOPPLER SHIFT REMOVAL END var/flip_chance = 10 custom_price = PAYCHECK_LOWER * 0.8 + reagent_container_liquid_sound = SFX_PLASTIC_BOTTLE_LIQUID_SLOSH /// DOPPLER SHIFT REMOVAL BEGIN /*/obj/item/reagent_containers/cup/glass/waterbottle/Initialize(mapload) diff --git a/code/modules/reagents/reagent_containers/misc.dm b/code/modules/reagents/reagent_containers/misc.dm index 8b13ab4a54beb..735fd1b9fb17a 100644 --- a/code/modules/reagents/reagent_containers/misc.dm +++ b/code/modules/reagents/reagent_containers/misc.dm @@ -128,6 +128,7 @@ has_variable_transfer_amount = FALSE volume = 5 spillable = FALSE + reagent_container_liquid_sound = null /obj/item/reagent_containers/cup/rag/Initialize(mapload) . = ..() diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index a1792a9670db3..17ce2fea149f4 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -25,6 +25,7 @@ volume = 250 possible_transfer_amounts = list(5,10) var/spray_sound = 'sound/effects/spray2.ogg' + reagent_container_liquid_sound = SFX_DEFAULT_LIQUID_SLOSH /obj/item/reagent_containers/spray/ranged_interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) return try_spray(interacting_with, user) ? ITEM_INTERACT_SUCCESS : ITEM_INTERACT_BLOCKING diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 06537e591c976..8e8d9c1b9b15e 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -138,7 +138,7 @@ */ /obj/item/reagent_containers/syringe/on_accidental_consumption(mob/living/carbon/victim, mob/living/carbon/user, obj/item/source_item, discover_after = TRUE) if(source_item) - to_chat(victim, span_boldwarning("There's a [src] in [source_item]!!")) + to_chat(victim, span_boldwarning("There's \a [src] in [source_item]!!")) else to_chat(victim, span_boldwarning("[src] injects you!")) diff --git a/code/modules/recycling/conveyor.dm b/code/modules/recycling/conveyor.dm index b4580a8bc2353..44d9631a60950 100644 --- a/code/modules/recycling/conveyor.dm +++ b/code/modules/recycling/conveyor.dm @@ -34,15 +34,18 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) var/flipped = FALSE /// Are we currently conveying items? var/conveying = FALSE - //Direction -> if we have a conveyor belt in that direction + ///Direction -> if we have a conveyor belt in that direction var/list/neighbors + /// are we operating in wire power mode + var/wire_mode = FALSE + /// weakref to attached cable if wire mode + var/datum/weakref/attached_wire_ref /obj/machinery/conveyor/Initialize(mapload, new_dir, new_id) . = ..() AddElement(/datum/element/footstep_override, priority = STEP_SOUND_CONVEYOR_PRIORITY) AddElement(/datum/element/give_turf_traits, string_list(list(TRAIT_TURF_IGNORE_SLOWDOWN))) register_context() - if(new_dir) setDir(new_dir) if(new_id) @@ -58,6 +61,9 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) AddElement(/datum/element/connect_loc, loc_connections) update_move_direction() LAZYADD(GLOB.conveyors_by_id[id], src) + if(wire_mode) + update_cable() + START_PROCESSING(SSmachines, src) /obj/machinery/conveyor/examine(mob/user) . = ..() @@ -66,6 +72,7 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) . += "\nLeft-click with a wrench to rotate." . += "Left-click with a screwdriver to invert its direction." . += "Right-click with a screwdriver to flip its belt around." + . += "Left-click with a multitool to toggle whether this conveyor receives power via cable. Toggling connects and disconnects." . += "Using another conveyor belt assembly on this will place a new conveyor belt in the direction this one is pointing." /obj/machinery/conveyor/add_context(atom/source, list/context, obj/item/held_item, mob/user) @@ -80,6 +87,9 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) context[SCREENTIP_CONTEXT_LMB] = "Invert conveyor belt" context[SCREENTIP_CONTEXT_RMB] = "Flip conveyor belt" return CONTEXTUAL_SCREENTIP_SET + if(held_item?.tool_behaviour == TOOL_MULTITOOL) + context[SCREENTIP_CONTEXT_LMB] = "Toggle conveyor belt wire mode" + return CONTEXTUAL_SCREENTIP_SET /obj/machinery/conveyor/centcom_auto id = "round_end_belt" @@ -118,6 +128,7 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) /obj/machinery/conveyor/Destroy() set_operating(FALSE) LAZYREMOVE(GLOB.conveyors_by_id[id], src) + attached_wire_ref = null return ..() /obj/machinery/conveyor/vv_edit_var(var_name, var_value) @@ -295,7 +306,16 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) inverted = !inverted update_move_direction() to_chat(user, span_notice("You set [src]'s direction [inverted ? "backwards" : "back to default"].")) - + else if(attacking_item.tool_behaviour == TOOL_MULTITOOL) + attacking_item.play_tool_sound(src) + wire_mode = !wire_mode + update_cable() + power_change() + if(wire_mode) + START_PROCESSING(SSmachines, src) + else + STOP_PROCESSING(SSmachines, src) + to_chat(user, span_notice("You set [src]'s wire mode [wire_mode ? "on" : "off"].")) else if(istype(attacking_item, /obj/item/stack/conveyor)) // We should place a new conveyor belt machine on the output turf the conveyor is pointing to. var/turf/target_turf = get_step(get_turf(src), forwards) @@ -334,10 +354,51 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) return user.Move_Pulled(src) +/obj/machinery/conveyor/powered(chan = power_channel, ignore_use_power = FALSE) + if(!wire_mode) + return ..() + var/datum/powernet/powernet = get_powernet() + if(!isnull(powernet)) + return clamp(powernet.avail-powernet.load, 0, powernet.avail) >= active_power_usage + return ..() + /obj/machinery/conveyor/power_change() . = ..() update() +/obj/machinery/conveyor/process() + if(!wire_mode) + return PROCESS_KILL + if(isnull(attached_wire_ref)) + update_cable() + return + var/datum/powernet/powernet = get_powernet() + if(isnull(powernet)) + return + if(powered()) + powernet.load += active_power_usage + else + power_change() + + +/obj/machinery/conveyor/proc/update_cable() + if(!wire_mode) + attached_wire_ref = null + return + var/turf/our_turf = get_turf(src) + attached_wire_ref = WEAKREF(locate(/obj/structure/cable) in our_turf) + if(attached_wire_ref) + return power_change() + +/obj/machinery/conveyor/proc/get_powernet() + if(!wire_mode) + return + var/obj/structure/cable/cable = attached_wire_ref.resolve() + if(isnull(cable)) + attached_wire_ref = null + return + return cable.powernet + // Conveyor switch /obj/machinery/conveyor_switch name = "conveyor switch" diff --git a/code/modules/religion/honorbound/honorbound_trauma.dm b/code/modules/religion/honorbound/honorbound_trauma.dm index 6bc0879b12592..ed4ecde1592ba 100644 --- a/code/modules/religion/honorbound/honorbound_trauma.dm +++ b/code/modules/religion/honorbound/honorbound_trauma.dm @@ -73,6 +73,8 @@ guilty(attacked_mob, "for blasphemous magicks!") if(HAS_TRAIT(attacked_mob, TRAIT_CULT_HALO)) guilty(attacked_mob, "for blasphemous worship!") + if(HAS_TRAIT(attacked_mob, TRAIT_EVIL)) + guilty(attacked_mob, "an almost fanatical commitment to EEEEVIL!") if(attacked_mob.mind) var/datum/mind/guilty_conscience = attacked_mob.mind if(guilty_conscience.has_antag_datum(/datum/antagonist/abductor)) diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index d07deca292691..15a5fed08eb08 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -21,6 +21,26 @@ ) departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING +/datum/design/board/power_connector + name = "Power Connector Board" + desc = "The circuit board for a portable SMES power connector." + id = "power_connector" + build_path = /obj/item/circuitboard/machine/smes/connector + category = list( + RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING + +/datum/design/board/smesbank + name = "Portable SMES Board" + desc = "The circuit board for a portable SMES, which requires a connector to use." + id = "portable_smes" + build_path = /obj/item/circuitboard/machine/smesbank + category = list( + RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING + /datum/design/board/announcement_system name = "Automated Announcement System Board" desc = "The circuit board for an automated announcement system." @@ -1257,3 +1277,73 @@ RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ENGINEERING ) departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_CARGO | DEPARTMENT_BITFLAG_SERVICE + +/datum/design/board/manulathe + name = "Manufacturing Lathe Board" + desc = "The circuit board for this machine." + id = "manulathe" + build_path = /obj/item/circuitboard/machine/manulathe + category = list( + RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_CARGO + +/datum/design/board/manucrafter + name = "Manufacturing Assembling Machine Board" + desc = "The circuit board for this machine." + id = "manucrafter" + build_path = /obj/item/circuitboard/machine/manucrafter + category = list( + RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_CARGO + +/datum/design/board/manucrusher + name = "Manufacturing Crusher Board" + desc = "The circuit board for this machine." + id = "manucrusher" + build_path = /obj/item/circuitboard/machine/manucrusher + category = list( + RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_CARGO + +/datum/design/board/manurouter + name = "Manufacturing Router Board" + desc = "The circuit board for this machine." + id = "manurouter" + build_path = /obj/item/circuitboard/machine/manurouter + category = list( + RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_CARGO + +/datum/design/board/manusorter + name = "Conveyor Sort-Router Board" + desc = "The circuit board for this machine." + id = "manusorter" + build_path = /obj/item/circuitboard/machine/manusorter + category = list( + RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_CARGO + +/datum/design/board/manuunloader + name = "Manufacturing Crate Unloader Board" + desc = "The circuit board for this machine." + id = "manuunloader" + build_path = /obj/item/circuitboard/machine/manuunloader + category = list( + RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_CARGO + +/datum/design/board/manusmelter + name = "Manufacturing Smelter Board" + desc = "The circuit board for this machine." + id = "manusmelter" + build_path = /obj/item/circuitboard/machine/manusmelter + category = list( + RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_CARGO diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index f0e0978a6074a..ebda0f1e3b464 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -434,7 +434,7 @@ desc = "A mace fit for a cleric. Useful for bypassing plate armor, but too bulky for much else." id = "cleric_mace" build_type = AUTOLATHE - materials = list(MAT_CATEGORY_ITEM_MATERIAL = SHEET_MATERIAL_AMOUNT * 6) + materials = list(MAT_CATEGORY_ITEM_MATERIAL = SHEET_MATERIAL_AMOUNT * 4.5, MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = SHEET_MATERIAL_AMOUNT * 1.5) build_path = /obj/item/melee/cleric_mace category = list(RND_CATEGORY_IMPORTED) diff --git a/code/modules/research/machinery/_production.dm b/code/modules/research/machinery/_production.dm index f503f158a0e6b..36ffe07eb5944 100644 --- a/code/modules/research/machinery/_production.dm +++ b/code/modules/research/machinery/_production.dm @@ -174,7 +174,7 @@ SHOULD_CALL_PARENT(FALSE) //first play the insertion animation - flick_overlay_view(material_insertion_animation(mat_ref.greyscale_colors), 1 SECONDS) + flick_overlay_view(material_insertion_animation(mat_ref), 1 SECONDS) //now play the progress bar animation flick_overlay_view(mutable_appearance('icons/obj/machines/research.dmi', "protolathe_progress"), 1 SECONDS) diff --git a/code/modules/research/techweb/nodes/engi_nodes.dm b/code/modules/research/techweb/nodes/engi_nodes.dm index 0d8572130fb80..4ef55e21bc97a 100644 --- a/code/modules/research/techweb/nodes/engi_nodes.dm +++ b/code/modules/research/techweb/nodes/engi_nodes.dm @@ -148,6 +148,13 @@ "light_tube", "crossing_signal", "guideway_sensor", + "manuunloader", + "manusmelter", + "manucrusher", + "manucrafter", + "manulathe", + "manusorter", + "manurouter", ) /datum/techweb_node/energy_manipulation @@ -159,6 +166,8 @@ "apc_control", "powermonitor", "smes", + "portable_smes", + "power_connector", "emitter", "grounding_rod", "tesla_coil", diff --git a/code/modules/research/xenobiology/crossbreeding/_clothing.dm b/code/modules/research/xenobiology/crossbreeding/_clothing.dm index 89baa18720d7b..caaafd056423d 100644 --- a/code/modules/research/xenobiology/crossbreeding/_clothing.dm +++ b/code/modules/research/xenobiology/crossbreeding/_clothing.dm @@ -150,6 +150,10 @@ Slimecrossing Armor slowdown = 4 var/hit_reflect_chance = 40 +/obj/item/clothing/suit/armor/heavy/adamantine/Initialize(mapload) + . = ..() + AddComponent(/datum/component/item_equipped_movement_rustle, SFX_PLATE_ARMOR_RUSTLE, 8) + /obj/item/clothing/suit/armor/heavy/adamantine/IsReflect(def_zone) if((def_zone in list(BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG)) && prob(hit_reflect_chance)) return TRUE diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index fb6fabfe1f5f9..735b0f641a91c 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -542,6 +542,11 @@ areas += E hyperspace_sound(HYPERSPACE_LAUNCH, areas) enterTransit() + + //Tell the events we're starting, so they can time their spawns or do some other stuff + for(var/datum/shuttle_event/event as anything in event_list) + event.start_up_event(SSshuttle.emergency_escape_time * engine_coeff) + mode = SHUTTLE_ESCAPE launch_status = ENDGAME_LAUNCHED setTimer(SSshuttle.emergency_escape_time * engine_coeff) @@ -552,15 +557,11 @@ color_override = "orange", ) INVOKE_ASYNC(SSticker, TYPE_PROC_REF(/datum/controller/subsystem/ticker, poll_hearts)) - SSmapping.mapvote() //If no map vote has been run yet, start one. + INVOKE_ASYNC(SSvote, TYPE_PROC_REF(/datum/controller/subsystem/vote, initiate_vote), /datum/vote/map_vote, vote_initiator_name = "Map Rotation", forced = TRUE) if(!is_reserved_level(z)) CRASH("Emergency shuttle did not move to transit z-level!") - //Tell the events we're starting, so they can time their spawns or do some other stuff - for(var/datum/shuttle_event/event as anything in event_list) - event.start_up_event(SSshuttle.emergency_escape_time * engine_coeff) - if(SHUTTLE_STRANDED, SHUTTLE_DISABLED) SSshuttle.checkHostileEnvironment() @@ -627,7 +628,7 @@ var/list/names = list() for(var/datum/shuttle_event/event as anything in subtypesof(/datum/shuttle_event)) if(prob(initial(event.event_probability))) - event_list.Add(new event(src)) + add_shuttle_event(event) names += initial(event.name) if(LAZYLEN(names)) log_game("[capitalize(name)] has selected the following shuttle events: [english_list(names)].") diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index 5203d7d20e86b..d4f7c3ddfcd09 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -167,19 +167,54 @@ All ShuttleMove procs go here /obj/machinery/door/airlock/beforeShuttleMove(turf/newT, rotation, move_mode, obj/docking_port/mobile/moving_dock) . = ..() + + if (cycle_pump) + INVOKE_ASYNC(cycle_pump, TYPE_PROC_REF(/obj/machinery/atmospherics/components/unary/airlock_pump, undock)) + for(var/obj/machinery/door/airlock/other_airlock in range(2, src)) // includes src, extended because some escape pods have 1 plating turf exposed to space other_airlock.shuttledocked = FALSE other_airlock.air_tight = TRUE + if (other_airlock.cycle_pump) + INVOKE_ASYNC(other_airlock.cycle_pump, TYPE_PROC_REF(/obj/machinery/atmospherics/components/unary/airlock_pump, undock)) + continue INVOKE_ASYNC(other_airlock, TYPE_PROC_REF(/obj/machinery/door/, close), FALSE, TRUE) // force crush /obj/machinery/door/airlock/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() var/current_area = get_area(src) + var/turf/local_turf + var/tile_air_pressure for(var/obj/machinery/door/airlock/other_airlock in orange(2, src)) // does not include src, extended because some escape pods have 1 plating turf exposed to space if(get_area(other_airlock) != current_area) // does not include double-wide airlocks unless actually docked // Cycle linking is only disabled if we are actually adjacent to another airlock shuttledocked = TRUE other_airlock.shuttledocked = TRUE + if (other_airlock.cycle_pump) + local_turf = get_step(src, REVERSE_DIR(other_airlock.cycle_pump.dir)) + tile_air_pressure = 0 + if (local_turf) + tile_air_pressure = max(0, local_turf.return_air().return_pressure()) + INVOKE_ASYNC(other_airlock.cycle_pump, TYPE_PROC_REF(/obj/machinery/atmospherics/components/unary/airlock_pump, on_dock_request), tile_air_pressure) + // Save external airlocks turf in case our own docking purpouses + local_turf = get_turf(other_airlock) + + if (cycle_pump) + tile_air_pressure = 0 + if (local_turf) + local_turf = get_step(local_turf, REVERSE_DIR(cycle_pump.dir)) + if (local_turf) + tile_air_pressure = max(0, local_turf.return_air().return_pressure()) + INVOKE_ASYNC(cycle_pump, TYPE_PROC_REF(/obj/machinery/atmospherics/components/unary/airlock_pump, on_dock_request), tile_air_pressure) + else + // In case, somebody decides to build an airlock on evac shuttle, we count CentComs blastdoors as valid docking airlock + local_turf = get_step(src, REVERSE_DIR(cycle_pump.dir)) + if (local_turf) + for(var/obj/machinery/door/poddoor/shuttledock/centcom_airlock in local_turf) + // For some reason on docking moment those tiles are vacuum, and pump denies safe_dock attempt + // To fix this we're lying, that external pressure is nominal + INVOKE_ASYNC(cycle_pump, TYPE_PROC_REF(/obj/machinery/atmospherics/components/unary/airlock_pump, on_dock_request), ONE_ATMOSPHERE) + break + /obj/machinery/camera/beforeShuttleMove(turf/newT, rotation, move_mode, obj/docking_port/mobile/moving_dock) . = ..() diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 68a0a41a2e092..bf6e81a955760 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -264,7 +264,7 @@ /obj/docking_port/stationary/proc/load_roundstart() if(json_key) - var/sid = SSmapping.config.shuttles[json_key] + var/sid = SSmapping.current_map.shuttles[json_key] roundstart_template = SSmapping.shuttle_templates[sid] if(!roundstart_template) CRASH("json_key:[json_key] value \[[sid]\] resulted in a null shuttle template for [src]") @@ -1204,6 +1204,14 @@ for(var/item in removees) event_list.Remove(item) +/// Give a typepath of a shuttle event to add to the shuttle. If added during endgame transit, will insta start the event +/obj/docking_port/mobile/proc/add_shuttle_event(typepath) + var/datum/shuttle_event/event = new typepath (src) + event_list.Add(event) + if(launch_status == ENDGAME_LAUNCHED) + event.start_up_event(0) + return event + #ifdef TESTING #undef DOCKING_PORT_HIGHLIGHT #endif diff --git a/code/modules/shuttle/shuttle_events/_shuttle_events.dm b/code/modules/shuttle/shuttle_events/_shuttle_events.dm index f809e274dc601..3c6425018aa46 100644 --- a/code/modules/shuttle/shuttle_events/_shuttle_events.dm +++ b/code/modules/shuttle/shuttle_events/_shuttle_events.dm @@ -21,7 +21,11 @@ src.port = port /datum/shuttle_event/proc/start_up_event(evacuation_duration) - activate_at = world.time + evacuation_duration * activation_fraction + if(port.launch_status == ENDGAME_LAUNCHED) + active = TRUE //if added during endgame, instant activate + activate() + else + activate_at = world.time + evacuation_duration * activation_fraction ///We got activated /datum/shuttle_event/proc/activate() diff --git a/code/modules/shuttle/shuttle_events/blackhole.dm b/code/modules/shuttle/shuttle_events/blackhole.dm new file mode 100644 index 0000000000000..c73245be926a9 --- /dev/null +++ b/code/modules/shuttle/shuttle_events/blackhole.dm @@ -0,0 +1,82 @@ +///Sensors indicate that a black hole's gravitational field is affecting the region of space we were headed through +/datum/shuttle_event/simple_spawner/black_hole + name = "Black Hole (Oh no!)" + event_probability = 0 // only admin spawnable + spawn_probability_per_process = 10 + activation_fraction = 0.35 + spawning_flags = SHUTTLE_EVENT_HIT_SHUTTLE + spawning_list = list(/obj/singularity/shuttle_event = 1) + // only spawn it once + remove_from_list_when_spawned = TRUE + self_destruct_when_empty = TRUE + +///Kobayashi Maru version +/datum/shuttle_event/simple_spawner/black_hole/adminbus + name = "Black Holes (OH GOD!)" + spawn_probability_per_process = 50 + activation_fraction = 0.2 + spawning_list = list(/obj/singularity/shuttle_event = 10) + remove_from_list_when_spawned = TRUE + +/// No Escape traitor final objective +/datum/shuttle_event/simple_spawner/black_hole/no_escape + name = "Black Hole Massive (is not admin spawnable)" + spawn_probability_per_process = -1.875 // starts in the negative but increases over time + activation_fraction = 0 // no delay + spawning_list = list(/obj/singularity/shuttle_event/no_escape = 1) + remove_from_list_when_spawned = TRUE + /// How much the spawn_probability_per_process increases or decreases over time + /// since spawn_probability starts negative after 15 seconds the prob reaches 0% + /// then every 8 seconds after, the prob increases by ~1% + var/probability_rate_of_change = 0.125 + /// The beacon that is drawing the singularity closer to the escape shuttle + var/obj/machinery/power/singularity_beacon/syndicate/no_escape/beacon + +/datum/shuttle_event/simple_spawner/black_hole/no_escape/proc/announcement() + priority_announce( + text = "Sensors indicate that a black hole's gravitational field is affecting the region of space we are heading through.", + title = "The Orion Trail", + sound = 'sound/announcer/notice/notice1.ogg', + has_important_message = TRUE, + sender_override = "Emergency Shuttle", + color_override = "red", + ) + +/datum/shuttle_event/simple_spawner/black_hole/no_escape/activate() + . = ..() + + addtimer(CALLBACK(src, PROC_REF(announcement)), 5 SECONDS) + port.setTimer(port.timeLeft(1) + 1 MINUTES) // the singularity causes a time distortion + +/datum/shuttle_event/simple_spawner/black_hole/no_escape/event_process() + . = ..() + if(!.) + return + + if((SSshuttle.emergency.mode == SHUTTLE_ESCAPE)) // only while shuttle is in transit + if(beacon && beacon.active) + var/area/escape_shuttle_area = get_area(beacon) + if(istype(escape_shuttle_area, /area/shuttle/escape) && SSshuttle.emergency.is_in_shuttle_bounds(beacon)) + spawn_probability_per_process += probability_rate_of_change + else // beacon is not on shuttle and likely got jettisoned in space + // since the beacon is still powered and attracting the singularity it results in x2 rate of decrease + spawn_probability_per_process -= (probability_rate_of_change * 2) + else // beacon is unpowered or destroyed + spawn_probability_per_process -= probability_rate_of_change + + if(prob(spawn_probability_per_process)) + spawn_movable(get_type_to_spawn()) + return SHUTTLE_EVENT_CLEAR + +/datum/shuttle_event/simple_spawner/black_hole/no_escape/get_spawn_turf() + RETURN_TYPE(/turf) + + if(beacon && beacon.active) + var/area/escape_shuttle_area = get_area(beacon) + if(istype(escape_shuttle_area, /area/shuttle/escape) && SSshuttle.emergency.is_in_shuttle_bounds(beacon)) + // beacon is active and on shuttle so singularity will directly hit the shuttle + return pick(spawning_turfs_hit) + + // otherwise beacon is turned off, destroyed, or spaced so there is a chance to miss + // the singularity is 11x11 so even a miss can have a glancing hit against the shuttle + return pick(spawning_turfs_hit + spawning_turfs_miss) diff --git a/code/modules/shuttle/shuttle_events/carp.dm b/code/modules/shuttle/shuttle_events/carp.dm index 18529f1c02884..c54f3e44716e9 100644 --- a/code/modules/shuttle/shuttle_events/carp.dm +++ b/code/modules/shuttle/shuttle_events/carp.dm @@ -16,19 +16,6 @@ //Give the carp the goal to migrate in a straight line so they dont just idle in hyperspace carpee.migrate_to(list(WEAKREF(get_edge_target_turf(carpee.loc, angle2dir(dir2angle(port.preferred_direction) - 180))))) -///CARPTIDE! CARPTIDE! CARPTIDE! Magical carp will attack the shuttle! -/datum/shuttle_event/simple_spawner/carp/magic - name = "Magical Carp Nest! (Very Dangerous!)" - event_probability = 0 - activation_fraction = 0.2 - - spawning_list = list(/mob/living/basic/carp/magic = 12, /mob/living/basic/carp/magic/chaos = 1) - spawning_flags = SHUTTLE_EVENT_HIT_SHUTTLE | SHUTTLE_EVENT_MISS_SHUTTLE - spawn_probability_per_process = 20 - - remove_from_list_when_spawned = TRUE - self_destruct_when_empty = TRUE - ///Spawn a bunch of friendly carp to view from inside the shuttle! May occassionally pass through and nibble some windows, but are otherwise pretty harmless /datum/shuttle_event/simple_spawner/carp/friendly name = "Passive Carp Nest! (Mostly Harmless!)" @@ -60,3 +47,34 @@ spawn_probability_per_process = 100 remove_from_list_when_spawned = FALSE + +///CARPTIDE! CARPTIDE! CARPTIDE! Magical carp will attack the shuttle! +/datum/shuttle_event/simple_spawner/carp/magic + name = "Magical Carp Nest! (Very Dangerous!)" + spawning_list = list(/mob/living/basic/carp/magic = 12, /mob/living/basic/carp/magic/chaos = 3) + spawning_flags = SHUTTLE_EVENT_HIT_SHUTTLE | SHUTTLE_EVENT_MISS_SHUTTLE + + event_probability = 0 + activation_fraction = 0.2 + spawn_probability_per_process = 20 + + remove_from_list_when_spawned = TRUE + self_destruct_when_empty = TRUE + +/// Spawns some player controlled fire sharks +/datum/shuttle_event/simple_spawner/player_controlled/fire_shark + name = "Three player controlled fire sharks! (Dangerous!)" + spawning_list = list(/mob/living/basic/heretic_summon/fire_shark = 3) + spawning_flags = SHUTTLE_EVENT_HIT_SHUTTLE + + event_probability = 0 + activation_fraction = 0.2 + spawn_probability_per_process = 100 + spawns_per_spawn = 3 + + spawn_anyway_if_no_player = FALSE + ghost_alert_string = "Would you like to be a fire shark attacking the shuttle?" + remove_from_list_when_spawned = TRUE + self_destruct_when_empty = TRUE + + role_type = ROLE_SENTIENCE diff --git a/code/modules/shuttle/shuttle_events/humans.dm b/code/modules/shuttle/shuttle_events/humans.dm new file mode 100644 index 0000000000000..99f4006d5bb28 --- /dev/null +++ b/code/modules/shuttle/shuttle_events/humans.dm @@ -0,0 +1,122 @@ +/// Human spawning events, with the ability to give them outfits! +/datum/shuttle_event/simple_spawner/player_controlled/human + /// Outfits equipped to human mobs we send to the shuttle + var/datum/outfit/outfit = /datum/outfit/job/assistant + +/datum/shuttle_event/simple_spawner/player_controlled/human/post_spawn(atom/movable/spawnee) + ..() + + if(ishuman(spawnee)) + prepare_human(spawnee) + +/datum/shuttle_event/simple_spawner/player_controlled/human/proc/prepare_human(mob/living/carbon/human/human) + human.equipOutfit(new outfit ()) + +/datum/shuttle_event/simple_spawner/player_controlled/human/greytide + name = "Greytide! (10 assistants)" + spawning_list = list(/mob/living/carbon/human = 10) + spawning_flags = SHUTTLE_EVENT_HIT_SHUTTLE + outfit = /datum/outfit/job/assistant/breath_mask + + event_probability = 0.1 + spawn_probability_per_process = 5 + activation_fraction = 0.05 + spawns_per_spawn = 10 + + spawn_anyway_if_no_player = TRUE + ghost_alert_string = "Would you like to be an assistant shot at the shuttle?" + remove_from_list_when_spawned = TRUE + self_destruct_when_empty = TRUE + + role_type = ROLE_HERMIT + +/datum/outfit/job/assistant/breath_mask + name = "Assistant - Breathmask" + mask = /obj/item/clothing/mask/breath + l_pocket = /obj/item/tank/internals/emergency_oxygen + internals_slot = ITEM_SLOT_LPOCKET + +/datum/shuttle_event/simple_spawner/player_controlled/human/greytide/interns + name = "Intern Wave (Unarmed, 10 interns)" + event_probability = 0 + outfit = /datum/outfit/centcom/centcom_intern/unarmed + + spawn_anyway_if_no_player = FALSE + ghost_alert_string = "Would you like to be a centcom intern shot at the shuttle?" + +/datum/shuttle_event/simple_spawner/player_controlled/human/greytide/interns/activate() + ..() + + minor_announce("We're sending you our bravest interns, please let them in when they arrive.", + title = "Emergency Shuttle", alert = TRUE) + +/datum/shuttle_event/simple_spawner/player_controlled/human/greytide/interns/armed + name = "Intern Wave (Armed, 10 interns)" + event_probability = 0 + outfit = /datum/outfit/centcom/centcom_intern + + spawn_anyway_if_no_player = FALSE + ghost_alert_string = "Would you like to be a centcom intern shot at the shuttle?" + +/datum/shuttle_event/simple_spawner/player_controlled/human/hitchhiker + name = "Hitchhiker! (Harmless, single ghost spawn)" + spawning_list = list(/mob/living/carbon/human = 1) + spawning_flags = SHUTTLE_EVENT_HIT_SHUTTLE + outfit = /datum/outfit/job/assistant/hitchhiker + + event_probability = 1 + spawn_probability_per_process = 5 + activation_fraction = 0.2 + + spawn_anyway_if_no_player = TRUE + ghost_alert_string = "Would you like to be an assistant shot at the shuttle?" + remove_from_list_when_spawned = TRUE + self_destruct_when_empty = TRUE + + role_type = ROLE_HERMIT + +/datum/outfit/job/assistant/hitchhiker + name = "Assistant - Hitchhiker" + mask = /obj/item/clothing/mask/breath + suit = /obj/item/clothing/suit/space/eva + head = /obj/item/clothing/head/helmet/space/eva + l_pocket = /obj/item/tank/internals/emergency_oxygen + r_hand = /obj/item/storage/briefcase/hitchiker + internals_slot = ITEM_SLOT_LPOCKET + +/datum/shuttle_event/simple_spawner/player_controlled/human/nukie + name = "Nuclear Operative (Dangerous as heck)!" + spawning_list = list(/mob/living/carbon/human = 1) + spawning_flags = SHUTTLE_EVENT_HIT_SHUTTLE + outfit = /datum/outfit/deathmatch_loadout/nukie + + event_probability = 0 + spawn_probability_per_process = 100 + + spawn_anyway_if_no_player = FALSE + ghost_alert_string = "Would you like to be a nuclear operative to assault the shuttle?" + remove_from_list_when_spawned = TRUE + self_destruct_when_empty = TRUE + + role_type = ROLE_NUCLEAR_OPERATIVE + +/datum/outfit/shuttle_nukie + name = "Shuttle Nuclear Operative" + + uniform = /obj/item/clothing/under/syndicate/tacticool + back = /obj/item/mod/control/pre_equipped/nuclear + r_hand = /obj/item/gun/ballistic/shotgun/bulldog/unrestricted + belt = /obj/item/gun/ballistic/automatic/pistol/clandestine + r_pocket = /obj/item/reagent_containers/hypospray/medipen/stimulants + l_pocket = /obj/item/grenade/syndieminibomb + implants = list(/obj/item/implant/explosive) + suit_store = /obj/item/tank/internals/emergency_oxygen + + internals_slot = ITEM_SLOT_SUITSTORE + + backpack_contents = list( + /obj/item/ammo_box/c10mm, + /obj/item/ammo_box/magazine/m12g = 2, + /obj/item/pen/edagger, + /obj/item/reagent_containers/hypospray/medipen/atropine, + ) diff --git a/code/modules/shuttle/shuttle_events/meteors.dm b/code/modules/shuttle/shuttle_events/meteors.dm index ef0b6002e5774..ad3814186acd7 100644 --- a/code/modules/shuttle/shuttle_events/meteors.dm +++ b/code/modules/shuttle/shuttle_events/meteors.dm @@ -40,3 +40,15 @@ spawning_flags = SHUTTLE_EVENT_MISS_SHUTTLE spawning_list = list(/obj/effect/meteor/medium = 10, /obj/effect/meteor/big = 5, /obj/effect/meteor/flaming = 3, /obj/effect/meteor/cluster = 1, /obj/effect/meteor/irradiated = 3, /obj/effect/meteor/bluespace = 2) + +/datum/shuttle_event/simple_spawner/meteor/dust/meaty + name = "Meaty Meteors! (Mostly Safe)" + spawning_list = list(/obj/effect/meteor/meaty = 1) + spawning_flags = SHUTTLE_EVENT_MISS_SHUTTLE | SHUTTLE_EVENT_HIT_SHUTTLE + + event_probability = 0.1 + activation_fraction = 0.1 + spawn_probability_per_process = 100 + spawns_per_spawn = 3 + + hit_the_shuttle_chance = 2 diff --git a/code/modules/shuttle/shuttle_events/misc.dm b/code/modules/shuttle/shuttle_events/misc.dm index f65eddadf7cbf..9f6db855a7611 100644 --- a/code/modules/shuttle/shuttle_events/misc.dm +++ b/code/modules/shuttle/shuttle_events/misc.dm @@ -38,24 +38,3 @@ while(islist(spawn_list)) spawn_list = pick_weight(spawn_list) return spawn_list - -///Sensors indicate that a black hole's gravitational field is affecting the region of space we were headed through -/datum/shuttle_event/simple_spawner/black_hole - name = "Black Hole (Oh no!)" - event_probability = 0 // only admin spawnable - spawn_probability_per_process = 10 - activation_fraction = 0.35 - spawning_flags = SHUTTLE_EVENT_HIT_SHUTTLE - spawning_list = list(/obj/singularity/shuttle_event = 1) - // only spawn it once - remove_from_list_when_spawned = TRUE - self_destruct_when_empty = TRUE - -///Kobayashi Maru version -/datum/shuttle_event/simple_spawner/black_hole/adminbus - name = "Black Holes (OH GOD!)" - event_probability = 0 - spawn_probability_per_process = 50 - activation_fraction = 0.2 - spawning_list = list(/obj/singularity/shuttle_event = 10) - remove_from_list_when_spawned = TRUE diff --git a/code/modules/shuttle/shuttle_events/player_controlled.dm b/code/modules/shuttle/shuttle_events/player_controlled.dm index 86d134f29f727..6954a5eaa7879 100644 --- a/code/modules/shuttle/shuttle_events/player_controlled.dm +++ b/code/modules/shuttle/shuttle_events/player_controlled.dm @@ -17,12 +17,16 @@ /// Attempt to grant control of a mob to ghosts before spawning it in. if spawn_anyway_if_no_player = TRUE, we spawn the mob even if there's no ghosts /datum/shuttle_event/simple_spawner/player_controlled/proc/try_grant_ghost_control(spawn_type) - var/mob/chosen_one = SSpolling.poll_ghost_candidates(ghost_alert_string + " (Warning: you will not be able to return to your body!)", check_jobban = role_type, poll_time = 10 SECONDS, alert_pic = spawn_type, role_name_text = "shot at shuttle", amount_to_pick = 1) - if(isnull(chosen_one) && !spawn_anyway_if_no_player) - return - var/mob/living/new_mob = new spawn_type (get_turf(get_spawn_turf())) - new_mob.ckey = chosen_one.ckey + var/mob/living/new_mob = new spawn_type (null) + ADD_TRAIT(new_mob, TRAIT_STASIS, type) post_spawn(new_mob) + var/mob/chosen_one = SSpolling.poll_ghost_candidates(ghost_alert_string + " (Warning: you will not be able to return to your body!)", check_jobban = role_type, poll_time = 10 SECONDS, alert_pic = new_mob, role_name_text = "shot at shuttle", amount_to_pick = 1) + if(isnull(chosen_one) && !spawn_anyway_if_no_player || !isdead(chosen_one)) //we can get sniped if there's multiple spawns, so check if dead + qdel(new_mob) + return + new_mob.forceMove(get_turf(get_spawn_turf())) + REMOVE_TRAIT(new_mob, TRAIT_STASIS, type) + new_mob.ckey = chosen_one?.ckey ///BACK FOR REVENGE!!! /datum/shuttle_event/simple_spawner/player_controlled/alien_queen diff --git a/code/modules/shuttle/shuttle_events/projectile.dm b/code/modules/shuttle/shuttle_events/projectile.dm new file mode 100644 index 0000000000000..940dddb61a798 --- /dev/null +++ b/code/modules/shuttle/shuttle_events/projectile.dm @@ -0,0 +1,23 @@ +/// Spawn projectiles towards the shuttle +/datum/shuttle_event/simple_spawner/projectile + /// Spread of the fired projectiles, to add some flair to it + var/angle_spread = 0 + +/datum/shuttle_event/simple_spawner/projectile/post_spawn(atom/movable/spawnee) + . = ..() + + if(isprojectile(spawnee)) + var/obj/projectile/pew = spawnee + var/angle = dir2angle(REVERSE_DIR(port.preferred_direction)) + rand(-angle_spread, angle_spread) + pew.fire(angle) + +/datum/shuttle_event/simple_spawner/projectile/fireball //bap bap bapaba bap + name = "Fireball Burst (Surprisingly safe!)" + activation_fraction = 0.5 // this doesn't matter for hijack events but just in case its forced + + spawning_list = list(/obj/projectile/magic/fireball = 1) + angle_spread = 10 + spawns_per_spawn = 10 + spawning_flags = SHUTTLE_EVENT_HIT_SHUTTLE | SHUTTLE_EVENT_HIT_SHUTTLE + spawn_probability_per_process = 2 + self_destruct_when_empty = TRUE diff --git a/code/modules/shuttle/shuttle_rotate.dm b/code/modules/shuttle/shuttle_rotate.dm index cb7cad65b6ba1..15af6db6a4f6d 100644 --- a/code/modules/shuttle/shuttle_rotate.dm +++ b/code/modules/shuttle/shuttle_rotate.dm @@ -33,9 +33,9 @@ If ever any of these procs are useful for non-shuttles, rename it to proc/rotate //Owerride non zero bound_x, bound_y, pixel_x, pixel_y to zero. //Dont take in account starting bound_x, bound_y, pixel_x, pixel_y. //So it can unintentionally shift physical bounds of things that starts with non zero bound_x, bound_y. - if(((bound_height != world.icon_size) || (bound_width != world.icon_size)) && (bound_x == 0) && (bound_y == 0)) //Dont shift things that have non zero bound_x and bound_y, or it move somewhere. Now it BSA and Gateway. - pixel_x = dir & (NORTH|EAST) ? -bound_width+world.icon_size : 0 - pixel_y = dir & (NORTH|WEST) ? -bound_width+world.icon_size : 0 + if(((bound_height != ICON_SIZE_Y) || (bound_width != ICON_SIZE_X)) && (bound_x == 0) && (bound_y == 0)) //Dont shift things that have non zero bound_x and bound_y, or it move somewhere. Now it BSA and Gateway. + pixel_x = dir & (NORTH|EAST) ? -bound_width+ICON_SIZE_X : 0 + pixel_y = dir & (NORTH|WEST) ? -bound_width+ICON_SIZE_X : 0 //? bound_x = pixel_x bound_y = pixel_y diff --git a/code/modules/shuttle/special.dm b/code/modules/shuttle/special.dm index 3cbe494c8d0fb..07aaeed7b48c4 100644 --- a/code/modules/shuttle/special.dm +++ b/code/modules/shuttle/special.dm @@ -48,7 +48,7 @@ . = ..() icon_state = active ? icon_state_on : initial(icon_state) -/obj/machinery/power/emitter/energycannon/magical/process() +/obj/machinery/power/emitter/energycannon/magical/process_early(seconds_per_tick) . = ..() if(active_tables.len >= tables_required) if(!active) diff --git a/code/modules/spells/spell_types/pointed/tie_shoes.dm b/code/modules/spells/spell_types/pointed/tie_shoes.dm index b8efafaf3ba92..42c47779aea2d 100644 --- a/code/modules/spells/spell_types/pointed/tie_shoes.dm +++ b/code/modules/spells/spell_types/pointed/tie_shoes.dm @@ -46,7 +46,7 @@ return isliving(cast_on) // We need to override this, as trying to change next_use_time in cast() will just result in it being overridden. -/datum/action/cooldown/spell/touch/before_cast(atom/cast_on) +/datum/action/cooldown/spell/pointed/untie_shoes/before_cast(atom/cast_on) return ..() | SPELL_NO_IMMEDIATE_COOLDOWN /datum/action/cooldown/spell/pointed/untie_shoes/cast(mob/living/carbon/cast_on) diff --git a/code/modules/spells/spell_types/right_and_wrong.dm b/code/modules/spells/spell_types/right_and_wrong.dm index cafea93fce691..05a7da0fadab1 100644 --- a/code/modules/spells/spell_types/right_and_wrong.dm +++ b/code/modules/spells/spell_types/right_and_wrong.dm @@ -17,7 +17,7 @@ GLOBAL_LIST_INIT(summoned_guns, list( /obj/item/gun/energy/e_gun/advtaser, /obj/item/gun/energy/laser, /obj/item/gun/ballistic/revolver, - /obj/item/gun/ballistic/revolver/syndicate, + /obj/item/gun/ballistic/revolver/badass, /obj/item/gun/ballistic/revolver/c38/detective, /obj/item/gun/ballistic/automatic/pistol/deagle/camo, /obj/item/gun/ballistic/automatic/gyropistol, diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index 6ee76a9f695af..fd62d0292f35f 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -208,9 +208,9 @@ if(arm_owner.hud_used) var/atom/movable/screen/inventory/hand/associated_hand = arm_owner.hud_used.hand_slots["[held_index]"] associated_hand?.update_appearance() - if(arm_owner.gloves) - arm_owner.dropItemToGround(arm_owner.gloves, TRUE) . = ..() + if(arm_owner.num_hands == 0) + arm_owner.dropItemToGround(arm_owner.gloves, TRUE) arm_owner.update_worn_gloves() //to remove the bloody hands overlay /obj/item/bodypart/leg/drop_limb(special, dismembered, move_to_floor = TRUE) @@ -321,6 +321,8 @@ new_limb_owner.updatehealth() new_limb_owner.update_body() new_limb_owner.update_damage_overlays() + if(!special) + new_limb_owner.hud_used?.update_locked_slots() SEND_SIGNAL(new_limb_owner, COMSIG_CARBON_POST_ATTACH_LIMB, src, special) return TRUE diff --git a/code/modules/surgery/bodyparts/parts.dm b/code/modules/surgery/bodyparts/parts.dm index 992d60142bdcf..c94bd0db701f4 100644 --- a/code/modules/surgery/bodyparts/parts.dm +++ b/code/modules/surgery/bodyparts/parts.dm @@ -396,11 +396,31 @@ unarmed_damage_low = 7 unarmed_damage_high = 15 unarmed_effectiveness = 15 + biological_state = BIO_STANDARD_JOINTED /// Datum describing how to offset things worn on the foot of this leg, note that an x offset won't do anything here var/datum/worn_feature_offset/worn_foot_offset /// Used by the bloodysoles component to make footprints var/footprint_sprite = FOOTPRINT_SPRITE_SHOES - biological_state = BIO_STANDARD_JOINTED + /// What does our footsteps (barefoot) sound like? Only BAREFOOT, CLAW, HEAVY, and SHOE (or null, I guess) are valid + var/footstep_type = FOOTSTEP_MOB_BAREFOOT + /// You can set this to a list of sounds to pick from when a footstep is played rather than use the footstep types + /// Requires special formatting: list(list(sounds, go, here), volume, range modifier) + var/list/special_footstep_sounds + +/obj/item/bodypart/leg/Initialize(mapload) + . = ..() + if(PERFORM_ALL_TESTS(focus_only/humanstep_validity)) + // Update this list if more types are suported in the footstep element + var/list/supported_types = list( + null, + FOOTSTEP_MOB_BAREFOOT, + FOOTSTEP_MOB_CLAW, + FOOTSTEP_MOB_HEAVY, + FOOTSTEP_MOB_SHOE, + ) + if(!(footstep_type in supported_types)) + stack_trace("Invalid footstep type set on leg: \[[footstep_type]\] \ + If you want to use this type, you will need to create a global footstep index for it.") /obj/item/bodypart/leg/Destroy() QDEL_NULL(worn_foot_offset) diff --git a/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm index 0de9322e70b8c..cf938994ef404 100644 --- a/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm +++ b/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm @@ -76,6 +76,7 @@ limb_id = BODYPART_ID_DIGITIGRADE bodyshape = BODYSHAPE_HUMANOID | BODYSHAPE_DIGITIGRADE footprint_sprite = FOOTPRINT_SPRITE_CLAWS + footstep_type = FOOTSTEP_MOB_CLAW /obj/item/bodypart/leg/left/digitigrade/update_limb(dropping_limb = FALSE, is_creating = FALSE) . = ..() @@ -92,6 +93,7 @@ limb_id = BODYPART_ID_DIGITIGRADE bodyshape = BODYSHAPE_HUMANOID | BODYSHAPE_DIGITIGRADE footprint_sprite = FOOTPRINT_SPRITE_CLAWS + footstep_type = FOOTSTEP_MOB_CLAW /obj/item/bodypart/leg/right/digitigrade/update_limb(dropping_limb = FALSE, is_creating = FALSE) . = ..() diff --git a/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm index b0acf914079f3..0125601bda5a7 100644 --- a/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm +++ b/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm @@ -12,6 +12,10 @@ head_flags = HEAD_EYESPRITES bodypart_flags = BODYPART_UNHUSKABLE +/obj/item/bodypart/head/plasmaman/Initialize(mapload) + . = ..() + AddComponent(/datum/component/self_ignition) + /obj/item/bodypart/chest/plasmaman icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi' icon_state = "plasmaman_chest" @@ -29,6 +33,10 @@ /obj/item/bodypart/chest/plasmaman/get_butt_sprite() return icon('icons/mob/butts.dmi', BUTT_SPRITE_PLASMA) +/obj/item/bodypart/chest/plasmaman/Initialize(mapload) + . = ..() + AddComponent(/datum/component/self_ignition) + /obj/item/bodypart/arm/left/plasmaman icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi' icon_state = "plasmaman_l_arm" @@ -41,6 +49,10 @@ burn_modifier = 1.5 //Plasmemes are weak bodypart_flags = BODYPART_UNHUSKABLE +/obj/item/bodypart/arm/left/plasmaman/Initialize(mapload) + . = ..() + AddComponent(/datum/component/self_ignition) + /obj/item/bodypart/arm/right/plasmaman icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi' icon_state = "plasmaman_r_arm" @@ -53,6 +65,10 @@ burn_modifier = 1.5 //Plasmemes are weak bodypart_flags = BODYPART_UNHUSKABLE +/obj/item/bodypart/arm/right/plasmaman/Initialize(mapload) + . = ..() + AddComponent(/datum/component/self_ignition) + /obj/item/bodypart/leg/left/plasmaman icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi' icon_state = "plasmaman_l_leg" @@ -65,6 +81,10 @@ burn_modifier = 1.5 //Plasmemes are weak bodypart_flags = BODYPART_UNHUSKABLE +/obj/item/bodypart/leg/left/plasmaman/Initialize(mapload) + . = ..() + AddComponent(/datum/component/self_ignition) + /obj/item/bodypart/leg/right/plasmaman icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi' icon_state = "plasmaman_r_leg" @@ -76,3 +96,7 @@ brute_modifier = 1.5 //Plasmemes are weak burn_modifier = 1.5 //Plasmemes are weak bodypart_flags = BODYPART_UNHUSKABLE + +/obj/item/bodypart/leg/right/plasmaman/Initialize(mapload) + . = ..() + AddComponent(/datum/component/self_ignition) diff --git a/code/modules/surgery/organs/_organ.dm b/code/modules/surgery/organs/_organ.dm index 3e67b5c43792b..6a5dabc112fd0 100644 --- a/code/modules/surgery/organs/_organ.dm +++ b/code/modules/surgery/organs/_organ.dm @@ -356,7 +356,7 @@ INITIALIZE_IMMEDIATE(/obj/item/organ) /// Tries to replace the existing organ on the passed mob with this one, with special handling for replacing a brain without ghosting target /obj/item/organ/proc/replace_into(mob/living/carbon/new_owner) - return Insert(new_owner, special = TRUE, movement_flags = DELETE_IF_REPLACED) + Insert(new_owner, special = TRUE, movement_flags = DELETE_IF_REPLACED) /// Get all possible organ slots by checking every organ, and then store it and give it whenever needed diff --git a/code/modules/surgery/organs/external/tails.dm b/code/modules/surgery/organs/external/tails.dm index 656eac6c8418b..3ae057f5965cc 100644 --- a/code/modules/surgery/organs/external/tails.dm +++ b/code/modules/surgery/organs/external/tails.dm @@ -165,9 +165,6 @@ wag_flags = WAG_ABLE -/datum/bodypart_overlay/mutant/tail/get_global_feature_list() - return SSaccessories.tails_list_human - /obj/item/organ/external/tail/cat/get_butt_sprite() return icon('icons/mob/butts.dmi', BUTT_SPRITE_CAT) @@ -176,6 +173,9 @@ feature_key = "tail_cat" color_source = ORGAN_COLOR_HAIR +/datum/bodypart_overlay/mutant/tail/cat/get_global_feature_list() + return SSaccessories.tails_list_felinid + /obj/item/organ/external/tail/monkey name = "monkey tail" preference = "feature_monkey_tail" diff --git a/code/modules/surgery/organs/external/wings/functional_wings.dm b/code/modules/surgery/organs/external/wings/functional_wings.dm index e97ed1bbd363d..2b48337204a1a 100644 --- a/code/modules/surgery/organs/external/wings/functional_wings.dm +++ b/code/modules/surgery/organs/external/wings/functional_wings.dm @@ -62,7 +62,7 @@ ///Check if we're still eligible for flight (wings covered, atmosphere too thin, etc) /obj/item/organ/external/wings/functional/proc/can_fly(mob/living/carbon/human/human) - if(human.stat || human.body_position == LYING_DOWN) + if(human.stat || human.body_position == LYING_DOWN || isnull(human.client)) return FALSE //Jumpsuits have tail holes, so it makes sense they have wing holes too if(!cant_hide && human.wear_suit && ((human.wear_suit.flags_inv & HIDEJUMPSUIT) && (!human.wear_suit.species_exception || !is_type_in_list(src, human.wear_suit.species_exception)))) @@ -110,6 +110,7 @@ human.AddElement(/datum/element/forced_gravity, 0) passtable_on(human, SPECIES_FLIGHT_TRAIT) RegisterSignal(human, COMSIG_MOB_CLIENT_MOVE_NOGRAV, PROC_REF(on_client_move)) + RegisterSignal(human, COMSIG_MOB_ATTEMPT_HALT_SPACEMOVE, PROC_REF(on_pushoff)) START_PROCESSING(SSnewtonian_movement, src) open_wings() to_chat(human, span_notice("You beat your wings and begin to hover gently above the ground...")) @@ -122,7 +123,7 @@ human.remove_movespeed_modifier(/datum/movespeed_modifier/jetpack/wings) human.RemoveElement(/datum/element/forced_gravity, 0) passtable_off(human, SPECIES_FLIGHT_TRAIT) - UnregisterSignal(human, COMSIG_MOB_CLIENT_MOVE_NOGRAV) + UnregisterSignal(human, list(COMSIG_MOB_CLIENT_MOVE_NOGRAV, COMSIG_MOB_ATTEMPT_HALT_SPACEMOVE)) STOP_PROCESSING(SSnewtonian_movement, src) to_chat(human, span_notice("You settle gently back onto the ground...")) close_wings() @@ -138,6 +139,17 @@ source.newtonian_move(dir2angle(source.client.intended_direction), instant = TRUE, drift_force = FUNCTIONAL_WING_FORCE, controlled_cap = max_drift_force) source.setDir(source.client.intended_direction) +/obj/item/organ/external/wings/functional/proc/on_pushoff(mob/source, movement_dir, continuous_move, atom/backup) + SIGNAL_HANDLER + + if (get_dir(source, backup) == movement_dir || source.loc == backup.loc) + return + + if (!can_fly(source) || !source.client.intended_direction) + return + + return COMPONENT_PREVENT_SPACEMOVE_HALT + /obj/item/organ/external/wings/functional/process(seconds_per_tick) if (!owner || !can_fly(owner) || isnull(owner.drift_handler)) return diff --git a/code/modules/surgery/organs/external/wings/moth_wings.dm b/code/modules/surgery/organs/external/wings/moth_wings.dm index 16b9832f6de0f..266d777b4572c 100644 --- a/code/modules/surgery/organs/external/wings/moth_wings.dm +++ b/code/modules/surgery/organs/external/wings/moth_wings.dm @@ -21,11 +21,12 @@ RegisterSignal(receiver, COMSIG_HUMAN_BURNING, PROC_REF(try_burn_wings)) RegisterSignal(receiver, COMSIG_LIVING_POST_FULLY_HEAL, PROC_REF(heal_wings)) RegisterSignal(receiver, COMSIG_MOB_CLIENT_MOVE_NOGRAV, PROC_REF(on_client_move)) + RegisterSignal(receiver, COMSIG_MOB_ATTEMPT_HALT_SPACEMOVE, PROC_REF(on_pushoff)) START_PROCESSING(SSnewtonian_movement, src) /obj/item/organ/external/wings/moth/on_mob_remove(mob/living/carbon/organ_owner) . = ..() - UnregisterSignal(organ_owner, list(COMSIG_HUMAN_BURNING, COMSIG_LIVING_POST_FULLY_HEAL, COMSIG_MOB_CLIENT_MOVE_NOGRAV)) + UnregisterSignal(organ_owner, list(COMSIG_HUMAN_BURNING, COMSIG_LIVING_POST_FULLY_HEAL, COMSIG_MOB_CLIENT_MOVE_NOGRAV, COMSIG_MOB_ATTEMPT_HALT_SPACEMOVE)) STOP_PROCESSING(SSnewtonian_movement, src) /obj/item/organ/external/wings/moth/make_flap_sound(mob/living/carbon/wing_owner) @@ -75,6 +76,17 @@ source.newtonian_move(dir2angle(source.client.intended_direction), instant = TRUE, drift_force = MOTH_WING_FORCE, controlled_cap = max_drift_force) source.setDir(source.client.intended_direction) +/obj/item/organ/external/wings/moth/proc/on_pushoff(mob/source, movement_dir, continuous_move, atom/backup) + SIGNAL_HANDLER + + if (get_dir(source, backup) == movement_dir || source.loc == backup.loc) + return + + if (!allow_flight() || !source.client.intended_direction) + return + + return COMPONENT_PREVENT_SPACEMOVE_HALT + ///check if our wings can burn off ;_; /obj/item/organ/external/wings/moth/proc/try_burn_wings(mob/living/carbon/human/human) SIGNAL_HANDLER diff --git a/code/modules/surgery/organs/organ_movement.dm b/code/modules/surgery/organs/organ_movement.dm index 99a74d9b491e1..16889ec0588a3 100644 --- a/code/modules/surgery/organs/organ_movement.dm +++ b/code/modules/surgery/organs/organ_movement.dm @@ -97,6 +97,8 @@ for(var/datum/status_effect/effect as anything in organ_effects) organ_owner.apply_status_effect(effect, type) + if(!special) + organ_owner.hud_used?.update_locked_slots() RegisterSignal(owner, COMSIG_ATOM_EXAMINE, PROC_REF(on_owner_examine)) SEND_SIGNAL(src, COMSIG_ORGAN_IMPLANTED, organ_owner) SEND_SIGNAL(organ_owner, COMSIG_CARBON_GAIN_ORGAN, src, special) @@ -184,6 +186,8 @@ organ_owner.synchronize_bodytypes() organ_owner.synchronize_bodyshapes() + if(!special) + organ_owner.hud_used?.update_locked_slots() var/list/diseases = organ_owner.get_static_viruses() if(!LAZYLEN(diseases)) @@ -243,6 +247,15 @@ color = bodypart_overlay.draw_color // so a pink felinid doesn't drop a gray tail + if(greyscale_config) + get_greyscale_color_from_draw_color() + else + color = bodypart_overlay.draw_color // so a pink felinid doesn't drop a gray tail + +///Here we define how draw_color from the bodypart overlay sets the greyscale colors of organs that use GAGS +/obj/item/organ/proc/get_greyscale_color_from_draw_color() + color = bodypart_overlay.draw_color //Defaults to the legacy behaviour of applying the color to the item. + /// In space station videogame, nothing is sacred. If somehow an organ is removed unexpectedly, handle it properly /obj/item/organ/proc/forced_removal() SIGNAL_HANDLER diff --git a/code/modules/tgui/states/standing.dm b/code/modules/tgui/states/standing.dm new file mode 100644 index 0000000000000..5d6a49c401e9d --- /dev/null +++ b/code/modules/tgui/states/standing.dm @@ -0,0 +1,17 @@ +/** + * tgui state: standing_state + * + * Checks that the user isn't incapacitated and is standing upright + */ + +GLOBAL_DATUM_INIT(standing_state, /datum/ui_state/not_incapacitated_state/standing, new) + +/datum/ui_state/not_incapacitated_state/standing + +/datum/ui_state/not_incapacitated_state/standing/can_use_topic(src_object, mob/user) + if (!isliving(user)) + return ..() + var/mob/living/living_user = user + if (living_user.body_position) + return UI_DISABLED + return ..() diff --git a/code/modules/tooltip/tooltip.dm b/code/modules/tooltip/tooltip.dm index 9956305db26e0..f3c691ce3e953 100644 --- a/code/modules/tooltip/tooltip.dm +++ b/code/modules/tooltip/tooltip.dm @@ -37,7 +37,7 @@ Notes: /datum/tooltip/proc/show(atom/movable/thing, params = null, title = null, content = null, theme = "default", special = "none") - if (!thing || !params || (!title && !content) || !owner || !isnum(world.icon_size)) + if (!thing || !params || (!title && !content) || !owner || !isnum(ICON_SIZE_ALL)) return FALSE if (!isnull(last_target)) @@ -50,7 +50,7 @@ Notes: if (!init) //Initialize some vars init = 1 - owner << output(list2params(list(world.icon_size, control)), "[control]:tooltip.init") + owner << output(list2params(list(ICON_SIZE_ALL, control)), "[control]:tooltip.init") showing = 1 diff --git a/code/modules/transport/transport_module.dm b/code/modules/transport/transport_module.dm index 01a3493130501..3e4a5be979fb3 100644 --- a/code/modules/transport/transport_module.dm +++ b/code/modules/transport/transport_module.dm @@ -225,11 +225,11 @@ for(var/y in first_y to last_y) - var/y_pixel_offset = world.icon_size * y + var/y_pixel_offset = ICON_SIZE_Y * y for(var/x in first_x to last_x) - var/x_pixel_offset = world.icon_size * x + var/x_pixel_offset = ICON_SIZE_X * x var/turf/set_turf = locate(x + min_x, y + min_y, z) @@ -294,8 +294,8 @@ destination = travel_direction travel_direction = get_dir_multiz(loc, travel_direction) - var/x_offset = ROUND_UP(bound_width / 32) - 1 //how many tiles our horizontally farthest edge is from us - var/y_offset = ROUND_UP(bound_height / 32) - 1 //how many tiles our vertically farthest edge is from us + 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 //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 diff --git a/code/modules/tutorials/_tutorial.dm b/code/modules/tutorials/_tutorial.dm index 1211f8e299355..97274a2e32d10 100644 --- a/code/modules/tutorials/_tutorial.dm +++ b/code/modules/tutorials/_tutorial.dm @@ -135,11 +135,11 @@ var/list/origin_offsets = screen_loc_to_offset(initial_screen_loc, view) // A little offset to the right - var/matrix/origin_transform = TRANSLATE_MATRIX(origin_offsets[1] - world.icon_size * 0.5, origin_offsets[2] - world.icon_size * 1.5) + var/matrix/origin_transform = TRANSLATE_MATRIX(origin_offsets[1] - ICON_SIZE_X * 0.5, origin_offsets[2] - ICON_SIZE_Y * 1.5) var/list/target_offsets = screen_loc_to_offset(target_screen_loc, view) // `- world.icon_Size * 0.5` to patch over a likely bug in screen_loc_to_offset with CENTER, needs more looking at - var/matrix/animate_to_transform = TRANSLATE_MATRIX(target_offsets[1] - world.icon_size * 1.5, target_offsets[2] - world.icon_size) + var/matrix/animate_to_transform = TRANSLATE_MATRIX(target_offsets[1] - ICON_SIZE_X * 1.5, target_offsets[2] - ICON_SIZE_Y) preview.transform = origin_transform diff --git a/code/modules/tutorials/tutorial_instruction.dm b/code/modules/tutorials/tutorial_instruction.dm index 0ad9ce6f2e0fe..d5a1734978a37 100644 --- a/code/modules/tutorials/tutorial_instruction.dm +++ b/code/modules/tutorials/tutorial_instruction.dm @@ -38,7 +38,7 @@ var/view = client?.view_size.getView() maptext_width = view ? view_to_pixels(view)[1] : 480 - pixel_x = (maptext_width - world.icon_size) * -0.5 + pixel_x = (maptext_width - ICON_SIZE_X) * -0.5 change_message(message) diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index 826edbfdf33f0..3bfa85c140de8 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -99,6 +99,7 @@ #include "bake_a_cake.dm" #include "barsigns.dm" #include "baseturfs.dm" +#include "bee.dm" #include "bespoke_id.dm" #include "binary_insert.dm" #include "bitrunning.dm" @@ -118,6 +119,7 @@ #include "circuit_component_category.dm" #include "client_colours.dm" #include "closets.dm" +#include "clothing_drops_items.dm" #include "clothing_under_armor_subtype_check.dm" #include "combat.dm" #include "combat_stamina.dm" @@ -133,6 +135,7 @@ #include "dcs_get_id_from_elements.dm" #include "designs.dm" #include "dismemberment.dm" +#include "dna_infusion.dm" #include "door_access.dm" #include "dragon_expiration.dm" #include "drink_icons.dm" @@ -209,7 +212,6 @@ #include "operating_table.dm" #include "orderable_items.dm" #include "organ_bodypart_shuffle.dm" -#include "organ_set_bonus.dm" #include "organs.dm" #include "orphaned_genturf.dm" #include "outfit_sanity.dm" diff --git a/code/modules/unit_tests/bee.dm b/code/modules/unit_tests/bee.dm new file mode 100644 index 0000000000000..dad3a4d1a7372 --- /dev/null +++ b/code/modules/unit_tests/bee.dm @@ -0,0 +1,15 @@ +/// Test beegent transfer +/datum/unit_test/beegent + +/datum/unit_test/beegent/Run() + var/mob/living/basic/bee/bee = allocate(__IMPLIED_TYPE__) + var/turf/bee_turf = get_turf(bee) + var/datum/reagent/picked = GLOB.chemical_reagents_list[/datum/reagent/toxin/fentanyl] + bee.assign_reagent(picked) + bee.death() + var/obj/item/trash/bee/dead_bee = locate() in bee_turf + TEST_ASSERT_NOTNULL(dead_bee, "The bee did not leave a corpse.") + TEST_ASSERT_EQUAL(dead_bee.beegent, picked, "The bee's corpse did not have the correct beegent assigned.") + TEST_ASSERT(dead_bee.reagents.has_reagent(/datum/reagent/toxin/fentanyl), "The bee's corpse did not contain any of the beegent.") + // clean up, we aren't allocated + QDEL_NULL(dead_bee) diff --git a/code/modules/unit_tests/clothing_drops_items.dm b/code/modules/unit_tests/clothing_drops_items.dm new file mode 100644 index 0000000000000..8f1653bf4b6d2 --- /dev/null +++ b/code/modules/unit_tests/clothing_drops_items.dm @@ -0,0 +1,53 @@ +/// Tests that removing a piece of clothing drops items that hold said piece of clothing +/datum/unit_test/clothing_drops_items + +/datum/unit_test/clothing_drops_items/Run() + test_human() + test_android() + +/datum/unit_test/clothing_drops_items/proc/test_human() + var/list/dummy_items = allocate_items() + var/mob/living/carbon/human/consistent/dummy = allocate(__IMPLIED_TYPE__) + + for(var/slot in dummy_items) + TEST_ASSERT(dummy.equip_to_slot_if_possible(dummy_items[slot], text2num(slot)), \ + "[/datum/species/human::name] Dummy failed to equip one of the starting items ([dummy_items[slot]]). Test aborted.") + + dummy.dropItemToGround(dummy.w_uniform) + + for(var/slot in dummy_items) + var/obj/item/item = dummy_items[slot] + if(item.slot_flags & ITEM_SLOT_ICLOTHING) + continue + else if(item.slot_flags & (ITEM_SLOT_BACK|ITEM_SLOT_FEET)) + TEST_ASSERT_EQUAL(item.loc, dummy, "[item] should not have been dropped when unequipping the jumpsuit from \a [/datum/species/human::name].") + else + TEST_ASSERT_EQUAL(item.loc, dummy.loc, "[item] should have been dropped when unequipping the jumpsuit from \a [/datum/species/human::name].") + +/datum/unit_test/clothing_drops_items/proc/test_android() + var/list/robo_dummy_items = allocate_items() + var/mob/living/carbon/human/consistent/robo_dummy = allocate(__IMPLIED_TYPE__) + robo_dummy.set_species(/datum/species/android) + + for(var/slot in robo_dummy_items) + TEST_ASSERT(robo_dummy.equip_to_slot_if_possible(robo_dummy_items[slot], text2num(slot)), \ + "[/datum/species/android::name] Dummy failed to equip one of the starting items ([robo_dummy_items[slot]]). Test aborted.") + + robo_dummy.dropItemToGround(robo_dummy.w_uniform) + + for(var/slot in robo_dummy_items) + var/obj/item/item = robo_dummy_items[slot] + if(item.slot_flags & ITEM_SLOT_ICLOTHING) + continue + TEST_ASSERT_EQUAL(item.loc, robo_dummy, "[item] should not have been dropped when unequipping the jumpsuit from \a [/datum/species/android::name].") + +/datum/unit_test/clothing_drops_items/proc/allocate_items() + return list( + "[ITEM_SLOT_ICLOTHING]" = allocate(/obj/item/clothing/under/color/rainbow), // do this one first, it holds everything + "[ITEM_SLOT_FEET]" = allocate(/obj/item/clothing/shoes/jackboots), + "[ITEM_SLOT_BELT]" = allocate(/obj/item/storage/belt/utility), + "[ITEM_SLOT_BACK]" = allocate(/obj/item/storage/backpack), + "[ITEM_SLOT_ID]" = allocate(/obj/item/card/id/advanced/gold/captains_spare), + "[ITEM_SLOT_RPOCKET]" = allocate(/obj/item/assembly/flash/handheld), + "[ITEM_SLOT_LPOCKET]" = allocate(/obj/item/toy/plush/lizard_plushie), + ) diff --git a/code/modules/unit_tests/dcs_check_list_arguments.dm b/code/modules/unit_tests/dcs_check_list_arguments.dm index 67d7417062b27..769574cf95f29 100644 --- a/code/modules/unit_tests/dcs_check_list_arguments.dm +++ b/code/modules/unit_tests/dcs_check_list_arguments.dm @@ -11,7 +11,7 @@ * * Most of the time, you won't encounter two different static lists with similar contents used as element args, * meaning using static lists is accepted. However, should that happen, it's advised to replace the instances - * with various string_x procs: lists, assoc_lists, assoc_nested_lists or numbers_list, depending on the type. + * with either string_list(), string_assoc_list(), string_assoc_nested_list() or string_numbers_list(), depending on the contents of the list. * * In the case of an element where the position of the contents of each datum list argument is important, * ELEMENT_DONT_SORT_LIST_ARGS should be added to its flags, to prevent such issues where the contents are similar @@ -51,5 +51,5 @@ TEST_FAIL("Found [length(bad_lists)] datum list arguments with similar contents for [element_type]. Contents: [json_encode(unsorted_list)].") ///Let's avoid sending the same instructions over and over, as it's just going to clutter the CI and confuse someone. if(we_failed) - TEST_FAIL("Ensure that each list is static or cached. string_lists() (as well as similar procs) is your friend here.\n\ + TEST_FAIL("Ensure that each list is static or cached. string_list() (as well as similar procs) is your friend here.\n\ Check the documentation from dcs_check_list_arguments.dm for more information!") diff --git a/code/modules/unit_tests/organ_set_bonus.dm b/code/modules/unit_tests/dna_infusion.dm similarity index 83% rename from code/modules/unit_tests/organ_set_bonus.dm rename to code/modules/unit_tests/dna_infusion.dm index 1231ddd5c6670..d96a76de4a19b 100644 --- a/code/modules/unit_tests/organ_set_bonus.dm +++ b/code/modules/unit_tests/dna_infusion.dm @@ -1,3 +1,16 @@ +///Check that input types that aren't living mobs have the TRAIT_VALID_DNA_INFUSION trait +/datum/unit_test/valid_dna_infusion + +/datum/unit_test/valid_dna_infusion/Run() + for(var/datum/infuser_entry/infuser_entry as anything in flatten_list(GLOB.infuser_entries)) + for(var/input_type as anything in infuser_entry.input_obj_or_mob) + if(ispath(input_type, /mob/living)) + continue + var/atom/movable/movable = allocate(input_type) + if(!HAS_TRAIT(movable, TRAIT_VALID_DNA_INFUSION)) + //TEST_FAIL() doesn't early return the unit test so we can keep checking. + TEST_FAIL("[input_type] is in the 'input_obj_or_mob' list for [infuser_entry.type] but doesn't have TRAIT_VALID_DNA_INFUSION.") + /// Checks that all "organ_set_bonus" status effects have unique "id" vars. /// Required to ensure that the status effects are treated as "unique". /datum/unit_test/organ_set_bonus_id @@ -34,7 +47,9 @@ inserted_organs += organ // Search for added Status Effect. - var/datum/status_effect/organ_set_bonus/added_status = locate(/datum/status_effect/organ_set_bonus) in lab_rat.status_effects + var/datum/status_effect/organ_set_bonus/added_status + if(!infuser_entry.unreachable_effect) + added_status = locate(/datum/status_effect/organ_set_bonus) in lab_rat.status_effects // If threshold_desc is filled-in, it implies the organ_set_bonus Status Effect should be activated. // Without it, we'll assume there isn't a Status Effect to look for. diff --git a/code/modules/unit_tests/focus_only_tests.dm b/code/modules/unit_tests/focus_only_tests.dm index 31f34d9f2fb94..c9bfea88e5ef0 100644 --- a/code/modules/unit_tests/focus_only_tests.dm +++ b/code/modules/unit_tests/focus_only_tests.dm @@ -50,3 +50,6 @@ /// Ensures only whitelisted planes can have TOPDOWN_LAYERing, and vis versa /datum/unit_test/focus_only/topdown_filtering + +/// Catches any invalid footstep types set for humans +/datum/unit_test/focus_only/humanstep_validity diff --git a/code/modules/unit_tests/screenshot_high_luminosity_eyes.dm b/code/modules/unit_tests/screenshot_high_luminosity_eyes.dm index 4b0c3a986f122..1e2c10c2f2952 100644 --- a/code/modules/unit_tests/screenshot_high_luminosity_eyes.dm +++ b/code/modules/unit_tests/screenshot_high_luminosity_eyes.dm @@ -57,7 +57,7 @@ for(var/mutable_appearance/light_underlay as anything in test_subject.underlays) if(light_underlay.icon == 'icons/effects/light_overlays/light_cone.dmi') // The light cone icon is 96x96, so we have to shift it over to have it match our sprites. x = 1, y = 1 is the lower left corner so we shift 32 pixels opposite to that. - final_icon.Blend(get_flat_icon_for_all_directions(light_underlay, no_anim = FALSE), ICON_UNDERLAY, -world.icon_size + 1, -world.icon_size + 1) + final_icon.Blend(get_flat_icon_for_all_directions(light_underlay, no_anim = FALSE), ICON_UNDERLAY, -ICON_SIZE_X + 1, -ICON_SIZE_Y + 1) return final_icon #undef UPDATE_EYES_LEFT diff --git a/code/modules/unit_tests/unit_test.dm b/code/modules/unit_tests/unit_test.dm index 84c0fa20a678b..b8b2b542f1881 100644 --- a/code/modules/unit_tests/unit_test.dm +++ b/code/modules/unit_tests/unit_test.dm @@ -158,7 +158,7 @@ GLOBAL_VAR_INIT(focused_tests, focused_tests()) /// Logs a test message. Will use GitHub action syntax found at https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions /datum/unit_test/proc/log_for_test(text, priority, file, line) - var/map_name = SSmapping.config.map_name + var/map_name = SSmapping.current_map.map_name // Need to escape the text to properly support newlines. var/annotation_text = replacetext(text, "%", "%25") @@ -177,14 +177,14 @@ GLOBAL_VAR_INIT(focused_tests, focused_tests()) GLOB.current_test = test var/duration = REALTIMEOFDAY - var/skip_test = (test_path in SSmapping.config.skipped_tests) + var/skip_test = (test_path in SSmapping.current_map.skipped_tests) var/test_output_desc = "[test_path]" var/message = "" log_world("::group::[test_path]") if(skip_test) - log_world("[TEST_OUTPUT_YELLOW("SKIPPED")] Skipped run on map [SSmapping.config.map_name].") + log_world("[TEST_OUTPUT_YELLOW("SKIPPED")] Skipped run on map [SSmapping.current_map.map_name].") else diff --git a/code/modules/uplink/uplink_items/dangerous.dm b/code/modules/uplink/uplink_items/dangerous.dm index faf3751d7a51e..3feb8dc30ca3a 100644 --- a/code/modules/uplink/uplink_items/dangerous.dm +++ b/code/modules/uplink/uplink_items/dangerous.dm @@ -91,11 +91,11 @@ /datum/uplink_item/dangerous/revolver name = "Syndicate Revolver" - desc = "Waffle Corp's modernized Syndicate revolver. Fires 7 brutal rounds of .357 Magnum." - item = /obj/item/gun/ballistic/revolver/syndicate + desc = "A brutally simple Syndicate revolver that fires .357 Magnum rounds and has 7 chambers." + item = /obj/item/gun/ballistic/revolver cost = 13 surplus = 50 - purchasable_from = ~UPLINK_ALL_SYNDIE_OPS //nukies get their own version + purchasable_from = ~UPLINK_ALL_SYNDIE_OPS //only traitors get the original revolver /datum/uplink_item/dangerous/cat name = "Feral cat grenade" diff --git a/code/modules/uplink/uplink_items/job.dm b/code/modules/uplink/uplink_items/job.dm index c4cfd2410d261..0ec9373249a17 100644 --- a/code/modules/uplink/uplink_items/job.dm +++ b/code/modules/uplink/uplink_items/job.dm @@ -361,7 +361,7 @@ name = "Simian Agent Reinforcements" desc = "Call in an extremely well trained monkey secret agent from our Syndicate Banana Department. \ They've been trained to operate machinery and can read, but they can't speak Common. \ - Please note that these are free-range monkeys that don't react with Mutadone." + Please note that these are free-range monkeys that don't react with Mutadone. May contain severe allergies to species-changing phenomena." item = /obj/item/antag_spawner/loadout/monkey_man cost = 6 restricted_roles = list(JOB_RESEARCH_DIRECTOR, JOB_SCIENTIST, JOB_GENETICIST, JOB_ASSISTANT, JOB_MIME, JOB_CLOWN, JOB_PUN_PUN) diff --git a/code/modules/vending/cola.dm b/code/modules/vending/cola.dm index d9fddd07f1731..21f61f9a98b28 100644 --- a/code/modules/vending/cola.dm +++ b/code/modules/vending/cola.dm @@ -36,6 +36,40 @@ extra_price = PAYCHECK_CREW payment_department = ACCOUNT_SRV + var/static/list/spiking_booze = list( + // Your "common" spiking booze + /datum/reagent/consumable/ethanol/vodka = 5, + /datum/reagent/consumable/ethanol/beer = 5, + /datum/reagent/consumable/ethanol/whiskey = 5, + /datum/reagent/consumable/ethanol/gin = 5, + /datum/reagent/consumable/ethanol/rum = 5, + // A bit rarer, can be dangerous if you take too much + /datum/reagent/consumable/ethanol/thirteenloko = 3, + /datum/reagent/consumable/ethanol/absinthe = 3, + /datum/reagent/consumable/ethanol/hooch = 3, + /datum/reagent/consumable/ethanol/moonshine = 3, + // Gets funky here + /datum/reagent/consumable/ethanol/beepsky_smash = 1, + /datum/reagent/consumable/ethanol/gargle_blaster = 1, + /datum/reagent/consumable/ethanol/neurotoxin = 1, + ) + +/obj/machinery/vending/cola/on_dispense(obj/item/vended_item) + // 35% chance that your drink will be safe, as safe pure acid and sugar that these drinks probably are can be + if(!onstation || !HAS_TRAIT(SSstation, STATION_TRAIT_SPIKED_DRINKS) || !prob(65)) + return + // Don't fill booze with more booze + if (isnull(vended_item.reagents) || vended_item.reagents.has_reagent(/datum/reagent/consumable/ethanol, check_subtypes = TRUE)) + return + var/removed_volume = vended_item.reagents.remove_all(rand(5, vended_item.reagents.maximum_volume * 0.5)) + if (!removed_volume) + return + // Don't want bubbling sodas when we add some rum to cola + ADD_TRAIT(vended_item, TRAIT_SILENT_REACTIONS, VENDING_MACHINE_TRAIT) + vended_item.reagents.add_reagent(pick_weight(spiking_booze), removed_volume) + vended_item.reagents.handle_reactions() + REMOVE_TRAIT(vended_item, TRAIT_SILENT_REACTIONS, VENDING_MACHINE_TRAIT) + /obj/item/vending_refill/cola machine_name = "Robust Softdrinks" icon_state = "refill_cola" diff --git a/code/modules/vending/games.dm b/code/modules/vending/games.dm index 98a77c7f40c3d..4989b17498244 100644 --- a/code/modules/vending/games.dm +++ b/code/modules/vending/games.dm @@ -45,7 +45,7 @@ /obj/item/stack/pipe_cleaner_coil/random = 10, ), ), - list( + list( "name" = "Fishing", "icon" = "fish", "products" = list( @@ -54,6 +54,7 @@ /obj/item/storage/box/fishing_lines = 2, /obj/item/storage/box/fishing_lures = 2, /obj/item/book/manual/fish_catalog = 5, + /obj/item/fish_feed = 4, /obj/item/fish_analyzer = 2, /obj/item/fishing_rod/telescopic = 1, ), diff --git a/code/modules/vending/liberation_toy.dm b/code/modules/vending/liberation_toy.dm index 0bfb2e6c2dfdc..e569779370303 100644 --- a/code/modules/vending/liberation_toy.dm +++ b/code/modules/vending/liberation_toy.dm @@ -8,31 +8,34 @@ vend_reply = "Come back for more!" circuit = /obj/item/circuitboard/machine/vending/syndicatedonksofttoyvendor products = list( - /obj/item/gun/ballistic/automatic/toy/unrestricted = 10, - /obj/item/gun/ballistic/automatic/pistol/toy = 10, - /obj/item/gun/ballistic/shotgun/toy/unrestricted = 10, - /obj/item/toy/sword = 10, + /obj/item/card/emagfake = 4, + /obj/item/hot_potato/harmless/toy = 4, + /obj/item/toy/sword = 12, + /obj/item/dualsaber/toy = 12, + /obj/item/toy/foamblade = 12, + /obj/item/gun/ballistic/automatic/pistol/toy/riot = 8, + /obj/item/gun/ballistic/automatic/toy/riot = 8, + /obj/item/gun/ballistic/shotgun/toy/riot = 8, /obj/item/ammo_box/foambox = 20, - /obj/item/toy/foamblade = 10, - /obj/item/toy/balloon/syndicate = 10, - /obj/item/clothing/suit/syndicatefake = 5, - /obj/item/clothing/head/syndicatefake = 5, //OPS IN DORMS oh wait it's just an assistant ) contraband = list( - /obj/item/gun/ballistic/shotgun/toy/crossbow = 10, //Congrats, you unlocked the +18 setting! - /obj/item/gun/ballistic/automatic/c20r/toy/unrestricted/riot = 10, - /obj/item/gun/ballistic/automatic/l6_saw/toy/unrestricted/riot = 10, + /obj/item/toy/balloon/syndicate = 1, + /obj/item/gun/ballistic/shotgun/toy/crossbow/riot = 8, + /obj/item/toy/katana = 12, + ) + premium = list( + /obj/item/toy/cards/deck/syndicate = 12, + /obj/item/storage/box/fakesyndiesuit = 4, + /obj/item/gun/ballistic/automatic/c20r/toy/unrestricted/riot = 4, + /obj/item/gun/ballistic/automatic/l6_saw/toy/unrestricted/riot = 4, /obj/item/ammo_box/foambox/riot = 20, - /obj/item/toy/katana = 10, - /obj/item/dualsaber/toy = 5, - /obj/item/toy/cards/deck/syndicate = 10, //Gambling and it hurts, making it a +18 item ) armor_type = /datum/armor/vending_toyliberationstation resistance_flags = FIRE_PROOF refill_canister = /obj/item/vending_refill/donksoft - default_price = PAYCHECK_COMMAND + default_price = PAYCHECK_CREW extra_price = PAYCHECK_COMMAND - payment_department = ACCOUNT_SRV + payment_department = NO_FREEBIES light_mask = "donksoft-light-mask" /datum/armor/vending_toyliberationstation diff --git a/code/modules/vending/toys.dm b/code/modules/vending/toys.dm index e3f3b3316f244..8f92e438b5149 100644 --- a/code/modules/vending/toys.dm +++ b/code/modules/vending/toys.dm @@ -9,27 +9,31 @@ light_mask = "donksoft-light-mask" circuit = /obj/item/circuitboard/machine/vending/donksofttoyvendor products = list( - /obj/item/gun/ballistic/automatic/toy/unrestricted = 10, - /obj/item/gun/ballistic/automatic/pistol/toy = 10, - /obj/item/gun/ballistic/shotgun/toy/unrestricted = 10, - /obj/item/toy/sword = 10, - /obj/item/ammo_box/foambox = 20, - /obj/item/toy/foamblade = 10, - /obj/item/toy/balloon/syndicate = 10, - /obj/item/clothing/suit/syndicatefake = 5, - /obj/item/clothing/head/syndicatefake = 5, + /obj/item/card/emagfake = 4, + /obj/item/hot_potato/harmless/toy = 4, + /obj/item/toy/sword = 12, + /obj/item/toy/foamblade = 12, + /obj/item/gun/ballistic/automatic/pistol/toy = 8, + /obj/item/gun/ballistic/automatic/toy = 8, + /obj/item/gun/ballistic/shotgun/toy = 8, + /obj/item/ammo_box/foambox/mini = 20, ) contraband = list( - /obj/item/gun/ballistic/shotgun/toy/crossbow = 10, - /obj/item/gun/ballistic/automatic/c20r/toy/unrestricted = 10, - /obj/item/gun/ballistic/automatic/l6_saw/toy/unrestricted = 10, - /obj/item/toy/katana = 10, - /obj/item/dualsaber/toy = 5, + /obj/item/toy/balloon/syndicate = 1, + /obj/item/gun/ballistic/shotgun/toy/crossbow = 8, + /obj/item/toy/katana = 12, + /obj/item/ammo_box/foambox/riot/mini = 20, + ) + premium = list( + /obj/item/dualsaber/toy = 4, + /obj/item/storage/box/fakesyndiesuit = 4, + /obj/item/gun/ballistic/automatic/c20r/toy/unrestricted = 4, + /obj/item/gun/ballistic/automatic/l6_saw/toy/unrestricted = 4, ) refill_canister = /obj/item/vending_refill/donksoft default_price = PAYCHECK_CREW extra_price = PAYCHECK_COMMAND - payment_department = ACCOUNT_SRV + payment_department = NO_FREEBIES /obj/item/vending_refill/donksoft machine_name = "Donksoft Toy Vendor" diff --git a/code/modules/wiremod/components/action/laserpointer.dm b/code/modules/wiremod/components/action/laserpointer.dm index eb1324280cf72..0eb7f822db1ea 100644 --- a/code/modules/wiremod/components/action/laserpointer.dm +++ b/code/modules/wiremod/components/action/laserpointer.dm @@ -59,10 +59,9 @@ silicon.flash_act(affect_silicon = TRUE) /// no stunning, just a blind to_chat(silicon, span_danger("Your sensors were overloaded by a weakened laser shone by [shell]!")) - var/image/laser_location = image('icons/obj/weapons/guns/projectiles.dmi',target_location,"[pointer_icon_state]_laser",10) + var/mutable_appearance/laser_location = mutable_appearance('icons/obj/weapons/guns/projectiles.dmi', "[pointer_icon_state]_laser") laser_location.pixel_x = clamp(target.pixel_x + image_pixel_x.value,-15,15) laser_location.pixel_y = clamp(target.pixel_y + image_pixel_y.value,-15,15) - target_location.add_overlay(laser_location) - addtimer(CALLBACK(target_location, TYPE_PROC_REF(/atom, cut_overlay), laser_location), 1 SECONDS) + target_location.flick_overlay_view(laser_location, 1 SECONDS) diff --git a/code/modules/wiremod/shell/brain_computer_interface.dm b/code/modules/wiremod/shell/brain_computer_interface.dm index 7e9f79a58f65a..e3ddf54135af8 100644 --- a/code/modules/wiremod/shell/brain_computer_interface.dm +++ b/code/modules/wiremod/shell/brain_computer_interface.dm @@ -151,6 +151,9 @@ )) /obj/item/circuit_component/bci_core/input_received(datum/port/input/port) + if (!COMPONENT_TRIGGERED_BY(send_message_signal, port)) + return + var/sent_message = trim(message.value) if (!sent_message) return diff --git a/config/config.txt b/config/config.txt index d676e0d045646..96a8c869f4c7c 100644 --- a/config/config.txt +++ b/config/config.txt @@ -231,6 +231,8 @@ REQUEST_INTERNET_ALLOWED youtube\.com\/watch?v=,youtu\.be\/,soundcloud\.com\/,ba ## Jobs have specific "keys" tied to their in-game datums, those should sync up otherwise it will fail to load. ## Setting Total/Spawn Positions to -1 will open unlimited join slots for it. ## Playtime Requirements is in minutes, Required Account Age is in days. +## Human Authority Whitelist Setting can either be 0 or 1. +## Make sure to read the start of the file to get a more in-depth explanation of what each entry does! #LOAD_JOBS_FROM_TXT ## Uncomment this to forbid admins from possessing the singularity. diff --git a/config/game_options.txt b/config/game_options.txt index 3d3bf1fbf2461..c2f714ad9129a 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -122,11 +122,12 @@ PROTECT_ROLES_FROM_ANTAGONIST ## Uncomment to prohibit assistants from becoming most antagonists. #PROTECT_ASSISTANT_FROM_ANTAGONIST -## If non-human species are barred from joining as a head of staff -#ENFORCE_HUMAN_AUTHORITY - -## If non-human species are barred from joining as a head of staff, including jobs flagged as allowed for non-humans, ie. Quartermaster. -#ENFORCE_HUMAN_AUTHORITY_ON_EVERYONE +## How human authority should be distributed. Can be set to four options (Make sure that what you type is exact!): +## "DISABLED"/Comment out/Put any invalid value: non-human races can be heads of staff and "human only" settings on jobs will be fully ignored. +## "HUMAN_WHITELIST": all heads-of-staff jobs will be able to be played by non-humans, unless that job incorporates the "human only" flag (Which can be configured via a variable or the job config txt). +## "NON_HUMAN_WHITELIST": non-humans will not be able to play as heads of staff, unless that job incorporates the "allow non-humans" flag (Which can be configured via a variable or the job config txt). +## "ENFORCED": non-humans cannot be heads of staff, only humans can. the "allow non-humans" setting will be ignored. +HUMAN_AUTHORITY HUMAN_WHITELIST ## If late-joining players have a chance to become a traitor/changeling ALLOW_LATEJOIN_ANTAGONISTS diff --git a/config/jobconfig.toml b/config/jobconfig.toml index 7b101bc05ac1e..cbd35045a5b9d 100644 --- a/config/jobconfig.toml +++ b/config/jobconfig.toml @@ -1,11 +1,12 @@ ## This is the configuration file for the job system. ## This will only be enabled when the config flag LOAD_JOBS_FROM_TXT is enabled. ## We use a system of keys here that directly correlate to the job, just to ensure they don't desync if we choose to change the name of a job. -## You are able to change (as of now) five different variables in this file. +## You are able to change (as of now) five (six if the job is a command head) different variables in this file. ## Total Positions are how many job slots you get in a shift, Spawn Positions are how many you get that load in at spawn. If you set this to -1, it is unrestricted. ## Playtime Requirements is in minutes, and the job will unlock when a player reaches that amount of time. ## However, that can be superseded by Required Account Age, which is a time in days that you need to have had an account on the server for. ## Also there is a required character age in years. It prevents player from joining as this job, if their character's age as is lower than required. Setting it to 0 means it is turned off for this job. +## Lastly there's Human Authority Whitelist Setting. You can set it to either "HUMANS_ONLY" or "NON_HUMANS_ALLOWED". Check the "Human Authority" setting on the game_options file to know which you should choose. Note that this entry only appears on jobs that are marked as heads of staff. ## As time goes on, more config options may be added to this file. ## You can use the admin verb 'Generate Job Configuration' in-game to auto-regenerate this config as a downloadable file without having to manually edit this file if we add more jobs or more things you can edit here. @@ -61,6 +62,7 @@ "# Total Positions" = 3 [CAPTAIN] +"# Human Authority Whitelist Setting" = "HUMANS_ONLY" "# Playtime Requirements" = 180 "# Required Account Age" = 14 "# Required Character Age" = 30 @@ -89,6 +91,7 @@ "# Total Positions" = 2 [CHIEF_ENGINEER] +"# Human Authority Whitelist Setting" = "HUMANS_ONLY" "# Playtime Requirements" = 180 "# Required Account Age" = 7 "# Required Character Age" = 25 @@ -96,6 +99,7 @@ "# Total Positions" = 1 [CHIEF_MEDICAL_OFFICER] +"# Human Authority Whitelist Setting" = "HUMANS_ONLY" "# Playtime Requirements" = 180 "# Required Account Age" = 7 "# Required Character Age" = 30 @@ -134,7 +138,7 @@ "# Playtime Requirements" = 120 "# Required Account Age" = 21 "# Required Character Age" = 0 -"# Spawn Positions" = 1 +"# Spawn Positions" = 3 "# Total Positions" = 0 [DETECTIVE] @@ -152,6 +156,7 @@ "# Total Positions" = 2 [HEAD_OF_PERSONNEL] +"# Human Authority Whitelist Setting" = "HUMANS_ONLY" "# Playtime Requirements" = 180 "# Required Account Age" = 10 "# Required Character Age" = 25 @@ -159,6 +164,7 @@ "# Total Positions" = 1 [HEAD_OF_SECURITY] +"# Human Authority Whitelist Setting" = "HUMANS_ONLY" "# Playtime Requirements" = 300 "# Required Account Age" = 14 "# Required Character Age" = 25 @@ -215,6 +221,7 @@ "# Total Positions" = 1 [QUARTERMASTER] +"# Human Authority Whitelist Setting" = "NON_HUMANS_ALLOWED" "# Playtime Requirements" = 0 "# Required Account Age" = 7 "# Required Character Age" = 21 @@ -222,6 +229,7 @@ "# Total Positions" = 1 [RESEARCH_DIRECTOR] +"# Human Authority Whitelist Setting" = "HUMANS_ONLY" "# Playtime Requirements" = 180 "# Required Account Age" = 7 "# Required Character Age" = 25 diff --git a/config/map_vote.txt b/config/map_vote.txt new file mode 100644 index 0000000000000..edc5629df95d9 --- /dev/null +++ b/config/map_vote.txt @@ -0,0 +1,12 @@ + +## A flat bonus to give to all maps after a map vote is concluded. +MAP_VOTE_FLAT_BONUS 5 + +## The minimum number of tallies a map can have for purposes of map rotation. +MAP_VOTE_MINIMUM_TALLIES 1 + +## The maximum number of tallies a map can have for purposes of keeping things sane. +MAP_VOTE_MAXIMUM_TALLIES 200 + +## The percentage of tallies that are carried over between rounds. +MAP_VOTE_TALLY_CARRYOVER_PERCENTAGE 100 diff --git a/config/spaceruinblacklist.txt b/config/spaceruinblacklist.txt index f2ff777c1c07f..6df29bb5ace53 100644 --- a/config/spaceruinblacklist.txt +++ b/config/spaceruinblacklist.txt @@ -20,6 +20,9 @@ #_maps/RandomRuins/SpaceRuins/caravanambush.dmm #_maps/RandomRuins/SpaceRuins/clericden.dmm #_maps/RandomRuins/SpaceRuins/clownplanet.dmm +#_maps/RandomRuins/SpaceRuins/commsbuoy_lowtech.dmm +#_maps/RandomRuins/SpaceRuins/commsbuoy_nt.dmm +#_maps/RandomRuins/SpaceRuins/commsbuoy_pirate.dmm #_maps/RandomRuins/SpaceRuins/crashedclownship.dmm #_maps/RandomRuins/SpaceRuins/crashedship.dmm #_maps/RandomRuins/SpaceRuins/cyborg_mothership.dmm diff --git a/html/changelogs/AutoChangeLog-pr-86791.yml b/html/changelogs/AutoChangeLog-pr-86791.yml deleted file mode 100644 index 8cad532c946c4..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-86791.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "00-Steven" -delete-after: True -changes: - - rscadd: "You can now see people whispering, even if you cannot hear what they're saying, unless you are blind (obviously). The speaker wearing something that covers their mouth, being invisible, or being inside of something counteracts this." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-86820.yml b/html/changelogs/AutoChangeLog-pr-86820.yml deleted file mode 100644 index d57e4f388337f..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-86820.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "00-Steven" -delete-after: True -changes: - - balance: "The pAI digital messenger software now includes the NTNRC client." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-86834.yml b/html/changelogs/AutoChangeLog-pr-86834.yml deleted file mode 100644 index 4742c8725c79d..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-86834.yml +++ /dev/null @@ -1,7 +0,0 @@ -author: "ArcaneMusic" -delete-after: True -changes: - - bugfix: "Artifact boulders should keep their alien icon even after a first round of processing." - - bugfix: "Boulders are less likely to exist with zero materials after processing." - - bugfix: "Boulders should be slightly less laggy on conveyor belts." - - bugfix: "Grammar of refinery/smeltery examine is corrected." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-86859.yml b/html/changelogs/AutoChangeLog-pr-86859.yml deleted file mode 100644 index 6619ac4e8b5de..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-86859.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "timothymtorres" -delete-after: True -changes: - - code_imp: "Add missing signal to reagent dispenser RMB interactions." - - sound: "Fix missing pour sounds from reagent dispensers" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-86863.yml b/html/changelogs/AutoChangeLog-pr-86863.yml deleted file mode 100644 index 0ef2a98f9138b..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-86863.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "00-Steven" -delete-after: True -changes: - - bugfix: "Imaginary friends can now hear their host wherever they are." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-86865.yml b/html/changelogs/AutoChangeLog-pr-86865.yml deleted file mode 100644 index 5392926586867..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-86865.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "00-Steven" -delete-after: True -changes: - - qol: "Imaginary friend smite ghost poll actually lets you jump to the target and shows their name." - - admin: "Imaginary friend smite now works with build mode." - - admin: "The imaginary friend smite configuration menus have been changed slightly." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-86873.yml b/html/changelogs/AutoChangeLog-pr-86873.yml deleted file mode 100644 index c7562c525da85..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-86873.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - bugfix: "Added missing venue prices for certain foods and reagents" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-86897.yml b/html/changelogs/AutoChangeLog-pr-86897.yml deleted file mode 100644 index 85ac5c543263c..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-86897.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - bugfix: "Players no longer can randomly get semi-permanently offset from being shoved" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-86909.yml b/html/changelogs/AutoChangeLog-pr-86909.yml deleted file mode 100644 index 4a71fc158ecea..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-86909.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - bugfix: "Mindswap can no longer be used inside of pipes" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-86910.yml b/html/changelogs/AutoChangeLog-pr-86910.yml deleted file mode 100644 index 8c093c570c9f4..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-86910.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SyncIt21" -delete-after: True -changes: - - bugfix: "Fixes ethereal APC drain/charge attack" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-86912.yml b/html/changelogs/AutoChangeLog-pr-86912.yml deleted file mode 100644 index 7598fc5b582d6..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-86912.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "vinylspiders" -delete-after: True -changes: - - bugfix: "fixes pulsing tumor failing to spawn the elite if no ghosts respond to the poll and leaving you in a bugged state, and possibly other related issues" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-86914.yml b/html/changelogs/AutoChangeLog-pr-86914.yml deleted file mode 100644 index a743ee3a28cc3..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-86914.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "timothymtorres" -delete-after: True -changes: - - bugfix: "Fix air alarms being stuck and not updating their icons." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-86915.yml b/html/changelogs/AutoChangeLog-pr-86915.yml deleted file mode 100644 index 956d4b2fa5773..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-86915.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "timothymtorres" -delete-after: True -changes: - - bugfix: "Fix air alarm helper to ignore gas when appropriate" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-86917.yml b/html/changelogs/AutoChangeLog-pr-86917.yml deleted file mode 100644 index 334faafa398a8..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-86917.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "timothymtorres" -delete-after: True -changes: - - bugfix: "Fix air alarms warning message to use pressure & temp settings" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-86918.yml b/html/changelogs/AutoChangeLog-pr-86918.yml deleted file mode 100644 index 8663c672627a0..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-86918.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "timothymtorres" -delete-after: True -changes: - - bugfix: "Fix air alarm not checking missing gases" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-86922.yml b/html/changelogs/AutoChangeLog-pr-86922.yml deleted file mode 100644 index 9365a9a1bebf6..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-86922.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Sealed101" -delete-after: True -changes: - - bugfix: "A joint effort of Gorlex Marauders and MI13 tech support teams has finally managed to center the Syndicate Infiltrator shuttle's preview on the navigation console. Nuclear Ops teams sector-wide, rejoice!" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-86923.yml b/html/changelogs/AutoChangeLog-pr-86923.yml deleted file mode 100644 index a1757370637a6..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-86923.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "timothymtorres" -delete-after: True -changes: - - bugfix: "Fix Meta's medical freezer air alarm to not trigger on cold temps. Fix missing atmos alarm in Wawa kitchen coldroom." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-86925.yml b/html/changelogs/AutoChangeLog-pr-86925.yml deleted file mode 100644 index 8bbb16786d86a..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-86925.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Ben10Omintrix" -delete-after: True -changes: - - bugfix: "fixes raptors retaliating against each other and their owners" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87086.yml b/html/changelogs/AutoChangeLog-pr-87086.yml new file mode 100644 index 0000000000000..6197c676d6729 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87086.yml @@ -0,0 +1,5 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Plasmaman space suit internal extinguisher works and can be refilled now" + - refactor: "Refactored plasmamen self-ignition to be limb-side instead of being handled by their species" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87102.yml b/html/changelogs/AutoChangeLog-pr-87102.yml new file mode 100644 index 0000000000000..e4e89d68206c3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87102.yml @@ -0,0 +1,4 @@ +author: "Striders13" +delete-after: True +changes: + - balance: "replaced gas mask fov with pepperspray applying tint to gas masks, making the wearer blind until washed off." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87110.yml b/html/changelogs/AutoChangeLog-pr-87110.yml new file mode 100644 index 0000000000000..6db52e7bde460 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87110.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "You can buy a fishing rod pre-equipped with a rescue hook from the mining order console." + - balance: "Paramedics can get a rescue fishing hook as a heirloom." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87126.yml b/html/changelogs/AutoChangeLog-pr-87126.yml new file mode 100644 index 0000000000000..d8282e1ebb2b8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87126.yml @@ -0,0 +1,6 @@ +author: "grungussuss" +delete-after: True +changes: + - rscadd: "a lot of basic mobs and pets got new emotes" + - refactor: "emotes triggered by petting pets work differently now, please report any oddities with these behaviors." + - sound: "new emotes for basic mobs got sounds" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87143.yml b/html/changelogs/AutoChangeLog-pr-87143.yml new file mode 100644 index 0000000000000..10696da59b6a6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87143.yml @@ -0,0 +1,5 @@ +author: "Jewelry-x" +delete-after: True +changes: + - bugfix: "the ghost \"t-ray view\" no longer requires a double press to activate a second time." + - qol: "renamed \"t-ray view\" to \"t-ray scan\" for clarity." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87145.yml b/html/changelogs/AutoChangeLog-pr-87145.yml new file mode 100644 index 0000000000000..70afb26c7855e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87145.yml @@ -0,0 +1,4 @@ +author: "grungussuss" +delete-after: True +changes: + - balance: "all chainsaws can now behead people" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87154.yml b/html/changelogs/AutoChangeLog-pr-87154.yml new file mode 100644 index 0000000000000..00abf6ba49819 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87154.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fish like slimefish, unmarine bonemass and deepfryer fish can now be used for DNA infusions." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87158.yml b/html/changelogs/AutoChangeLog-pr-87158.yml new file mode 100644 index 0000000000000..7d1810b7fd5c9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87158.yml @@ -0,0 +1,4 @@ +author: "YakumoChen" +delete-after: True +changes: + - spellcheck: "Proofreads some faxes sent during radioactive nebulae" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87160.yml b/html/changelogs/AutoChangeLog-pr-87160.yml new file mode 100644 index 0000000000000..f580e6406402f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87160.yml @@ -0,0 +1,4 @@ +author: "Ben10Omintrix" +delete-after: True +changes: + - bugfix: "fixes ashdrake arena attack not clearing out lavaland walls" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87168.yml b/html/changelogs/AutoChangeLog-pr-87168.yml new file mode 100644 index 0000000000000..cf39b3a5484fe --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87168.yml @@ -0,0 +1,4 @@ +author: "grungussuss" +delete-after: True +changes: + - bugfix: "snore emote works properly now" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87183.yml b/html/changelogs/AutoChangeLog-pr-87183.yml new file mode 100644 index 0000000000000..53ac31882e606 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87183.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Untie shoes should have its cooldown increased correctly when casting it from a long distance" \ No newline at end of file diff --git a/html/changelogs/archive/2024-09.yml b/html/changelogs/archive/2024-09.yml index 00d9a59b348d8..8c4e724d2030f 100644 --- a/html/changelogs/archive/2024-09.yml +++ b/html/changelogs/archive/2024-09.yml @@ -847,3 +847,107 @@ - bugfix: Debug chem synthesizer now has temperature control for adding reagents grungussuss: - sound: the volume of the nuclear fission explosive have been reduced +2024-09-29: + 00-Steven: + - bugfix: Fixed trims which did have an associated job but whose assignment didn't + match a job title causing null jobs to be assigned to accounts. This fixes departmental + security officers not being able to purchase things from the security vendors. + - qol: Imaginary friend smite ghost poll actually lets you jump to the target and + shows their name. + - admin: Imaginary friend smite now works with build mode. + - admin: The imaginary friend smite configuration menus have been changed slightly. + - bugfix: Imaginary friends can now hear their host wherever they are. + - balance: The pAI digital messenger software now includes the NTNRC client. + - rscadd: You can now see people whispering, even if you cannot hear what they're + saying, unless you are blind (obviously). The speaker wearing something that + covers their mouth, being invisible, or being inside of something counteracts + this. + ArcaneMusic: + - bugfix: Artifact boulders should keep their alien icon even after a first round + of processing. + - bugfix: Boulders are less likely to exist with zero materials after processing. + - bugfix: Boulders should be slightly less laggy on conveyor belts. + - bugfix: Grammar of refinery/smeltery examine is corrected. + Ben10Omintrix: + - bugfix: fixes raptors retaliating against each other and their owners + FlufflesTheDog: + - bugfix: The automated announcement system once more announces new arrivals to + the station. + Jewelry-x: + - bugfix: fix wiki manuals by making them open wiki page on browser + Sealed101: + - bugfix: A joint effort of Gorlex Marauders and MI13 tech support teams has finally + managed to center the Syndicate Infiltrator shuttle's preview on the navigation + console. Nuclear Ops teams sector-wide, rejoice! + SmArtKar: + - bugfix: Added missing venue prices for certain foods and reagents + - bugfix: Mindswap can no longer be used inside of pipes + - bugfix: Players no longer can randomly get semi-permanently offset from being + shoved + SyncIt21: + - bugfix: Fixes ethereal APC drain/charge attack + carlarctg: + - rscadd: Altered the blood loss on teleportation. Instead of silently always losing + ten blood, you now lose ~15 25% of the time, fitting in with the teleporter's + random design. In practice this usually evens out, but the immediate side-effects + when it does happen will be much more noticeable. The rest of the time you'll + still lose 5. + - qol: Improved the visible effects when using the teleporter. On teleporting, it + causes a tiny blood red wave at the destination, which is slightly larger and + more vibrant red if you lose blood. Telefragging someone now throws them a random + turf away alongside the stun. + - bugfix: Fixed NOBLOOD check missing from non-emergency teleport bloodloss. + timothymtorres: + - bugfix: Fix air alarms warning message to use pressure & temp settings + - bugfix: Fix air alarm helper to ignore gas when appropriate + - bugfix: Fix air alarms being stuck and not updating their icons. + - bugfix: Fix Meta's medical freezer air alarm to not trigger on cold temps. Fix + missing atmos alarm in Wawa kitchen coldroom. + - code_imp: Add missing signal to reagent dispenser RMB interactions. + - sound: Fix missing pour sounds from reagent dispensers + - bugfix: Fix air alarm not checking missing gases + vinylspiders: + - bugfix: fixes pulsing tumor failing to spawn the elite if no ghosts respond to + the poll and leaving you in a bugged state, and possibly other related issues +2024-09-30: + 00-Steven: + - bugfix: The trait that allows you to see the type of thing that's biting when + fishing actually shows it instead of just saying "fish!!!" for everything. + Ben10Omintrix: + - bugfix: hygeinebots are better at chasing unclean people + Ghommie: + - bugfix: Fixes fishing tips (from fishing toolboxes) being empty. + - bugfix: Fixed a series of small issues with bait preferences, fish growth, a small + nit with the hunger bar in the fish analyzer UI, and fishing challenges aborting + if double-clicking during the waiting phase. + - balance: Fishing lures are a smidge easier to use. Fryish now takes less time + to grow up. + Hardly: + - image: Resprited face scarf to be more GAGS friendly + Melbert: + - qol: Light Eater now displays a quick attack animation when quenching un-attackable + objects (like lamps, flashlights) + - bugfix: Light Eater animation for attacking light fixtures has been restored + SmArtKar: + - admin: Fixed VV DNA infusion tool + ZephyrTFA: + - refactor: Map Votes are now carried over between rounds. When a map vote is actually + a contest, the winning map will have its votes reset. + carlarctg: + - balance: '- Uncomplicated the Ragnarok arena. The center area''s river has been + muddied over, the bonfires have been made dense, the ants on the ground everywhere + have been removed. The Warrior and Scribe have had their loadouts simplified.' + - qol: '- The Rat''var Apostate''s beakers are now named so people other than me + can get the joke.' + - bugfix: '- Unbreakable lattices are now actually unbreakable and can''t be snipped + into nothingness.' + - bugfix: '- Added true invis walls to the edges of Lattice Battles. Moved spare + rods to the pockets.' + - bugfix: '- Species Warfare: Added no_smoothing to the funny, so it''s actually + hidden now.' + krookodilehunter: + - rscadd: Added more flowers to loadouts + mc-oofert: + - rscadd: added the manufacturing smelter,router,sorter,crafter,lathe,crusher,unloader + tonty: + - code_imp: made some code relating to the world's icon size more readable diff --git a/html/changelogs/archive/2024-10.yml b/html/changelogs/archive/2024-10.yml new file mode 100644 index 0000000000000..f24338d28bdc9 --- /dev/null +++ b/html/changelogs/archive/2024-10.yml @@ -0,0 +1,347 @@ +2024-10-01: + DaCoolBoss: + - balance: Donksoft vendors now stock slightly more items, slightly less of each + item, and has increased prices across the board. +2024-10-02: + EEASAS: + - bugfix: fixes multiple issues in metastation cargo + Ghommie: + - bugfix: Items that adjust fishing difficulty no longer have misleading examine + tips. + Hardly: + - image: Resprited kitsune masks + - image: Kitsune masks are now adjustable. Use it in-hand! + Jewelry-x: + - qol: you only need to wait 1 second if you can move into that z level instead + of most cases + - code_imp: mob/verb/up() and mob/verb/down() cleanup + grungus: + - rscadd: cat mobs can *meow and *purr + - sound: sound for meow and purr emotes + - code_imp: added support for passing emotes into the pet_bonus element +2024-10-03: + Ben10Omintrix: + - bugfix: goldgrub AI now correctly digs away from people + Dmeto: + - bugfix: Printing factory machine boards now results in their respective board + and not the assembled machine. + - bugfix: Sorter machines now use their respective board. + Hatterhat: + - rscadd: Portable power storage units and power connectors! Under the same research + node as regular power storage units, and not mapped in anywhere. Build a connector + and portable unit, wire the connector like a regular SMES, wrench the portable + unit onto the connector, unwrench as needed. + - code_imp: SMES attackby was broken up into several tool_acts instead of a big + attackby chain. If something stops working in regards to using tools on SMESes, + please file a bug report. + Time-Green: + - rscadd: Adds an assistant and hitchiker shuttle event, replenishing the crew mid + flight! + - admin: Adds two intern wave shuttle events + - code_imp: You can now supply shuttle events with outfits! + - code_imp: You can now shoot projectiles with the shuttle events! + - bugfix: Fixes projectiles bugging out when fired in shuttle transit space + - bugfix: Fixes admin forced shuttle events not activating when added mid transit + carlarctg: + - bugfix: fixed chappies being able to buy an unintended nullrod type + grungussuss: + - bugfix: fixed footsteps counting twice on diagonal movement +2024-10-04: + 00-Steven: + - rscadd: Reinforced tables may now be hooked up directly to the grid much like + grilles, electrocuting people who attempt to disassemble it. + Ben10Omintrix: + - bugfix: fixes some mobs having their aggro appearance linger around after sentience + - refactor: basic mob AI interactions has been refactored. please report any bugs + Chubbygummibear: + - bugfix: fixed multi-z weather overlays stacking and not hiding overlays above + you + DaCoolBoss: + - bugfix: Donk Co. and S.E.L.F. crates now properly display their lock (or lack + therof). + - image: New sprites for unlocked Donk Co. crates and locked S.E.L.F. crates. + - spellcheck: The names of syndicate-branded crates now use proper nouns. + - spellcheck: Fixed a typo in the description for Donk Co. fridges. + Jewelry-x: + - qol: change floor button now interacts with ladder if it is in the current turf + - bugfix: fixes stun not getting applied if you are riding a carp + SmArtKar: + - bugfix: Fixed BCIs sending messages twice and circuit laser pointers sometimes + failing to work + - qol: Added an explanation of how to change tether length and cut them to tether + anchors + - qol: MODsuits can now quickly snap all tethers attached to you + - balance: Tethers can now be cut significantly quicker + Y0SH1M4S73R: + - balance: The hatchlings on the Derelict Outpost are marginally less deadly, to + the extent that fighting them is slightly more feasible. + grungussuss: + - bugfix: fixed all mobs being able to meow + - bugfix: fixed wabbajack statue not activating + timothymtorres: + - code_imp: Automatically link maps multi-z up/down traits +2024-10-05: + 00-Steven: + - bugfix: Prosopagnosia actually accounts for hover screentips, showing humans as + Unknown in those too. + Archemagus: + - qol: Airlock_pump now dock with shuttles in more pleasant way + Bisar: + - rscadd: Clothing can now hide what you're wearing on your belt. + EnterTheJake: + - bugfix: Heretic Carving Knife runes are no longer triggered by hovering projectiles. + GremlinSeeker: + - rscadd: Birdshot Cargo now has a lobby and is slightly more open overall. + - rscadd: Re-added the DnD room to Birdshot + - rscadd: re-added the skill station to the library. + Jewelry-x: + - bugfix: Security Officers (Engineering) can now open crucial doors in Engineering + on Birdshot + - bugfix: Corrected access inconsistencies for maintenance doors in the Engineering + department on Birdshot + - bugfix: Resolved naming inconsistency for the front doors of Engineering on Birdshot + Melbert: + - qol: Runes, crayons, and similar decals no longer have shadows + - bugfix: Blood and similar "mess" decals no longer have shadows (again) + SmArtKar: + - bugfix: Fixed luminiscent major extract activation button not disappearing/updating + when it should've + Timberpoes: + - bugfix: Fixes a bug where the game would assign multiple players to single-slot + command roles. + Xackii: + - rscadd: Showers now heals stamina when you washing. But not for you catgitls. + grungussuss: + - bugfix: fixed drones being able to store multiple of the same type of tools in + their toolbox + imedial: + - qol: puts silicon laws in the status panel + timothymtorres: + - bugfix: Fix air alarms to work correctly while connected to a gas sensor + - bugfix: Fix paired air alarms and sensors to be able to relink to other devices + if turned off, reset, or destroyed. + - bugfix: Fix air alarm disabled setting to silence warnings +2024-10-06: + Ghommie: + - bugfix: The pre-emagged fishing portal circuitboard now actually gives you an + emagged fishing portal generator. + LemonInTheDark: + - map: added a map specific changelog entry + SmArtKar: + - qol: Jetpack movement is now much smoother + iwishforducks: + - image: Traitors now get the classic Revolver in their uplink. Nuclear Operatives + still keep the red look for their revolvers. +2024-10-07: + 00-Steven: + - bugfix: Syringes can be put into cake/bread/cheese on right click again. + - spellcheck: Biting into a hidden syringe no longer displays things like "a the + syringe". + DaCoolBoss: + - balance: MI13 Fugitive Hunters can no longer spawn with machine trappers, instead + they may now spawn with thermal goggles. + Ghommie: + - rscadd: Space carps and space dragons can now fish. Space dragons can now eat + fish too, for a very mild healing. + - rscadd: The carp rift is now a fishing spot, filled with carp-related loot, including + baby space carps (aquarium fish that eventually grows into a real space carp + in a matter of half a dozen minutes). + - rscadd: Added a shark form (and relative achievement) to space dragons, unlocked + after eating an unspecificatedly high amount of fish. + - refactor: Refactored materials code. report any issue. + - rscadd: Cleric maces (The autolathe-printable weapon design from outer space) + can now be made of two different materials. + - balance: Buffed cleric maces a little. + - bugfix: toolboxes' stats are now affected by materials again. + Jewelry-x: + - spellcheck: capitalise cure_text for advanced slime mutation + - bugfix: fixed not being able to stop looking up or down if unable to find something + until you found something + - qol: feedback for "Look Up" or "Look Down" verbs to reduce confusion caused by + the verbs + - qol: limited usage of "Look Up" and "Look Down" to cases where there is a turf + above your or below you accordingly + - qol: automatically stops you from looking up or down when there is no turf above + or below you + - bugfix: fixes exception during shuttle map rotation vote + JohnFulpWillard: + - balance: Human AIs spawn with a space suit on Wawastation. + - balance: Human AIs no longer have slowdown and a ton of restrictions such as ladders + when outside of the satellite. + - qol: Spawning in with a space suit now has its thermal regulation on by default. + Melbert: + - bugfix: Fixed manual construction of hygiene bots + - rscdel: Having any wounds no longer gives you an alert in the top right + - qol: Having any wounds now make the corresponding bodypart on your health doll + (the lil dude on the right side of the screen) glow red. + - refactor: Refactored how the hud's health doll shows up for humans. Report any + oddities + OrionTheFox: + - rscadd: '3 new Space Ruins: two small Comms Buoys (fluff) and an NT Bluespace + Comms Buoy. Employees are asked not to touch vital components when nearby this + critical infrastructure.' + - spellcheck: added a 's to Personal/Job lockers created with card readers, renamed + 'Departmental' to 'Job' to prevent confusion, and made the description easier + to read + Pickle-Coding: + - balance: The supermatter accumulates zap energy and discharges a portion of it + to use for zapping per atmos tick, no longer being bounded by machinery ticking. + Sealed101: + - bugfix: fixed PANDEMIC not updating its UI when a beaker is removed via right-click + - bugfix: splashing a reagent holder with blood with a fluids-transmitted virus + now properly creates an infective blood splatter + - bugfix: fixed hand tele portals that have been deleted in the process of opening + a new portal pair clogging up hand tele's portal pair list. If you try to create + portals that would end up like this (i.e. on an active teleporter hub), the + hand tele will indicate that. + SyncIt21: + - bugfix: tools from the drone toolbox cannot be forcefully removed in certain situations + e.g. when using the drone gas analyser to upgrade the camera assembly + - qol: adds extra examines & screentips for inducer + - bugfix: inducer charging rate scales with cell rating + - bugfix: syndicate inducers now have correct charge & batteries installed + - refactor: inducer attack chain has been improved & redundant vars/procs have been + removed, report bugs on github + TheSmallBlue: + - config: Both human authority settings were combined into a singular one, allowing + for more flexibility + ViralMilk22: + - map: Additional Icebox Ruin has been added "Hunters Lodge". + carlarctg: + - bugfix: We found out that the money meant to purchase mutation vaccines for Syndicate + Monkey agents against mutation was being embezzled to buy Space Yachts. We've + repurposed their biomass towards a new and improved vaccine, which has the minor + side effect of causing allergies if their species type is forcibly altered. + grungussuss: + - bugfix: fixed a clientless AI spawning when a ghost poll for syndicate modsuit + AI had no volunteers + - admin: AI rolebanned players can no longer role for Syndicate modsuit AI + - sound: riot suits and swat suits now make noise when moving around in them. + grungussuss and redemptionarc: + - sound: snoring now has sounds, snoring will happen more often while asleep + mc-oofert: + - balance: you may wear gloves one armed + - bugfix: you can now put more than 1 non-stack item relevant to the recipe in a + manufacturing crafter + - bugfix: manufacturing router does not bug out when handling stacks in some cases + at the cost of being slower to do so + timothymtorres: + - rscadd: Add no escape final traitor objective that spawns a stage six (11x11) + singularity shuttle event. +2024-10-08: + Ben10Omintrix: + - rscadd: adds a new station trait, "bring your pet to work" day + Melbert: + - admin: Items now have a header in VV allowing for quicker editing of combat properties + - refactor: Refactored footsteps for humans. Human footstep sound effects are now + determined by your leg type. Report any oddities. + - qol: Digitigrade legs now play claw footstep SFX. "plat plat" is dead, long live + "tap tap". + - qol: Unusable inventory slots (as according to your bodyparts or equipment) will + now be dimmed (similarly to how unusable inventory slots are dimmed for certain + species like Golems). + SmArtKar: + - balance: You can no longer view operating computer UI while lying down + antropod: + - rscadd: You can now link to multiple trapdoors with one remote + - rscadd: Trapdoor will automatically close in 5 seconds (ctrl-clicking on a remote + will toggle autoclose) + grungussuss: + - sound: ballistics have new handling sounds + siliconOpossum: + - bugfix: The preview for writing on paper updates in real-time again + timothymtorres: + - admin: Organize admin verbs for shuttle events into shuttle category + vinylspiders: + - qol: lets you continue to read paperwork after putting it into a folder + wonderinghost: + - rscadd: Adds a few lights + - bugfix: removes the darkspot in wawa med +2024-10-09: + Ghommie: + - rscadd: 'Added a new infusion to the game: Fish. Its main gimmick revolves around + being stronger and slippery when wet while weaker when dry.' + - balance: Buffed tetrodotoxin a little against liver tolerance and purging reagents. + Iajret: + - bugfix: health analyzers will show if your heart is missing once again + SmArtKar: + - image: Carp infusion now changes how your skin looks to reflect your fishy nature + SyncIt21: + - bugfix: you can drop/put drone tools back in the toolbox + - bugfix: you cannot dump the contents of the drone toolbox + necromanceranne: + - rscadd: Fundamentally Evil quirk. You might act normal, but you know deep down + that you totally don't give a shit about anyone but yourself. Empaths better + watch out. +2024-10-10: + Ghommie: + - bugfix: The fishing portal generator (fish-porter 3000) now correctly links with + lava turfs from lavaland. + Jewelry-x: + - bugfix: fixed reagents not being applied correctly by venomous mobs + - bugfix: dead borgs no longer become invisible upon changing z level + SmArtKar: + - rscadd: New station trait "Spiked Drinks" that will add booze to most sodas has + been added to rotation. + StrangeWeirdKitten: + - admin: The Law Panel now properly logs and communicates law edits. +2024-10-11: + Absolucy: + - bugfix: Allow dot radio prefixes to also work with the tgui-say radio prefix display. + DATA-xPUNGED: + - bugfix: Xeno queens can once again promote Drones to Praetorians + - bugfix: They can also once again do hand emotes + - bugfix: Ghosts can now see the details of an ID from any distance + - bugfix: Server Hopping should fade your screen into black, as it should. + EnterTheJake: + - bugfix: Dark matter singularity no longer gets stuck on other z levels when summoned. + - bugfix: Space Phase now makes the Heretic Space proof. + Ghommie: + - rscadd: The fishing skillchip now grants an action that dispenses fishing tips. + - bugfix: fixed fish infusion. Whoopsies. + - rscadd: Feeding fish certain reagents may have some effects. Mutagen for increased + evolution probability. Growth serum for faster growth. Teslium for electrogenesis. + KazooBard: + - rscadd: More cardboard cutout icons (Pirate, ninja, changeling, heretic, abductor) + Melbert: + - bugfix: Fixed medipens injecting 2x their contents + - bugfix: Fixes stuff staying on your body after removing your clothes + Qwertytoforty: + - bugfix: Anomalies no longer spawn in objects or mobs from the supermatter. + grungussuss: + - sound: plate armor now makes sound when moving around in it + - sound: reagent containers now make sounds if there is liquid in them when picked + up or dropped + - sound: fire extinguishers now make sounds when dropped or picked up + - bugfix: removed a few var edits from maps + junkgle01: + - image: resprited surplus limbs + unit0016: + - bugfix: Shuttles that land next to plasma turfs no longer ruin the mass hallucination + that is Icebox having Plasma and not just super-deadly; spiky basalt deltas. + You're welcome; unreality fans. +2024-10-12: + Cruix: + - bugfix: Fixed chameleon clothing sometimes making you bald or hiding other parts + of your sprite. + EEASAS: + - bugfix: adds plasma to wawastation's xenobio + EuSouAFazer: + - balance: '[TGC] Rebalances nearly every card in the game.' + - balance: '[TGC] Several keywords had their effects modified.' + - bugfix: '[TGC] Black Gaia is no longer an "Artifact", Fryer no longer mentions + tapping it.' + - spellcheck: '[TGC] Replaced "Tap this card:" with just "Tap:" alongside other + wording improvements' + - spellcheck: '[TGC] Mana has been replaced with Plasma. This is a completely cosmetic + change.' + - refactor: '[TGC] Merged many, many redudant card subtypes (the mechanic, not the + byond code stuff) into more comprehensive ones.' + FlufflesTheDog: + - bugfix: Mops and similar work properly on multi-z stations + Melbert: + - bugfix: Dead bees maintain their color and reagents + SmArtKar: + - qol: Jetpack movement near walls should be much smoother + grungussuss: + - bugfix: a lot of items that shouldn't slosh when picked up will no longer slosh diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index d8b68c88d3812..278edffb855e8 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/hud/lobby/signup_button.dmi b/icons/hud/lobby/signup_button.dmi index e015fa71948a3..26d32e9af8384 100644 Binary files a/icons/hud/lobby/signup_button.dmi and b/icons/hud/lobby/signup_button.dmi differ diff --git a/icons/hud/radial_fishing.dmi b/icons/hud/radial_fishing.dmi index 90b2b17c83a8a..d77d9064882ff 100644 Binary files a/icons/hud/radial_fishing.dmi and b/icons/hud/radial_fishing.dmi differ diff --git a/icons/hud/screen_alert.dmi b/icons/hud/screen_alert.dmi index 96a990090f518..e0206b9753323 100644 Binary files a/icons/hud/screen_alert.dmi and b/icons/hud/screen_alert.dmi differ diff --git a/icons/hud/screen_gen.dmi b/icons/hud/screen_gen.dmi index 86383abbef1e2..5b1c24d7789cc 100644 Binary files a/icons/hud/screen_gen.dmi and b/icons/hud/screen_gen.dmi differ diff --git a/icons/mob/augmentation/surplus_augments.dmi b/icons/mob/augmentation/surplus_augments.dmi index 0fafab0533694..82e83ec27d76b 100644 Binary files a/icons/mob/augmentation/surplus_augments.dmi and b/icons/mob/augmentation/surplus_augments.dmi differ diff --git a/icons/mob/clothing/mask.dmi b/icons/mob/clothing/mask.dmi index 4ac9143e7a834..117511dd8741e 100644 Binary files a/icons/mob/clothing/mask.dmi and b/icons/mob/clothing/mask.dmi differ diff --git a/icons/mob/effects/talk.dmi b/icons/mob/effects/talk.dmi index c6281b29cc48b..5efb7328971a4 100644 Binary files a/icons/mob/effects/talk.dmi and b/icons/mob/effects/talk.dmi differ diff --git a/icons/mob/human/fish_features.dmi b/icons/mob/human/fish_features.dmi new file mode 100644 index 0000000000000..185b89d88fc1d Binary files /dev/null and b/icons/mob/human/fish_features.dmi differ diff --git a/icons/mob/human/species/misc/bodypart_overlay_simple.dmi b/icons/mob/human/species/misc/bodypart_overlay_simple.dmi index dbaaeec55cd24..84dd6c4a39e2b 100644 Binary files a/icons/mob/human/species/misc/bodypart_overlay_simple.dmi and b/icons/mob/human/species/misc/bodypart_overlay_simple.dmi differ diff --git a/icons/mob/human/textures.dmi b/icons/mob/human/textures.dmi index c5f420c7de866..4408c3e067281 100644 Binary files a/icons/mob/human/textures.dmi and b/icons/mob/human/textures.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index ebcfea5967596..f38ce00161941 100644 Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index b8fd65ec07206..4639b290fe371 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/mob/nonhuman-player/spacedragon.dmi b/icons/mob/nonhuman-player/spacedragon.dmi index a1f3d4d782bc9..a453b4441e3a5 100644 Binary files a/icons/mob/nonhuman-player/spacedragon.dmi and b/icons/mob/nonhuman-player/spacedragon.dmi differ diff --git a/icons/obj/aquarium/fish.dmi b/icons/obj/aquarium/fish.dmi index eec60317b0e08..deabb8c7a3681 100644 Binary files a/icons/obj/aquarium/fish.dmi and b/icons/obj/aquarium/fish.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index 436785ce6e5e9..595893177355b 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/fluff/general.dmi b/icons/obj/fluff/general.dmi index f99cbaabc9a1d..b05ce2f83e8bb 100644 Binary files a/icons/obj/fluff/general.dmi and b/icons/obj/fluff/general.dmi differ diff --git a/icons/obj/machines/engine/other.dmi b/icons/obj/machines/engine/other.dmi index 92dd420c84c32..7fb5ac6e7656d 100644 Binary files a/icons/obj/machines/engine/other.dmi and b/icons/obj/machines/engine/other.dmi differ diff --git a/icons/obj/machines/manufactorio.dmi b/icons/obj/machines/manufactorio.dmi new file mode 100644 index 0000000000000..95bbd8fccb0eb Binary files /dev/null and b/icons/obj/machines/manufactorio.dmi differ diff --git a/icons/obj/medical/organs/infuser_organs.dmi b/icons/obj/medical/organs/infuser_organs.dmi index c2551b41f6668..57c719dbbbb35 100644 Binary files a/icons/obj/medical/organs/infuser_organs.dmi and b/icons/obj/medical/organs/infuser_organs.dmi differ diff --git a/icons/obj/pet_carrier.dmi b/icons/obj/pet_carrier.dmi index 0a2b4f6c430e9..366fddd414412 100644 Binary files a/icons/obj/pet_carrier.dmi and b/icons/obj/pet_carrier.dmi differ diff --git a/icons/obj/storage/crates.dmi b/icons/obj/storage/crates.dmi index 5f8fecab7a0ff..7695ac5f84854 100644 Binary files a/icons/obj/storage/crates.dmi and b/icons/obj/storage/crates.dmi differ diff --git a/icons/obj/weapons/cleric_mace.dmi b/icons/obj/weapons/cleric_mace.dmi index 3dc90bf10c446..ad7fdbc09a22a 100644 Binary files a/icons/obj/weapons/cleric_mace.dmi and b/icons/obj/weapons/cleric_mace.dmi differ diff --git a/icons/obj/weapons/guns/projectiles.dmi b/icons/obj/weapons/guns/projectiles.dmi index cbf79a92b538f..911ef3e44e425 100644 Binary files a/icons/obj/weapons/guns/projectiles.dmi and b/icons/obj/weapons/guns/projectiles.dmi differ diff --git a/icons/ui/achievements/achievements.dmi b/icons/ui/achievements/achievements.dmi index 740759467e0cc..8f6b9e1f42af9 100644 Binary files a/icons/ui/achievements/achievements.dmi and b/icons/ui/achievements/achievements.dmi differ diff --git a/modular_doppler/automapper/code/area_spawn_subsystem.dm b/modular_doppler/automapper/code/area_spawn_subsystem.dm index ee6554d589f89..d28568d7ac344 100644 --- a/modular_doppler/automapper/code/area_spawn_subsystem.dm +++ b/modular_doppler/automapper/code/area_spawn_subsystem.dm @@ -272,7 +272,7 @@ SUBSYSTEM_DEF(area_spawn) * Attempts to find a location using an algorithm to spawn the desired atom. */ /datum/area_spawn/proc/try_spawn() - if(SSmapping.config.map_name in blacklisted_stations) + if(SSmapping.current_map.map_name in blacklisted_stations) return // Turfs that are available @@ -288,7 +288,7 @@ SUBSYSTEM_DEF(area_spawn) if(!LAZYLEN(available_turfs)) if(!optional) - log_mapping("[src.type] could not find any suitable turfs on map [SSmapping.config.map_name]!") + log_mapping("[src.type] could not find any suitable turfs on map [SSmapping.current_map.map_name]!") SSarea_spawn.failed_area_spawns += src.type return @@ -326,7 +326,7 @@ SUBSYSTEM_DEF(area_spawn) * Spawn the atoms. */ /datum/area_spawn_over/proc/try_spawn() - if(SSmapping.config.map_name in blacklisted_stations) + if(SSmapping.current_map.map_name in blacklisted_stations) return for(var/area_type in target_areas) diff --git a/modular_doppler/automapper/code/automapper_subsystem.dm b/modular_doppler/automapper/code/automapper_subsystem.dm index 39e3d96bc341b..ec8c4f5a5e778 100644 --- a/modular_doppler/automapper/code/automapper_subsystem.dm +++ b/modular_doppler/automapper/code/automapper_subsystem.dm @@ -41,7 +41,7 @@ SUBSYSTEM_DEF(automapper) // !builtin is a magic code for built in maps, ie CentCom levels. // We'll pretend it's loaded with the station z-level, because they by definition they are loaded before the station z-levels. - var/requires_builtin = (required_map == AUTOMAPPER_MAP_BUILTIN) && ((SSmapping.config.map_file in map_names) || SSmapping.config.map_file == map_names) + var/requires_builtin = (required_map == AUTOMAPPER_MAP_BUILTIN) && ((SSmapping.current_map.map_file in map_names) || SSmapping.current_map.map_file == map_names) if(!requires_builtin && !(required_map in map_names)) continue @@ -73,7 +73,7 @@ SUBSYSTEM_DEF(automapper) if(!islist(map_names)) map_names = list(map_names) for(var/datum/map_template/automap_template/iterating_template as anything in preloaded_map_templates) - if(iterating_template.affects_builtin_map && ((SSmapping.config.map_file in map_names) || SSmapping.config.map_file == map_names)) + if(iterating_template.affects_builtin_map && ((SSmapping.current_map.map_file in map_names) || SSmapping.current_map.map_file == map_names)) // CentCom already started loading objects, place them in the netherzone for(var/turf/old_turf as anything in iterating_template.get_affected_turfs(iterating_template.load_turf, FALSE)) init_contents(old_turf) diff --git a/modular_doppler/hearthkin/primitive_genemod/code/special_metals.dm b/modular_doppler/hearthkin/primitive_genemod/code/special_metals.dm index 8268c148f6b23..c57f118554433 100644 --- a/modular_doppler/hearthkin/primitive_genemod/code/special_metals.dm +++ b/modular_doppler/hearthkin/primitive_genemod/code/special_metals.dm @@ -6,7 +6,7 @@ name = "cobolterium" desc = "Cobolterium" color = list(0.2,0.5,0.7,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0) - greyscale_colors = "#264d61" + greyscale_color = "#264d61" categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL = TRUE) sheet_type = /obj/item/stack/sheet/cobolterium @@ -35,7 +35,7 @@ name = "copporcitite" desc = "Copporcitite" color = list(0.8,0.35,0.1,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0) - greyscale_colors = "#c55a1d" + greyscale_color = "#c55a1d" categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL = TRUE) sheet_type = /obj/item/stack/sheet/copporcitite @@ -64,7 +64,7 @@ name = "tinumium" desc = "Tinumium" color = list(0.45,0.5,0.6,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0) - greyscale_colors = "#717e97" + greyscale_color = "#717e97" categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL = TRUE) sheet_type = /obj/item/stack/sheet/tinumium @@ -93,7 +93,7 @@ name = "brussite" desc = "Brussite" color = list(0.9,0.75,0.4,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0) - greyscale_colors = "#E1C16E" + greyscale_color = "#E1C16E" categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL = TRUE) sheet_type = /obj/item/stack/sheet/brussite diff --git a/modular_doppler/hearthkin/primitive_structures/code/railroad.dm b/modular_doppler/hearthkin/primitive_structures/code/railroad.dm index 3ee15cccb85f0..d6fd2bf3fd850 100644 --- a/modular_doppler/hearthkin/primitive_structures/code/railroad.dm +++ b/modular_doppler/hearthkin/primitive_structures/code/railroad.dm @@ -65,7 +65,7 @@ desc = "A wonderful form of locomotion. It will only ride while on tracks. It does have storage" icon = 'modular_doppler/hearthkin/primitive_structures/icons/railroad.dmi' icon_state = "railcart" - material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_GREYSCALE | MATERIAL_COLOR + material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR /// The mutable appearance used for the overlay over buckled mobs. var/mutable_appearance/railoverlay /// whether there is sand in the cart diff --git a/modular_doppler/modular_customization/accessories/code/aquatic_accessories/aquatic_tail.dm b/modular_doppler/modular_customization/accessories/code/aquatic_accessories/aquatic_tail.dm index f7286f05239bc..bf7f0187dd1f5 100644 --- a/modular_doppler/modular_customization/accessories/code/aquatic_accessories/aquatic_tail.dm +++ b/modular_doppler/modular_customization/accessories/code/aquatic_accessories/aquatic_tail.dm @@ -1,18 +1,10 @@ /datum/sprite_accessory/tails/fish icon = 'modular_doppler/modular_customization/accessories/icons/aquatic/aquatic_tail.dmi' -/datum/sprite_accessory/tails/fish/default - name = "Shark" - icon_state = "shark" - /datum/sprite_accessory/tails/fish/shark_finless name = "Shark (Finless)" icon_state = "sharknofin" -/datum/sprite_accessory/tails/fish/carp - name = "Carp" - icon_state = "fish" - /datum/sprite_accessory/tails/fish/akula name = "Azulean" icon_state = "akula" diff --git a/modular_doppler/modular_customization/accessories/icons/aquatic/aquatic_tail.dmi b/modular_doppler/modular_customization/accessories/icons/aquatic/aquatic_tail.dmi index 0aff2d4772c33..6011a2f984330 100644 Binary files a/modular_doppler/modular_customization/accessories/icons/aquatic/aquatic_tail.dmi and b/modular_doppler/modular_customization/accessories/icons/aquatic/aquatic_tail.dmi differ diff --git a/modular_doppler/modular_customization/organs/external/tail.dm b/modular_doppler/modular_customization/organs/external/tail.dm index d518e6939f53c..a0ffd7a86871f 100644 --- a/modular_doppler/modular_customization/organs/external/tail.dm +++ b/modular_doppler/modular_customization/organs/external/tail.dm @@ -163,15 +163,6 @@ // /obj/item/organ/external/tail/fish preference = "feature_fish_tail" - dna_block = null - wag_flags = WAG_ABLE - bodypart_overlay = /datum/bodypart_overlay/mutant/tail/fish - -/datum/bodypart_overlay/mutant/tail/fish - feature_key = "tail_other" - -/datum/bodypart_overlay/mutant/tail/fish/get_global_feature_list() - return SSaccessories.tails_list_fish /// Cybernetic tail // diff --git a/modular_doppler/modular_customization/preferences/ears.dm b/modular_doppler/modular_customization/preferences/ears.dm index 827cd72ba3a03..6a16d00b4a401 100644 --- a/modular_doppler/modular_customization/preferences/ears.dm +++ b/modular_doppler/modular_customization/preferences/ears.dm @@ -72,13 +72,13 @@ /// All current ear types to choose from // Cat -/datum/preference/choiced/ears +/datum/preference/choiced/felinid_ears category = PREFERENCE_CATEGORY_CLOTHING relevant_external_organ = null should_generate_icons = TRUE main_feature_name = "Ears" -/datum/preference/choiced/ears/is_accessible(datum/preferences/preferences) +/datum/preference/choiced/felinid_ears/is_accessible(datum/preferences/preferences) . = ..() var/datum/species/species = preferences.read_preference(/datum/preference/choiced/species) if(species.type in GLOB.species_blacklist_no_mutant) @@ -88,15 +88,15 @@ return TRUE return FALSE -/datum/preference/choiced/ears/create_default_value() +/datum/preference/choiced/felinid_ears/create_default_value() return /datum/sprite_accessory/ears/none::name -/datum/preference/choiced/ears/apply_to_human(mob/living/carbon/human/target, value) +/datum/preference/choiced/felinid_ears/apply_to_human(mob/living/carbon/human/target, value) ..() if(target.dna.ear_type == CAT) target.dna.features["ears"] = value -/datum/preference/choiced/ears/icon_for(value) +/datum/preference/choiced/felinid_ears/icon_for(value) var/datum/sprite_accessory/chosen_ears = SSaccessories.ears_list[value] return generate_ears_icon(chosen_ears) diff --git a/modular_doppler/modular_customization/preferences/tail.dm b/modular_doppler/modular_customization/preferences/tail.dm index 5a564a1c4f6f9..ec68c4f5634b7 100644 --- a/modular_doppler/modular_customization/preferences/tail.dm +++ b/modular_doppler/modular_customization/preferences/tail.dm @@ -6,7 +6,6 @@ var/list/tails_list_mouse var/list/tails_list_bird var/list/tails_list_deer - var/list/tails_list_fish var/list/tails_list_bug var/list/tails_list_synth var/list/tails_list_humanoid @@ -20,7 +19,6 @@ tails_list_mouse = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/mouse)["default_sprites"] tails_list_bird = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/bird)["default_sprites"] tails_list_deer = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/deer)["default_sprites"] - tails_list_fish = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/fish)["default_sprites"] tails_list_bug = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/bug)["default_sprites"] tails_list_synth = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/cybernetic)["default_sprites"] tails_list_humanoid = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/humanoid)["default_sprites"] @@ -49,6 +47,10 @@ var/obj/item/organ/replacement = SSwardrobe.provide_type(/obj/item/organ/external/tail/monkey) replacement.Insert(target, special = TRUE, movement_flags = DELETE_IF_REPLACED) return . + else if(target.dna.features["fish_tail"] != /datum/sprite_accessory/tails/fish/none::name && !(type in GLOB.species_blacklist_no_mutant) && target.dna.features["fish_tail"] != /datum/sprite_accessory/blank::name) + var/obj/item/organ/replacement = SSwardrobe.provide_type(/obj/item/organ/external/tail/fish) + replacement.Insert(target, special = TRUE, movement_flags = DELETE_IF_REPLACED) + return . else if((target.dna.features["tail_other"] != /datum/sprite_accessory/tails/lizard/none::name && !(type in GLOB.species_blacklist_no_mutant) && target.dna.features["tail_other"] != /datum/sprite_accessory/blank::name) && (target.dna.tail_type != NO_VARIATION)) var/obj/item/organ/organ_path = text2path("/obj/item/organ/external/tail/[target.dna.tail_type]") var/obj/item/organ/replacement = SSwardrobe.provide_type(organ_path) @@ -92,23 +94,33 @@ target.dna.features["tail_lizard"] = /datum/sprite_accessory/tails/lizard/none::name target.dna.features["tail_cat"] = /datum/sprite_accessory/tails/human/none::name target.dna.features["tail_monkey"] = /datum/sprite_accessory/tails/monkey/none::name + target.dna.features["fish_tail"] = /datum/sprite_accessory/tails/fish/none::name target.dna.features["tail_other"] = /datum/sprite_accessory/tails/none::name if(LIZARD) target.dna.features["tail_cat"] = /datum/sprite_accessory/tails/human/none::name target.dna.features["tail_monkey"] = /datum/sprite_accessory/tails/monkey/none::name + target.dna.features["fish_tail"] = /datum/sprite_accessory/tails/fish/none::name target.dna.features["tail_other"] = /datum/sprite_accessory/tails/none::name if(CAT) target.dna.features["tail_lizard"] = /datum/sprite_accessory/tails/lizard/none::name target.dna.features["tail_monkey"] = /datum/sprite_accessory/tails/monkey/none::name + target.dna.features["fish_tail"] = /datum/sprite_accessory/tails/fish/none::name target.dna.features["tail_other"] = /datum/sprite_accessory/tails/none::name if(MONKEY) target.dna.features["tail_cat"] = /datum/sprite_accessory/tails/human/none::name target.dna.features["tail_lizard"] = /datum/sprite_accessory/tails/lizard/none::name + target.dna.features["fish_tail"] = /datum/sprite_accessory/tails/fish/none::name + target.dna.features["tail_other"] = /datum/sprite_accessory/tails/none::name + if(FISH) + target.dna.features["tail_cat"] = /datum/sprite_accessory/tails/human/none::name + target.dna.features["tail_lizard"] = /datum/sprite_accessory/tails/lizard/none::name + target.dna.features["tail_monkey"] = /datum/sprite_accessory/tails/monkey/none::name target.dna.features["tail_other"] = /datum/sprite_accessory/tails/none::name else target.dna.features["tail_lizard"] = /datum/sprite_accessory/tails/lizard/none::name target.dna.features["tail_cat"] = /datum/sprite_accessory/tails/human/none::name target.dna.features["tail_monkey"] = /datum/sprite_accessory/tails/monkey/none::name + target.dna.features["fish_tail"] = /datum/sprite_accessory/tails/fish/none::name /// All current tail types to choose from // Lizard @@ -139,13 +151,13 @@ return generate_back_icon(chosen_tail, "tail") // Cat -/datum/preference/choiced/tail_human // it's a lie +/datum/preference/choiced/tail_felinid category = PREFERENCE_CATEGORY_CLOTHING relevant_external_organ = null should_generate_icons = TRUE main_feature_name = "Tail" -/datum/preference/choiced/tail_human/is_accessible(datum/preferences/preferences) +/datum/preference/choiced/tail_felinid/is_accessible(datum/preferences/preferences) . = ..() var/datum/species/species = preferences.read_preference(/datum/preference/choiced/species) if(species.type in GLOB.species_blacklist_no_mutant) @@ -155,14 +167,14 @@ return TRUE return FALSE -/datum/preference/choiced/tail_human/create_default_value() +/datum/preference/choiced/tail_felinid/create_default_value() return /datum/sprite_accessory/tails/human/none::name -/datum/preference/choiced/tail_human/apply_to_human(mob/living/carbon/human/target, value) +/datum/preference/choiced/tail_felinid/apply_to_human(mob/living/carbon/human/target, value) target.dna.features["tail_cat"] = value -/datum/preference/choiced/tail_human/icon_for(value) - var/datum/sprite_accessory/chosen_tail = SSaccessories.tails_list_human[value] +/datum/preference/choiced/tail_felinid/icon_for(value) + var/datum/sprite_accessory/chosen_tail = SSaccessories.tails_list_felinid[value] return generate_back_icon(chosen_tail, "tail") // Dog @@ -416,8 +428,7 @@ return /datum/sprite_accessory/tails/fish/none::name /datum/preference/choiced/fish_tail/apply_to_human(mob/living/carbon/human/target, value) - if(target.dna.tail_type == FISH) - target.dna.features["tail_other"] = value + target.dna.features["fish_tail"] = value /datum/preference/choiced/fish_tail/icon_for(value) var/datum/sprite_accessory/chosen_tail = SSaccessories.tails_list_fish[value] diff --git a/modular_doppler/modular_customization/tri_color/ears.dm b/modular_doppler/modular_customization/tri_color/ears.dm index 2a0481cba3369..2839c175ade63 100644 --- a/modular_doppler/modular_customization/tri_color/ears.dm +++ b/modular_doppler/modular_customization/tri_color/ears.dm @@ -1,5 +1,5 @@ // Gotta add to the ears selector -/datum/preference/choiced/ears/compile_constant_data() +/datum/preference/choiced/felinid_ears/compile_constant_data() var/list/data = ..() data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/ears_color::savefile_key return data diff --git a/modular_doppler/modular_customization/tri_color/tail.dm b/modular_doppler/modular_customization/tri_color/tail.dm index 5d955a42fa9d8..6344589031afc 100644 --- a/modular_doppler/modular_customization/tri_color/tail.dm +++ b/modular_doppler/modular_customization/tri_color/tail.dm @@ -5,7 +5,7 @@ data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/tail_color::savefile_key return data -/datum/preference/choiced/tail_human/compile_constant_data() +/datum/preference/choiced/tail_felinid/compile_constant_data() var/list/data = ..() data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/tail_color::savefile_key return data diff --git a/modular_doppler/reagent_forging/code/centrifuge.dm b/modular_doppler/reagent_forging/code/centrifuge.dm index 9bb4272a5c0cc..3ccb1aed5ce19 100644 --- a/modular_doppler/reagent_forging/code/centrifuge.dm +++ b/modular_doppler/reagent_forging/code/centrifuge.dm @@ -3,7 +3,7 @@ desc = "A small cup that allows a person to slowly spin out liquids they do not desire." icon = 'modular_doppler/reagent_forging/icons/obj/misc_tools.dmi' icon_state = "primitive_centrifuge" - material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_GREYSCALE | MATERIAL_COLOR + material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR /obj/item/reagent_containers/cup/primitive_centrifuge/examine() . = ..() diff --git a/modular_doppler/reagent_forging/code/forge_clothing.dm b/modular_doppler/reagent_forging/code/forge_clothing.dm index 4d142d5eeb7ad..571822c2e5f52 100644 --- a/modular_doppler/reagent_forging/code/forge_clothing.dm +++ b/modular_doppler/reagent_forging/code/forge_clothing.dm @@ -9,7 +9,7 @@ resistance_flags = FIRE_PROOF obj_flags_doppler = ANVIL_REPAIR armor_type = /datum/armor/armor_forging_plate_armor - material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_GREYSCALE | MATERIAL_COLOR + material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR /datum/armor/armor_forging_plate_armor melee = 40 @@ -34,7 +34,7 @@ resistance_flags = FIRE_PROOF obj_flags_doppler = ANVIL_REPAIR armor_type = /datum/armor/gloves_forging_plate_gloves - material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_GREYSCALE | MATERIAL_COLOR + material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR body_parts_covered = HANDS|ARMS /datum/armor/gloves_forging_plate_gloves @@ -59,7 +59,7 @@ flags_inv = null obj_flags_doppler = ANVIL_REPAIR armor_type = /datum/armor/helmet_forging_plate_helmet - material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_GREYSCALE | MATERIAL_COLOR + material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR /datum/armor/helmet_forging_plate_helmet melee = 40 @@ -84,7 +84,7 @@ icon_state = "plate_boots" supports_variations_flags = CLOTHING_DIGITIGRADE_VARIATION armor_type = /datum/armor/shoes_forging_plate_boots - material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_GREYSCALE | MATERIAL_COLOR + material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR resistance_flags = FIRE_PROOF obj_flags_doppler = ANVIL_REPAIR can_be_tied = FALSE @@ -123,7 +123,7 @@ body_parts_covered = NECK slot_flags = ITEM_SLOT_NECK w_class = WEIGHT_CLASS_SMALL - material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_GREYSCALE | MATERIAL_COLOR + material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR obj_flags_doppler = ANVIL_REPAIR /obj/item/clothing/neck/collar/reagent_clothing/Initialize(mapload) @@ -133,7 +133,7 @@ /obj/item/restraints/handcuffs/reagent_clothing name = "reagent handcuffs" desc = "A pair of handcuffs that are ready to keep someone captive." - material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_GREYSCALE | MATERIAL_COLOR + material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR obj_flags_doppler = ANVIL_REPAIR /obj/item/restraints/handcuffs/reagent_clothing/Initialize(mapload) diff --git a/modular_doppler/reagent_forging/code/forge_items.dm b/modular_doppler/reagent_forging/code/forge_items.dm index 3d19ad9caad6c..fb095e79052c2 100644 --- a/modular_doppler/reagent_forging/code/forge_items.dm +++ b/modular_doppler/reagent_forging/code/forge_items.dm @@ -97,7 +97,7 @@ GLOBAL_LIST_INIT(allowed_forging_materials, list( ///the path of the item that will be spawned upon completion var/spawn_item //because who doesn't want to have a plasma sword? - material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_GREYSCALE | MATERIAL_COLOR + material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR /obj/item/forging/incomplete/tong_act(mob/living/user, obj/item/tool) . = ..() @@ -192,7 +192,7 @@ GLOBAL_LIST_INIT(allowed_forging_materials, list( ///the path of the item that will be created var/spawning_item //because who doesn't want to have a plasma sword? - material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_GREYSCALE | MATERIAL_COLOR + material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR /obj/item/forging/complete/examine(mob/user) . = ..() diff --git a/modular_doppler/reagent_forging/code/forge_weapons.dm b/modular_doppler/reagent_forging/code/forge_weapons.dm index af1602e9e3800..113d9d0138e93 100644 --- a/modular_doppler/reagent_forging/code/forge_weapons.dm +++ b/modular_doppler/reagent_forging/code/forge_weapons.dm @@ -3,7 +3,7 @@ lefthand_file = 'modular_doppler/reagent_forging/icons/mob/forge_weapon_l.dmi' righthand_file = 'modular_doppler/reagent_forging/icons/mob/forge_weapon_r.dmi' worn_icon = 'modular_doppler/reagent_forging/icons/mob/forge_weapon_worn.dmi' - material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_GREYSCALE | MATERIAL_COLOR + material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR obj_flags = UNIQUE_RENAME obj_flags_doppler = ANVIL_REPAIR toolspeed = 0.9 //Slightly better than avg. - A forged hammer or knife is probably better than a standard one @@ -209,7 +209,7 @@ transparent = FALSE max_integrity = 150 //over double that of a wooden one w_class = WEIGHT_CLASS_NORMAL - material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_GREYSCALE | MATERIAL_AFFECT_STATISTICS + material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_AFFECT_STATISTICS obj_flags_doppler = ANVIL_REPAIR shield_break_sound = 'sound/effects/bang.ogg' shield_break_leftover = /obj/item/forging/complete/plate diff --git a/modular_doppler/stone/code/stone.dm b/modular_doppler/stone/code/stone.dm index d5e8fa5e19704..1bd29c23d3dcd 100644 --- a/modular_doppler/stone/code/stone.dm +++ b/modular_doppler/stone/code/stone.dm @@ -41,7 +41,7 @@ GLOBAL_LIST_INIT(stone_recipes, list ( \ value_per_unit = 0.005 beauty_modifier = 0.01 color = "#59595a" - greyscale_colors = "#59595a" + greyscale_color = "#59595a" value_per_unit = 0.0025 armor_modifiers = list(MELEE = 0.75, BULLET = 0.5, LASER = 1.25, ENERGY = 0.5, BOMB = 0.5, BIO = 0.25, FIRE = 1.5, ACID = 1.5) beauty_modifier = 0.3 diff --git a/sound/creatures/cat/attribution.txt b/sound/creatures/cat/attribution.txt new file mode 100644 index 0000000000000..66180d00b10bb --- /dev/null +++ b/sound/creatures/cat/attribution.txt @@ -0,0 +1,10 @@ +{ +cat_meow1.ogg +cat_meow2.ogg +cat_meow3.ogg +cat_purr1.ogg +cat_purr2.ogg +cat_purr3.ogg +cat_purr4.ogg +} - made by sadboysuss, License: CC-BY-SA +oranges_meow.ogg - voiced by orangesnz, License: CC0 diff --git a/sound/creatures/cat/cat_meow1.ogg b/sound/creatures/cat/cat_meow1.ogg new file mode 100644 index 0000000000000..a1889e18fbf76 Binary files /dev/null and b/sound/creatures/cat/cat_meow1.ogg differ diff --git a/sound/creatures/cat/cat_meow2.ogg b/sound/creatures/cat/cat_meow2.ogg new file mode 100644 index 0000000000000..919a071a8719f Binary files /dev/null and b/sound/creatures/cat/cat_meow2.ogg differ diff --git a/sound/creatures/cat/cat_meow3.ogg b/sound/creatures/cat/cat_meow3.ogg new file mode 100644 index 0000000000000..dc8116109969b Binary files /dev/null and b/sound/creatures/cat/cat_meow3.ogg differ diff --git a/sound/creatures/cat/cat_purr1.ogg b/sound/creatures/cat/cat_purr1.ogg new file mode 100644 index 0000000000000..c90d78282bfb0 Binary files /dev/null and b/sound/creatures/cat/cat_purr1.ogg differ diff --git a/sound/creatures/cat/cat_purr2.ogg b/sound/creatures/cat/cat_purr2.ogg new file mode 100644 index 0000000000000..0b4aa509e91ca Binary files /dev/null and b/sound/creatures/cat/cat_purr2.ogg differ diff --git a/sound/creatures/cat/cat_purr3.ogg b/sound/creatures/cat/cat_purr3.ogg new file mode 100644 index 0000000000000..5a59adea58685 Binary files /dev/null and b/sound/creatures/cat/cat_purr3.ogg differ diff --git a/sound/creatures/cat/cat_purr4.ogg b/sound/creatures/cat/cat_purr4.ogg new file mode 100644 index 0000000000000..8ad7a05301834 Binary files /dev/null and b/sound/creatures/cat/cat_purr4.ogg differ diff --git a/sound/creatures/cat/oranges_meow1.ogg b/sound/creatures/cat/oranges_meow1.ogg new file mode 100644 index 0000000000000..19c74143495f6 Binary files /dev/null and b/sound/creatures/cat/oranges_meow1.ogg differ diff --git a/sound/items/handling/armor_rustle/plate_armor/attribution.txt b/sound/items/handling/armor_rustle/plate_armor/attribution.txt new file mode 100644 index 0000000000000..681f995687fb3 --- /dev/null +++ b/sound/items/handling/armor_rustle/plate_armor/attribution.txt @@ -0,0 +1,2 @@ +plate armor rustle: +armor.wav by juryduty -- https://freesound.org/s/180231/ -- License: Creative Commons 0 diff --git a/sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle1.ogg b/sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle1.ogg new file mode 100644 index 0000000000000..0d5d521ad5b1b Binary files /dev/null and b/sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle1.ogg differ diff --git a/sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle2.ogg b/sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle2.ogg new file mode 100644 index 0000000000000..dbbf25bbc3658 Binary files /dev/null and b/sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle2.ogg differ diff --git a/sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle3.ogg b/sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle3.ogg new file mode 100644 index 0000000000000..074e1c61197b6 Binary files /dev/null and b/sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle3.ogg differ diff --git a/sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle4.ogg b/sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle4.ogg new file mode 100644 index 0000000000000..6a105b85ac525 Binary files /dev/null and b/sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle4.ogg differ diff --git a/sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle5.ogg b/sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle5.ogg new file mode 100644 index 0000000000000..b2069180364e1 Binary files /dev/null and b/sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle5.ogg differ diff --git a/sound/effects/suitstep1.ogg b/sound/items/handling/armor_rustle/riot_armor/suitstep1.ogg similarity index 100% rename from sound/effects/suitstep1.ogg rename to sound/items/handling/armor_rustle/riot_armor/suitstep1.ogg diff --git a/sound/effects/suitstep2.ogg b/sound/items/handling/armor_rustle/riot_armor/suitstep2.ogg similarity index 100% rename from sound/effects/suitstep2.ogg rename to sound/items/handling/armor_rustle/riot_armor/suitstep2.ogg diff --git a/sound/items/handling/gun/ballistics/attribution.txt b/sound/items/handling/gun/ballistics/attribution.txt new file mode 100644 index 0000000000000..7311c7d8e3313 --- /dev/null +++ b/sound/items/handling/gun/ballistics/attribution.txt @@ -0,0 +1,17 @@ +shotgun_pickup1.ogg - https://freesound.org/people/PNMCarrieRailfan/sounds/681692/ , License: CC BY-NC 4.0 +shotgun_drop1.ogg - https://freesound.org/people/PNMCarrieRailfan/sounds/681690/ , License: CC BY-NC 4.0 +pistol_pickup1.ogg - https://freesound.org/people/PNMCarrieRailfan/sounds/682043/ , License: CC BY-NC 4.0 +pistol_drop1.ogg - https://freesound.org/people/PNMCarrieRailfan/sounds/682043/ , License: CC BY-NC 4.0 +rifle_pickup.ogg - https://freesound.org/people/the_Carlos/sounds/706972/ , License: CC BY 4.0 +rifle_drop1.ogg - https://freesound.org/people/the_Carlos/sounds/706972/ , License: CC BY 4.0 +smg_drop1.ogg - https://freesound.org/people/hyperix6/sounds/676588/ , License: CC0 +smg_pickup1.ogg - https://freesound.org/people/hyperix6/sounds/676588/ , License: CC0 +magazine_pickup1.ogg - https://freesound.org/people/PNMCarrieRailfan/sounds/681511/ , License: CC BY-NC 4.0 +magazine_drop1.ogg - https://freesound.org/people/PNMCarrieRailfan/sounds/681511/ , License: CC BY-NC 4.0 + + + + + + + diff --git a/sound/items/handling/gun/ballistics/magazine/magazine_drop1.ogg b/sound/items/handling/gun/ballistics/magazine/magazine_drop1.ogg new file mode 100644 index 0000000000000..024b0343cb27b Binary files /dev/null and b/sound/items/handling/gun/ballistics/magazine/magazine_drop1.ogg differ diff --git a/sound/items/handling/gun/ballistics/magazine/magazine_pickup1.ogg b/sound/items/handling/gun/ballistics/magazine/magazine_pickup1.ogg new file mode 100644 index 0000000000000..077f44a029d13 Binary files /dev/null and b/sound/items/handling/gun/ballistics/magazine/magazine_pickup1.ogg differ diff --git a/sound/items/handling/gun/ballistics/pistol/pistol_drop1.ogg b/sound/items/handling/gun/ballistics/pistol/pistol_drop1.ogg new file mode 100644 index 0000000000000..d0081424414ea Binary files /dev/null and b/sound/items/handling/gun/ballistics/pistol/pistol_drop1.ogg differ diff --git a/sound/items/handling/gun/ballistics/pistol/pistol_pickup1.ogg b/sound/items/handling/gun/ballistics/pistol/pistol_pickup1.ogg new file mode 100644 index 0000000000000..28922b2c2c26a Binary files /dev/null and b/sound/items/handling/gun/ballistics/pistol/pistol_pickup1.ogg differ diff --git a/sound/items/handling/gun/ballistics/rifle/rifle_drop1.ogg b/sound/items/handling/gun/ballistics/rifle/rifle_drop1.ogg new file mode 100644 index 0000000000000..eada3f9bf7692 Binary files /dev/null and b/sound/items/handling/gun/ballistics/rifle/rifle_drop1.ogg differ diff --git a/sound/items/handling/gun/ballistics/rifle/rifle_pickup1.ogg b/sound/items/handling/gun/ballistics/rifle/rifle_pickup1.ogg new file mode 100644 index 0000000000000..470c5e2309688 Binary files /dev/null and b/sound/items/handling/gun/ballistics/rifle/rifle_pickup1.ogg differ diff --git a/sound/items/handling/gun/ballistics/shotgun/shotgun_drop1.ogg b/sound/items/handling/gun/ballistics/shotgun/shotgun_drop1.ogg new file mode 100644 index 0000000000000..97d3a9e6fb946 Binary files /dev/null and b/sound/items/handling/gun/ballistics/shotgun/shotgun_drop1.ogg differ diff --git a/sound/items/handling/gun/ballistics/shotgun/shotgun_pickup1.ogg b/sound/items/handling/gun/ballistics/shotgun/shotgun_pickup1.ogg new file mode 100644 index 0000000000000..76c3f8ce2317e Binary files /dev/null and b/sound/items/handling/gun/ballistics/shotgun/shotgun_pickup1.ogg differ diff --git a/sound/items/handling/gun/ballistics/smg/smg_drop1.ogg b/sound/items/handling/gun/ballistics/smg/smg_drop1.ogg new file mode 100644 index 0000000000000..c0a39efbc2823 Binary files /dev/null and b/sound/items/handling/gun/ballistics/smg/smg_drop1.ogg differ diff --git a/sound/items/handling/gun/ballistics/smg/smg_pickup1.ogg b/sound/items/handling/gun/ballistics/smg/smg_pickup1.ogg new file mode 100644 index 0000000000000..1d732f893b1f3 Binary files /dev/null and b/sound/items/handling/gun/ballistics/smg/smg_pickup1.ogg differ diff --git a/sound/items/handling/reagent_containers/default/attribution.txt b/sound/items/handling/reagent_containers/default/attribution.txt new file mode 100644 index 0000000000000..102c46ad5919c --- /dev/null +++ b/sound/items/handling/reagent_containers/default/attribution.txt @@ -0,0 +1,2 @@ +default_liquid_slosh: +Liquid bottle shaking long.mp3 by Hope-Sounds -- https://freesound.org/s/502668/ -- License: Creative Commons 0 diff --git a/sound/items/handling/reagent_containers/default/default_liquid_slosh1.ogg b/sound/items/handling/reagent_containers/default/default_liquid_slosh1.ogg new file mode 100644 index 0000000000000..2177effd93077 Binary files /dev/null and b/sound/items/handling/reagent_containers/default/default_liquid_slosh1.ogg differ diff --git a/sound/items/handling/reagent_containers/default/default_liquid_slosh2.ogg b/sound/items/handling/reagent_containers/default/default_liquid_slosh2.ogg new file mode 100644 index 0000000000000..a641635ff0c07 Binary files /dev/null and b/sound/items/handling/reagent_containers/default/default_liquid_slosh2.ogg differ diff --git a/sound/items/handling/reagent_containers/default/default_liquid_slosh3.ogg b/sound/items/handling/reagent_containers/default/default_liquid_slosh3.ogg new file mode 100644 index 0000000000000..89eecf36337ad Binary files /dev/null and b/sound/items/handling/reagent_containers/default/default_liquid_slosh3.ogg differ diff --git a/sound/items/handling/reagent_containers/default/default_liquid_slosh4.ogg b/sound/items/handling/reagent_containers/default/default_liquid_slosh4.ogg new file mode 100644 index 0000000000000..feb7c0d29702e Binary files /dev/null and b/sound/items/handling/reagent_containers/default/default_liquid_slosh4.ogg differ diff --git a/sound/items/handling/reagent_containers/default/default_liquid_slosh5.ogg b/sound/items/handling/reagent_containers/default/default_liquid_slosh5.ogg new file mode 100644 index 0000000000000..b2ba3ee73c99b Binary files /dev/null and b/sound/items/handling/reagent_containers/default/default_liquid_slosh5.ogg differ diff --git a/sound/items/handling/reagent_containers/plastic_bottle/attribution.txt b/sound/items/handling/reagent_containers/plastic_bottle/attribution.txt new file mode 100644 index 0000000000000..dd3b21b412e39 --- /dev/null +++ b/sound/items/handling/reagent_containers/plastic_bottle/attribution.txt @@ -0,0 +1,2 @@ +plastic_bottle_liquid_slosh: +liquid in bottle shaking by mrrap4food -- https://freesound.org/s/470606/ -- License: Creative Commons 0 diff --git a/sound/items/handling/reagent_containers/plastic_bottle/plastic_bottle_liquid_slosh1.ogg b/sound/items/handling/reagent_containers/plastic_bottle/plastic_bottle_liquid_slosh1.ogg new file mode 100644 index 0000000000000..597a7b2fb5f8a Binary files /dev/null and b/sound/items/handling/reagent_containers/plastic_bottle/plastic_bottle_liquid_slosh1.ogg differ diff --git a/sound/items/handling/reagent_containers/plastic_bottle/plastic_bottle_liquid_slosh2.ogg b/sound/items/handling/reagent_containers/plastic_bottle/plastic_bottle_liquid_slosh2.ogg new file mode 100644 index 0000000000000..4f8eb03293f34 Binary files /dev/null and b/sound/items/handling/reagent_containers/plastic_bottle/plastic_bottle_liquid_slosh2.ogg differ diff --git a/sound/mobs/humanoids/human/snore/attribution.txt b/sound/mobs/humanoids/human/snore/attribution.txt new file mode 100644 index 0000000000000..e462719312383 --- /dev/null +++ b/sound/mobs/humanoids/human/snore/attribution.txt @@ -0,0 +1,2 @@ +male snores voiced by sadboysuss, license - CC-BY-SA +female snores and mimimi voiced by redemptionarc, license - CC-BY-SA diff --git a/sound/mobs/humanoids/human/snore/snore_female1.ogg b/sound/mobs/humanoids/human/snore/snore_female1.ogg new file mode 100644 index 0000000000000..51cfeb0424fa6 Binary files /dev/null and b/sound/mobs/humanoids/human/snore/snore_female1.ogg differ diff --git a/sound/mobs/humanoids/human/snore/snore_female2.ogg b/sound/mobs/humanoids/human/snore/snore_female2.ogg new file mode 100644 index 0000000000000..c5a9b44a4b896 Binary files /dev/null and b/sound/mobs/humanoids/human/snore/snore_female2.ogg differ diff --git a/sound/mobs/humanoids/human/snore/snore_female3.ogg b/sound/mobs/humanoids/human/snore/snore_female3.ogg new file mode 100644 index 0000000000000..68adb30fb1e29 Binary files /dev/null and b/sound/mobs/humanoids/human/snore/snore_female3.ogg differ diff --git a/sound/mobs/humanoids/human/snore/snore_male1.ogg b/sound/mobs/humanoids/human/snore/snore_male1.ogg new file mode 100644 index 0000000000000..3c9dfe97be8e2 Binary files /dev/null and b/sound/mobs/humanoids/human/snore/snore_male1.ogg differ diff --git a/sound/mobs/humanoids/human/snore/snore_male2.ogg b/sound/mobs/humanoids/human/snore/snore_male2.ogg new file mode 100644 index 0000000000000..de5993e518799 Binary files /dev/null and b/sound/mobs/humanoids/human/snore/snore_male2.ogg differ diff --git a/sound/mobs/humanoids/human/snore/snore_male3.ogg b/sound/mobs/humanoids/human/snore/snore_male3.ogg new file mode 100644 index 0000000000000..cd63a7fb4cfd0 Binary files /dev/null and b/sound/mobs/humanoids/human/snore/snore_male3.ogg differ diff --git a/sound/mobs/humanoids/human/snore/snore_male4.ogg b/sound/mobs/humanoids/human/snore/snore_male4.ogg new file mode 100644 index 0000000000000..fce8320a6c7e2 Binary files /dev/null and b/sound/mobs/humanoids/human/snore/snore_male4.ogg differ diff --git a/sound/mobs/humanoids/human/snore/snore_male5.ogg b/sound/mobs/humanoids/human/snore/snore_male5.ogg new file mode 100644 index 0000000000000..6773add51eccb Binary files /dev/null and b/sound/mobs/humanoids/human/snore/snore_male5.ogg differ diff --git a/sound/mobs/humanoids/human/snore/snore_mimimi1.ogg b/sound/mobs/humanoids/human/snore/snore_mimimi1.ogg new file mode 100644 index 0000000000000..31f84ec2a14aa Binary files /dev/null and b/sound/mobs/humanoids/human/snore/snore_mimimi1.ogg differ diff --git a/sound/mobs/humanoids/human/snore/snore_mimimi2.ogg b/sound/mobs/humanoids/human/snore/snore_mimimi2.ogg new file mode 100644 index 0000000000000..21d4f9f07d4f2 Binary files /dev/null and b/sound/mobs/humanoids/human/snore/snore_mimimi2.ogg differ diff --git a/strings/fishing_tips.txt b/strings/fishing_tips.txt index 6b25cc5e5391c..f7143c8796665 100644 --- a/strings/fishing_tips.txt +++ b/strings/fishing_tips.txt @@ -35,6 +35,7 @@ Some species of fish can be bred into new species under the right conditions. Most fish don't survive outside water, so get them somewhere safe like an aquarium or a fish case, or even a toilet or a moisture trap! No matter how you look at it, most people won't care about fishing. Don't let that stop you. They're just jealous. To fish on ice you have to puncture the ice layer with a pick or shovel first. +Fishing rods are particularly effective melee weapons against spacemen deeply infused with fish DNA from genetics. Depending on the kinds of fish inside it and whether they're alive or dead, an aquarium can improve the beauty of the room or worsen it. Almost all fish can be ground in an All-in-one-Grinder. Don't think too hard about how you're fitting a giant fish into a blender. Nanotrasen technology is weird like that. The sludgefish from the toilets can be used as a steady supply of cheap fish and fillets due to its self-reproducing behaviour. However it's quite fragile. @@ -43,7 +44,10 @@ The legendary fishing hat isn't just cosmetic. Space carps (as well as young lob Have you ever heard a lobster or crab talk? Well, neither have I, but they say they're quite the fishy punsters. You can get an experiscanner from science to perform fish scanning experiments, which can unlock more modules for the fishing portal, as well as fishing technology nodes (better equipment) to research. Fish is, of course, edible. Is it safe to eat raw? Well, if you've strong stomach, otherwise your best option is to cook it for a at least half a spessman minute if you don't want to catch nasty diseases. -After researching the Advanced Fishing Technology Node, you can print special fishing gloves that let you fish without having to carry around a fishing rod. There's one pair that even trains athletics on top of fishing.You can get an experiscanner from science to perform fish scanning experiments, which can unlock more modules for the fishing portal, as well as fishing technology nodes (better equipment) for research. -If you have enough credits, you can buy a set of fishing lures from cargo. Each lure allows you to catch different species of fish and won't get consumed, however they need to be spun at intervals to work. +After researching the Advanced Fishing Technology Node, you can print special fishing gloves that let you fish without having to carry around a fishing rod. There's one pair that even trains athletics on top of fishing. You can get an experiscanner from science to perform fish scanning experiments, which can unlock more modules for the fishing portal, as well as fishing technology nodes (better equipment) for research. +If you have enough credits, you can buy a set of fishing lures from cargo (or the library vending machine). Each lure allows you to catch different species of fish and won't get consumed, however they need to be spun at intervals to work. Various clothing and handheld items, as well as chairs you sit on, can make fishing easier (or sometimes harder). A trained fisherman can tell what can help and what won't, so keep an eye out. -This may sound silly, but (live) squids and their ink sacs can be used as weapons to temporarily blind foes. \ No newline at end of file +This may sound silly, but (live) squids and their ink sacs can be used as weapons to temporarily blind foes. +Got a bioelectricity generator aquarium but no electrogenic fish? Worry not, you can always feed your fish some teslium or liquid electricity to temporarily grant them (slightly less powerful) eletrogenesis. It'll also gradually hurt them however. +Fish can grow in size and weight if you fed them somewhat frequently. Giving them growth serum (from fly amanita) will also boost the rate at which they grow. +Feeding a fish mutagen can triple the probability of generating evolved offsprings, provided it has an evolution. \ No newline at end of file diff --git a/strings/tcg/keywords.json b/strings/tcg/keywords.json index 854ac936fef1e..869dc8dbe607a 100644 --- a/strings/tcg/keywords.json +++ b/strings/tcg/keywords.json @@ -1,18 +1,18 @@ { - "Asimov": "Creatures possessing this trait cannot attack or defend against creatures with the Human subtype", + "Asimov": "Does not deal damage to other creature cards, only to players.", "Blocker": "The creature cannot declare attacks, but can defend", - "Changeling": "This creature possesses all creature subtypes simultaneously. Any effects which affect a specific subtype apply to Changelings", - "Clockwork": "The creature can copy a single keyword on another creature on the field, until they lose the clockwork keyword or leave the field", - "Deadeye": "This creature can always hit opponents, regardless of effects or immunities", + "Changeling": "This creature possesses all creature subtypes simultaneously, even outside of the field. Any effects which affect a specific subtype apply to Changelings", + "Clockwork": "On Summon: The creature can copy a single keyword on another creature on the field, until they lose the clockwork keyword or leave the field", + "Deadeye": "The following effect triggers when the creature damages the opponent.", "Faction": "Groupings of cards that can often share effects and traits together", "First Strike": "This creature has attack priority in combat", - "Fury": "The creature must attack at every possibility", - "Graytide": "When this creature enters the battlefield, it gains +1/+1 for the number of creatures on your side of the field with Graytide, until the end of the turn", + "Fury": "This creature is not tapped when it kills another unit in combat.", + "Graytide": "This creature gains +1/+1 for the number of other creatures on your side of the field with Graytide.", "Hivemind": "The creature enters combat with a hivemind token on it.The first time this card would take damage, remove that token instead. This does not apply to immediate removal effects, only points of damage", "Holy": "Immunity to all event cards", "Immunity": "The creature cannot be affected by card effects or combat of its immunity type. This includes both friendly and opposing effects", "On Equip": "This effect is activated once its item cost is paid and it enters the battlefield, equipping itself to a chosen card on your side of the field (Unless otherwise stated)", "On Summon": "This effect is activated once its creature cost is paid and it enters the battlefield", - "Squad Tactics": "When this creature attacks an opponent's creature and defeats it in combat, the owner of the defeated card takes 1 lifeshard of damage from combat", - "Taunt": "All opposing creature attacks must be directed towards the creature with Taunt" + "Squad Tactics": "This effect is activated when a card is added to your hand.", + "Taunt": "The following effect triggers when this card is on the field and any other card is added to your hand." } diff --git a/strings/tcg/set_one.json b/strings/tcg/set_one.json index de24543a66b96..73851198cd267 100644 --- a/strings/tcg/set_one.json +++ b/strings/tcg/set_one.json @@ -13,9 +13,9 @@ "id": "AI", "name": "AI", "desc": "The latest generation of NT's top secret artificial intelligence project, this time with actual human brains in a jar! Don't tell the press though.", - "rules": "{$Asimov}", + "rules": "{$Asimov} {$Fury}", "icon_state": "ai", - "power": "3", + "power": "5", "resolve": "6", "faction": "Science", "summoncost": "5", @@ -29,14 +29,14 @@ "id": "stickman", "name": "Angry Stickman", "desc": "Sure, he's flat and crudely drawn, but watch out! He's a menace!", - "rules": "{$On Summon}: If another 'Angry Stickman' card has been destroyed, you may summon it for at double cost. This ability may be activated only once per turn.", + "rules": "{$On Summon}: You can pay 1 plasma to summon an Angry Stickman from the discard pile.", "icon_state": "angry_stickman", "power": "1", "resolve": "1", "faction": "Xeno", "summoncost": "1", "cardtype": "Creature", - "cardsubtype": "Construct", + "cardsubtype": "Wizardry", "rarity": "uncommon", "summon_icon_file": "icons/mob/simple/animal.dmi", "summon_icon_state": "stickman" @@ -45,7 +45,7 @@ "id": "changeling", "name": "Armoured Changeling", "desc": "The strange creatures known as changelings have been known to develop natural armour as a defense mechanism when in combat.", - "rules": "{$Changeling}", + "rules": "{$Changeling} {$Deadeye}: Add 1 creature with Changeling from your Deck to your hand.", "icon_state": "armored_changeling", "power": "2", "resolve": "8", @@ -61,14 +61,14 @@ "id": "assistant", "name": "Staff Assistant", "desc": "The lowest ladder on the Nanotrasen Employment Ladder, Staff Assistants are employed to help out with tasks deemed 'too menial for robots'.", - "rules": "{$Graytide}, for every card with '{$Graytide}', this card has +1/+1 on the field.", + "rules": "{$Graytide}. The buff this card gains from Graytide is doubled.", "icon_state": "assistant", "power": "1", "resolve": "1", "faction": "Service", "summoncost": "1", "cardtype": "Creature", - "cardsubtype": "Human Employee", + "cardsubtype": "Maintenance Service", "rarity": "common", "summon_icon_state": "Assistant" }, @@ -76,14 +76,14 @@ "id": "atmos_tech", "name": "Atmospheric Technician", "desc": "The Atmospheric Technicians are tasked with keeping the station's air clean, breathable, and, most importantly, devoid of plasma.", - "rules": "{$On Summon}: Search your deck for an Atmospherics Battlefield card, and add it to your hand. Shuffle your deck afterward.", + "rules": "{$On Summon}: Search your deck for a Battlefield card, and add it to your hand. Shuffle your deck afterward.", "icon_state": "atmos_tech", - "power": "2", - "resolve": "3", + "power": "3", + "resolve": "2", "faction": "Engineering", - "summoncost": "4", + "summoncost": "2", "cardtype": "Creature", - "cardsubtype": "Human Engineer", + "cardsubtype": "Atmospherics Engineering", "rarity": "common", "summon_icon_state": "Atmospheric Technician" }, @@ -91,14 +91,14 @@ "id": "bartender", "name": "Bartender", "desc": "Prior to the introduction of on-station psychologists, the Bartender served to alleviate many employees' woes and fears. Remember, always drink responsibly.", - "rules": "", + "rules": "All your other creatures gain +1 power.", "icon_state": "bartender", - "power": "3", + "power": "2", "resolve": "2", "faction": "Service", - "summoncost": "3", + "summoncost": "2", "cardtype": "Creature", - "cardsubtype": "Human Employee", + "cardsubtype": "Service Bar", "rarity": "common", "summon_icon_state": "Bartender" }, @@ -106,14 +106,14 @@ "id": "botanist", "name": "Botanist", "desc": "The Botanist is in charge of keeping the station's food supply happy, healthy, and preferably not laced with hallucinogens.", - "rules": "", + "rules": "Start of turn: Heal 1 lifeshard.", "icon_state": "botanist", - "power": "1", - "resolve": "4", + "power": "0", + "resolve": "3", "faction": "Service", "summoncost": "1", "cardtype": "Creature", - "cardsubtype": "Human Employee", + "cardsubtype": "Service Bar Plant", "rarity": "common", "summon_icon_state": "Botanist" }, @@ -121,14 +121,14 @@ "id": "captain", "name": "Captain", "desc": "Every Captain is expected to lay down their life for their assigned station. Any Captain who returns to Centcom alive without permission is ceremonially executed before being cloned and stripped of rank.", - "rules": "Tap this card: inflict -1/-1 to an opposing creature card.", + "rules": "Tap: Reduce the power of all opponent creatures to 0 for this turn.", "icon_state": "captain", "power": "5", "resolve": "5", "faction": "Command", "summoncost": "7", "cardtype": "Creature", - "cardsubtype": "Human Commander", + "cardsubtype": "Command", "rarity": "rare", "summon_icon_state": "Captain" }, @@ -138,26 +138,26 @@ "desc": "A heavily customized Apadyne Technologies Mk.2 R.I.O.T. Suit, rebuilt and refitted to Nanotrasen's highest standards for issue to Station Captains.", "rules": "{$On Equip}: tap the equipped card for 2 turns, without triggering the target card's effects.", "icon_state": "captain_hardsuit", - "power": "-1", - "resolve": "5", + "power": "0", + "resolve": "4", "faction": "Command", - "summoncost": "3", + "summoncost": "1", "cardtype": "Equipment", - "cardsubtype": "Armour", + "cardsubtype": "Command", "rarity": "epic" }, { "id": "cargo_tech", "name": "Cargo Technician", "desc": "The grunts of Cargo. Any reports that Cargo Technicians are frequently overcome by revolutionary fervour are exaggerated.", - "rules": "Once per turn, you may give 'Cargo Technician' -1/0 until the start of your next turn and gain 1 mana.", + "rules": "Tap: Gain 1 plasma.", "icon_state": "cargo_tech", - "power": "3", - "resolve": "1", + "power": "1", + "resolve": "2", "faction": "Cargo", "summoncost": "2", "cardtype": "Creature", - "cardsubtype": "Human Employee", + "cardsubtype": "Cargo Maintenance", "rarity": "common", "summon_icon_state": "Cargo Technician" }, @@ -170,23 +170,23 @@ "power": "2", "resolve": "2", "faction": "Service", - "summoncost": "2", + "summoncost": "3", "cardtype": "Equipment", - "cardsubtype": "Armour", + "cardsubtype": "Service Wizardry", "rarity": "common" }, { "id": "chemist", "name": "Chemist", "desc": "Chemists are encouraged to not set up illicit methamphetamine factories on the company's dime.", - "rules": "Tap this card: flip a coin. If heads: a friendly Medical {$Faction} card gains 0/+2. If tails, an opponents creature of your choice gains +2/0.", + "rules": "Tap: Give another unit +2/+2. Destroy it at the end of the turn.", "icon_state": "chemist", "power": "0", "resolve": "3", "faction": "Medical", "summoncost": "2", "cardtype": "Creature", - "cardsubtype": "Human Doctor", + "cardsubtype": "Medical", "rarity": "common", "summon_icon_state": "Chemist" }, @@ -194,14 +194,14 @@ "id": "CE", "name": "Chief Engineer", "desc": "The Chief Engineer is in charge of keeping the station powered and intact.", - "rules": "If a battlefield card would otherwise be destroyed by an opponent's card effect, you may sacrifice an Engineering faction card of yours in play to negate the battlefield's destruction.", + "rules": "Battlefield cards you control cannot be destroyed.", "icon_state": "ce", - "power": "3", - "resolve": "6", + "power": "2", + "resolve": "2", "faction": "Engineering", - "summoncost": "5", + "summoncost": "1", "cardtype": "Creature", - "cardsubtype": "Human Engineer", + "cardsubtype": "Command Engineer", "rarity": "uncommon", "summon_icon_state": "Chief Engineer" }, @@ -209,14 +209,14 @@ "id": "ce_suit", "name": "Nakamura Engineering R.I.G.Suit (Advanced)", "desc": "An updated version of Nakamura Engineering's R.I.G.Suit, fitted with advanced radiation shielding and extra armour.", - "rules": "Tap this card: tap the equipped creature. The equipped creature avoids the effects of the active battlefield until removed from the field.", + "rules": "On Equip: Tap the equipped creature. It gains Immunity from Battlefields.", "icon_state": "ce_hardsuit", - "power": "0", - "resolve": "3", + "power": "1", + "resolve": "2", "faction": "Engineering", - "summoncost": "3", + "summoncost": "1", "cardtype": "Equipment", - "cardsubtype": "Armour", + "cardsubtype": "Engineering Syndicate Cybersun", "rarity": "rare" }, { @@ -230,7 +230,7 @@ "faction": "Medical", "summoncost": "5", "cardtype": "Creature", - "cardsubtype": "Human Doctor", + "cardsubtype": "Medical Command", "rarity": "common", "summon_icon_state": "Chief Medical Officer" }, @@ -238,28 +238,28 @@ "id": "cmo_suit", "name": "DeForest Medical Corporation 'Lifesaver' Carapace", "desc": "An advanced voidsuit designed for emergency medical personnel. Features include a built-in medical HUD and advanced medical gauntlets.", - "rules": "Tap this card: tap the equipped creature and re-equip 'DeForest Medical Corporation 'Lifesaver' Carapace' on a different creature on your side of the field. This effect may be activated once per turn.", + "rules": "Once per turn: equip 'DeForest Medical Corporation 'Lifesaver' Carapace' on a different creature on your side of the field.", "icon_state": "cmo_hardsuit", "power": "1", "resolve": "3", "faction": "Medical", - "summoncost": "3", + "summoncost": "2", "cardtype": "Equipment", - "cardsubtype": "Armour", + "cardsubtype": "Medical", "rarity": "uncommon" }, { "id": "chrono", "name": "Chrono Legionnaire", "desc": "Currently in the earliest stages of development, the Chrono Legionnaire project is expected to weaponize time itself.", - "rules": "If this card is destroyed or discarded, flip 3 coins. If the result has 2 or more heads, add this card back to your hand. Otherwise, send it to your graveyard.", + "rules": "If this card is destroyed flip a coin. If the result is heads, add this card back to your hand.", "icon_state": "chrono_legionnaire", - "power": "6", - "resolve": "2", + "power": "3", + "resolve": "3", "faction": "Security", - "summoncost": "4", + "summoncost": "3", "cardtype": "Creature", - "cardsubtype": "Human Soldier", + "cardsubtype": "Wizardry Maintenance", "rarity": "epic", "summon_icon_file": "icons/obj/toys/tcgsummons.dmi", "summon_icon_state": "chrono" @@ -268,14 +268,14 @@ "id": "sloth", "name": "Citrus", "desc": "Cargo's happy sloth pal. Known for his cute sweater and always getting in the way.", - "rules": "Tap this card: Tap an opponent's card until the start of your next turn", + "rules": "Tap: Tap an opponent's card until the start of your next turn", "icon_state": "citrus", "power": "0", "resolve": "3", "faction": "Cargo", "summoncost": "2", "cardtype": "Creature", - "cardsubtype": "Sloth", + "cardsubtype": "Cargo Animal", "rarity": "common", "summon_icon_file": "icons/mob/simple/pets.dmi", "summon_icon_state": "cool_sloth" @@ -286,12 +286,12 @@ "desc": "Every Nanotrasen station has a clown on board, as high command believes that a source of entertainment will reduce instances of murder-suicide on board Spinward Stations. The results of this hypothesis are, as of yet, unproven.", "rules": "{$Taunt}", "icon_state": "clown", - "power": "2", - "resolve": "4", + "power": "1", + "resolve": "3", "faction": "Service", "summoncost": "2", "cardtype": "Creature", - "cardsubtype": "Clown", + "cardsubtype": "Bar Maintenance Abomination Clown", "rarity": "common", "summon_icon_state": "Clown" }, @@ -306,7 +306,7 @@ "faction": "Service", "summoncost": "2", "cardtype": "Creature", - "cardsubtype": "Silicon Clown", + "cardsubtype": "Silicon Bar Clown", "rarity": "uncommon", "summon_icon_file": "icons/mob/silicon/robots.dmi", "summon_icon_state": "clown" @@ -321,7 +321,7 @@ "resolve": "0", "faction": "Service", "summoncost": "1", - "cardtype": "Equipment", + "cardtype": "Clown", "cardsubtype": "Armour", "rarity": "epic" }, @@ -329,7 +329,7 @@ "id": "abductor_armour", "name": "Abductor Combat Armour", "desc": "Recovered from the strange alien species known as the Abductors, this armour is made from an extremely tough yet flexible material that has been dubbed as Alien Alloy by researchers.", - "rules": "{$On Equip}: give the equipped unit Effect {$Immunity} and Spell {$Immunity}.", + "rules": "{$On Equip}: give the equipped unit Holy.", "icon_state": "abductor_combat", "power": "1", "resolve": "3", @@ -350,7 +350,7 @@ "faction": "Service", "summoncost": "3", "cardtype": "Creature", - "cardsubtype": "Human Employee", + "cardsubtype": "Bar Plants", "rarity": "common", "summon_icon_state": "Cook" }, @@ -365,21 +365,21 @@ "faction": "Syndicate", "summoncost": "1", "cardtype": "Equipment", - "cardsubtype": "Armour", + "cardsubtype": "Wizardry", "rarity": "rare" }, { "id": "curator", "name": "Curator", "desc": "In Nanotrasen polls, the Curator has ranked as the most pointless job on station, much to the ire of the Curator's union. Thankfully, we don't have to listen to them.", - "rules": "{$On Summon}: Draw 1 card: if it's an event card, discard it.", + "rules": "{$On Summon}: Draw 1 card.", "icon_state": "curator", "power": "1", "resolve": "1", "faction": "Service", - "summoncost": "2", + "summoncost": "1", "cardtype": "Creature", - "cardsubtype": "Human Worker", + "cardsubtype": "Wizardry", "rarity": "common", "summon_icon_state": "Curator" }, @@ -394,7 +394,7 @@ "faction": "Science", "summoncost": "2", "cardtype": "Creature", - "cardsubtype": "Silicon Corgi", + "cardsubtype": "Silicon Animal", "rarity": "rare", "summon_icon_file": "icons/obj/toys/tcgsummons.dmi", "summon_icon_state": "borgi" @@ -405,26 +405,26 @@ "desc": "The most advanced set of armour available for purchase from Apadyne Technologies, the Mk.3 R.I.O.T. Carapace is issued to Nanotrasen's most elite forces.", "rules": "{$On Equip}: if the equipped creature is of the Security faction, it gains {$Taunt}.", "icon_state": "deathsquad", - "power": "3", - "resolve": "3", + "power": "2", + "resolve": "1", "faction": "Security", - "summoncost": "1", + "summoncost": "2", "cardtype": "Equipment", - "cardsubtype": "Armour", + "cardsubtype": "Security ERT", "rarity": "epic" }, { "id": "det", "name": "Detective", "desc": "Nanotrasen hires nothing but the best detectives to investigate crime on our stations. A penchant for cigarettes and outdated fashion isn't mandatory, but is appreciated.", - "rules": "{$Deadeye}", + "rules": "{$Deadeye}: Draw 1 card. Cannot be attacked if you have other untapped creatures.", "icon_state": "detective", "power": "3", "resolve": "2", "faction": "Security", - "summoncost": "5", + "summoncost": "3", "cardtype": "Creature", - "cardsubtype": "Human Officer", + "cardsubtype": "Maintenance Bar", "rarity": "uncommon", "summon_icon_state": "Detective" }, @@ -437,9 +437,9 @@ "power": "5", "resolve": "5", "faction": "Syndicate", - "summoncost": "7", + "summoncost": "8", "cardtype": "Creature", - "cardsubtype": "Syndicate Soldier", + "cardsubtype": "Syndicate Cybersun", "rarity": "rare", "summon_icon_file": "icons/obj/toys/tcgsummons.dmi", "summon_icon_state": "syndicate_stormtrooper_sword" @@ -448,14 +448,14 @@ "id": "engiborg", "name": "Cyborg (Engineering Shell)", "desc": "A common sight on Nanotrasen Stations, Engineering Shells maintain critical station systems in hazardous conditions.", - "rules": "{$Asimov}", + "rules": "{$Asimov} Tap: Draw 1 card.", "icon_state": "borg_engi", "power": "2", "resolve": "2", "faction": "Engineering", "summoncost": "2", "cardtype": "Creature", - "cardsubtype": "Silicon", + "cardsubtype": "Silicon Engineering Atmosian", "rarity": "common", "summon_icon_file": "icons/mob/silicon/robots.dmi", "summon_icon_state": "engineer" @@ -464,41 +464,41 @@ "id": "ert_command", "name": "NT P.A.V. Suit (Command)", "desc": "Issued to members of Emergency Response Teams, the P.A.V. Suit gives superior protection from any threat the galaxy can throw at it. This particular model is outfitted with a sidearm holster and a sleek blue finish.", - "rules": "While equipped, give the equipped unit {$Squad Tactics} and {$First Strike}.", + "rules": "While equipped, give the equipped unit {$First Strike}.", "icon_state": "ert_command", - "power": "2", - "resolve": "2", + "power": "0", + "resolve": "0", "faction": "Command", "summoncost": "2", "cardtype": "Equipment", - "cardsubtype": "Armour", + "cardsubtype": "Command ERT", "rarity": "rare" }, { "id": "ert_engi", "name": "NT P.A.V. Suit (Engineering)", "desc": "Issued to members of Emergency Response Teams, the P.A.V. Suit gives superior protection from any threat the galaxy can throw at it. This particular model is outfitted with a welding screen and a flashy yellow finish.", - "rules": "While equipped, give the equipped unit {$Squad Tactics}.", + "rules": "While equipped, give the equipped unit {$Squad Tactics}: Gain +1/+1 until the end of the turn.", "icon_state": "ert_engi", "power": "1", "resolve": "1", "faction": "Engineering", "summoncost": "1", "cardtype": "Equipment", - "cardsubtype": "Armour", + "cardsubtype": "ERT Atmospherics", "rarity": "uncommon" }, { "id": "ert_med", "name": "NT P.A.V. Suit (Medical)", "desc": "Issued to members of Emergency Response Teams, the P.A.V. Suit gives superior protection from any threat the galaxy can throw at it. This particular model is outfitted with a sterile coating and a calming white finish.", - "rules": "While equipped, give the equipped unit {$Squad Tactics}.", + "rules": "Whenever the equipped unit deals damage it heals you (the player) for that amount.", "icon_state": "ert_med", "power": "1", - "resolve": "2", + "resolve": "1", "faction": "Medical", "summoncost": "2", - "cardtype": "Equipment", + "cardtype": "ERT Medical", "cardsubtype": "Armour", "rarity": "uncommon" }, @@ -506,28 +506,28 @@ "id": "ert_sec", "name": "NT P.A.V. Suit (Security)", "desc": "Issued to members of Emergency Response Teams, the P.A.V. Suit gives superior protection from any threat the galaxy can throw at it. This particular model is outfitted with bulletproof padding and an intimidating red finish.", - "rules": "While equipped, give the equipped unit {$Squad Tactics}.", + "rules": "While equipped, give the equipped unit {$Fury}.", "icon_state": "ert_sec", - "power": "2", - "resolve": "1", + "power": "-1", + "resolve": "0", "faction": "Security", "summoncost": "2", "cardtype": "Equipment", - "cardsubtype": "Armour", + "cardsubtype": "ERT Security", "rarity": "uncommon" }, { "id": "explorer", "name": "Explorer", "desc": "The Nanotrasen Explorers Corps boldly goes where humanity has never gone before. Or would, if they weren't buried under mounds of bureaucracy.", - "rules": "You may tap this card: Flip a coin, if heads, gain 4 mana this turn, if tails, tap this card for 2 turns.", + "rules": "Tap: Flip a coin, if heads, gain 1 plasma.", "icon_state": "explorer", "power": "2", "resolve": "2", "faction": "Cargo", - "summoncost": "2", + "summoncost": "1", "cardtype": "Creature", - "cardsubtype": "Human Explorer", + "cardsubtype": "Atmospherics", "rarity": "legendary", "summon_icon_file": "icons/obj/toys/tcgsummons.dmi", "summon_icon_state": "explorer" @@ -541,7 +541,7 @@ "power": "3", "resolve": "3", "faction": "Science", - "summoncost": "2", + "summoncost": "1", "cardtype": "Creature", "cardsubtype": "Silicon", "rarity": "common", @@ -552,14 +552,14 @@ "id": "geneticist", "name": "Geneticist", "desc": "Geneticists are tasked with manipulating human DNA to produce special effects. Nanotrasen maintains a strict 'no superhero' policy for mutations, following the Superhero Civil War of 2150.", - "rules": "You may tap this card and pay 3 mana: Give a friendly creature {$Hivemind} until this card leaves the field.", + "rules": "Tap: Give a friendly creature {$Hivemind} until this card leaves the field.", "icon_state": "geneticist", - "power": "3", - "resolve": "4", + "power": "2", + "resolve": "3", "faction": "Science", "summoncost": "3", "cardtype": "Creature", - "cardsubtype": "Human Scientist", + "cardsubtype": "Science Abomination", "rarity": "common", "summon_icon_state": "Geneticist" }, @@ -567,14 +567,14 @@ "id": "med_geneticist", "name": "Geneticist", "desc": "Geneticists are tasked with manipulating human DNA to produce special effects. Nanotrasen maintains a strict 'no superhero' policy for mutations, following the Superhero Civil War of 2150.", - "rules": "{$Graytide}, {$Hivemind}", + "rules": "All friendly creatures everywhere gain {$Hivemind} while this card is on the field.", "icon_state": "geneticist_med", - "power": "3", - "resolve": "6", + "power": "2", + "resolve": "3", "faction": "Medical", - "summoncost": "8", + "summoncost": "3", "cardtype": "Creature", - "cardsubtype": "Human Doctor", + "cardsubtype": "Science Abomination", "rarity": "misprint", "summon_icon_state": "Geneticist" }, @@ -582,14 +582,14 @@ "id": "spookian", "name": "Ghost Ian", "desc": "Oh my god! Ian's dead!", - "rules": "{$On Summon}: Search your deck for a battlefield, and add it to your hand. Shuffle your deck afterwards.", + "rules": "When destroyed: Add this card back to your hand.", "icon_state": "ian_ghost", "power": "1", "resolve": "1", "faction": "Service", - "summoncost": "3", + "summoncost": "2", "cardtype": "Creature", - "cardsubtype": "Spirit Corgi", + "cardsubtype": "Wizardry Animal", "rarity": "epic", "summon_icon_file": "icons/obj/toys/tcgsummons.dmi", "summon_icon_state": "ghost" @@ -598,14 +598,14 @@ "id": "HOP", "name": "Head of Personnel", "desc": "The head of the Cargo and Service Departments, guardian of all access, and Ian's lovable, yet dumb, sidekick.", - "rules": "Once per turn: Select a friendly creature card. That card gains {$Changeling}.", + "rules": "Tap: Another animal you control gains Holy and cannot be damaged for the rest of this turn.", "icon_state": "hop", - "power": "4", - "resolve": "3", + "power": "2", + "resolve": "2", "faction": "Service", - "summoncost": "7", + "summoncost": "1", "cardtype": "Creature", - "cardsubtype": "Human Commander", + "cardsubtype": "Command Animal", "rarity": "uncommon", "summon_icon_state": "Head of Personnel" }, @@ -613,14 +613,14 @@ "id": "HOS", "name": "Head of Security", "desc": "Nanotrasen hires most heads of staff based on their qualifications as being amicable, good at conflict resolution, ability to handle high-stakes situations, humanity, and desire to learn. Heads of Security only need a highschool degree.", - "rules": "{$On Summon}: Select a card type. That card type now costs 1 extra mana to summon. This effect persists until Head of Security is removed from the battlefield.", + "rules": "Must declare a direct attack when attacking (but can still be blocked). {$Deadeye}: Deal 3 damage to your opponent or a unit. {$Fury} ", "icon_state": "hos", "power": "4", - "resolve": "4", + "resolve": "6", "faction": "Security", "summoncost": "7", "cardtype": "Creature", - "cardsubtype": "Human Officer", + "cardsubtype": "Command Security", "rarity": "uncommon", "summon_icon_state": "Head of Security" }, @@ -628,28 +628,28 @@ "id": "hos_suit", "name": "Apadyne Technologies 'Tyrant' Class Hardshell", "desc": "The distinctive shape of the Tyrant Class Hardshell is caused, in part, by the large amount of kevlar reinforcement and the ablative armour layer. Perhaps more importantly, it also looks rad.", - "rules": "Grant the equip card {$Fury} until this card is removed from play.", + "rules": "When the equipped card destroys a creature: It deals 1 damage to another creature.", "icon_state": "hos_hardsuit", - "power": "4", - "resolve": "2", + "power": "1", + "resolve": "1", "faction": "Security", - "summoncost": "5", + "summoncost": "3", "cardtype": "Equipment", - "cardsubtype": "Armour", + "cardsubtype": "Command Security", "rarity": "rare" }, { "id": "ian", "name": "Ian", "desc": "This adorable corgi has become the defacto mascot of the Spinward Stations to many. He comes in many forms, many sizes, and many shapes, but he's still just as lovable. Hand wash only.", - "rules": "{$Holy}, You may Sacrifice this card on the field: Play a Command card from your hand for free.", + "rules": "{$Holy} On destroyed: Both players can summon a creature from their hand for free.", "icon_state": "ian", "power": "0", "resolve": "3", "faction": "Service", - "summoncost": "4", + "summoncost": "5", "cardtype": "Creature", - "cardsubtype": "Corgi", + "cardsubtype": "Animal", "rarity": "common", "summon_icon_file": "icons/mob/simple/pets.dmi", "summon_icon_state": "corgi" @@ -658,28 +658,28 @@ "id": "inquisitor_suit", "name": "Inquisitor's Hardsuit", "desc": "Nanotrasen officially doesn't believe in ghosts, magic, or anything that can't be solved with science. When you see someone show up in one of these, let that remind you of that fact.", - "rules": "Apply {$First Strike} to the equip creature.", + "rules": "Shuffle into the opponent's deck any creatures destroyed by battle with the equipped creature. The shuffled card's on destruction effects do not activate.", "icon_state": "inquisitor", - "power": "2", - "resolve": "2", + "power": "1", + "resolve": "1", "faction": "Service", - "summoncost": "4", + "summoncost": "1", "cardtype": "Equipment", - "cardsubtype": "Armour", + "cardsubtype": "Wizardry ERT", "rarity": "epic" }, { "id": "intern", "name": "Intern", "desc": "All Nanotrasen interns come with 3 things: A resume, a desire to learn, and vague promises that they're getting paid at some point. So don't be too rough on them.", - "rules": "{$First Strike}", + "rules": "{$First Strike} {$Graytide}", "icon_state": "intern", "power": "1", "resolve": "1", "faction": "Command", "summoncost": "1", "cardtype": "Creature", - "cardsubtype": "Human Employee", + "cardsubtype": "ERT Maintenance", "rarity": "common", "summon_icon_file": "icons/obj/toys/tcgsummons.dmi", "summon_icon_state": "intern" @@ -688,14 +688,14 @@ "id": "jannie", "name": "Janitor", "desc": "A true testament to futility, they clean and they clean and they clean, knowing that there's no way they can clean it all. Yet, they persevere, knowing that without them, the crew would simply give in to their base animalistic nature.", - "rules": "{$Taunt}", + "rules": "{$Taunt} {$Deadeye}: Shuffle a card from the opponent's discard pile to their deck.", "icon_state": "janitor", "power": "1", - "resolve": "1", + "resolve": "2", "faction": "Service", "summoncost": "1", "cardtype": "Creature", - "cardsubtype": "Human Employee", + "cardsubtype": "Maintenance", "rarity": "common", "summon_icon_state": "Janitor" }, @@ -703,14 +703,14 @@ "id": "jannieborg", "name": "Cyborg (Custodial Shell)", "desc": "A powerful, state of the act cleaning machine. They exist to eradicate stains, snag garbage, and replace lights, forever. We are legally obligated by the Janitor's Union to state that these machines are no replacement for a flesh-and-blood janitor.", - "rules": "{$Asimov}, you may tap this card: Tap an opponent's Human Creature as well.", + "rules": "{$Asimov} {$Deadeye}: Shuffle up to 3 cards from the opponent's discard pile to their deck.", "icon_state": "borg_janitor", "power": "1", "resolve": "3", "faction": "Service", "summoncost": "2", "cardtype": "Creature", - "cardsubtype": "Silicon", + "cardsubtype": "Silicon Maintenance", "rarity": "common", "summon_icon_file": "icons/mob/silicon/robots.dmi", "summon_icon_state": "janitor" @@ -719,14 +719,14 @@ "id": "lawyer", "name": "Lawyer", "desc": "Nanotrasen knows the value of a good lawyer. That's why they're all working hard at our home offices defending us from frivolous labor suits from lazy no-good employees who should be working hard instead of slacking off reading trading cards.", - "rules": "When an opponent attacks with a creature with 3 or more power, this card gains {$Taunt}.", + "rules": "When an opponent attacks with a creature with 3 or less power, this card gains {$Taunt}.", "icon_state": "lawyer", "power": "0", "resolve": "4", "faction": "Service", "summoncost": "2", "cardtype": "Creature", - "cardsubtype": "Human Employee", + "cardsubtype": "Service Security", "rarity": "common", "summon_icon_state": "Lawyer" }, @@ -734,7 +734,7 @@ "id": "legion", "name": "Legion", "desc": "They are the cursed, damned souls of civilizations born and lost in the flames of Indecipheres, conglomerated into a lump of emaciated bodies, wandering the realms they used to rule... or something along those lines, anyway.", - "rules": "When Legion is destroyed, search your deck for a human card, and summon it to the battlefield. Shuffle your deck afterward.", + "rules": "When Legion is destroyed, search your deck for a creature card costing 3 or less and add it to your hand. Shuffle your deck afterward.", "icon_state": "legion", "power": "2", "resolve": "1", @@ -750,14 +750,14 @@ "id": "medborg", "name": "Cyborg (Medical Shell)", "desc": "A state of the art medical shell, for when biological life just can't take care of itself. Comes equipped with built-in surgical equipment and all the medicated lollipops you could ever want.", - "rules": "{$Asimov}, you may tap this card and pay 2 mana: Reset a card's resolve to its original value.", + "rules": "{$Asimov} Tap: Reset a card's resolve to its original value (if possible) and heal it (if possible).", "icon_state": "borg_medical", "power": "2", "resolve": "3", "faction": "Medical", - "summoncost": "4", + "summoncost": "2", "cardtype": "Creature", - "cardsubtype": "Silicon Doctor", + "cardsubtype": "Silicon Medical", "rarity": "uncommon", "summon_icon_file": "icons/mob/silicon/robots.dmi", "summon_icon_state": "medical" @@ -766,14 +766,14 @@ "id": "doc", "name": "Medical Doctor", "desc": "Nanotrasen's doctors are well known for their ability to treat almost any ailment known to mankind... as well as causing a fair few in the process.", - "rules": "You may tap this card: Select a card that has less attack than this card from your graveyard, and summon it to your side of the field.", + "rules": "Tap: Add a card from your discard pile to your hand, except another 'Medical Doctor'.", "icon_state": "md", - "power": "2", + "power": "1", "resolve": "3", "faction": "Medical", "summoncost": "3", "cardtype": "Creature", - "cardsubtype": "Human Doctor", + "cardsubtype": "Medical", "rarity": "common", "summon_icon_state": "Medical Doctor" }, @@ -781,14 +781,14 @@ "id": "mime", "name": "Mime", "desc": "Si vous regardez attentivement dans les yeux d'un mime, vous pouvez voir le tourment sans fin derrière leur façade silencieuse. C'est vraiment tragique.", - "rules": "You may tap this card: Pick an opponent's card and nullify its effect until it leaves play.", + "rules": "Tap: Target creature and all its attached equipment loses all its effect text until this card leaves the field.", "icon_state": "mime", - "power": "2", + "power": "0", "resolve": "1", "faction": "Service", "summoncost": "1", "cardtype": "Creature", - "cardsubtype": "Mime", + "cardsubtype": "Bar", "rarity": "uncommon", "summon_icon_state": "Mime" }, @@ -796,14 +796,14 @@ "id": "miningborg", "name": "Cyborg (Mining Shell)", "desc": "Fitted with a drill and tracks, the Mining Shell is designed to hold up to the rigors of mining, be that on the hellish surface of Indecipheres, or in the silent vacuum of the asteroid belt.", - "rules": "{$Asimov}, at the end of your turn, if this card is not tapped, you may tap this card at the start of your next turn to gain 1 mana.", + "rules": "{$Asimov} At the start of your turn: Tap: Gain 2 plasma.", "icon_state": "borg_miner", "power": "3", - "resolve": "1", + "resolve": "2", "faction": "Cargo", "summoncost": "2", "cardtype": "Creature", - "cardsubtype": "Silicon Miner", + "cardsubtype": "Silicon Cargo", "rarity": "common", "summon_icon_file": "icons/mob/silicon/robots.dmi", "summon_icon_state": "minerOLD" @@ -812,14 +812,14 @@ "id": "monkey", "name": "Monkey", "desc": "Nanotrasen seeks to phase out animal testing by 2570, in accordance with new TerraGov legislation. This will be replaced with more ethical solutions, such as computer simulations, or experimentation on Staff Assistants.", - "rules": "{$Graytide}, this card is considered Human with a Geneticist on your side of the field.", + "rules": "{$Graytide} {$Squad Tactics}: Deal 1 damage to your opponent.", "icon_state": "monkey", "power": "1", "resolve": "1", "faction": "Science", "summoncost": "1", "cardtype": "Creature", - "cardsubtype": "Primate", + "cardsubtype": "Animal Science", "rarity": "common", "summon_icon_file": "icons/obj/toys/tcgsummons.dmi", "summon_icon_state": "monkey" @@ -828,14 +828,14 @@ "id": "nukeop", "name": "Nuclear Operative", "desc": "The frontline grunts of the syndicate army, Nuclear Operatives are typically well trained and equipped for their grim duty.", - "rules": "{$Squad Tactics}", + "rules": "On Play: Gain +1/+1 until the end of the turn", "icon_state": "nukie_red", - "power": "4", - "resolve": "2", + "power": "3", + "resolve": "3", "faction": "Syndicate", - "summoncost": "4", + "summoncost": "3", "cardtype": "Creature", - "cardsubtype": "Syndicate Soldier", + "cardsubtype": "Syndicate Cybersun", "rarity": "rare", "summon_icon_file": "icons/obj/toys/tcgsummons.dmi", "summon_icon_state": "syndicate_space_shotgun" @@ -851,7 +851,7 @@ "faction": "Medical", "summoncost": "3", "cardtype": "Creature", - "cardsubtype": "Human Doctor", + "cardsubtype": "Medical", "rarity": "common", "summon_icon_state": "Paramedic" }, @@ -859,14 +859,14 @@ "id": "peaceborg", "name": "Cyborg (Peacekeeper Shell)", "desc": "After the unilateral phasing out of Security Shells in 2554 following mass reports of cyborg-on-human violence, the Peacekeeper Shell was introduced as a stopgap solution until the problems could be resolved.", - "rules": "{$Asimov}, this card loses -1 power for every creature on your opponent's side of the field", + "rules": "{$Asimov} {$Taunt} {$Blocker} When damaged: Return this card to the hand.", "icon_state": "borg_peace", "power": "3", "resolve": "3", "faction": "Security", "summoncost": "2", "cardtype": "Creature", - "cardsubtype": "Silicon Officer", + "cardsubtype": "Silicon Security", "rarity": "uncommon", "summon_icon_file": "icons/mob/silicon/robots.dmi", "summon_icon_state": "peace" @@ -875,14 +875,14 @@ "id": "plasma_engi", "name": "Station Engineer (Plasmaman)", "desc": "The ever industrious plasmamen are well suited to engineering work, due to their natural radiation resistance.", - "rules": "{$Immunity} to Battlefields", + "rules": "{$Immunity} to Battlefields. When this creature dies deal 1 damage to all other creatures.", "icon_state": "engi_plasma", "power": "2", "resolve": "4", "faction": "Engineering", - "summoncost": "5", + "summoncost": "3", "cardtype": "Creature", - "cardsubtype": "Plasmaman Engineer", + "cardsubtype": "Atmospherics", "rarity": "common", "summon_icon_file": "icons/obj/toys/tcgsummons.dmi", "summon_icon_state": "plasmaman" @@ -891,14 +891,14 @@ "id": "QM", "name": "Quartermaster", "desc": "Every Nanotrasen station has a Quartermaster, who controls the flow of cargo to and from the station, and by extension to and from the hands of the crew. He's not given the distinction of being a head, though. His job isn't hard enough.", - "rules": "Pay 3 mana and tap this card: All card cards on your side of the field gain +1/+1 until the end of this turn.", + "rules": "You cannot be damaged while this unit is on the field. Holy.", "icon_state": "qm", - "power": "3", - "resolve": "3", + "power": "0", + "resolve": "7", "faction": "Cargo", "summoncost": "6", "cardtype": "Creature", - "cardsubtype": "Human Employee", + "cardsubtype": "Cargo Command", "rarity": "uncommon", "summon_icon_state": "Quartermaster" }, @@ -906,14 +906,14 @@ "id": "qm_head", "name": "Quartermaster", "desc": "Every Nanotrasen station has a Quartermaster, who controls the flow of cargo to and from the station, and by extension to and from the hands of the crew.", - "rules": "Pay 8 mana and permanently tap this card: All cargo cards on your side of the field gain +2/+2 until this card leaves play.", + "rules": "You cannot be damaged while this unit is on the field. Holy.", "icon_state": "qm_head", - "power": "6", - "resolve": "6", + "power": "7", + "resolve": "7", "faction": "Cargo", - "summoncost": "10", + "summoncost": "6", "cardtype": "Creature", - "cardsubtype": "Human Employee", + "cardsubtype": "Cargo Command", "rarity": "misprint", "summon_icon_state": "Quartermaster" }, @@ -921,14 +921,14 @@ "id": "rabbit_pai", "name": "Personal AI Device (Rabbit Shell)", "desc": "Personal AI Devices are able to take the form of many household pets, to provide a homely sense of comfort and companionship to their owners.", - "rules": "This card may steal the {$Asimov} keyword off of another friendly silicon creature.", + "rules": "Tap: Remove the {$Asimov} keyword off of another friendly silicon creature.", "icon_state": "pai_rabbit", "power": "0", "resolve": "1", "faction": "Science", - "summoncost": "2", + "summoncost": "1", "cardtype": "Creature", - "cardsubtype": "Silicon Rabbit", + "cardsubtype": "Silicon Creature", "rarity": "common", "summon_icon_file": "icons/mob/silicon/pai.dmi", "summon_icon_state": "rabbit" @@ -937,14 +937,14 @@ "id": "drone_pai", "name": "Personal AI Device (Drone Shell)", "desc": "The most basic Personal AI shell, the Drone Shell resembles the old maintainance drones used on Nanotrasen Stations prior to 'the incident', and is perfect for the tech-savvy AI-owner.", - "rules": "You may pay 1 mana and tap this card: a silicon card may attack one additional time this turn.", + "rules": "Tap this card: Add a silicon card from your discard pile to your hand.", "icon_state": "pai_drone", "power": "2", "resolve": "4", "faction": "Science", - "summoncost": "5", + "summoncost": "4", "cardtype": "Creature", - "cardsubtype": "Silicon Drone", + "cardsubtype": "Silicon", "rarity": "common", "summon_icon_file": "icons/mob/silicon/pai.dmi", "summon_icon_state": "repairbot" @@ -953,14 +953,14 @@ "id": "RD", "name": "Research Director", "desc": "The Research Director is the head of the Science Division, and is responsible for, shockingly, directing research.", - "rules": "Once per turn, you may tap all Science faction cards in play, activate the effect of an event card twice.", + "rules": "Tap: The effect of the next event or instant card you activate this turn is played twice.", "icon_state": "rd", "power": "2", "resolve": "5", "faction": "Science", - "summoncost": "7", + "summoncost": "6", "cardtype": "Creature", - "cardsubtype": "Human Scientist", + "cardsubtype": "Science Command", "rarity": "uncommon", "summon_icon_state": "Research Director" }, @@ -968,28 +968,28 @@ "id": "rd_suit", "name": "Nakamura Engineering B.O.M.B.Suit", "desc": "The Nakamura Engineering B.O.M.B.Suit is an innovative combination of a R.I.G.Suit and a bomb suit, perfect for toxins research.", - "rules": "Reduces all battlefield damage to the equipped creature by 2.", + "rules": "Damage to the equipped creature cannot exceed 2.", "icon_state": "rd_hardsuit", "power": "0", "resolve": "0", "faction": "Science", "summoncost": "1", "cardtype": "Equipment", - "cardsubtype": "Armour", + "cardsubtype": "Science", "rarity": "rare" }, { "id": "roboticist", "name": "Roboticist", "desc": "The roboticist's work is as close as Nanotrasen legally allows its employees to come to necromancy.", - "rules": "If a {$Asimov} card on your side of the field is destroyed, you may pay 2 mana and tap this card: Return that card to your hand.", + "rules": "On Play: Add a Silicon from your deck to your hand.", "icon_state": "roboticist", "power": "2", "resolve": "2", "faction": "Science", "summoncost": "3", "cardtype": "Creature", - "cardsubtype": "Human Scientist", + "cardsubtype": "Science Silicon", "rarity": "uncommon", "summon_icon_state": "Roboticist" }, @@ -997,14 +997,14 @@ "id": "runtime", "name": "Runtime", "desc": "Runtime is the CMO's personal feline companion, and is well known for her laziness. It's said that opening a tin of tuna anywhere on the station will bring her running.", - "rules": "You may sacrifice this card: reduce the cost of summoning a medical faction card this turn by 2 mana.", + "rules": "Sacrifice this card: reduce the cost of summoning your next medical faction card this turn by 2 mana.", "icon_state": "runtime", "power": "0", "resolve": "1", "faction": "Medical", - "summoncost": "3", + "summoncost": "1", "cardtype": "Creature", - "cardsubtype": "Cat", + "cardsubtype": "Animal Medical", "rarity": "uncommon", "summon_icon_file": "icons/mob/simple/pets.dmi", "summon_icon_state": "cat" @@ -1013,14 +1013,14 @@ "id": "scientist", "name": "Scientist", "desc": "Rumours that Nanotrasen hires 'mad scientists' are greatly exaggerated. Scientists are regularly screened to ensure that their insanity remains within acceptable limits.", - "rules": "When this card is targeted by an opponent's single target event, you gain 1 lifeshard.", + "rules": "{$On Summon}: Destroy a creature with 4 or more power.", "icon_state": "scientist", "power": "1", - "resolve": "2", + "resolve": "3", "faction": "Science", - "summoncost": "4", + "summoncost": "3", "cardtype": "Creature", - "cardsubtype": "Human Scientist", + "cardsubtype": "Science", "rarity": "common", "summon_icon_state": "Scientist" }, @@ -1028,14 +1028,14 @@ "id": "secborg", "name": "Cyborg (Security Shell)", "desc": "Following an incident in 2554, the Security Cyborg Shell was unilaterally phased out and replaced by the Peacekeeper. Nonetheless, many units remain in service with various other organisations such as private militaries.", - "rules": "{$Asimov}, when this card targets a human creature, deal 1 damage to it after the battle resolves.", + "rules": "{$Asimov} When this attacks deal 1 damage to the blocker before the battle resolves (ignoring Asimov).", "icon_state": "borg_sec", "power": "4", "resolve": "2", "faction": "Security", - "summoncost": "6", + "summoncost": "2", "cardtype": "Creature", - "cardsubtype": "Silicon Officer", + "cardsubtype": "Silicon Security", "rarity": "epic", "summon_icon_file": "icons/mob/silicon/robots.dmi", "summon_icon_state": "sec" @@ -1044,14 +1044,14 @@ "id": "sec_officer", "name": "Security Officer", "desc": "Nanotrasen would like to remind all employees to support their station security team; remember, the boys in red keep you safe!", - "rules": "{$Squad Tactics}", + "rules": "{$Squad Tactics}: Heal this unit to full resolve.", "icon_state": "sec", - "power": "2", - "resolve": "2", + "power": "3", + "resolve": "3", "faction": "Security", "summoncost": "3", "cardtype": "Creature", - "cardsubtype": "Human Officer", + "cardsubtype": "Security", "rarity": "common", "summon_icon_state": "Security Officer" }, @@ -1061,26 +1061,26 @@ "desc": "Fashioned from paranormally reinforced brass, the Ratvar Cult's clockwork armour is as beautiful as it is heretical.", "rules": "While equipped, give the equipped unit {$Clockwork}.", "icon_state": "clock_cultist", - "power": "2", - "resolve": "2", + "power": "0", + "resolve": "0", "faction": "Syndicate", - "summoncost": "4", + "summoncost": "1", "cardtype": "Equipment", - "cardsubtype": "Armour", + "cardsubtype": "Wizardry", "rarity": "epic" }, { "id": "beercanborg", - "name": "Cyborg (Service Shell- Beercan)", + "name": "Cyborg (Service Shell - Beercan)", "desc": "Despite being based on the Medical Shell, this particular Service Shell is tasked with destroying livers, rather than healing them.", - "rules": "{$Asimov}, you may discard this card: draw one Service {$Faction} card from your deck, then shuffle.", + "rules": "{$Asimov} All enemy creatures gain {$Fury} and -1 Resolve while this is on the field.", "icon_state": "borg_serv_can", "power": "1", "resolve": "1", "faction": "Service", "summoncost": "1", "cardtype": "Creature", - "cardsubtype": "Silicon", + "cardsubtype": "Silicon Bar", "rarity": "uncommon", "summon_icon_file": "icons/mob/silicon/robots.dmi", "summon_icon_state": "kent" @@ -1089,46 +1089,46 @@ "id": "flamboyantborg", "name": "Cyborg (Service Shell- Flamboyant)", "desc": "Sometimes a cyborg just needs to show a bit of flamboyance, you know?", - "rules": "{$Asimov}, gains +2/+2 when it's the only card on your side of the field.", + "rules": "{$Asimov}, gains +2/+2 and loses {$Asimov} when it's the only card on your side of the field.", "icon_state": "borg_serv_pink", "power": "0", "resolve": "1", "faction": "Service", "summoncost": "1", "cardtype": "Creature", - "cardsubtype": "Silicon", + "cardsubtype": "Silicon Bar", "rarity": "common", "summon_icon_file": "icons/mob/silicon/robots.dmi", "summon_icon_state": "brobot" }, { "id": "skirtborg", - "name": "Cyborg (Service Shell- Skirted)", + "name": "Cyborg (Service Shell - Skirted)", "desc": "The Service Shell is intended to be the most human of the Cyborg Shells, due to its outwardly social role- none exemplify this better than the Skirted Shell, showing that even robots can't escape fashion norms.", - "rules": "{$Asimov}", + "rules": "{$Asimov} On Play: You (the player) heal 1 for every creature on your side of the field.", "icon_state": "borg_serv_skirt", "power": "0", "resolve": "3", "faction": "Service", - "summoncost": "1", + "summoncost": "2", "cardtype": "Creature", - "cardsubtype": "Silicon", + "cardsubtype": "Silicon Bar", "rarity": "common", "summon_icon_file": "icons/mob/silicon/robots.dmi", "summon_icon_state": "service_f" }, { "id": "classicborg", - "name": "Cyborg (Service Shell- Classic)", + "name": "Cyborg (Service Shell - Classic)", "desc": "The classic Service Shell, the Classic Shell is what most crewmembers think of when they think of a 'useless robot that serves drinks'.", - "rules": "{$Asimov}, for every piece of equipment in play, gain +1 temporary resolve during the opponent's turn. That temporary resolve is lost at the start of your turn.", + "rules": "{$Asimov}, for every equipment in play gain +1 resolve during the opponent's turn only.", "icon_state": "borg_serv_suit", "power": "1", "resolve": "1", "faction": "Service", "summoncost": "2", "cardtype": "Creature", - "cardsubtype": "Silicon", + "cardsubtype": "Silicon Bar", "rarity": "common", "summon_icon_file": "icons/mob/silicon/robots.dmi", "summon_icon_state": "service_m" @@ -1137,14 +1137,14 @@ "id": "stylinborg", "name": "Cyborg (Service Shell- Ritzy)", "desc": "Ooh, isn't this robot one cool cat?", - "rules": "{$Asimov}", + "rules": "{$Asimov} On Play: Remove {$Asimov} from a creature.", "icon_state": "borg_serv_tux", "power": "1", "resolve": "2", "faction": "Service", "summoncost": "1", "cardtype": "Creature", - "cardsubtype": "Silicon", + "cardsubtype": "Silicon Bar", "rarity": "common", "summon_icon_file": "icons/mob/silicon/robots.dmi", "summon_icon_state": "tophat" @@ -1153,14 +1153,14 @@ "id": "miner", "name": "Shaft Miner", "desc": "When the station needs materials, these are the guys who risk their lives, bravely pioneering the wastes of Indecipheres, to bring them in.", - "rules": "Once per turn, you may pay 1 mana and tap this card: Draw one card from your deck, and either discard it, or send it to the bottom of your deck.", + "rules": "Tap: Look at the top 3 cards of your deck, choose one to add to your hand and shuffle the rest back into your deck.", "icon_state": "miner", "power": "5", "resolve": "3", "faction": "Cargo", - "summoncost": "5", + "summoncost": "4", "cardtype": "Creature", - "cardsubtype": "Human Miner", + "cardsubtype": "Cargo", "rarity": "rare", "summon_icon_state": "Shaft Miner" }, @@ -1168,14 +1168,14 @@ "id": "engi", "name": "Station Engineer", "desc": "Station Engineers maintain the intricate and delicate web of machinery that keeps you, and everyone else aboard your station, alive. No pressure there, then.", - "rules": "Tap this card: Reduce the damage a card would take this turn from a battlefield to zero.", + "rules": "{$Graytide} Tap: Destroy or return to the hand a Battlefield card on the field.", "icon_state": "engi", "power": "2", "resolve": "2", "faction": "Engineering", - "summoncost": "4", + "summoncost": "2", "cardtype": "Creature", - "cardsubtype": "Human Engineer", + "cardsubtype": "Atmospherics Maintenance", "rarity": "common", "summon_icon_state": "Station Engineer" }, @@ -1183,14 +1183,14 @@ "id": "swarmer", "name": "Swarmer", "desc": "Leading researchers theorise that Swarmers were designed as some kind of vanguard for an alien invasion force, which seemingly has never materialised.", - "rules": "{$Graytide}, {$Immunity} to Engineering creature cards.", + "rules": "{$Graytide}, {$Squad Tactics}: Create a 1/1 'Swarmer Spawn' token.", "icon_state": "swarmer", "power": "0", "resolve": "1", "faction": "Syndicate", "summoncost": "1", "cardtype": "Creature", - "cardsubtype": "Robot", + "cardsubtype": "Silicon Maintenance", "rarity": "rare", "summon_icon_file": "icons/obj/toys/tcgsummons.dmi", "summon_icon_state": "swarmer" @@ -1199,14 +1199,14 @@ "id": "viro", "name": "Virologist", "desc": "Officially, the virologist is present on station to deal with novel diseases and ailments that originate from deep space. As everyone knows, this is not what the virologist actually does.", - "rules": "", + "rules": "On Play: Gain +3 Power until the end of this turn.", "icon_state": "viro", - "power": "5", + "power": "1", "resolve": "1", "faction": "Medical", - "summoncost": "3", + "summoncost": "1", "cardtype": "Creature", - "cardsubtype": "Human Doctor", + "cardsubtype": "Medical", "rarity": "common", "summon_icon_state": "Virologist" }, @@ -1214,10 +1214,10 @@ "id": "warden", "name": "Warden", "desc": "The Warden is tasked with the herculean (and futile) feat of defending the armory and brig, and never leaving his post, no matter the situation.", - "rules": "{$Squad Tactics}, {$Blocker}", + "rules": "{$Holy}, {$Blocker}", "icon_state": "warden", "power": "2", - "resolve": "4", + "resolve": "6", "faction": "Security", "summoncost": "4", "cardtype": "Creature", @@ -1234,7 +1234,7 @@ "power": "2", "resolve": "3", "faction": "Xeno", - "summoncost": "4", + "summoncost": "3", "cardtype": "Creature", "cardsubtype": "Xenomorph", "series": "coreset2020", @@ -1246,14 +1246,14 @@ "id": "tough_choices", "name": "Tough Choices", "desc": "Every Nanotrasen employee will, at some point, be forced to make a tough choice. Make sure you make the right one!", - "rules": "Draw the top three cards from your deck. Summon one at no cost, and discard the other two.", + "rules": "Draw the top three cards from your deck. Choose one to add to your hand and discard the other two.", "icon_state": "tough_choices", "power": "0", "resolve": "0", "faction": "Syndicate", - "summoncost": "2", + "summoncost": "1", "cardtype": "Event", - "cardsubtype": "Instant", + "cardsubtype": "Security", "series": "coreset2020", "rarity": "common" }, @@ -1261,14 +1261,14 @@ "id": "bsa_barrage", "name": "Bluespace Barrage", "desc": "The officers at Centcom are well known for their ability to hit targets extremely accurately with their bluespace artillery, especially when stupid pictures show up at their fax machine.", - "rules": "Destroy any creature on the opponent's battlefield. If your opponent has no creatures, deal 2 damage directly to them.", + "rules": "The opponent chooses a creature they control. It is destroyed. If your opponent has no creatures, deal 5 damage directly to them.", "icon_state": "bsa_barrage", "power": "0", "resolve": "0", "faction": "Security", - "summoncost": "3", - "cardtype": "Event", - "cardsubtype": "Instant", + "summoncost": "4", + "cardtype": "Instant", + "cardsubtype": "Command ERT", "series": "coreset2020", "rarity": "uncommon" }, @@ -1282,8 +1282,8 @@ "resolve": "0", "faction": "Science", "summoncost": "1", - "cardtype": "Event", - "cardsubtype": "Instant", + "cardtype": "Instant", + "cardsubtype": "Silicon", "series": "coreset2020", "rarity": "common" }, @@ -1291,14 +1291,14 @@ "id": "adrenals", "name": "Adrenals", "desc": "A potent mixture of stimulants, designed to enhance a soldier's ability in the field. Technically illegal in Terragov territory, but since when has that stopped anyone?", - "rules": "Grant +2/+1 to a Creature card that you control.", + "rules": "Grant +2/+1 to a Creature card that you control until the end of this turn.", "icon_state": "adrenals", "power": "+2", "resolve": "+1", "faction": "Medical", "summoncost": "1", - "cardtype": "Event", - "cardsubtype": "Instant", + "cardtype": "Instant", + "cardsubtype": "Medical Security", "series": "coreset2020", "rarity": "common" }, @@ -1311,7 +1311,7 @@ "power": "0", "resolve": "0", "faction": "Engineering", - "summoncost": "3", + "summoncost": "1", "cardtype": "Battlefield", "cardsubtype": "Atmospherics", "series": "coreset2020", @@ -1321,14 +1321,14 @@ "id": "psych", "name": "Psychologist", "desc": "The psychologist is the newest addition to Nanotrasen's medical workforce, quickly settling into their role as the job that does nothing valuable.", - "rules": "", + "rules": "Tap: Destroy an equipment card on the field.", "icon_state": "psych", "power": "1", "resolve": "1", "faction": "Medical", "summoncost": "1", "cardtype": "Creature", - "cardsubtype": "Human Doctor", + "cardsubtype": "Medical", "series": "coreset2020", "rarity": "common", "summon_icon_state": "Psychologist" @@ -1343,8 +1343,8 @@ "resolve": "0", "faction": "Security", "summoncost": "2", - "cardtype": "Event", - "cardsubtype": "Instant", + "cardtype": "Instant", + "cardsubtype": "Security", "series": "coreset2020", "rarity": "uncommon" }, @@ -1359,7 +1359,7 @@ "faction": "Science", "summoncost": "3", "cardtype": "Battlefield", - "cardsubtype": "Anomaly", + "cardsubtype": "Wizardry Science", "series": "coreset2020", "rarity": "common" }, @@ -1374,7 +1374,7 @@ "faction": "Science", "summoncost": "3", "cardtype": "Event", - "cardsubtype": "Instant", + "cardsubtype": "Science", "series": "coreset2020", "rarity": "uncommon" }, @@ -1389,7 +1389,7 @@ "faction": "Cargo", "summoncost": "2", "cardtype": "Battlefield", - "cardsubtype": "Event", + "cardsubtype": "Cargo", "series": "coreset2020", "rarity": "common" }, @@ -1403,7 +1403,7 @@ "resolve": "0", "faction": "Service", "summoncost": "0", - "cardtype": "Artifact", + "cardtype": "Equipment", "cardsubtype": "Plant", "series": "coreset2020", "rarity": "legendary" @@ -1419,7 +1419,7 @@ "faction": "Security", "summoncost": "2", "cardtype": "Event", - "cardsubtype": "Instant", + "cardsubtype": "Security Maintenance", "series": "coreset2020", "rarity": "common" }, @@ -1432,9 +1432,9 @@ "power": "2", "resolve": "3", "faction": "Syndicate", - "summoncost": "3", + "summoncost": "2", "cardtype": "Creature", - "cardsubtype": "Spirit", + "cardsubtype": "Wizardry", "series": "coreset2020", "rarity": "rare", "summon_icon_file": "icons/mob/simple/mob.dmi", @@ -1444,14 +1444,14 @@ "id": "re_education", "name": "Re-Education", "desc": "Nobody ever seems to return from re-education. Probably best not to question it.", - "rules": "Destroy any creature on the opponent's battlefield.", + "rules": "Destroy a creature on the opponent's battlefield.", "icon_state": "re_education", "power": "0", "resolve": "0", "faction": "Security", - "summoncost": "2", - "cardtype": "Event", - "cardsubtype": "Instant", + "summoncost": "5", + "cardtype": "Instant", + "cardsubtype": "Security", "series": "coreset2020", "rarity": "uncommon" }, @@ -1459,14 +1459,14 @@ "id": "immoral_surgeon", "name": "Immoral Surgeon", "desc": "Remember, the Hippocratic oath is only a suggestion.", - "rules": "2 Mana- You may tap Immoral Surgeon and give a creature +1/+1.", + "rules": "Tap: Give a creature +1/-1.", "icon_state": "immoral_surgeon", "power": "2", - "resolve": "4", + "resolve": "1", "faction": "Medical", - "summoncost": "4", + "summoncost": "1", "cardtype": "Creature", - "cardsubtype": "Lizard Doctor", + "cardsubtype": "Medical", "series": "coreset2020", "rarity": "uncommon", "summon_icon_file": "icons/obj/toys/tcgsummons.dmi", @@ -1476,14 +1476,14 @@ "id": "botanist_plant", "name": "Committed Botanist", "desc": "When you've grown the plants, nurtured the plants, and harvested the plants, there's only one place to go from there... becoming the plant.", - "rules": "While Committed Botanist is on your battlefield, you can play Plant and Service cards at half their cost, rounded up.", + "rules": "While Committed Botanist is on your battlefield you can play Plant cards at half their cost, rounded up.", "icon_state": "botanist_plant", "power": "2", "resolve": "3", "faction": "Service", "summoncost": "4", "cardtype": "Creature", - "cardsubtype": "Plant Worker", + "cardsubtype": "Plant Bar", "series": "coreset2020", "rarity": "rare", "summon_icon_file": "icons/obj/toys/tcgsummons.dmi", @@ -1493,14 +1493,14 @@ "id": "scientist_moth", "name": "Scientist (Moth)", "desc": "Moths are a common sight in Nanotrasen research departments, acting as integral ideas guys for new clothing designs and lighting innovations.", - "rules": "", + "rules": "Enemy creatures cannot block this unit if it is attacking directly.", "icon_state": "scientist_moth", "power": "2", "resolve": "2", "faction": "Science", "summoncost": "1", "cardtype": "Creature", - "cardsubtype": "Moth Scientist", + "cardsubtype": "Scientist", "series": "coreset2020", "rarity": "common", "summon_icon_file": "icons/obj/toys/tcgsummons.dmi", @@ -1510,14 +1510,14 @@ "id": "inducer", "name": "Inducer", "desc": "The inducer is a marvelous piece of tech, allowing the recharging of an internal cell without opening a machine.", - "rules": "Pay 3 lifeshards: Gain 3 mana this turn.", + "rules": "Pay 2 lifeshards to gain 1 plasma.", "icon_state": "inducer", "power": "0", "resolve": "0", "faction": "Engineering", "summoncost": "0", "cardtype": "Event", - "cardsubtype": "Instant", + "cardsubtype": "Science", "series": "coreset2020", "rarity": "common" }, @@ -1525,7 +1525,7 @@ "id": "fryer", "name": "Deep Fryer", "desc": "God bless the United States of Space America.", - "rules": "For 2 mana: Tap this card and destroy an opposing equipment card.", + "rules": "Destroy an opposing equipment card.", "icon_state": "fryer", "power": "0", "resolve": "0", @@ -1540,14 +1540,14 @@ "id": "sleeping_carp", "name": "Scroll of the Sleeping Carp", "desc": "Created by the long-extinct Carp Monks of Space Tibet, the Sleeping Carp style has been kept alive by dedicated practitioners, and even found its way into the Syndicate's training regime.", - "rules": "{$On Equip}: Your opponent must show you one card in their hand of their choice.", + "rules": "{$On Equip}: Your opponent must show you their entire hand.", "icon_state": "sleeping_carp", - "power": "3", + "power": "1", "resolve": "1", "faction": "Syndicate", - "summoncost": "3", + "summoncost": "1", "cardtype": "Equipment", - "cardsubtype": "Weapon", + "cardsubtype": "Syndicate", "series": "coreset2020", "rarity": "epic" }, @@ -1555,14 +1555,14 @@ "id": "nuclear_option", "name": "The Nuclear Option", "desc": "The Gorlex Marauders are well known for their nuclear weapons, and their nuke first, second, third and fourth policy with regards to deploying them.", - "rules": "Destroy the active battlefield card. Deal 2 damage to all creatures on both battlefields.", + "rules": "Destroy the active battlefield card. Destroy all creatures on both battlefields.", "icon_state": "nuclear_option", "power": "0", "resolve": "0", "faction": "Syndicate", - "summoncost": "3", - "cardtype": "Event", - "cardsubtype": "Instant", + "summoncost": "5", + "cardtype": "Instant", + "cardsubtype": "Atmospherics Syndicate", "series": "coreset2020", "rarity": "rare" }, @@ -1570,14 +1570,14 @@ "id": "bepis", "name": "B.E.P.I.S. Chamber", "desc": "Created as an automated investment machine for a venture capitalism company, the B.E.P.I.S. ended up in the hands of Nanotrasen's research division after bankrupting the original creators... and 27 other corporations.", - "rules": "Flip a coin. If heads, gain 2 mana. If tails, lose up to 2 mana.", + "rules": "Flip a coin. If heads, gain 4 mana.", "icon_state": "bepis", "power": "0", "resolve": "0", "faction": "Science", - "summoncost": "0", + "summoncost": "2", "cardtype": "Event", - "cardsubtype": "Instant", + "cardsubtype": "Clown Science", "series": "coreset2020", "rarity": "common" }, @@ -1591,8 +1591,8 @@ "resolve": "0", "faction": "Medical", "summoncost": "3", - "cardtype": "Event", - "cardsubtype": "Instant", + "cardtype": "Instant", + "cardsubtype": "Clown Medical", "series": "coreset2020", "rarity": "uncommon" }, @@ -1600,14 +1600,14 @@ "id": "disco_inferno", "name": "Disco Inferno", "desc": "(Burn baby burn) burn that mother down y'all\n(Burn baby burn) Disco Inferno\n(Burn baby burn) burn that mother down", - "rules": "For 2 mana: Tap this card permanantly. While tapped, all active creatures take 3 damage during the first play phase of each turn. This card is destroyed after 2 turns of being tapped.", + "rules": "All active creatures take 3 damage during the first play phase of each turn. This card is destroyed after this effect triggers 4 times.", "icon_state": "disco_inferno", "power": "0", "resolve": "0", "faction": "Science", "summoncost": "4", "cardtype": "Battlefield", - "cardsubtype": "Shuttle", + "cardsubtype": "Science Atmosian", "series": "coreset2020", "rarity": "uncommon" } diff --git a/strings/tcg/set_two.json b/strings/tcg/set_two.json index 02331326deaee..935fbfaf840c1 100644 --- a/strings/tcg/set_two.json +++ b/strings/tcg/set_two.json @@ -1,6 +1,6 @@ { "templates": [ - { + { "template": "default", "icon": "icons/runtime/tcg/xenos.dmi", "series": "resinfront", @@ -13,12 +13,12 @@ "id": "xenoborg", "name": "Xenoborg", "desc": "With a mini-gun in one hand and a rocket launcher in the other, the Xenoborg is a failed hybridization of a Xenomorph and a cyborg.", - "rules": "{$Asimov}. Once per turn, you may sacrifice a silicon card, and pay the difference between that card's summon cost and this card's summon cost to summon this card from your hand.", + "rules": "You may sacrifice a silicon, reducing the cost of this card by the sacrificed creature's plasma cost, to summon this card from your hand.", "icon_state": "xeno_borg", "power": 7, "resolve": 5, "faction": "Science", - "summoncost": 6, + "summoncost": 5, "cardtype": "Creature", "cardsubtype": "Silicon Xenomorph", "rarity": "epic", @@ -28,10 +28,10 @@ "id": "sentinel", "name": "Xenomorph Sentinel", "desc": "The juices from a Sentinel's neurotoxin gland pair brilliantly with a Pan-Galactic Gargle Blaster.", - "rules": "{$Hivemind}", + "rules": "{$Hivemind} {$Taunt} {$Blocker}", "icon_state": "xeno_sentinel", "power": 5, - "resolve": 3, + "resolve": 2, "faction": "Xeno", "summoncost": 4, "cardtype": "Creature", @@ -43,12 +43,12 @@ "id": "drone", "name": "Xenomorph Drone", "desc": "Rarely seen on the frontline, the Drone is your average worker that lays the foundation of the hive.", - "rules": "{$Hivemind}. Tap this card: you may summon a Xeno faction creature for 1 less mana this turn.", + "rules": "{$Hivemind}. Tap: Summon a Xeno faction creature for 1 less mana.", "icon_state": "xeno_drone", "power": 1, "resolve": 1, "faction": "Xeno", - "summoncost": 2, + "summoncost": 1, "cardtype": "Creature", "cardsubtype": "Xenomorph", "rarity": "common", @@ -63,7 +63,7 @@ "power": 6, "resolve": 3, "faction": "Xeno", - "summoncost": 5, + "summoncost": 4, "cardtype": "Creature", "cardsubtype": "Xenomorph", "rarity": "uncommon", @@ -73,10 +73,10 @@ "id": "spitter", "name": "Xenomorph Spitter", "desc": "While their acid gland is too dangerous to mix with alcohol (not that it stops the marines), a Spitter's acid is useful for industry as it can melt almost anything with ease.", - "rules": "{$Hivemind}. Tap this card: draw the top 2 cards of your deck, you may re-arrange their order, then return them to the top of your deck.", + "rules": "{$Hivemind}. Tap: Draw the top 2 cards of your deck then discard any that weren't Xenomorph.", "icon_state": "xeno_spitter", - "power": 3, - "resolve": 3, + "power": 2, + "resolve": 1, "faction": "Xeno", "summoncost": 3, "cardtype": "Creature", @@ -103,12 +103,12 @@ "id": "praetorian", "name": "Xenomorph Praetorian", "desc": "The Praetorian is the Queen's royal guard, never seen far from the Queen's chambers.", - "rules": "{$Hivemind}. If you have 2 or more other Xeno cards on your field alongside this card, you may sacrifice 3 Xeno cards and add Xenomorph Queen to your hand from your deck.", + "rules": "{$Hivemind}. {On Summon}: Add a Xenomorph Queen card to your hand from your deck.", "icon_state": "xeno_praetorian", - "power": 3, - "resolve": 6, + "power": 2, + "resolve": 3, "faction": "Xeno", - "summoncost": 5, + "summoncost": 2, "cardtype": "Creature", "cardsubtype": "Xenomorph", "rarity": "rare", @@ -118,7 +118,7 @@ "id": "hivelord", "name": "Xenomorph Hivelord", "desc": "The Hivelord is the last word in construction, capable of building entire hives in a matter of seconds.", - "rules": "{$Hivemind}. For two mana, tap this card and summon a 0/2 Resin Wall counter creature. Each Resin Wall has {$Blocker}.", + "rules": "{$Hivemind}. Tap; summon a 0/2 Resin Wall counter creature. Each Resin Wall has {$Blocker}.", "icon_state": "xeno_hivelord", "power": 1, "resolve": 3, @@ -133,7 +133,7 @@ "id": "boiler", "name": "Xenomorph Boiler", "desc": "The Boiler is a long-range artillery machine, capable of spewing clouds of acid that melt everything in seconds.", - "rules": "{$Hivemind}. If this card attacks, it is tapped for an additional turn before it is untapped.", + "rules": "{$Hivemind}. This creatures' direct attacks cannot be blocked..", "icon_state": "xeno_boiler", "power": 6, "resolve": 2, @@ -150,7 +150,7 @@ "desc": "With large scythe claws for hands, the furious Ravager goes berserk at the sight of fire.", "rules": "{$Hivemind}, {$Fury}", "icon_state": "xeno_ravager", - "power": 4, + "power": 2, "resolve": 2, "faction": "Xeno", "summoncost": 3, @@ -181,9 +181,9 @@ "rules": "{$Hivemind}, {$Blocker}", "icon_state": "xeno_defender", "power": 1, - "resolve": 2, + "resolve": 1, "faction": "Xeno", - "summoncost": 2, + "summoncost": 0, "cardtype": "Creature", "cardsubtype": "Xenomorph", "rarity": "common", @@ -193,10 +193,10 @@ "id": "warrior", "name": "Xenomorph Warrior", "desc": "Warriors exhibit greater cruelty than other Xeno strains, enjoying snapping a victim's limbs before finishing them off.", - "rules": "{$Hivemind}", + "rules": "{$Hivemind} {$First Strike}", "icon_state": "xeno_warrior", - "power": 4, - "resolve": 4, + "power": 3, + "resolve": 3, "faction": "Xeno", "summoncost": 4, "cardtype": "Creature", @@ -208,12 +208,12 @@ "id": "queen", "name": "Xenomorph Queen (Resin Frontier)", "desc": "The ruler of the hive. Organs from a Queen fetch a high price amongst researchers and less-than-moral surgeons.", - "rules": "For 2 mana, tap the equipped creature and summon a 1/1 Xenomorph Brood counter creature, with {$Hivemind}.", + "rules": "If the equipped card is a Xenomorph give it {$Taunt} {$First Strike} {$Blocker}.", "icon_state": "xeno_queen", - "power": 5, - "resolve": 5, + "power": 0, + "resolve": 0, "faction": "Xeno", - "summoncost": 5, + "summoncost": 3, "cardtype": "Equipment", "cardsubtype": "Armour", "rarity": "epic" @@ -222,7 +222,7 @@ "id": "carrier", "name": "Xenomorph Carrier", "desc": "Carriers are like the Easter Bunny except the eggs they hide will kill you.", - "rules": "{$Hivemind}, {$Squad Tactics}", + "rules": "{$Hivemind}, {$Deadeye}: Add one Xenomorph from your Deck to your hand.", "icon_state": "xeno_carrier", "power": 2, "resolve": 2, @@ -237,7 +237,7 @@ "id": "defiler", "name": "Xenomorph Defiler", "desc": "Instead of utilizing eggs, the Defiler prefers to inject an unknown chemical in their victim, causing a devastating infection.", - "rules": "{$Hivemind}. When this card attacks a target enemy creature, calculate damage as though the target creature has this card's power subtracted from it first.", + "rules": "{$Hivemind}. While this creature is on the field all enemy creatures lose 1 power.", "icon_state": "xeno_defiler", "power": 1, "resolve": 3, @@ -255,7 +255,7 @@ "rules": "{$Hivemind}, {$Changeling}", "icon_state": "xeno_predalien", "power": 4, - "resolve": 3, + "resolve": 2, "faction": "Xeno", "summoncost": 3, "cardtype": "Creature", @@ -267,12 +267,12 @@ "id": "shrike", "name": "Xenomorph Shrike", "desc": "It is unknown why Shrikes are able to lead a Hive, but their hives are always much smaller than a Queen's.", - "rules": "{$Hivemind}. If Xenomorph Queen would be destroyed, you may re-equip Xenomorph Queen on this card instead, once per game.", + "rules": "{$Hivemind}. Tap: Add Xenomorph Queen from your discard pile to your hand.", "icon_state": "xeno_shrike", - "power": 3, + "power": 2, "resolve": 1, "faction": "Xeno", - "summoncost": 2, + "summoncost": 1, "cardtype": "Creature", "cardsubtype": "Xenomorph", "rarity": "rare", @@ -297,7 +297,7 @@ "id": "hivemind", "name": "Xenomorph Hivemind", "desc": "Recently discovered to have sapience, this pulsating orb will dig into the earth and rapidly spread resin throughout planets.", - "rules": "Defender", + "rules": "{$Blocker} Tap: Add 1 Xenomorph creature from your Deck to your hand.", "icon_state": "xeno_hivemind", "power": 0, "resolve": 1, @@ -312,7 +312,7 @@ "id": "screecher", "name": "Xenomorph Screecher", "desc": "The Screecher's screeches are more psychologically damaging than the resulting hearing damage.", - "rules": "{$Deadeye}", + "rules": "{$Deadeye}: All tapped enemy creatures take 1 damage.", "icon_state": "xeno_screecher", "power": 3, "resolve": 2, @@ -327,12 +327,12 @@ "id": "creep", "name": "Xenomorph Creep", "desc": "This special Hunter strain prioritizes stalking its target. It evolves into a strain of Hunter that is (mercifully) rarely seen aboard space stations.", - "rules": "Tap this card: Until the start of your next turn, this card has immunity to Xeno Creatures.", + "rules": "Tap this card: Until the start of your next turn, this card has immunity to creatures.", "icon_state": "xeno_creep", - "power": 4, - "resolve": 3, + "power": 2, + "resolve": 2, "faction": "Xeno", - "summoncost": 5, + "summoncost": 1, "cardtype": "Creature", "cardsubtype": "Xenomorph", "rarity": "common", diff --git a/tgstation.dme b/tgstation.dme index 4eee10ec5257d..a5edb43551db1 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -345,6 +345,7 @@ #include "code\__DEFINES\dcs\signals\signals_operating_computer.dm" #include "code\__DEFINES\dcs\signals\signals_operatives.dm" #include "code\__DEFINES\dcs\signals\signals_painting.dm" +#include "code\__DEFINES\dcs\signals\signals_plane_master_group.dm" #include "code\__DEFINES\dcs\signals\signals_proxmonitor.dm" #include "code\__DEFINES\dcs\signals\signals_radiation.dm" #include "code\__DEFINES\dcs\signals\signals_reagent.dm" @@ -716,6 +717,7 @@ #include "code\controllers\subsystem\lighting.dm" #include "code\controllers\subsystem\lua.dm" #include "code\controllers\subsystem\machines.dm" +#include "code\controllers\subsystem\map_vote.dm" #include "code\controllers\subsystem\mapping.dm" #include "code\controllers\subsystem\market.dm" #include "code\controllers\subsystem\materials.dm" @@ -767,6 +769,8 @@ #include "code\controllers\subsystem\transport.dm" #include "code\controllers\subsystem\tts.dm" #include "code\controllers\subsystem\tutorials.dm" +#include "code\controllers\subsystem\unplanned_ai_idle_controllers.dm" +#include "code\controllers\subsystem\unplanned_controllers.dm" #include "code\controllers\subsystem\verb_manager.dm" #include "code\controllers\subsystem\vis_overlays.dm" #include "code\controllers\subsystem\vote.dm" @@ -815,6 +819,7 @@ #include "code\controllers\subsystem\processing\fishing.dm" #include "code\controllers\subsystem\processing\greyscale.dm" #include "code\controllers\subsystem\processing\instruments.dm" +#include "code\controllers\subsystem\processing\manufacturing.dm" #include "code\controllers\subsystem\processing\obj.dm" #include "code\controllers\subsystem\processing\plumbing.dm" #include "code\controllers\subsystem\processing\processing.dm" @@ -1114,6 +1119,7 @@ #include "code\datums\components\boomerang.dm" #include "code\datums\components\boss_music.dm" #include "code\datums\components\breeding.dm" +#include "code\datums\components\bubble_icon_override.dm" #include "code\datums\components\bullet_intercepting.dm" #include "code\datums\components\bumpattack.dm" #include "code\datums\components\burning.dm" @@ -1125,6 +1131,7 @@ #include "code\datums\components\chuunibyou.dm" #include "code\datums\components\cleaner.dm" #include "code\datums\components\clickbox.dm" +#include "code\datums\components\clothing_dirt.dm" #include "code\datums\components\clothing_fov_visor.dm" #include "code\datums\components\codeword_hearing.dm" #include "code\datums\components\combo_attacks.dm" @@ -1189,11 +1196,13 @@ #include "code\datums\components\heart_eater.dm" #include "code\datums\components\heirloom.dm" #include "code\datums\components\hide_highest_offset.dm" +#include "code\datums\components\hide_weather_planes.dm" #include "code\datums\components\holderloving.dm" #include "code\datums\components\igniter.dm" #include "code\datums\components\infective.dm" #include "code\datums\components\interaction_booby_trap.dm" #include "code\datums\components\irradiated.dm" +#include "code\datums\components\item_equipped_movement_rustle.dm" #include "code\datums\components\itembound.dm" #include "code\datums\components\itempicky.dm" #include "code\datums\components\jetpack.dm" @@ -1261,6 +1270,7 @@ #include "code\datums\components\security_vision.dm" #include "code\datums\components\seethrough.dm" #include "code\datums\components\seethrough_mob.dm" +#include "code\datums\components\self_ignition.dm" #include "code\datums\components\shell.dm" #include "code\datums\components\shielded.dm" #include "code\datums\components\shovel_hands.dm" @@ -1673,6 +1683,7 @@ #include "code\datums\id_trim\syndicate.dm" #include "code\datums\job_configs\_job_configs.dm" #include "code\datums\job_configs\default_positions.dm" +#include "code\datums\job_configs\human_authority.dm" #include "code\datums\job_configs\playtime_requirements.dm" #include "code\datums\job_configs\required_account_age.dm" #include "code\datums\job_configs\required_character_age.dm" @@ -1825,6 +1836,7 @@ #include "code\datums\quirks\neutral_quirks\borg_ready.dm" #include "code\datums\quirks\neutral_quirks\colorist.dm" #include "code\datums\quirks\neutral_quirks\deviant_tastes.dm" +#include "code\datums\quirks\neutral_quirks\evil.dm" #include "code\datums\quirks\neutral_quirks\extrovert.dm" #include "code\datums\quirks\neutral_quirks\foreigner.dm" #include "code\datums\quirks\neutral_quirks\gamer.dm" @@ -1966,6 +1978,7 @@ #include "code\datums\storage\subtypes\backpack.dm" #include "code\datums\storage\subtypes\bag_of_holding.dm" #include "code\datums\storage\subtypes\cards.dm" +#include "code\datums\storage\subtypes\drone.dm" #include "code\datums\storage\subtypes\duffel_bag.dm" #include "code\datums\storage\subtypes\extract_inventory.dm" #include "code\datums\storage\subtypes\fish_case.dm" @@ -1980,7 +1993,6 @@ #include "code\datums\votes\custom_vote.dm" #include "code\datums\votes\map_vote.dm" #include "code\datums\votes\restart_vote.dm" -#include "code\datums\votes\rock_the_vote.dm" #include "code\datums\weather\weather.dm" #include "code\datums\weather\weather_types\ash_storm.dm" #include "code\datums\weather\weather_types\floor_is_lava.dm" @@ -2096,7 +2108,7 @@ #include "code\game\machinery\digital_clock.dm" #include "code\game\machinery\dish_drive.dm" #include "code\game\machinery\dna_scanner.dm" -#include "code\game\machinery\droneDispenser.dm" +#include "code\game\machinery\drone_dispenser.dm" #include "code\game\machinery\ecto_sniffer.dm" #include "code\game\machinery\fat_sucker.dm" #include "code\game\machinery\firealarm.dm" @@ -2212,12 +2224,14 @@ #include "code\game\machinery\computer\records\security.dm" #include "code\game\machinery\dna_infuser\dna_infuser.dm" #include "code\game\machinery\dna_infuser\dna_infusion.dm" +#include "code\game\machinery\dna_infuser\infuser_actions.dm" #include "code\game\machinery\dna_infuser\infuser_book.dm" #include "code\game\machinery\dna_infuser\infuser_entry.dm" #include "code\game\machinery\dna_infuser\infuser_entries\infuser_tier_one_entries.dm" #include "code\game\machinery\dna_infuser\infuser_entries\infuser_tier_two_entries.dm" #include "code\game\machinery\dna_infuser\infuser_entries\infuser_tier_zero_entries.dm" #include "code\game\machinery\dna_infuser\organ_sets\carp_organs.dm" +#include "code\game\machinery\dna_infuser\organ_sets\fish_organs.dm" #include "code\game\machinery\dna_infuser\organ_sets\fly_organs.dm" #include "code\game\machinery\dna_infuser\organ_sets\fox_organs.dm" #include "code\game\machinery\dna_infuser\organ_sets\goliath_organs.dm" @@ -2914,6 +2928,7 @@ #include "code\modules\actionspeed\modifiers\addiction.dm" #include "code\modules\actionspeed\modifiers\base.dm" #include "code\modules\actionspeed\modifiers\drugs.dm" +#include "code\modules\actionspeed\modifiers\mobs.dm" #include "code\modules\actionspeed\modifiers\mood.dm" #include "code\modules\actionspeed\modifiers\status_effects.dm" #include "code\modules\actionspeed\modifiers\wound.dm" @@ -2992,12 +3007,12 @@ #include "code\modules\admin\verbs\adminjump.dm" #include "code\modules\admin\verbs\adminpm.dm" #include "code\modules\admin\verbs\adminsay.dm" +#include "code\modules\admin\verbs\adminshuttle.dm" #include "code\modules\admin\verbs\ai_triumvirate.dm" #include "code\modules\admin\verbs\anonymousnames.dm" #include "code\modules\admin\verbs\atmosdebug.dm" #include "code\modules\admin\verbs\beakerpanel.dm" #include "code\modules\admin\verbs\borgpanel.dm" -#include "code\modules\admin\verbs\change_shuttle_events.dm" #include "code\modules\admin\verbs\cinematic.dm" #include "code\modules\admin\verbs\color_blind_test.dm" #include "code\modules\admin\verbs\commandreport.dm" @@ -3036,7 +3051,6 @@ #include "code\modules\admin\verbs\secrets.dm" #include "code\modules\admin\verbs\selectequipment.dm" #include "code\modules\admin\verbs\server.dm" -#include "code\modules\admin\verbs\shuttlepanel.dm" #include "code\modules\admin\verbs\spawnobjasmob.dm" #include "code\modules\admin\verbs\special_verbs.dm" #include "code\modules\admin\verbs\lua\_wrappers.dm" @@ -3384,6 +3398,7 @@ #include "code\modules\antagonists\traitor\objectives\final_objective\battlecruiser.dm" #include "code\modules\antagonists\traitor\objectives\final_objective\final_objective.dm" #include "code\modules\antagonists\traitor\objectives\final_objective\infect_ai.dm" +#include "code\modules\antagonists\traitor\objectives\final_objective\no_escape.dm" #include "code\modules\antagonists\traitor\objectives\final_objective\objective_dark_matteor.dm" #include "code\modules\antagonists\traitor\objectives\final_objective\romerol.dm" #include "code\modules\antagonists\traitor\objectives\final_objective\supermatter_cascade.dm" @@ -4555,8 +4570,9 @@ #include "code\modules\library\skill_learning\skill_station.dm" #include "code\modules\library\skill_learning\skillchip.dm" #include "code\modules\library\skill_learning\generic_skillchips\matrix_taunt.dm" +#include "code\modules\library\skill_learning\generic_skillchips\misc.dm" +#include "code\modules\library\skill_learning\generic_skillchips\musical.dm" #include "code\modules\library\skill_learning\generic_skillchips\point.dm" -#include "code\modules\library\skill_learning\generic_skillchips\rod_suplex.dm" #include "code\modules\library\skill_learning\job_skillchips\_job.dm" #include "code\modules\library\skill_learning\job_skillchips\chef.dm" #include "code\modules\library\skill_learning\job_skillchips\clown.dm" @@ -4564,6 +4580,7 @@ #include "code\modules\library\skill_learning\job_skillchips\janitor.dm" #include "code\modules\library\skill_learning\job_skillchips\miner.dm" #include "code\modules\library\skill_learning\job_skillchips\psychologist.dm" +#include "code\modules\library\skill_learning\job_skillchips\research_director.dm" #include "code\modules\library\skill_learning\job_skillchips\roboticist.dm" #include "code\modules\library\skill_learning\job_skillchips\station_engineer.dm" #include "code\modules\lighting\lighting_area.dm" @@ -4633,6 +4650,17 @@ #include "code\modules\mafia\roles\town\town_killing.dm" #include "code\modules\mafia\roles\town\town_protective.dm" #include "code\modules\mafia\roles\town\town_support.dm" +#include "code\modules\manufactorio\_manufacturing.dm" +#include "code\modules\manufactorio\machines\crafter.dm" +#include "code\modules\manufactorio\machines\crusher.dm" +#include "code\modules\manufactorio\machines\debug.dm" +#include "code\modules\manufactorio\machines\lathe.dm" +#include "code\modules\manufactorio\machines\router.dm" +#include "code\modules\manufactorio\machines\smelter.dm" +#include "code\modules\manufactorio\machines\sorter.dm" +#include "code\modules\manufactorio\machines\sorter_filters.dm" +#include "code\modules\manufactorio\machines\storagebox.dm" +#include "code\modules\manufactorio\machines\unloader.dm" #include "code\modules\mapfluff\centcom\nuke_ops.dm" #include "code\modules\mapfluff\ruins\generic.dm" #include "code\modules\mapfluff\ruins\lavaland_ruin_code.dm" @@ -4663,6 +4691,7 @@ #include "code\modules\mapfluff\ruins\spaceruin_code\bigderelict1.dm" #include "code\modules\mapfluff\ruins\spaceruin_code\caravanambush.dm" #include "code\modules\mapfluff\ruins\spaceruin_code\clericsden.dm" +#include "code\modules\mapfluff\ruins\spaceruin_code\commsbuoy.dm" #include "code\modules\mapfluff\ruins\spaceruin_code\crashedclownship.dm" #include "code\modules\mapfluff\ruins\spaceruin_code\crashedship.dm" #include "code\modules\mapfluff\ruins\spaceruin_code\cyborgmothership.dm" @@ -4991,6 +5020,7 @@ #include "code\modules\mob\living\basic\pets\fox.dm" #include "code\modules\mob\living\basic\pets\penguin.dm" #include "code\modules\mob\living\basic\pets\pet.dm" +#include "code\modules\mob\living\basic\pets\pet_designer.dm" #include "code\modules\mob\living\basic\pets\sloth.dm" #include "code\modules\mob\living\basic\pets\cat\bread_cat_ai.dm" #include "code\modules\mob\living\basic\pets\cat\cat.dm" @@ -5527,6 +5557,7 @@ #include "code\modules\power\powernet.dm" #include "code\modules\power\rtg.dm" #include "code\modules\power\smes.dm" +#include "code\modules\power\smes_portable.dm" #include "code\modules\power\solar.dm" #include "code\modules\power\terminal.dm" #include "code\modules\power\thermoelectric_generator.dm" @@ -5696,10 +5727,10 @@ #include "code\modules\projectiles\projectile\special\ion.dm" #include "code\modules\projectiles\projectile\special\meteor.dm" #include "code\modules\projectiles\projectile\special\mindflayer.dm" -#include "code\modules\projectiles\projectile\special\neurotoxin.dm" #include "code\modules\projectiles\projectile\special\plasma.dm" #include "code\modules\projectiles\projectile\special\rocket.dm" #include "code\modules\projectiles\projectile\special\saboteur.dm" +#include "code\modules\projectiles\projectile\special\spit.dm" #include "code\modules\projectiles\projectile\special\temperature.dm" #include "code\modules\projectiles\projectile\special\wormhole.dm" #include "code\modules\reagents\chem_splash.dm" @@ -5934,10 +5965,13 @@ #include "code\modules\shuttle\syndicate.dm" #include "code\modules\shuttle\white_ship.dm" #include "code\modules\shuttle\shuttle_events\_shuttle_events.dm" +#include "code\modules\shuttle\shuttle_events\blackhole.dm" #include "code\modules\shuttle\shuttle_events\carp.dm" +#include "code\modules\shuttle\shuttle_events\humans.dm" #include "code\modules\shuttle\shuttle_events\meteors.dm" #include "code\modules\shuttle\shuttle_events\misc.dm" #include "code\modules\shuttle\shuttle_events\player_controlled.dm" +#include "code\modules\shuttle\shuttle_events\projectile.dm" #include "code\modules\shuttle\shuttle_events\turbulence.dm" #include "code\modules\spatial_grid\cell_tracker.dm" #include "code\modules\spells\spell.dm" @@ -6156,6 +6190,7 @@ #include "code\modules\tgui\states\observer.dm" #include "code\modules\tgui\states\physical.dm" #include "code\modules\tgui\states\self.dm" +#include "code\modules\tgui\states\standing.dm" #include "code\modules\tgui\states\zlevel.dm" #include "code\modules\tgui_input\alert.dm" #include "code\modules\tgui_input\checkboxes.dm" diff --git a/tgui/packages/tgui-say/TguiSay.tsx b/tgui/packages/tgui-say/TguiSay.tsx index fbee44f00f9e2..c06e72405d4f1 100644 --- a/tgui/packages/tgui-say/TguiSay.tsx +++ b/tgui/packages/tgui-say/TguiSay.tsx @@ -206,7 +206,8 @@ export class TguiSay extends Component<{}, State> { // Is it a valid prefix? const prefix = typed .slice(0, 3) - ?.toLowerCase() as keyof typeof RADIO_PREFIXES; + ?.toLowerCase() + ?.replace('.', ':') as keyof typeof RADIO_PREFIXES; if (!RADIO_PREFIXES[prefix] || prefix === this.currentPrefix) { return; } diff --git a/tgui/packages/tgui/interfaces/Changelog.jsx b/tgui/packages/tgui/interfaces/Changelog.jsx index 7c1ed8b933c47..9d5bc3c70b8fb 100644 --- a/tgui/packages/tgui/interfaces/Changelog.jsx +++ b/tgui/packages/tgui/interfaces/Changelog.jsx @@ -37,6 +37,7 @@ const icons = { soundadd: { icon: 'tg-sound-plus', color: 'green' }, sounddel: { icon: 'tg-sound-minus', color: 'red' }, spellcheck: { icon: 'spell-check', color: 'green' }, + map: { icon: 'map', color: 'green' }, tgs: { icon: 'toolbox', color: 'purple' }, tweak: { icon: 'wrench', color: 'green' }, unknown: { icon: 'info-circle', color: 'label' }, diff --git a/tgui/packages/tgui/interfaces/FishAnalyzer.tsx b/tgui/packages/tgui/interfaces/FishAnalyzer.tsx index 171a22ed281f9..357434c129fcb 100644 --- a/tgui/packages/tgui/interfaces/FishAnalyzer.tsx +++ b/tgui/packages/tgui/interfaces/FishAnalyzer.tsx @@ -216,7 +216,7 @@ const FishItem = (props) => { Hunger:{' '} ; @@ -27,8 +34,8 @@ export function IconDisplay(props: Props) { fallback={fallback} icon={icon} icon_state={icon_state} - height={3} - width={3} + height={height} + width={width} /> ); } diff --git a/tgui/packages/tgui/interfaces/LootPanel/LootBox.tsx b/tgui/packages/tgui/interfaces/LootPanel/LootBox.tsx index 3fb94324b6a2b..b4fafcf57036c 100644 --- a/tgui/packages/tgui/interfaces/LootPanel/LootBox.tsx +++ b/tgui/packages/tgui/interfaces/LootPanel/LootBox.tsx @@ -56,7 +56,7 @@ export function LootBox(props: Props) { }); }} > - + {amount > 1 &&
{amount}
} {!is_blind && {name}} diff --git a/tgui/packages/tgui/interfaces/ManufacturingSorter.tsx b/tgui/packages/tgui/interfaces/ManufacturingSorter.tsx new file mode 100644 index 0000000000000..9ae38a3e5b616 --- /dev/null +++ b/tgui/packages/tgui/interfaces/ManufacturingSorter.tsx @@ -0,0 +1,113 @@ +import { BooleanLike } from 'common/react'; + +import { useBackend } from '../backend'; +import { Box, Button, Icon, LabeledList, Section, Stack } from '../components'; +import { Window } from '../layouts'; + +type Data = { + filters: Filter[]; + unmet_dir: number; +}; + +function dir2icon(dir) { + switch (dir) { + case 1: + return 'arrow-up'; + case 2: + return 'arrow-down'; + case 4: + return 'arrow-right'; + case 8: + return 'arrow-left'; + default: + return 'arrow-up'; + } +} + +type Filter = { + name: string; + ref: string; + inverted: BooleanLike; + dir: number; +}; + +export function ManufacturingSorter(props) { + const { act, data } = useBackend(); + const { filters, unmet_dir } = data; + + return ( + + + + +
act('new_filter')} + > + New filter + + } + > + + {filters.map((filter, i) => ( + + + + + + + + ))} + +
+
+ + + + If no criteria is met, outputting to: + + + + + + +
+
+
+ ); +} diff --git a/tgui/packages/tgui/interfaces/PaperSheet.tsx b/tgui/packages/tgui/interfaces/PaperSheet.tsx index 5c45877c68634..50dd73a88ed86 100644 --- a/tgui/packages/tgui/interfaces/PaperSheet.tsx +++ b/tgui/packages/tgui/interfaces/PaperSheet.tsx @@ -390,7 +390,7 @@ export class PrimaryView extends Component { bold={useBold} height="100%" backgroundColor={paper_color} - onChange={(e, text) => { + onInput={(e, text) => { setTextAreaText(text); if (this.scrollableRef.current) { diff --git a/tgui/packages/tgui/interfaces/PetBuilder.tsx b/tgui/packages/tgui/interfaces/PetBuilder.tsx new file mode 100644 index 0000000000000..289281ade7f73 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PetBuilder.tsx @@ -0,0 +1,431 @@ +import { useState } from 'react'; + +import { useBackend } from '../backend'; +import { + Box, + Button, + Dropdown, + Flex, + Icon, + Image, + Input, + LabeledList, + Section, + Stack, +} from '../components'; +import { Window } from '../layouts'; +import { IconDisplay } from './LootPanel/IconDisplay'; +type Data = { + pet_name: string | null; + pet_specie: string; + pet_path: string; + pet_gender: string; + pet_types: string[]; + pet_trick_name: string; + pet_options: PetOptions[]; + pet_carrier: string; + carrier_options: CarrierOptions[]; + pet_possible_emotes: String[]; +}; + +enum PetGender { + male = 'male', + female = 'female', + neuter = 'neuter', +} + +type CarrierOptions = { + carrier_color: string; + carrier_icon: string; +}; + +type PetOptions = { + pet_specie: string; + pet_name: string; + pet_icon: string; + pet_path: string; + pet_icon_state: string; +}; + +const RetrievePet = (pet_path: string, pet_options: PetOptions[]) => { + return pet_options.find((option) => option.pet_path === pet_path); +}; + +const RetrieveCarrier = (color: string, carrier_options: CarrierOptions[]) => { + return carrier_options.find((option) => option.carrier_color === color); +}; + +const FilterPetList = (pet_specie: string, pet_options: PetOptions[]) => { + return pet_options.filter((pet) => pet.pet_specie === pet_specie); +}; + +export const PetBuilder = (props) => { + const { act, data } = useBackend(); + const { + pet_name, + pet_path, + pet_gender, + pet_options, + pet_types, + pet_specie, + pet_trick_name, + carrier_options, + pet_carrier, + pet_possible_emotes, + } = data; + + const [selectedCarrier, setSelectedCarrier] = useState( + () => RetrieveCarrier(pet_carrier, carrier_options) || null, + ); + const [sequences, setSequences] = useState(['none', 'none', 'none']); + const [TrickName, setTrickName] = useState(pet_trick_name); + + const UpdateSequence = (Index: number, Trick: string) => { + const NewSequence = [...sequences]; + NewSequence[Index] = Trick; + setSequences(NewSequence); + }; + + const [selectedPath, setSelectedPath] = useState(pet_path); + const [selectedPet, setSelectedPet] = useState( + () => RetrievePet(selectedPath, pet_options) || null, + ); + const [selectedSpecie, setSelectedSpecie] = useState(pet_specie); + const [filteredPetList, setFilteredPetList] = useState( + () => FilterPetList(selectedSpecie, pet_options) || [], + ); + const [selectedName, setSelectedName] = useState(pet_name); + const [selectedGender, setSelectedGender] = useState(pet_gender); + + const ScrollPetSpecies = (direction: string) => { + let dir = direction === 'next' ? 1 : -1; + let currindex = pet_types.indexOf(selectedSpecie); + const newSpecie = + pet_types[(currindex + dir + pet_types.length) % pet_types.length]; + + const newFilteredPetList = FilterPetList(newSpecie, pet_options); + setSelectedSpecie(newSpecie); + setFilteredPetList(newFilteredPetList); + setSelectedPet(newFilteredPetList[0]); + }; + + const ScrollPetOptions = (direction: string) => { + if (!selectedPet) { + return; + } + let dir = direction === 'next' ? 1 : -1; + let currindex = filteredPetList.indexOf(selectedPet); + setSelectedPet( + filteredPetList[ + (currindex + dir + filteredPetList.length) % filteredPetList.length + ], + ); + }; + + return ( + + + + + + + + + +
+ +
+
+
+
+ +
+ + + + + + + + + +
+
+
+
+
+ ); +}; + +const PetSelector = ({ + selectedSpecie, + selectedPet, + pet_types, + ScrollPetSpecies, + ScrollPetOptions, +}: any) => ( +
+ + + + +
+); + +const PetDetails = ({ + selectedName, + setSelectedName, + selectedGender, + setSelectedGender, +}: any) => ( + + + + + Pet Name + + setSelectedName(value)} + style={{ borderRadius: '1em' }} + /> + + + + + + + + + + Pet Gender + + + +